Lantern Rise

A paper sky-lantern climbs a festival night on the breath of its own flame. That flame is the only light you have and the only fuel you have: stoke it to rise and see further, or coast to save it and go nearly blind. Built end to end by AI agents on Cocos Creator — concepted, modelled, animated, scored, compiled headless on Linux and audited until clean — and measured every build against the 4 MB WeChat mini-game gate.

Play it now

Hold Space / W / ↑ or touch to stoke · A D or ← → to steer · P pause · M reduced motion · N mute
3.3 MB web build · starts in seconds

▶  Play

The concept is the contract

Nothing was modelled before the concept pack existed. The hero sheet fixed the one thing the piece had to deliver — a lantern that is genuinely the light source, its flame raking warm amber across clay pantiles in a deep indigo night. Every art round after that was judged against this image, side by side, until a full audit round found nothing.

Concept hero sheet: a glowing paper sky-lantern above tiled rooftops at night
C1 — the hero sheet. The contract: the lantern is the light.
Live engine frame: the lantern glowing above lit pantile roofs and building masses
The live engine. Warm light on baked relief, over continuous rooftop masses.

Gray boxes before art

The whole loop played from placeholder rectangles first, driven by an autopilot through Playwright on desktop and mobile, before a single asset existed. Five real defects fell out at that stage — including a keyboard path that was silently dead until the player happened to click, and a level rule where the reward and the obstacle fought each other so hard that a perfect run still starved.

Gray-box blockout of the climb
Blockout round 7: cables, wishes, fuel and tiers all playing, no art.
Desktop and mobile frames side by side
Both legs. A round only counts as clean when desktop AND mobile complete the climb.

Light as the mechanic

The lab signature: a custom Cocos Effect that lights normal-mapped sprites from the lantern's live world position. Every lit surface ships an albedo pass and a camera-space normal pass baked in Blender, so the flame rakes across real relief rather than a painted highlight. It is load-bearing, not decoration — light radius is sight radius, so stoking to see further is the same act as spending your fuel.

Close crop of warm light raking across normal-mapped roof tiles
The rake, close up: per-tile highlights and distance falloff from the normal pass.
Above the clouds: moon, cloud sea and a sky of rising lanterns
Tier 3 ships as a WeChat subpackage — a whole tier of art outside the 4 MB cap.

Code-modelled in Blender

Every prop is code-modelled and rendered to sprites at one shared px-per-metre, each with a matching camera-space normal pass. The rooftop crowd is real motion data, not procedural posing: CMU clip 15_04 retargeted onto a rig and sampled to standing stances.

Concept callout board of every prop
C2 — the callout board every prop was modelled against.
Rendered prop sprites
Shipped sprites: lantern, wish slip, cable, washing, eave, paper lantern, pantiles, chimney, water tower.
Mocap crowd stances
Rooftop crowd from CMU 15_04. Two action clips were tried first and rejected as too animated to stand still.
Building facade and lantern garland sprites
Building masses and lantern garlands — added so the roofs read as one connected town.
Concept environment bands
C3 — three environment bands: rooftops, upper town, cloud sea.
Cloud and moon sprites
Tier-3 sky art, packed albedo-only into the subpackage atlas.

Measured, honestly

This lab's signature number is the WeChat main package against the 4,194,304-byte cap. Every figure below is measured from the shipped build, including the ones that are not flattering.

MeasurementValueConditions
WeChat main package3.38 MB (3,383,883 B)80.7% of the 4,194,304-byte cap — the gate this lab exists for. Re-measured after the 2026-08-24 readability round: the hazard tick signature and gap brackets are drawn in code, so they cost the main package 1,097 B.
Tier-3 subpackage45.9 kBoutside the cap; fetched on demand at tier 3
Cost of a whole tier of art1.5 kB to the main packagebecause the art itself went to the subpackage
Web build3.35 MBraw, uncompressed
Engine core, trimmed1.64 MB15 modules kept of 33 default
Engine core, untrimmed3.08 MBwhat the default config ships — 1.49× over the cap on its own
Prop atlas (albedo + normal)276.4 kB640×512, 19 sprites at one shared 96 px/m
Engine splash removed−0.20 MBno-splash baked into the build config; the removed logo was an embedded base64 image
Audio241.6 kBfive mono MP3s from sampled instruments
Art headroom left0.81 MBtighter than it looks once every lit surface needs a normal pass too
Audit rounds65+blockout through gate 7, plus this operator fix round
Verified playthroughdesktop and mobile both complete the climbzero console, page and network errors
Device verificationpendingWeChat devtools are Windows/macOS-only. A substitute harness boots the real package under a mocked host API with real headless GL — it proves the package is coherent and renders, not that it runs on a handset.

Real engine features, earned

Custom lighting Effect

A hand-written Cocos .effect lighting normal-mapped sprites from the lantern's live world position. The mechanic, not a filter.

Asset bundle → subpackage

Tier 3 ships as a WeChat subpackage, loaded on demand and excluded from the 4 MB main package.

ParticleSystem2D

Flame core that breathes with the stoke, an ambient ember field, and one-shot bursts on pickup and snuff.

Engine module trimming

33 default modules cut to 15, halving the engine core — the difference between fitting the gate and missing it.

Mocap animation

Rooftop crowd retargeted from CMU 15_04 onto a rigged figure; no procedural fallback used.

Sampled-instrument score

Koto and halo pad over a 26.7 s night loop; vibraphone, taiko and tubular bell for the cues. Nothing synthesised.

hit-stop 60 ms grace window 45 s light radius 150 → 320 px fuel 7.0/s stoking, 2.2/s coasting gap shift ≤ 190 px 4 parallax rates one PPU: 96 px/m