Pixel art as code
pxl is a small JavaScript language for pixel art: a .px.js file declares sprites and anims as grids, shapes and patches, and pxl paints them. A game imports a pxl file the way it imports any module, and the engine’s Vite plugin paints its sheet as the page loads, so no PNG or JSON enters the game’s folder. A save to the file redraws every sprite of its sheet in place, with no reload, and each sprite carries on from its place in its clip. Read Sprites first: an imported sheet is a sprite sheet like any other.
Import a pxl file
Section titled “Import a pxl file”Keep the file under src/sprites/, such as src/sprites/pickups.px.js, and pass its import to defineSpriteSheet with the pixels per metre your camera draws at:
import { defineSpriteSheet } from "@spawnite/engine/2d";import pickups from "./pickups.px.js";
// The coin and the heart pickups.px.js draws, at 32 pixels a metre: a// Sprite's clip="coin" turns the coin, and clip="heart" holds the heart.export const pickupsSheet = defineSpriteSheet({ ...pickups, pixelsPerMetre: 32,});The import gives the sheet’s image, pxl’s JSON as data, and one clip for each sprite and anim the file names:
- An anim plays its frames with their own durations, and holds its last frame when the anim says
loop: false. - A static sprite is a clip of its one frame, which shows for 1 second when
playClipplays it once.
A clip of your own replaces the file’s of the same name: clips: { ...pickups.clips, coin: { loop: ClipLoopMode.Once } }.
Which sprites make the sheet
Section titled “Which sprites make the sheet”A file that declares one sheet() imports as that sheet, packed as pxl’s own export packs it. A file with no sheet() imports as every sprite and anim it names, in the order it names them, one pixel apart. A name that starts with _ is a part that only stamps, and a scene() stays out of the sheet. A file that declares two sheets is refused: give each sheet its own file, and share their parts through include() of a file that declares none.
Clip names are typed
Section titled “Clip names are typed”The plugin writes the import’s types beside the file, pickups.px.d.ts, so clip="coins" on a Sprite is a type error. Commit the file with the art. The dev server writes it as it starts and again on each save, and spawnite pxl types writes it without one. A build writes none, and warns of a file whose types are out of date. A created game’s typecheck and check scripts run that command first. spawnite pxl types --check writes nothing and fails when a file’s types are out of date.
Name a pxl file .px.js, never .px.ts: TypeScript reads a .px.ts file in place of the types its import is given.
When the art has a mistake
Section titled “When the art has a mistake”A mistake in the file fails its import at the file, line and column pxl names, such as an unknown colour key or an anim with too many frames. A file that takes over 10 seconds to run and draw, such as one with a loop that never ends, fails its import too. On a dev server the page shows the error over the game and keeps drawing the last sheet that built. A build stops.
A sprite named like another’s frame is refused too, such as a sprite coin_0 beside an anim coin, because both would name the same frame of the sheet.
The art is yours
Section titled “The art is yours”pxl is MIT licensed, and the engine runs a copy of it. What your file paints is your game’s art. A sheet the asset library publishes from a pxl file carries the platform license.