Habitagram is a habit tracker I am building for a December 2026 release. Your streaks carry a wanderer up through six biomes: sea, desert, steppe, forest, volcano, mountain. The journey screen stacks them into one tall climb, six slabs of 1080x2400 pixels forming a 14,400-pixel canvas from navy sea floor to snow.
The SDXL version ran locally, with IP-Adapter feeding a reference image into the model so all six biomes would share one style.
Where SDXL lost
Three compounding problems. First, style anchoring bled more than style: at full anchor strength, a desert-crop reference turned the sea biome into ochre dunes, palette and all. Aiming the adapter at the style attention blocks alone, the layers that are supposed to carry look without palette, did not strip color the way the technique promises. Tunable, but every biome became a negotiation.
Second, no reproducibility. Every prompt tweak rerolled the whole image, so “make the shore slightly warmer” meant a new image with a hundred other uninvited changes.
Third: these six backgrounds must tile into one continuous climb. Each biome’s bottom edge has to meet its neighbor’s top edge exactly. A diffusion model cannot promise an edge.
So SDXL got demoted to what it is good at, one-off hero sprites, and I rebuilt the backgrounds as a deterministic engine: journey_biome.py, just over 700 lines of numpy and PIL that draw every slab from formulas and one seed.
A paper-cut style, from formulas
The look is layered paper: flat color bands with torn edges, like cut construction paper. Each biome is a stack of bands with one of three edge types: torn (a wavy line plus smoothed noise for the deckle), hard (a crisp cut for cross-hue boundaries where any gradient would bleed), or a Catmull-Rom curve through control points for shaped coastlines, the sea shore among them, which later got its own look-dev pass in a browser: the prototype in the browser entry.
What sells the paper is the grain. Two orthogonal passes of smoothed white noise, vertical fibers and horizontal fibers, blended half and half into a weave, then high-passed so only the ~4px tooth remains, plus a soft large-scale mottle for uneven lighting. Applied at 16% strength it reads as canvas texture instead of pixel noise.
One bug got past the design. Per-biome random-number streams were keyed with Python’s built-in hash(), which is salted per process. Every run rendered slightly different art while the code claimed seed 42, invisible until I diffed two renders byte for byte. The fix is hashlib.sha256 for any seed derivation that must reproduce. A test now pins every biome’s SHA-256 at seed 42 in test_refs/journey_biome_ref.json, so this class of bug cannot return silently; that harness is the golden fingerprints entry.
The seam model a montage hid and a phone exposed
The seams between biomes went through a full redesign, and the bug that forced it never appeared on my monitor.
The first model gave every slab transitions at both its top and bottom, each ramping to a shared junction color. In my review montage, all five seams side by side and compressed 4:1, it looked clean. On the phone (an Android dev build) at full scale, every boundary showed two torn edges and a wedge of junction color between them: stacked cards, not one continuous world.
The redesign gives each seam a single owner. The lower biome carries the one torn edge at its top and is painted above the tear in the upper biome’s own color; the upper biome ends flat in that same color. One edge per boundary, and the slab boundary itself becomes invisible. Ten pixels of flat color at each slab end are the insurance against a crop landing a pixel off.
The rule outlived the feature: judge stacked art at true device scale, one screen cropped at the seam. A compressed montage hides the vertical artifacts that matter.
The app’s end of the deal
React Native holds up the last piece. The images render in an Image with explicit width and height, because under React Native’s new architecture (0.83 here) an inset-styled image silently renders at its intrinsic bitmap size, which is how I got a 1080x2400 slab drawn at device points, a zoom into its top-left corner. Locked tiers show a pre-desaturated _gray variant shipped alongside each biome, cheaper and more consistent than runtime tinting.
Same seed, same bytes, every render. That is what days with a diffusion model could not give me.
If you are pinning generative art the same way, write me: contact@markostankovic.org.
