Steering code-generated pixel art toward a target style (Diablo II and Witchbrook as the two targets)
Scope note: Dead Cells’ 3D-to-pixel pipeline, PixelLab and Retro Diffusion features, and runtime SDF sprites are already covered in the sibling notes (sprites_characters_items.md, animation.md, styles_resolution_perspective.md). This file cites them briefly and spends its budget on the two targets, on example-based and statistical methods, on what an agent needs as input, and on IP. Sources fetched in this session are marked as fetched. Claims that come only from search-result summaries are marked “(snippet)”.
On the user’s premise (“code can put any pixel anywhere, so anything can be generated”): a 320x180 frame in 8 inks has 8^57,600 possible states, so the premise is true in principle. In practice the whole problem is specifying and checking which tiny corner of that space is “Diablo II” or “Witchbrook”. Every method below is a way to supply that specification: as geometry plus a renderer (3D, then quantize), as examples (synthesis), as numbers (statistics), as a learned prior (diffusion), or as a human’s judgment (critique loops). This framing is inference, not a cited claim.
1. Diablo II’s art pipeline (pre-rendered 3D, directions, palettes, colormaps, composite layers, lighting, tiles, the gothic look)
Takeaway
Diablo II is the textbook “model in 3D, render many angles, quantize to one 8-bit palette, recolor and light by lookup table” pipeline. 3D Studio Max rendered characters at 8 angles (monsters) or 16 (players), with armor rendered as separate parts and layered at runtime. Backgrounds were rendered rooms, lit from one fixed direction and cut into 160x80 isometric tiles. All lighting, transparency and monster recolors are 256-entry index remap tables applied to one 256-color palette per act. Almost every piece of this maps directly onto an indexed-color engine like Tycho/Ink.
Cited Findings
Primary source: Erich Schaefer’s postmortem (Game Developer, October 2000; fetched)
- “Almost all of Diablo II’s in-game and cinematic art was constructed and rendered in 3D Studio Max.” Textures and 2D interface work were mostly done in Photoshop. There were about a dozen character artists and a dozen background artists. — Schaefer, Postmortem: Diablo II, Game Developer, 2000-10-25
- “An in-house tool would render the files from many different angles (eight for all monsters, 16 for player characters)”, then export them in the game’s formats. — Schaefer 2000
- Player characters are 75 pixels tall in game, but were modeled and rendered at high resolution for the select screen and promotion. — Schaefer 2000
- Armor came in light, medium and heavy modular pieces. Artists tested combinations as “paper dolls” (on paper and in Photoshop). Each piece was rendered separately: head, torso, legs, arms, weapon, shield. — Schaefer 2000
- Monsters have 14 animation classes, and “Diablo is the only monster who uses every animation category available.” — Schaefer 2000
- Backgrounds were rendered in Max, then “cut into tiles and assembled into modular ‘rooms’ with an in-house tile-editing tool”. The engine reassembles rooms into random levels. — Schaefer 2000
- The team considered a 3D engine and voxels, then went back to 2D sprites at 640x480 in 8-bit color so it could show many characters, monsters and missiles at once. Its stated goals included “true transparency, colored light sources, and a quasi-3D perspective mode.” — Schaefer 2000
- What went wrong: the tools did not run inside the engine, so artists could not preview monsters in their settings. Art was sometimes redone months later; the Bone Helmet was remade “more than a year after having rendered them”. — Schaefer 2000
- The postmortem gives no render settings (lights, anti-aliasing, render size, downscale method) and no palette or gamma detail.
Artist recollections (Shacknews oral history; fetched)
- Max Schaefer first used StrataVision on a Mac, which “could take up to twenty hours to render images” and had no camera for the isometric view. Dave Glenn’s side-by-side test (“I can do this in thirty seconds while Strata takes twenty hours”) moved the team to 3D Studio Max. — Shacknews, How Diablo 2 evolved from gothic horror to epic fantasy
- Environment artists built rooms, baked lighting from one direction so shadows matched, rendered them, then cut them into tiles in Photoshop. Glenn introduced “set pieces” (pre-arranged tile groups such as statues and tapestries) that the level generator places whole. Ben Boos painted tiles and set pieces (palms, oases, dirt-smudged ground). — Shacknews
- Roles: Max Schaefer, background art director; Erich Schaefer, over the character artists; Phil Shenk, lead character artist (animated fire, including Blaze); Michio Okamura, illustrator and earlier lead; Kris Renkewitz (Andariel; “It’s about the silhouette the character makes on the game”); Mike Dashow (Sorceress and her armor sprite system). — Shacknews
- On the “gothic” look: Dave Brevik, “The reason that Diablo II doesn’t feel as dark and gothic is because it’s set outdoors”; Erich Schaefer said the team “recognize[d] that we were losing the first game’s scarier elements”, and attempts to bring back the first game’s atmosphere “tended to make the game slower”. Okamura said much of Diablo I’s style came from “technological limitations and resource limitations”. Kelly Johnson recalled night play when “you could only see a few feet in front of your character.” The article itself calls D2 “more colorful than the original” with “Glaringly bright deserts. Lush pastures.” — Shacknews
- Max Schaefer and Matt Uelmen (to IGN, as reported) said D2 was not truly 3D: everything was rendered sprites. — Wccftech (snippet)
Palettes and lookup tables (modding docs)
- One global palette per act, stored as
pal.dat(256 colors, 768 bytes, BGR) andpal.pl2under the global palette folder; the Act 5 files in d2data.mpq are outdated (the expansion updated them). DC6 frames are paletted and carry no palette of their own. — Phrozen Keep: Items and the palette; OpenDiablo2/dc6 (snippets) - The PL2 file is the palette plus precomputed 256-byte index remaps (fetched): 32 “dark-to-mid light levels”, 16 “mid-to-bright light levels”, 3x256 alpha-blend tables (25%, 50%, 75% against each palette color), 256 additive, 256 multiply, 256 “max component” blend tables, 111 “color variations”, single red, green and blue tone tables, a “darkened color shift”, plus a text palette and 14 text color shifts. — OpenDiablo2/pl2 README
- Colormaps (
.datfiles) let one animation be “declined into several color sets”. In COF-driven monsters, the monster’s token in MonStats.txt names the folder holdingPalShift.dat; colormaps can be applied per layer (e.g.,med:grey.dat:4). The MonStats “TransLvl” column picks the palshift entry. — Phrozen Keep: merging multi-part DCC; Scribd MonStats guide (snippets) - Erich Schaefer is reported as saying there were over 60 unique monster models, usually with three to four palette shifts each. This is secondhand (a community wiki), not the postmortem. — Diablo Wiki, Monsters archive (snippet)
Composite sprites (DCC/DC6/COF)
- A modern editor composites “all COF layers in draw order” and applies draw effects; layers carry armor-type codes (LIT/MED/HVY) and weapon codes. DCC limits each 4x4 pixel cell to 4 colors; the editor flags offending cells and reduces them on export. Item tints use the item’s InvTrans colormap plus the unique or set color. — pd2-sprite-studio README (fetched)
- That editor also exposes a local MCP server with 31 tools (sprite search, palette lookups, drawing, recolors, HSV shifts, outline and cleanup, Tile Maker) so an AI agent such as Claude Code can drive it. — pd2-sprite-studio
- Known community layer codes (HD, TR, LG, RA, LA, RH, LH, SH, S1–S8) and per-direction draw order are documented in Paul Siramy’s “Extracting Diablo II Animations”, but the PDF could not be fetched in this session. — Siramy PDF (unreachable)
Tiles, walls, light radius
- DT1 floor and wall tiles are 160x80 px (a 2:1 isometric diamond). Walls split along grid lines into orientation 1 (left) and 2 (right); lower walls use 16/17 and are drawn before floors; roofs use 15. — pd2-sprite-studio
- Wall orientation also decides how light affects a tile. Walls fade when the character is behind a high wall, and only when the walls are connected in one “chain”; tight mazes sometimes fail to fade. Values are community findings, not Blizzard docs. — Phrozen Keep: light radius in new DT1; Phrozen Keep KB: Advanced DT1; Wall transparency “secret” (snippets)
- Player light radius: base 13, maximum 18 (community wiki). — Diablo Wiki: Light Radius (snippet)
Diablo II: Resurrected (old versus new)
- D2R puts new 3D models over the original sprite simulation and lets the player toggle the legacy look; “under the hood, all of the logic and the simulation is still being run by sprites” (Gallerani to Eurogamer, as reported). — Wikipedia: D2R; PC Gamer hands-on (snippets)
- Executive producer Rod Ferguson said the lost original art assets were not essential because the team remade “every single asset”. — PC Gamer (snippet)
Inferences
- The “D2 recipe” for Tycho, all of it buildable in plain JS and fitting
Ink’s palette-index model: (1) one palette per world (D2’s per act); (2) a precomputed light table: index x level -> index (D2 uses 48 levels; Elsewhere’s 8 inks need only 4 to 8), so lighting a pixel is one array lookup and the palette limit stays real; (3) translucency as a 2D tableblend[a][b] -> index(D2’s 25/50/75% tables); (4) monster variants as 256-entry remaps (colormaps), i.e., one drawn sprite yields 3 to 4 “species”; (5) part layers (head, torso, legs, arms, weapon, shield) drawn in a per-direction order, each with its own remap; (6) floors as 2:1 diamonds lit from one fixed direction, walls split into left and right faces so a wall near the hero can be faded or cut. Elsewhere already uses a 2:1 grid, which is D2’s tile ratio (160x80). - Light radius in a D2-like view is a per-tile light level (distance from the hero, clamped by radius) fed through the light table. That gives the “you see a few feet around you” mood with no blending and no extra inks.
- Render settings for the original are undocumented, but the visible traits of D2 sprites (soft internal shading, no drawn outline, about 75 px characters; a measured player sheet in d2_sprite_sheet_study.md shows the edge is no darker than the body, so there is no dark rim either) are what you get from a lit 3D render quantized to a shared 256-color palette, not from hand-pixel rules. A code agent imitating D2 should therefore render (SDF or mesh, one key light from upper left, a dim fill, no outline pass) and quantize to an extracted D2-like palette, rather than draw with pixel-art cluster rules. This is a reasoned reading, not a documented fact.
- The DCC rule “at most 4 colors per 4x4 cell” is a measurable style constraint (it limits color noise) and could be one of the agent’s checks.
- “Gothic” in D2 is mostly darkness, low-saturation earth tones in the dungeon acts, and a small light radius, not film grain. The game’s own makers said D2 is brighter and less gothic than Diablo I.
Gaps
- No primary source on D2’s render settings (light rig, anti-aliasing, render size, downscale, how the palette was built). Not in the postmortem or the Shacknews piece.
- No source found on D2’s gamma control or any film-grain effect; the “desaturated, grainy” description could not be sourced and may be a conflation with Diablo I or with D2R.
- Siramy’s animation PDF and Paul’s DT1 doc (the best format references for COF layer order and wall orientations) were not reachable; layer codes above are from memory of the community docs and should be verified.
- No direct interview with Phil Shenk on the character pipeline was found.
2. Witchbrook’s art style (resolution, perspective, palette, lighting, proportions, Chucklefish statements)
Takeaway
Witchbrook is not 3/4 top-down any more: Chucklefish switched it to an isometric view in April 2020. It is hand-painted 2D pixel art (characters included) at small sprite sizes (about 40 px tall per its senior artist), animated in 8 directions (5 drawn, 3 mirrored), with layered recolorable clothing, and modern shaders, lighting and camera moves on top. Chucklefish has said nothing public about its internal resolution or palette. The release date is January 28, 2027.
Cited Findings
- The game first used a top-down 2D look; the new isometric look was revealed in April 2020 with the official site. Press called the old look “reminiscent of” Stardew Valley and Wargroove. — Game Informer, 2020-04-02 (fetched); Twinfinite; Nintendo Life (snippets)
- Dev blog “Express Yourself!” (Alexis and Senior Artist Jade Evans, 2025-11-26; fetched): “everything in this game is 2D, including our characters!”; “we animate 5 rotations and then the engine flips the remaining 3 angles to make 8”; walk cycles have 6 frames per direction; “over 1,300 frames of animation that have all been drawn by hand”; players wear “11 layers at a time (not counting hair, fringes and facial hair)”. — Witchbrook dev blog: Express Yourself!
- Clothing is a greyscale mask animated across frames, with textures projected onto it; “All of our clothing textures are designed using RGB base colours, which allows for separate colour assignment in our palette system”. 5 base masks make “60+ unique clothing items”. “Our sprites are tiny!”; complex patterns could not fit a mask “that’s less than 20 pixels wide”. — Express Yourself!
- Jade Evans (Bilbao International Game Conference, reported 2025-12-16; fetched): “Some of them are only about 40 pixels high”, yet the team fits “complex facial animations”; “combining different lighting effects or camera movements” was not possible in traditional pixel art; “it’s really exciting to be able to combine elements of 3D” with “really nice shaders, lighting effects”. Inspiration: “Studio Ghibli, particularly animations like Kiki’s Delivery Service”, and Google Street View for “how we can make roads look nice or make buildings look nice”. — Gamereactor; video: Gamereactor BIG interview
- Process (dev blog, as summarized by search): the isometric move was “a huge undertaking” for a team under 20; concept artists made draw-over sketches on greybox layouts, then pixel artists rendered them, adding seasonal details and lighting. — Witchbrook dev blog index (snippet; the specific post was not fetched)
- Press on later screenshots: “each location boasting warm and generous glows that give the game a soft, cosy feeling”. — GamesHub; RPG Site (snippets)
- Official site: seasons change the town’s plans, residents keep daily routines (shops in the morning, the arcade in the evening), screenshots show candlelit rooms, lamp-lined bridges, an autumn forest; launch January 28, 2027 on Steam, Switch, Switch 2, Xbox One, Series S/X, PS5. — witchbrook.com (fetched)
Inferences
- The Witchbrook recipe for a code agent: isometric 2:1 ground; characters about 40 px tall with large heads (chibi-leaning; inferred from screenshots and the 40 px figure, not stated); soft warm palette with hue-shifted ramps; lighting as a separate layer of warm glows (lamps, windows, candles) over a time-of-day tint; draw 5 directions, mirror 3. Its clothing system is exactly the D2 idea updated: draw a greyscale or index mask once, recolor through a palette system. Both targets converge on “draw once, recolor by table”.
- Witchbrook’s “3D elements” plus “shaders” plus “lighting” mean the base art is flat hand-pixeled 2D and the depth and light come at runtime. For Tycho, that maps to: paint the world in Ink indexes, then light it with a quantized light table per time of day (keeping the 8-ink rule), rather than additive blends that create new colors.
- Elsewhere’s 320x180 is a plausible Witchbrook-like scale for 40 px characters, but whether Witchbrook itself renders at 320x180, 384x216 or 480x270 is unknown.
Gaps
- No official statement on internal resolution, pixel scale, palette size, outline rules or light direction. Measuring those would require analyzing screenshots from the official press kit (an agent could do it with the metrics in section 3c, for study only).
- Whether lighting is truly dynamic with a day-night cycle is implied (routines, glows, seasons) but not stated technically in anything fetched.
- The “Winter comes to Mossport” and “Back to School” dev blogs were not fetched; they may hold more art detail.
3. Generic methods for reaching a target style from code
Takeaway
There are five levers, and they combine: (a) render from geometry and quantize (the D2 and Dead Cells route: best for volume, rotation and many directions); (b) synthesize from examples (WFC overlapping model, Efros-Leung, quilting: best for textures, tiles and terrain that must “look like” a reference); (c) measure the reference and turn the numbers into constraints and tests (cheap, deterministic, and what makes the other levers checkable); (d) diffusion models with palette constraints (the fastest route to a plausible sprite offline, but they need cleanup and raise licensing questions); (e) a human-curated style bible plus screenshot critique loops (what actually closes the gap).
Cited Findings
(a) Pre-rendered 3D, then quantize
- Diablo II: 3D Studio Max, in-house multi-angle renderer, 8 and 16 directions, separate parts per armor piece (see section 1). — Schaefer 2000
- Dead Cells (Thomas Vasseur, 2018): simple 3D models in 3ds Max, exported as FBX, rendered by an in-house tool at tiny size with no anti-aliasing, saved per frame as PNG plus a normal map, then lit by a toon shader in game; pixel flicker was never fully solved. (Covered in depth in
sprites_characters_items.md.) — Vasseur, Game Developer - t3ssel8r-style real-time 3D pixel art, as reconstructed by David Holland (2024, updated 2025; fetched): snap the camera to a view-aligned texel grid, then shift the output back by the snap error for smooth motion; edge-detect from depth and normal buffers with a 4-neighbor kernel so outlines stay 1 px; depth drives outlines, normals drive edge highlights; isolate convex edges (t3ssel8r’s early outlines “only appeared on the convex edges”); smooth light attenuation and add noise to normals to stop shadow popping; outline parameters need per-scene tuning. — David Holland, 3D Pixel Art Rendering; t3ssel8r’s own channel: youtube.com/@t3ssel8r
- Toon (cel) shading is “almost always the go-to” for Blender pixel art, because it reduces the color range. — PixelCAD write-up; Kyriota, Unity URP pixelated style (snippets)
- Pixelated image abstraction (Gerstner et al., NPAR 2012) solves jointly for a feature-preserving downsample and a reduced palette, i.e., a principled “render big, then pixelate” step better than nearest-neighbor plus k-means. — Gerstner et al. 2012; PDF
- Kopf and Lischinski’s “Depixelizing Pixel Art” (SIGGRAPH 2011) goes the other way (pixels to smooth vectors). Its similarity graph of pixels (which diagonal neighbors belong together) is a useful analysis tool for reading cluster and outline structure. — Kopf & Lischinski 2011; a Python implementation: depixelizer on PyPI
(b) Example-based synthesis
- WFC overlapping model (fetched): read the input bitmap, count its NxN patterns (N is typically 3; optional rotations and reflections), then fill the output by lowest-entropy collapse and propagation. Its two conditions: (C1) the output contains only NxN patterns that appear in the input; (weak C2) pattern frequencies approximate the input’s. It generalizes Merrell’s model synthesis and descends from Efros-Leung texture synthesis; it “suits level generation and pixel art better than large full-color textures”; correlations fall off quickly without global heuristics. — mxgmn/WaveFunctionCollapse
- Efros and Leung (ICCV 1999): non-parametric texture synthesis that grows an image pixel by pixel by matching neighborhoods against the example. Efros and Freeman’s image quilting (SIGGRAPH 2001) stitches example patches along minimum-error boundary cuts. — Efros & Leung; Efros & Freeman, Image Quilting
(c) Statistical style analysis (sources for the rules being measured)
- Slynyrd (Raymond Schlitter): a ramp is a small palette; he builds big palettes of many ramps and pulls subsets per piece; he likes strong hue shift “but 20 is about as high as I go” (degrees per step). — Slynyrd Pixelblog 1: Color Palettes (snippet)
- Common convention: cooler shadows, warmer highlights. — Pixel Joint forum (snippet)
- Saint11 (Pedro Medeiros): “cluster sketching”; “have as few clusters as I can and to avoid one-pixel clusters by all means. These one pixel clusters are also called orphan pixels” and make an image noisy. — Saint11, How to start making pixel art #2 (snippet)
- DCC’s 4-colors-per-4x4-cell limit (section 1) is an engine-imposed local color budget. — pd2-sprite-studio
(d) AI image models
- SD-πXL (Binninger and Sorkine-Hornung, SIGGRAPH Asia 2024; fetched): score distillation from a pretrained diffusion model into an HxWxn tensor over a fixed palette of n colors; Gumbel-softmax “allows for crisp pixel art effects”; optional image for spatial conditioning. Output is guaranteed to use only the given palette. — arXiv 2410.06236
- PixDiff-PIG: palette-informed diffusion for pixel art, with snap-to-nearest-palette as a post step; authors say standard diffusion struggles to keep discrete palettes and crisp silhouettes. Venue and date unverified. — ResearchGate (snippet)
- Voxify3D (arXiv 2512.07834): palette-constrained Gumbel-softmax quantization for voxel art, supervised by 2D pixel-art renders. — arXiv 2512.07834 (snippet)
- Retro Diffusion: the developer says the model is trained on art licensed from Astropulse (Cody Claus) and other consenting pixel artists, “a plurality of the dataset is even my own artwork”; the website and the Aseprite extension use different models; no independent audit was found. — astropulse.itch.io; Medium profile; Retro Diffusion docs (snippets)
- Scenario hosts Retro Diffusion models, describing them as trained “in collaboration with experienced pixel artists”. — Scenario help (snippet)
- PixelLab features (skeleton animation, 4 and 8 directions, tilesets) are covered in
animation.mdandsprites_characters_items.md.
Copyright and IP (plainly)
- US Copyright Office, Part 3 report (“Generative AI Training”, pre-publication, May 9, 2025): training is not categorically fair use; using copyrighted works to make expressive content that competes with them weighs against fair use; the report is non-binding and its Register was dismissed the day after release. — Jones Day summary; Wiley (snippets)
- Thaler v. Perlmutter (D.C. Cir., March 18, 2025): a work made solely by AI cannot be registered; human authorship is required. It does not settle human-AI collaborations. One source reports the Supreme Court declined review on March 2, 2026 (unverified). — Loeb & Loeb; The Register (snippets)
- Steam requires disclosure of AI content “consumed by players”; pre-generated content needs a statement that you have the rights to it; live-generated content also needs guardrails described on the store page. — GamingOnLinux, Jan 2024; PC Gamer on the form rewrite (snippets)
(e) Human-in-the-loop
- Witchbrook’s own pipeline: concept draw-overs on greybox, then pixel artists render (section 2). — Witchbrook dev blog index (snippet)
- Diablo II: paper-doll tests of armor combinations before rendering; the lack of in-engine preview was one of its listed failures. — Schaefer 2000
Inferences
- (a) for Tycho, offline: the D2 route fits a Node script, not the runtime. Model with SDFs or tiny meshes in JS, ray-march or rasterize at 4x the target size, light with one key light (direction fixed per world), downsample with a Gerstner-style or simple majority filter, quantize to the world’s ink sheet with ordered ramps (map lit value to ramp index, never nearest-RGB, so ramps stay clean), then run cleanup passes: remove orphans, enforce a 1 px outline on the silhouette only (convex edges for the t3ssel8r look; no outline for D2), and mirror 3 of 8 directions as Witchbrook does. Write the result as Ink index arrays in the repo. Determinism is free because there is no clock or
Math.random. - (b) as a metric, not only a generator: WFC’s condition C1 gives a direct style distance. Count the fraction of the output’s 3x3 index patterns (after mapping both to ramp-position classes) that occur anywhere in the reference. That is a cheap “does this look like the reference locally” score an agent can compute. WFC itself is best for ground textures and tile variants (a D2 dirt floor, a Witchbrook cobble street) trained on a small hand-made anchor.
- (c) the metric set an agent can compute from a reference and from its output, then compare (all in plain JS over palette indexes):
- palette: the distinct colors, sorted into ramps (by luminance within hue families); hue step per ramp step; saturation curve; darkest and lightest values;
- colors per sprite (D2-like renders use many shades; Witchbrook-like hand pixel art few) and colors per 4x4 cell (DCC’s budget);
- cluster-size histogram (4- or 8-connected same-index regions) and the orphan-pixel ratio (Saint11’s noise measure);
- outline: fraction of silhouette pixels that are the darkest ink; whether interior lines exist; outline color (black versus darkest local ramp color, “selout”);
- light direction: average of (luminance gradient) over the interior of each sprite gives the dominant light vector; check it agrees across all assets;
- line weight: run lengths of outline pixels perpendicular to the edge (1 px versus 2 px);
- proportions: sprite height in px, head height divided by body height (head found as the top cluster above the narrowest row near the neck);
- detail density: edges (index changes between neighbors) per opaque pixel;
- local pattern overlap (the WFC C1 score above). These are proposed by this researcher; no paper defines this exact set.
- (d) where diffusion fits: offline concept and anchor generation, then always snapped, cleaned and redrawn into Ink indexes. Palette-constrained methods (SD-πXL) prove the palette can be a hard constraint, not a post step. For a shipping game, the safest uses are models trained on licensed data and outputs a human substantially reworks (both for copyright, since purely AI output is not protectable in the US, and for quality).
- IP plainly: style (isometric view, warm palette, dark gothic mood, 8 directions, palette-shift variants) is not protected; specific assets are. Extracting D2’s
pal.dator sprites from the MPQs and shipping them, or training a LoRA on ripped Diablo II or Witchbrook art, uses Blizzard’s or Chucklefish’s copyrighted material and is not safe for a game you release. Measuring statistics from reference screenshots for private study, and writing your own palette that is like theirs, is the defensible line. Names and trademarks (“Diablo”, “Witchbrook”) should not appear in shipped content. This is a reading of the cited legal summaries, not legal advice.
Gaps
- No primary t3ssel8r write-up exists; the technique is reconstructed by third parties.
- No independent quality benchmark comparing PixelLab, Retro Diffusion and Scenario was found (also noted in the sibling notes).
- No paper was found that measures pixel-art “style statistics” as above and uses them as generator constraints; this seems to be an open niche.
- “Markov models over tiles” and “procedural generation by example for sprites” were not researched separately in this session (see
world_generation.mdfor tile-level methods).
4. What an AI coding agent needs as input to hit a style
Takeaway
An agent can render and check anything it can measure, so the input that matters most is checkable specification: exact palettes in hex grouped as ramps, exact pixel sizes, one light direction, explicit outline rules, a few hand-made anchor sprites at final size, and a numeric acceptance test that compares statistics of its output to the anchors. Reference images it can view help with intent, but cannot by themselves stop drift.
Cited Findings
- The targets’ own pipelines show what the “spec” was: D2 fixed the render tool, angles (8 or 16), character height (75 px), resolution and bit depth (640x480, 8-bit), one light direction for backgrounds, and modular parts. — Schaefer 2000; Shacknews
- Witchbrook fixed the view (isometric), directions (5 drawn plus 3 mirrored), walk frames (6), sprite scale (about 40 px characters, clothing masks under 20 px wide), and a recoloring palette system. — Express Yourself!; Gamereactor
- Tooling exists for agents to drive sprite editors directly: pd2-sprite-studio’s MCP server (31 tools); Aseprite MCP servers exist with tools such as “generate_color_ramp”; Retro Diffusion offers an MCP server (per
animation.md). — pd2-sprite-studio; aseprite-mcp on Glama - Elsewhere’s repository already has the loop pieces:
node test/look.js <id> 200 800makes screenshots of a quest as its bot plays,test/golden.jsonpins first frames, andInkstores pictures as palette indexes (per the project’s CLAUDE.md). — local:/Users/david/projects/elsewhere/CLAUDE.md
Inferences
A proposed “style pack” per target, kept in the repo beside the world (a sketch for the Tycho roadmap):
palette: hex values grouped into named ramps, dark to light, with each ramp’s role (skin, foliage, stone, light, shadow). For Elsewhere, 8 inks per frame; for a D2-like world, a darker, browner sheet; for a Witchbrook-like world, warm mid-values with hue-shifted shadows toward violet. Write your own values; do not copy extracted game palettes into a shipped game.scale: frame size (320x180), tile size (e.g., 32x16 for a 2:1 grid; D2 used 160x80 at 640x480), character height (D2 about 75 px at 640x480, roughly 37 px at 320x180; Witchbrook about 40 px), head-to-body ratio, directions (8 = 5 drawn plus 3 mirrored).light: one direction vector (e.g., from upper left), number of light levels in the light table, light radius rule, time-of-day tints as index remaps.line: outline on or off, color rule (black, darkest ramp color, or selective), weight (1 px), interior lines allowed or not, convex-edge highlights or not.anchors: 3 to 10 hand-made (or hand-finished) sprites and tiles at final size, as Ink index data and as PNGs the agent can view. These are what WFC and the pattern-overlap metric learn from, and what the agent imitates.board: reference screenshots for mood only, viewable by the agent, kept out of the shipped build and out of any training set.accept: thresholds on the section 3 metrics (e.g., orphan ratio below the anchors’ value plus a margin; all colors within the sheet; light vector within 20 degrees of spec; local pattern overlap above some fraction; sprite height exact), plus a golden screenshot the human signs off.- The loop: generate, render a contact sheet (all directions, all variants, on the real ground), compute the metrics, view the sheet, critique against the anchors in words, change the generator, repeat; commit only when the metrics pass and a human approves. The agent should research by reading (postmortems, modding docs, artist tutorials) and by measuring references, then write its findings into the style pack so later sessions inherit them.
Gaps
- No study was found on how well vision-language models judge pixel-art style fidelity, so the human approval step should stay.
- The metric thresholds above are untested proposals.
5. What is still hard: anatomy and animation of complex characters, faces at low resolution, perspective consistency
Takeaway
Hard cases are the ones where correctness is global and semantic, not local: a body must stay the same body across 8 directions and many frames, a face of a few pixels must read as an expression, and every object must agree on one projection and one light. Local statistics (WFC, palettes, cluster rules) cannot see those. Every production example solves them with structure the generator owns: a 3D model or skeleton (D2, Dead Cells), drawn masks and layers with mirroring (Witchbrook), or a human drawing the hard frames.
Cited Findings
- D2 got consistent anatomy across 16 directions and modular armor by rendering one 3D model per part from fixed cameras, but at a cost: no in-engine preview and art redone months later. — Schaefer 2000
- Dead Cells renders 3D without anti-aliasing for crisp pixels and still had unsolved flicker. — Vasseur
- t3ssel8r-style 3D needs texel-grid camera snapping and per-scene outline tuning to avoid creep and popping. — Holland
- Witchbrook hand-draws 1,300+ frames, uses masks so clothing follows the body frame by frame, mirrors 3 of 8 directions, and still calls fitting “complex facial animations” into about 40 px a point of pride. — Express Yourself!; Gamereactor
- WFC only guarantees local pattern validity; correlations fall off quickly, so it lacks global structure without extra heuristics. — mxgmn/WaveFunctionCollapse
- Palette-informed diffusion work states that standard diffusion struggles to keep discrete palettes and crisp silhouettes. — PixDiff-PIG (snippet)
- Kris Renkewitz on D2 monsters: “It’s about the silhouette the character makes on the game.” — Shacknews
Inferences
- Why it is hard: at 40 to 75 px, a single pixel is a whole feature (an eye, a knuckle, a fold), so the mapping from 3D form to pixels is not smooth; tiny pose changes flip pixels and read as flicker or “boiling”. Expression lives in 2 to 6 pixels whose meaning depends on convention, not geometry, so rendering a 3D face rarely gives a readable one. Perspective errors come from mixing sources (hand-drawn props, rendered characters, synthesized tiles) that each assume a slightly different camera.
- Workarounds that fit Tycho: (1) one projection module that every generator uses (the 2:1 grid, the same light vector), checked by the light-direction metric; (2) characters as layered parts on a small skeleton rendered offline per direction (D2’s paper doll, Witchbrook’s masks), with 3 of 8 directions mirrored; (3) faces as a hand-drawn library of tiny expression stamps (a few pixels each, per direction) composited onto generated heads, not generated; (4) temporal stability by rendering animation frames at a higher size and quantizing with hysteresis (keep a pixel’s previous index unless the change is large), or by hand cleanup of key frames; (5) silhouette-first checks: the agent tests each sprite’s filled silhouette alone for readability before shading.
- The user’s “limits are knowledge and imagination” is right in that these are specification problems, but the specification for anatomy and faces is so large that the cheapest known way to provide it is still a human-made anchor (a model, a skeleton, or drawn key frames). Code then multiplies it: directions, variants, recolors, lighting.
Gaps
- No research paper found that solves temporally stable low-resolution sprite animation from 3D; the evidence is practitioners’ write-ups.
- No source on how Witchbrook animates faces (separate layers or full redraws).