Code-drawn expressive characters: research notes (2026-09-14)
Three Sonnet research passes, condensed by Fable. Question: how do 2D indie games make a small character's states (grab, hang, wall slide, rope, crouch, jump, hurt) readable without hand-drawn frames? Our size: 14x19 px hitbox, 24 px tiles, 640x360 canvas (about 1/15 of the screen height, the same fraction as Pikuniku).
Shape-built characters, by game
- Pikuniku — an oval body with two dot eyes and two long posable legs, NO arms. Every state is a leg pose: walk, kick, roll (legs retracted), lasso (one leg taut to an anchor). No hang/wall states exist in that game. https://en.wikipedia.org/wiki/Pikuniku
- BoxBoy! (Qbby) — a square, two dot eyes (the devs say the eyes exist only to show facing), two thin legs, NO arms. Hanging/climbing is done by a generated box chain, not a limb: the game avoids the arm pose entirely. https://www.hallab.co.jp/eng/creative/story/prj001/
- CommanderVideo (Bit.Trip Runner) — a black rectangle torso, stick arms and legs, a white visor as the face. Run/jump/slide/kick are limb-angle changes on a fixed torso. A bendier 3D version was tried for Runner2 and REJECTED for the rigid-rectangle + stick-limb read.
- N / N++ ninja — a vector stick figure over a 6-particle + 5-stick physics body; wall slide, wall jump and ledge states all read on a stick figure. The closest existing "code character with Spelunky-shaped wall states". Whether live poses are procedural or vector key frames is unconfirmed. https://www.metanetsoftware.com/2014/n-development-update
- Rain World's slugcat — two circles locked at a distance = the body; limbs and tail are cosmetic, procedurally driven from input and physics, hands REACH for grab points (poles, ledges). No sprite sheet. GDC 2016 "Animation Bootcamp: Rainworld Animation Process". https://www.gdcvault.com/play/1023475/
- Thomas Was Alone — rectangles only; jump/fall/land carried by squash and stretch alone. Cannot carry hang/wall/crouch: those need visible contact.
- Stick Fight — ragdoll stick figures; great for chaos, poor for held poses.
Common construction: one core mass (carries weight, squash, orientation) + two legs; arms are usually omitted because those games have no grab states. Eyes are 1-2 dots. The head is never a separately hinged part.
Tiny sprites that carry many states
- Spelunky Classic: 16x16 spelunker. Crouch = half height; hang = both arms straight up on the corner, body below the surface line; rope = hands alternating above the head, body centered on the rope; jump = one held launch frame; hurt = a tilt; dead = splayed/ragdoll. 1-4 frames per state.
- Celeste Classic (Pico-8): 8x8 Madeline, SEVEN sprites total (idle, 4-step
run, one shared jump/fall, wall cling, crouch, look up). The hair is a chain of
five circles each easing toward the one before it:
h.x += (last.x - h.x)/1.5, radius tapering; it streams under velocity for free. https://gist.github.com/sherjilozair/0663956e065e9588fd3ab5c36f77575c - Kenta Cho, crisp-game-lib
char(): characters are ~6x6 text-art glyphs in code, letters = colors, two glyphs toggled on a timer = the whole animation. https://abagames.github.io/crisp-game-lib/ref_document/functions/char.html - Mega Man X is where the wall-cling pose enters the canon: body flat to the wall, legs bent, one arm braced. Mario NES: crouch = half-height rectangle.
- Principles (Derek Yu's tutorial, Saint11, Pixel Logic): silhouette first, 1-2 frames per state, exaggerate the defining pose, let code carry secondary motion.
State -> cue: crouch = half height, head low; hang = arms straight up, body below the corner; wall slide = body on the wall, one hand braced, legs bent; rope = hands alternating above the head; jump = one held pose; fall = looser jump; hurt = tilt; dead = horizontal or ragdoll.
Procedural technique
- David Rosen, "An Indie Approach to Procedural Animation" (GDC 2014): a few authored key poses; movement state selects them; phase from distance travelled, not time; mirror one side; physics secondary motion layered after. https://www.gdcvault.com/play/1020583/
- Rain World: body = point chain with distance constraints; limbs reach for grab targets (IK); always settling, never frozen.
- Two-bone IK (Alan Zucconi): law of cosines gives the knee/elbow from root, target and the two segment lengths; the bend side is a fixed sign per limb; out of reach = fully extended. https://www.alanzucconi.com/2018/05/02/ik-2d-1/
- Stepping (Little Polygon "Procedural Animation: Locomotion"): feet stay planted; when a foot's error to its ideal spot under the moving body exceeds a threshold it releases and arcs to a new spot projected ahead by velocity; feet are phase-offset by half a cycle. https://blog.littlepolygon.com/posts/loco1/
- Damped springs (Ryan Juckett): every animated quantity chases its target through a spring, so a state change animates itself; underdamped for landing bounce, critically damped for limb tracking. https://www.ryanjuckett.com/damped-springs/
- Gibbon: Beyond the Trees: a 2-point rig (hand + centre of mass) decides the grab; the hand's reach direction is chosen relative to velocity. https://www.gamedeveloper.com/programming/deep-dive-physics-based-animation-in-gibbon-beyond-the-trees
Recommended order per tick: state -> pose select -> blend -> springs -> grab overrides (hands to real world points, IK) -> idle drift -> squash/lean -> secondary chains.