At the time of writing, the engine is just a little baby. A lot is going to change, but the goal is to be as close to Pico-8 as possible; in terms of how it feels to use. With that said, here is a brief description of the methods you can expect to use:

cls(color = 0)

This is used to clear the screen. The most common time to do this is at the beginning of the draw function.

expose()

This causes most of the Engine functions to be available in the global scope. This is great for teaching newcomers, but some folks understandably don't want a bunch of new global functions, so it is opt-in.

preload(url)

You can use this in place of a sprite or sound definition, so that the same data is loaded from a URL instead. This is useful if you have another application which generates these in a friendly manner than hard-coding arrays; or if you want other folks to be able to contribute those without working in the same codebase.

start({ ... })

I talk much about this in Getting started , but here is where you plug the various bits of your game into the engine. You must call this will at least a draw function and sprites and sounds objects. Other common things include init , update , target , and background .

stop()

Use this when you want to stop the Engine from updating or drawing anything. I use it on the floaty website to stop one game when another one starts, but it would also be good for mini-games in modals or easter-eggs.

line(x1, y1, x2, y2, color = 7)

This will draw a line starting at x1 ,y1 to x2 ,y2 .

linePixels(x1, y1, x2, y2)

Sometimes you might want to draw more complex shapes than the ones supported by floaty . If you need the points that floaty would draw for a line, but don't want the line draw then this function is for you!

rect(x1, y1, x2, y2, color = 7)

This draws an unfilled rectangle from x1 ,y1 to x2 ,y2 . It does not use the linePixels method, so none of the built-in processing there is applied to the side of this rectangle.

rectPixels(x1, y1, x2, y2)

When you want to draw more complex shapes, and need rectangle pixels without drawing rectangles; you can use this method to tell you where the pixels would have been drawn.

rectFill(x1, y1, x2, y2, color = 7)

This does the same thing as rect , except that the rectangle is filled instead of just an outline.

rectFillPixels(x1, y1, x2, y2)

This does the same thing as rectPixels , including the all the pixels of the filled rectangle.

circ(x, y, radius, color = 7, thickness = 1)

This will draw an unfilled circle with the center on x ,y . Pico-8 doesn't have the concept of circle thickness, but I decided to add it because of how the unfilled circle drawing happens.

Under the hood, I draw a circle at radius , and then I subtract all the pixels in a filled circle at radius - 1 . This means a circle will never exceed radius , no matter how big you set thickness .

circPixels(x, y, radius, thickness = 1)

When you want to draw more complex shapes, and need circle pixels without drawing circles; you can use this method to tell you where the pixels would have been drawn.

circFill(x, y, radius, color = 7)

This does the same thing as circ , except that the circle is filled instead of just an outline.

circFillPixels(x, y, radius)

This does the same thing as circPixels , including the all the pixels of the filled circle.

sfx(key)

This plays a sound from the sounds variable you provide to start() .

removeDuplicatePixels(pixels)

This takes an array of pixel arrays and removes the duplicate pixels defined therein. This is useful for performance, when you're drawing shapes that have repeated pixels:

var pixels = [
    [0,1],
    [0,2],
    [0,3],
    [0,1],
];

pixels = engine.removeDuplicatePixels(pixels);

// pixels = [
//    [0,1],
//    [0,2],
//    [0,3],
// ];
removeCornerPixels(pixels)

This also takes an array of pixel arrays, but it tries to remove extra corner pixels; to make lines look cleaner:

var pixels = [
    [0,0],
    [1,0],
    [1,1],
    [2,1],
    [2,2],
];

pixels = engine.removeCornerPixels(pixels);

// pixels = [
//    [0,0],
//    [1,1],
//    [2,2],
// ];
pget(x, y)

This gets the color for the pixel at x ,y .

pset(x, y, color = 0)

This gets the color for the pixel as x ,y .

flipX(pixels, w = 8, h = 8)

This takes an array of pixel arrays and flips them horizontally. The w and h values are in pixels. If you're flipping a 8x8 sprite (the default) then you don't need to specify w or h . If you're flipping a custom shape or larger sprite then you need to adjust these values.

flipY(pixels, w = 8, h = 8)

This takes an array of pixel arrays and flips them vertically.

spr(key, x, y, w = 1, h = 1, flipX = false, flipY = false)

This fetches the pixels of a sprite from the sprites object and performs various optional transformations on it. The w and y are the number of tiles the sprite is wide and high. Since the default tile width is 8, w = 2 means the sprite definition has rows of 16 pixels.

fget(key, flag)

This fetches the flag value for a sprite. If the first flag is enabled fget('ground', 0) will return true.

fset(key, flag, value)

This overrides the flag value for a sprite, so that fget will return the new value instead of what is set initially in the sprite.

text(text, x, y, color = 7)

This draws pixelated text to the x ,y coordinates. The font is from Kenney , and is approximately 8 pixels tall.

btn([key])

This returns true /false depending on whether the button is being pressed. key is whatever is supported in a browser . If no key is provided, this will return true if any key is pressed.

btnp([key])

This returns true /false depending on whether the button was just pressed. Just pressed means it was pressed but hasn't been checked yet. Once checked, the key will not return true until it is pressed again. key is also optional with this method. If it is not provided, true will be returned when any key was just pressed.

pal([target, source])

This swaps the target color with another:

engine.pal(0, 7);
engine.pset(16, 16, 0);

This will change the color at 0 to the color at 7 . 7 will still be the same color. If you call it without arguments, the palette colors will be reset. This is really useful when you want to change the colors a sprite is drawn in without modifying the sprite:

for (var i = 0; i < 15; i++) {
    engine.pal(i, 7);
}

engine.spr('enemy');

engine.pal();

The 'enemy' sprite will appear white. Subsequent sprites and shapes will be drawn in their intended colors.

randomFloat()

This returns a random number between 0 and 1 .

randomIntegerBetween(min, max)

This returns a random integer between a min and max .

randomFloatBetween(min, max)

Same as randomIntegerBetween() but for floats.

rnd(limit = 1)

An easier function to use than randomFloatBetween that returns a random float between 0 and 1 .

circlesCollide(a, b)

Given two arrays of [x, y, radius] , this function tells whether they collide.

boxesCollide(a, b)

Given two arrays of [leftX, topY, rightX, bottomY] , this function tells whether they collide.

preload(url)

This creates a Preloader instance for the URL, so that it can be loaded at the beginning of the game. Useful for loading sprites and sounds from other places.

async load

This loads all the Preloader instances in sprites and sounds . You probably want to do this in the init function, and you also probably want to await it before you try to use any of the assets. You can mix and match formats, if you have to use assets before loading is finished:

var sounds = {
    'before-loading': [
        1,
        [40, 0.8, 2],
        [40, 0.8, 2],
        [40, 0.8, 2],
        [40, 0.8, 2],
        [30, 0.8, 2],
        [20, 0.8, 2],
        [10, 0.8, 2],
        [10, 0.8, 2],
        [10, 0.8, 2],
        [10, 0.8, 2],
    ],
    'after-loading': preload('https://example.com/after-loading'),
};

async function init() {
    // do things before loading...

    await this.load();

    // do things with the loaded assets...
}

engine.start({
    // ...
    init,
});
floaty is developed by assertchris as part of sandcastle.games