The second world is built around unmown grass that you push through instead of walking on. It slows you to 3.025 units a second. The road you flatten through it moves at 9.0. That three-to-one gap is the whole economy of the world, and everything else exists to make it readable or to let you pay for it.
It also does the one thing water cannot. Water closes behind you and takes no impression. A lawn keeps a record, so your own past movement becomes the terrain, the road network, and the thing the boss reads. The bloodhound who guards the yard does not track the cat. He tracks the freshest mark in the grid. Cut a straight line across his yard and he comes straight down it. Cut a closed loop and he follows it round while you walk out through the middle.
Every number was measured, and some of them were wrong
The world's spec computed its jump heights from the continuous kinematic identity. The game integrates semi-implicit Euler at 120 Hz. The two disagree by up to 4.4 pixels, which is not a rounding difference. It is the entire margin the placement rules are built on.
So the figures were measured two ways. A script mirroring the gravity code line for line produced a table, and then a measurement routine was run inside the engine against the shipped movement asset. Both gave the same numbers to four decimal places.
| Spec said | Measured | |
|---|---|---|
| Spring jump apex | 4.047 | 3.9715 |
| Ceiling on open ground | 6.566 | 6.4300 |
| Ceiling in the grass | 6.580 | 6.4445 |
| Gap between the two ceilings | 0.014 | 0.0145 |
| Spring airtime | 0.951 s | 1.175 s |
The one that mattered most was the ceiling. The placement rule called everything below 6.166 "reachable with margin". Anchored on the real ceiling the safe limit is 6.030, so a 4.4 pixel band that the rule called safe was out of the cat's reach. An assertion built on that number is worse than having none.
The good news the measurement bought: the two ceilings are under half a pixel apart, so one table of ledge heights really does serve both open lawn and thick grass.
The bug that would have deleted the mechanic
The first playable build let the cat bulldoze a whole stage at road speed without ever being slowed.
Flattening cuts every cell the body covers, including the one he is standing in. If you read the speed tier from under his feet, the sequence is: step one, he is in fresh grass and slow. Step one flattens that cell. Step two reads the cell under his feet as road and gives him the full 9.0, permanently.
The tier is now sampled at his leading edge, one full cell beyond his body, which is also what is physically true. The resistance is the standing grass he is pushing into, not the cut grass behind him. A first fix that sampled only 0.1 units ahead still landed inside an already-cut cell about half the time, and he crossed at 4.76 instead of 3.025. It takes a whole cell to clear.
The rule the player learns from this is the one the boss fight is built on: the road is a place you go back to.
Sixty-four tiles, and a palette that forced the art direction
The project had no outdoor art at all, only a sky, two cloud layers and a distant cottage seen through a window. There are now 43 garden tiles and 21 thick tiles. Both sets are generated, byte-identical across two runs, and both assert their own art direction and fail the build when they miss it.
The palette has exactly two greens. A garden lit neutrally is unbuildable in 70 colours: it comes out as one flat mid-green field with nothing separating a wall from a floor from a hazard. So the garden is lit by a low warm sun. Grass reads gold and amber where the light lands and violet where it does not, and the two greens are spent only on the deepest thatch and the coldest shade.
The generators caught five things a human eye would have shipped:
- The lawn had no directional light. Left-to-right spread measured +0.2, which is noise. The mower-stripe table is periodic by design, so it cannot carry a trend. Stripe and sun are two physical causes and are now two passes. The spread is now +9.3.
- A flowerpot was brighter than the road. The surface you stand on has to be the brightest thing in the frame, and picking the road out at speed is the game. The mown strip measured 90.0 against a terracotta wall at 97.9.
- Three coplanar deck boards fell 82 luma across them. That reads as a staircase. Boards in one plane under one light differ by weathering, not by a ramp step each.
- The least legible surface in the world was more legible than plain soil. The wet flags are meant to be the one place your eye slides off, because they are the one place a trail cannot be cut.
- The hedge was a perfect sawtooth.
(x * 7919) % 13looks random and is a period-13 sequence. It is the same class of defect as the period-2 comb the pipeline exists to prevent, at a longer period.
The world was not green
Three times in playtest feedback the same complaint came back: there is not enough grass on a lawn stage, green is the least of what is on screen, did the green terrain disappear again. It was a measurement, not a preference. Measured across the shipped art that morning:
| Art | Green before | Green after |
|---|---|---|
| All eight canopy tiles | 0% | 67% |
| Border planting | 4% | 75% |
| The fence | 0% | 35% |
| The tree line | 0% | 10% |
A stage built around two lawns had green in exactly one place, the floor tiles, which sit below the walking plane where the camera mostly does not look. Everything at eye level was brown.
Two rules caused it. The canopy had one green out of eight tones, and it was the third darkest, so the two brightest tones the eye actually reads were orange. And the background generator banned green outright, on the grounds that it broke the golden-hour law the world is lit by. That confused the light with the material. Golden hour makes grass gold-lit, not dead.
Both generators now assert a green floor instead of a green ban. Gold still owns the sky, the seed heads, the fence edges and the trail. The trail is the only object that ever needed to be the brightest thing on screen.
The road itself did not change, and that was deliberate. The canopy got new palette letters rather than a repointed legend, because the same letters draw the canopy and the road, and recolouring them would have turned the road green and destroyed the read the economy rests on.
The tighter rule is the one that matters. The canopy body now caps at 95 instead of 128, so all four ages of trail clear the field at 148, 134, 103 and 77 against a body mean of 56. At 128 the third age tied with the grass it was cut through.
Atmospheric depth nearly went. A first pass greened the whole tree line and the depth check refused it, because the greens ranged more saturated than the greys and the far trees overtook the middle ones. The fix is what a low sun actually does: the mass of the trees hazes to grey and only the sunward crown keeps its colour. The ladder came out far 0.13, mid 0.46, near 0.59.
Two traps are recorded for the next person:
- A blended green is not a palette colour. Mixing two greens for a stem mid-tone produced 1,508 pixels the palette check rightly refused.
- A tileability check is a ratio, and green is a narrower band than brown. One tile failed at 1.61 not because its seam got worse (it was identical) but because the flatter green field dropped the interior step from 21.2 to 4.5. The fix was to put the depth back where a real thicket has it, not to move the threshold.
Two boss fights that could not happen
The first boss was teleported out of his own arena every physics step. His arena had been merged into the back of a stage at an offset, but his roaming limits stayed in the old room's coordinates while the clamp runs on world position. He spawned at x 145 and was snapped to x 12.6 on his first step, 132 units west and gone. The fight could not occur at all. The limits are now written in world space from the offset the arena was handed.
Both bosses put their health bars on screen at scene load. The reset that arms a boss runs when the scene loads, and the second world's stage is 204 units long with the yard in the last 24. A full health bar sat across the bottom of the screen from the first frame, a hundred and eighty units before there is a dog. It reads as a broken HUD, and it spends the reveal, because the bar arriving is the announcement that the stage just became a boss fight. Both now arm on wake, and still re-arm on a death restart.
Small things
- The bloodhound needed his own animator. The existing boss animator finds its owner by looking for the first dog's component, which a second boss does not have, so the lookup returns nothing and the phase read stops silently. All nineteen poses he can enter have their own drawn clip.
- No snout-hit overlay on him, deliberately. A hairball on the first dog's nose makes him blink. On this one it blinds him, and the combat code already puts him into a drawn Woozy state. The reaction is the state, so an overlay would fight it.
- The font gained a question mark. The 46-glyph set had none, so a line written as a question was being exclaimed at the player, which is a different sentence. The glyph went on the end of the sheet rather than into the middle, because the sheet index doubles as the lookup table.
- Regenerating a sprite at a new size strands its metadata file, silently. One background came back at 224 by 112 while its meta still described a 224 by 127 rect, so the file existed on disk and loaded zero sprites. Reimporting does not fix it. Deleting the meta does.
- Recompiling while the game runs threw a null on the player every physics step, 734 in one session, which buries every other console message. Enemies had the same fault. Both now rebuild their setup when the scripts reload. (More on that in a later post.)
- The second world was passing the first world's indoor lighting, "a house interior at late afternoon, lit through four windows", which laid 175 light plates over a garden and rendered as grey blobs hanging in the sky.
