What it does
You ask for a kind of surface, such as panel, door, brick, light or lava, and retroTexture returns its
pixels. It paints them the way artists of the period did: every material uses one ramp of eight shades from
near-black to a highlight, flat areas carry a scattered one-shade grain so they never look flat, raised shapes get a
bright one-pixel edge on the top and left and a dark one on the bottom and right, and panels have cut corners and
rivets. Bricks and stones have rough, chipped edges in darker mortar and the odd crack. Because everything that
crosses an edge wraps round, every texture tiles on both axes.
Every texture also carries a height map, with seams and mortar low and rivet heads highest, and an emissive mask that
is lit only on lamps, screens, lit buttons, slime and lava. normalMap turns the heights into a tangent-space normal
map, so a lit 3D renderer can bump the surface and make its lights glow while a flat raycaster just uses the colours.
Slime, ooze, lava and water are animated: a strip of frames that loops cleanly, with blobs that swirl and catch the light, cracks of white-hot lava between drifting crust, and bright caustic lines on water. Generation is pure and seeded, with no clock and no unseeded randomness, so the same spec gives the same bytes on every machine and a game can rebuild its textures rather than ship them.
Features
- 32 kinds of surface — panels, tech walls, supports, doors, door trim, lights, crates, consoles, switches, vents, grates, pipes, girders, metal floor plate, hazard stripes, brick, stone, cobbles, concrete, tiles, marble, rock, wood, grass, window glass, fabric, plaster, server racks, slime, ooze, lava and water.
- Offices as well as bases — see-through glass (clear, frosted, wired, grimy, cracked, or a door with a push bar), carpets, runners and buttoned leather, painted walls with skirting and dado, suspended ceilings, and server racks whose lights blink.
- Period pixel-art look — eight-shade ramps, dithered grain, one-pixel bevels lit from the top left, chamfers, rivets, chipped edges and cracks.
- 28 built-in palettes — steel, gunmetal, lab white, stone, brick, rust, hazard, toxic green, lava, water, brass, alien purple, glass, carpet, leather and more, chosen to sit together in one level; or pass any CSS colours, dark to light.
- Variants and options — four layouts for most kinds, and options for counts, sizes, seams, wear, rust, moss,
states and styles, each documented with its range in
retroKinds. - Tiling on both axes — noise, mortar, stripes and shapes wrap at every edge, at any size from 16 to 256 pixels, square or not.
- Height, glow and normal maps — a height map and an emissive mask with every texture, and
normalMapfor lit renderers in either the OpenGL or DirectX convention. - Looping animation — liquids come as a strip of frames that loops without a jump, drifting by whole tiles if you ask them to flow.
- Themes for any surface name — tech base, industrial, castle, neon arena, crypt and office recipes by name, and a resolver
that guesses the rest from the words, so a level's
door-redorslime-pitgets a fitting texture unasked. - Two states for switches — the same switch on and off, with its lamps lit to match.
- Headless and deterministic — plain arrays out, no canvas needed;
paintRetroTextureputs a frame on a canvas when there is one.
Good for
- A corridor or sector shooter — tech bases, keyed doors, switches, nukage pools and lava without an art budget.
- A dungeon crawler — brick, mossy stone, cobbles, wood and torch-lit lamps from one palette set.
- A retro mode for a 3D game — the textures with their normal maps on real meshes keep the period look under modern lighting.
- Game jams and prototypes — a whole level of consistent textures in minutes, replaced with painted art later or never.
- Top-down games — grass, cobbles, floor plate, tiles and water tile just as well seen from above.
- Tools and editors —
retroKindslists every kind, variant and option, so a level editor can offer them as pickers.
Make it yours
Every kind takes a seed, a size or a width and height, a palette and an accent ramp, a variant and its own options. Bricks take courses, bricks per course, offset, mortar width and shade, roughness and cracks; panels take columns, rows, chamfers, rivets and grime; doors take a straight or stepped seam, a split, recessed panels, ribs, windows and a key-coloured stripe; lights take a grid, a shape and an on or off state. One wall might be a single riveted steel plate at 64 pixels; another a 128 by 256 door split top and bottom with a blue key stripe; a third a pale old brick in a custom ochre ramp with heavy cracks. Grates and girders can be see-through, and liquids take their blob size, swirl, drift and number of bubbles.
A quick look
Make a wall and a looping slime, then hand them to a raycast view or paint them into the atlas.
const wall = retroTexture({ kind: 'panel', size: 64, seed: 3, variant: 'quad' });
const slime = retroTexture({ kind: 'slime', frames: 8 });
view.texturePixels('wall', wall.width, wall.height, wall.rgba, wall.frames);
game.paint('slime', slime.width, slime.height, (ctx, f) => paintRetroTexture(ctx, slime, f), { frames: slime.frames });
const normals = normalMap(wall, { strength: 2 });
Works with
raycast-view— takes a texture's strip as it is, frames and all.world-3d— put the colours, normal map and glow mask on meshes for a lit retro scene.cell-dungeonandsector-map— the maps whose walls, floors and doors these textures dress.
Good to know
- It makes surfaces, not sprites or characters; paint those with the engine's own painting calls.
- Textures are 16 to 256 pixels a side, in multiples of 8; below 32 the finest details shrink away.
- Generation takes a few milliseconds for a still texture at 64 pixels and much longer for large animated ones, so make textures at start or between levels, not every frame.
- The look is fixed to light from the top left; for other lighting use the normal map in a lit renderer.






