Today, I started building Level 6 of North Is Not Up, and it has already turned into the most technically ambitious part of the game so far.
The new level is called Loch Ailsa. Instead of treating water as scenery or a boundary, the loch is part of the navigation problem. The player can swim between islands, use smaller islets as rest points, take longer land routes, fight predictable currents and read the map while treading water.
That sounds straightforward until all of those systems have to work together. The world has to feel continuous, but it is too large to keep every detailed shoreline, tree, rock and collision mesh live at once. Swimming also has to fit around the movement, animation and audio systems that already work across the first five levels.
So most of today was not just placing terrain. It was deciding how Level 6 should be built, proving the risky parts and fixing the problems that appeared once the plan met the actual game.
Starting with the shape of the world
The source map gave me the overall composition: a long irregular loch, wooded islands, exposed crags, a ruined cottage, a northern bridge, reed beds and several possible routes between them.
I split that world into 15 streaming regions. The divisions are ownership boundaries for the game, not visible borders. A player should never see the world loading in squares or find an invisible wall where one region ends and another begins.
The first playable slice deliberately stayed small: the western start, Pine Island and the central islets. Once that worked, I expanded north to Ruin Island and its bridge, then east to the crags, Reed Bay and Gull Island. The remaining shores and the final control course are still being held back.
Because this is an AI-assisted build, I treated those checkpoints as hard boundaries rather than suggestions. Each stage had to stop with screenshots, saved-world audits, route measurements and mechanical tests before the next part of the loch was authorised. That gave me something concrete to review and stopped a large generated world from outrunning the decisions behind it.
The scale needed a reality check too. Copying the reference image’s printed scale literally would have made the level nearly ten kilometres wide. Instead, the working world is about 1,050 by 575 metres, with every route measured using the real walking and swimming speeds.
That has already influenced the design. An early test found that the closest western departure made the introductory swim only about 14 seconds. Rather than stretching the island or changing the whole map, I kept that shortcut as a valid route and moved the main review approach farther along the same bank. The intended swim now lands at roughly 21 seconds, while players who spot the shorter line can still use it.
Making a large loch feel continuous
Level 6 builds on the streaming system I made for Level 5, but adapts it for open water. Detailed terrain and scenery are baked into small saved pages. Lightweight proxies keep distant hills and landmarks visible, while the full versions load in the background as the player approaches.
Normally the game aims to keep three to six detailed regions resident, with a hard design envelope of eight including anything being staged or retired. The important difference for swimming is that loading cannot just follow the direction the camera is facing. A player can turn around in the water, drift while reading the map or head for a different landing halfway through a crossing.
The loader therefore prepares every plausible nearby destination before the swimmer can reach it. Collision, scenery and audio all have to be ready—not just the ground mesh. If a safe landing is missing when the player arrives, that is a failed load, not an acceptable pop-in.
One of the first visual checks caught a good example of why this matters. The western mainland mesh originally stopped exactly at its region boundary, which made the ownership edge look like a new beach. The fix was to extend coarse visual context beyond the detailed region. The streaming boundary stayed where it was, but it stopped dictating the shape of the landscape.
Adding currents without rewriting movement
The existing player controller already handles walking, wading, buoyancy, breaststroke, treading water and both character animation sets. Replacing it for one level would have been an excellent way to break five finished levels.
Instead, Level 6 uses a small subclass. It adds the current at the controller’s existing pre-movement signal, which means intentional movement and environmental drift go through the same collision solve. There is no second movement pass and no teleporting the swimmer a little farther each frame.
That separation between intent and drift also solved the map problem. Opening the map in deep water now stops directional input and swimming strokes, switches the character to treading water and silences stroke audio—but buoyancy, collision and current remain active. The player can study the map, but the loch does not politely stop moving them.
Currents are stored as a persistent world-space field rather than attached to streamed regions. Around Gull Island and the eastern channel, broad overlapping zones blend towards the outflow. The foam cues use the same vectors as the gameplay force, so the water should not visually suggest one direction while pushing the player in another.
I also added stamina and safe-bank recovery. Active strokes drain more stamina than treading, dry land restores it, and exhaustion reduces intentional swimming without cancelling the current. Recovery prepares the last verified dry bank before moving the player and applies its time penalty once. The safe-bank record is deliberately separate from the streaming system’s last prepared position, because “the last place that loaded successfully” might still be deep water.


Turning the plan into places
The playable area now includes the western shore and woodland, Pine Island, stepping-stone islets, Ruin Island, the northern bridge, Eastern Crags, Reed Bay and Gull Island.
Ruin Island has two usable landings, rising internal paths, a cairn and the remains of a stone cottage. The bridge is about 41 metres long and was built as a single efficient visual mesh with continuous deck collision and collidable rails. The eastern side adds higher exposed ground, graded gullies, slope-aligned scree, a sheltered reed bay and a purpose-built beacon on Gull Island.
Several problems only appeared once I tried to walk the saved world. The ruined cottage foundation sat too low in its hillside, its path cut through the walls and a scene-ownership mistake omitted some nested geometry. Those were corrected before the measured build. Shore rocks were seated into the slopes, the route was moved around the ruin and the missing geometry was restored.
The eastern validation found more practical snags: a boulder obstructed the launch corridor, the beacon approach was awkward, some path cross-slopes were too steep and the outflow bank did not provide a clean route. Fixing those meant changing the saved terrain and collision, then regenerating the map from the same source so the paper map continued to match the 3D world.
That map is a single 4096-pixel survey built from the actual terrain, shoreline, contours, paths and landmarks. It is not the reference image pasted into the game and it is not assembled from regional map tiles. Compressing it with mipmaps brought the stored texture data down to about 21.3 MiB, compared with roughly 85.3 MiB for uncompressed RGBA plus mip levels.
The warning that turned out to be one line of code
One test run produced four strange Unicode parser warnings containing unexpected null characters. There were no null bytes in the project files, so searching and rewriting assets would have been the wrong fix.
A call-stack trace eventually led to the keyboard input handler. Non-text navigation and function keys can arrive with a Unicode value of zero, and the code was passing that value into String.chr as though it represented a printable character.
The fix was a two-line guard that skips text conversion for those events. Six deterministic reproductions produced six warnings before the change and none afterwards. Normal walking, letter handling and the existing Caps Lock behaviour still passed, so the fix stayed tightly scoped to the actual cause.
The frame hitch I have not pretended to fix
The most frustrating issue is still open.
An early long traversal caught a 254 ms frame with no useful instrumentation around it. A later test found a 37 ms hitch the first time the map opened, alongside the creation of new canvas pipelines and about 39.6 MiB of render allocation.
That map hitch had a practical fix: the game now creates and renders the real map for four frames behind the opaque loading screen, then keeps that same instance ready. Three fresh tests brought first-open windows down to roughly 12–13 ms without faking an input or swapping in a different map.
Unfortunately, the expanded eastern build also recorded unexplained 73 ms and 47 ms intervals during continuously drawn gameplay. They did not coincide with region loading, page activation, map opening or log export. A visibility-aware follow-up proved that window occlusion explained some later giant pauses, but not those two frames.
I could have kept rerunning the benchmark until it happened to produce a clean set, or changed random systems until the number disappeared. Neither would explain the problem. The evidence has been kept, strict timing acceptance remains open, and the next useful step would be a controlled native stack or GPU trace rather than a speculative rewrite of working gameplay code.
Where Level 6 stands tonight
The core idea is working. The player can cross the loch, compensate for currents, tread while using the map, land on readable shores, recover from exhaustion and reverse direction while destinations are still preparing. The latest mechanical suite passes 27 out of 27 checks, and the normal-speed eastern swims measured between roughly 20 and 50 seconds.
What does not exist yet is just as important: the remaining shoreline regions are still proxies, the final control course has not been placed, and the timing investigation is not closed.
That is the point of building the level in checkpoints. Today produced a large amount of visible world, but more importantly it produced a foundation I can test honestly before piling the rest of the game on top of it.



