Browser build live at omega-rain.pages.dev. The Unity build became playable today.
You spawn on a temple courtyard, walk on real terrain in the rain, and swing a sword that does damage. Before today the character fell out of the world on spawn and never stopped falling.
Five things landed: the procedural architecture kit is placed as an actual district, weather and sky work, the character is a skinned rig with animation, the ground is solid, and the area's boss is ported and standing in his arena.
What was verified
Each of these was confirmed by driving the game and reading the result, not by reading the code.
| What | How it was proven |
|---|---|
| Spawns on solid ground | The ground pass asserts a solid hit below the spawn and logs the clearance |
| Moves | Virtual pad driven; HUD reads "state Move, speed 5.0 m/s" |
| Attacks and deals damage | Console shows the dummy taking exactly the heavy value from the move table |
| Character animates | Pose changes between Idle and Run; six clips baked, animator driven every frame |
| Gamepad detected | HUD names the controller on a real pad |
| Camera follows | Third-person orbit rig tracking through all of the above |
What was built
| System | Lines | Measured result |
|---|---|---|
| District placement | 1,346 | 80 props, 104,254 verts, 11 draw calls, 40 lights, 241 colliders, 0 generator failures |
| Weather and sky | 1,300 | 6 rain emitters, 67 trees, 509 blossom cards, 18 standing-water pools, storm cloud deck |
| Skinned character | 1,191 | 36 bones, 11,752 verts, 5 materials, 6 clips, 666 animation curves |
| Exposure and lighting | 439 | Vista mean luma 0.160 against the reference 0.189 |
| Ground and spawn | 245 | Spawn asserted solid; fall-out-of-world guard added |
| Surface materials | 238 | Terrain tiling corrected from 85 m per tile to 10.7 m |
| GPU budget | 130 | Cloud steps 128 to 32, particle budget 29,700 to 8,316 |
Root causes
Recorded as causes rather than as a changelog, because in every case today the symptom pointed somewhere other than the fault.
The player fell out of the world forever
Spawn height was y = 1 — the height of the flat greybox floor that used to be there. The real heightfield is 17 m up at that point, so the character began inside the terrain, and a mesh collider is a membrane rather than a solid. It fell to y = -2,983 with the HUD stuck on "state Fall".
This is the same fault as the fog range and the camera far plane: a constant authored against a placeholder world and left behind when the real one arrived. It has now happened three times, so the spawn is no longer a number — it is a raycast, and it asserts.
The ground looked like a black bin bag
Two faults at once.
Setting smoothness did nothing at all. With a mask map bound, HDRP takes smoothness from the mask alpha channel through a remap pair and ignores the plain float — so every previous attempt to make the terrain less shiny had no effect whatsoever.
And tiling was 6× across a 512 m mesh, putting one texture tile across 85 metres of ground. At eye height that is a 40× magnification, so all detail was gone and only the gloss survived.
Found by sweeping from player eye height. From the 58 m vista camera every variant looks identical.
The clouds could never have worked
The volume profile had a fully configured, correctly persisted volumetric-cloud override. But the pipeline asset had cloud support switched off, and HDRP masks the feature per camera against that flag. No volume setting could have fixed it.
Separately, the profile had no visual-environment override, so the sky type fell through to the project default and the authored sky had never been selected at all.
The rain was visible and wrong, not invisible
The emitter sat 18 m above the old flat floor — but only 1 m above the real terrain. Rain was being born at eye level and, with stretch billboards and a particle size cap of half the screen height, smeared into screen-wide blue slabs.
The ground tool had a feedback loop
The spawn height climbed on every run — 16.7, 18.5, 20.4, 22.3. The downward ray was hitting the player's own capsule and reporting its top as the ground.
The verify step could not catch it either, because a ray that starts inside a collider registers no hit against it, so it correctly reported empty air. The pattern in the numbers is what gave it away.
The crash, and what it cost
The editor was killed mid-session by a GPU device reset. The weather pass had set volumetric clouds to 128 raymarch steps across an 8.7 km deck with cloud shadows on, over 25,500 particles and 200k triangles.
The expensive part is what came before it. For roughly twenty minutes captured frames came back either pure black or pure white, an exposure ladder returned zero at every value except one, and the obvious reading was that the lighting had broken. Time went into chasing that.
A rendering result is only evidence if the device that produced it was healthy.
The GPU envelope is now written into the project as code rather than remembered.
One deliberate retreat
Selecting the authored sky was the correct diagnosis. It also made the scene about five stops brighter, put a sun disc in frame, and blew every capture to white.
The whole scene — key light, fill, exposure, grade, materials — had been measured against the sky that was actually rendering, and changing it invalidated all of that at once. Re-deriving the lighting rig needs a trustworthy capture path, and at that moment there was not one.
So the sky selection was reverted to the one every good frame in this project has been shot under, and everything else from the weather pass was kept: the rain, the trees, the wet-surface response, the standing water, and the clouds at an affordable cost. The override is disabled rather than deleted, so turning it back on is a one-line change once the lighting can be re-measured properly.
This is a retreat to a known-good baseline, not a fix, and it is recorded as one.
The boss came across
The area's boss was the last core piece the Unity build did not have. It existed in the browser build only, and is now ported — 6,580 lines of C# across a combat brain and a rig.
The combat side carries its move table, its phases, telegraphs, hazards, hyper-armour and a bit-exact seeded RNG port. The rig side is 13,260 verts across 36 bones in 8 draw calls, with its arena.
Bindposes were verified numerically against the live hierarchy: max deviation 7.35e-6 across 36 bones. Winding was checked rather than blindly reversed — the skinned builder already handles it, and reversing twice renders a model inside out.
A data bug worth keeping
The authored arena centre sat at z = 262. The world is 512 m centred on the origin, so the terrain ends at z = 256 — the arena sat six metres past the edge of its own world, and a 24 m fight circle there would have had half its floor over the void.
It failed silently because the heightfield clamps at the boundary: every sample returns a flat value and the numbers all look perfectly grounded. The arena is now fitted to the real terrace.
A lighting trap that cost a sweep
He mounted as a pure black silhouette. Raising his hero lights did nothing — a sweep from 334 to 300,803 candela moved measured brightness by three parts in a thousand, and a 200× render came back pixel-identical.
HDRP does not read a punctual light's plain intensity field on its own; it has to be paired with the light's unit, and without that the write is silently discarded. The setter succeeds, the value reads back correctly, and nothing happens.
That is the worst failure mode there is, and it was the second time that day a silently-dropped write cost real time.
Measurements
| Metric | Before | After |
|---|---|---|
| Vista mean luma | 0.194 | 0.160 (reference 0.189) |
| Ravine mean luma | near black | 0.053 |
| Terrain texture footprint | 85 m/tile | 10.7 m/tile |
| Terrain smoothness | 0.46 unremapped | 0.02–0.18 remapped |
| District | 980 grey boxes | 80 generated structures, 11 draw calls |
| Player character | static mesh, no skeleton | 36-bone skinned rig, 6 clips |
| Particle budget | 29,700 | 8,316 |
