Procedural ASCII creature art engine for games. Define a skeleton, paint it on Canvas 2D, and the rendering pipeline turns it into ASCII art with lighting, edge detection, depth extrusion, and glow effects.
Built for roguelikes, MUDs, terminal games, and anything that wants creatures made of characters.
git clone https://github.com/mokn/ascii-forge.git
cd ascii-forge
npm install
npm run devOpen http://localhost:5173 to see the creature gallery. Click any creature to open its lab page with three panels:
- Skeleton — the bone structure (circle-chain spine + limb chains)
- ASCII — the final ASCII rendering
- Painted — the raw Canvas 2D artwork that feeds the renderer
Every creature is built from three layers:
A normalized (0-1) coordinate system defines the creature's bone structure:
export const goblinSkeleton = {
spine: [
{ id: 'head', x: 0.38, y: 0.28, radius: 0.082 },
{ id: 'neck', x: 0.42, y: 0.42, radius: 0.050 },
{ id: 'chest', x: 0.46, y: 0.52, radius: 0.095 },
{ id: 'belly', x: 0.48, y: 0.62, radius: 0.098 },
{ id: 'hip', x: 0.48, y: 0.72, radius: 0.080 },
],
limbs: [
{ attach: 'chest', side: 'near', segments: [
{ x: 0.44, y: 0.48, radius: 0.034 }, // shoulder
{ x: 0.52, y: 0.36, radius: 0.024 }, // elbow
{ x: 0.64, y: 0.16, radius: 0.020 }, // hand
]},
// ... more limbs
],
};The skeleton system generates smooth body outlines using tangent-hull contours and Catmull-Rom splines. Limbs are drawn as tapered chains with joint circles.
A drawCreatureClean(ctx, skeleton, w, h) function paints the creature on Canvas 2D using the skeleton coordinates. This is where the creature's visual identity lives — colors, textures, details, weapons.
The renderer (src/core/ascii-renderer.js) takes any Canvas 2D drawing and converts it to ASCII:
- Samples the painted canvas into a character grid
- Maps brightness to a character palette (
.,:;*+!=?#@) - Detects edges and uses directional edge characters (
-/|\) - Applies depth extrusion for 3D layering
- Adds glow effects around bright elements
- Fills background with subtle color tinting
Run npm run dev and explore the included creatures:
| Creature | Type | Pose | Key Features |
|---|---|---|---|
| Dire Rat | Quadruped | Crouched | Fur texture, glowing red-orange eyes, whiskers |
| Goblin | Humanoid | Axe overhead | Oversized head, huge pointed ears, pot belly |
| Kobold | Reptilian | Spear thrust | Digitigrade legs, horns, tail, scale texture |
| Skeleton | Undead | Sword raised | Ribcage, skull with brow ridge, exposed spine |
See docs/PIPELINE.md for the full creation pipeline, including design rules, color guidelines, pose vocabulary, and iteration gotchas.
The short version:
- Create
src/creatures/yourmonster/yourmonster.html— clone any existing creature's HTML - Create
src/creatures/yourmonster/yourmonster.js— define skeleton + render function + harness - Run
npm run devand open your creature's page - Iterate — the dev server hot-reloads on save
- Face LEFT. All creatures face toward the left edge of the canvas.
- Action pose. Mid-swing, lunging, crouching — never standing idle.
- Paint dark. Base body colors at 10-20% brightness. The renderer applies a 1.8x brightness boost.
- Accents pop. Eyes, teeth, claws at 80-100% brightness. Eyes are always the brightest element.
- Identity features. What makes this creature visually distinct from a generic humanoid? Ribcage for a skeleton, huge ears for a goblin, horns for a kobold. Spend most of your render function on these.
The pipeline doc (docs/PIPELINE.md) is written for AI agents (Claude, Codex, etc.) to create creatures autonomously. It includes:
- Step-by-step process with screenshot verification loop
- Pose vocabulary (limb position vs weapon direction vs body lean)
- Color/contrast rules calibrated for the ASCII renderer
- 7 specific iteration gotchas learned from building the included creatures
src/
core/
ascii-renderer.js # Canvas 2D → ASCII pipeline
skeleton-system.js # Body outline, limb chains, contour generation
drawing-helpers.js # Gradients, textures, AO, organic shapes
creatures/
{name}/
{name}.js # Skeleton def + render function + harness
{name}.html # Creature lab page (3-panel view)
renderAscii(ctx, drawFn, x, y, w, h, opts) — Renders any Canvas 2D drawing function as ASCII art.
drawBodyOutline(ctx, spine, w, h, fillStyle) — Generates a smooth body outline from spine circle-chain.
drawLimbChain(ctx, segments, w, h, color) — Draws a tapered limb from joint chain.
drawTail(ctx, points, startWidth, endWidth, w, h, color) — Draws a tapered tail along a point path.
ASCII rendering approach inspired by pretext by Cheng Lou.
Built for Ultimate Dominion, an on-chain RPG.
MIT

