Empires did not begin with a renderer, a globe, or a distant mountain. It began with people on a green field. There were trees to cut, stones to collect, structures to place, little panels full of practical numbers, and a question that mattered more than any shader: could a settlement game feel alive before it looked enormous?
That first version was two-dimensional, direct, and gloriously easy to read. The camera looked down on a paper-like world. A worker, a rock, a storehouse, and a boundary were unambiguous shapes. We could change a rule, run the game, and see the consequence without first wondering whether a depth buffer or a streaming boundary had lied to us.
The current build is very different. Its terrain has height. Water meets coastlines. The playable ground streams around a moving camera while six lower-detail rings carry the land towards the horizon. The sky changes with the day, objects settle into the landscape, and the old pixel-art people inhabit a world with genuine distance. It is tempting to tell that change as one decisive leap from 2D to 3D. The real story is more useful: it was a sequence of deliberately smaller bets, each made observable by tools and tests.
One game, rebuilt in layers
The visual technology changed repeatedly. The strategic idea moved forward in a more continuous line.
- 2D prototypeFind the loop and visual language.
- Maker toolsTurn worlds and rules into editable data.
- Evidence loopCapture real runs, frames, logs, and budgets.
- Game systemsBuild terrain, water, objects, UI, and time.
- 3D foundationAdd camera, depth, geometry, and native rendering.
- Planet branchLearn what curvature and global seams cost.
- Flat streamingRebuild the world around stable chunks and LOD.
- Playable 3DReturn the settlement to an expansive landscape.
01. First, make the game work in 2D
Starting in 2D was not a placeholder for the “real” game. It was a way to put the expensive questions in the right order. Before worrying about horizons, we needed to know what a player would do minute to minute. Before writing a terrain streaming system, we needed to know which parts of the terrain mattered to decisions. Before rendering a building as a mesh, we needed to know what selecting that building should reveal.
The prototype established a warm, illustrated vocabulary: soft green ground, outlined rocks and trees, tiny workers, open timber shelters, tents, camps, hearts, and panels that resembled pieces of a tabletop game. Its simplicity was productive. When a worker stood by a stone pile, the relationship was visible. When an influence radius covered the ground, it did not fight perspective. When a building panel opened, the player could connect the interface to the object beneath it immediately.
The crucial outcome was not a list of finished features. It was a shared model of the game. There would be a world that could be created and saved, objects that belonged to it, people who acted inside it, resources that moved through it, and tools that let both developers and eventually players alter it. Later test manifests still refer to a legacy gameplay scene alongside Map Maker, Building Maker, World Maker, generated maps, and Conquest gameplay. That is the trace left by a prototype that grew roots rather than being thrown away.
2D also taught us what had to survive the migration. The camera could change. A sprite could become a billboard or a model. A flat color could become a layered material. But selection, construction, inventories, zones, terrain rules, save data, and the rhythm of watching a settlement evolve could not be allowed to dissolve into renderer work.
The prototype was successful when it gave us a game worth making larger, not when it looked like a smaller version of the final render.
02. Build the tools before the spectacle
Once the loop had a shape, content became the bottleneck. A world-scale game cannot depend on changing constants in code every time a coastline feels too smooth or a building footprint is one cell too wide. The project needed ways to make, inspect, and break worlds quickly. That need produced an ecosystem rather than a single editor: Banner Editor, Map Maker, Building Maker, World Maker, world-gameplay scenes, generated-map scenes, and smaller diagnostic modes dedicated to particular rendering questions.
These tools carried two kinds of knowledge. The first was creative: terrain paint, land points, rulesets, building definitions, banners, water settings, object placement, and world composition. The second was diagnostic: map grids, rulers, camera readouts, render-distance controls, terrain overlays, projection checks, depth and occlusion views, and switches that could remove the ocean or horizon from a scene without changing anything else.
That second category became surprisingly important. A black strip in the distance might be a missing terrain sample, the back of an incorrectly wound triangle, ocean drawn in the wrong pass, or a gap between two levels of detail. “It looks broken” is a truthful observation, but it is not a useful diagnosis. A horizon toggle and an ocean toggle could turn one mysterious frame into two controlled comparisons. By July, the Conquest terrain debug panel had distance controls, drag-to-fit behavior, separate ocean and horizon switches, and a combined bare-terrain view. Each of those states was itself captured and tested.
A change could travel without a code rewrite
Rules became data, data became a world, and the same world could be opened by tools, gameplay, and automated evidence runs.
- RulesetMaterials, categories, terrain and object rules.
- Maker scenePaint, place, shape, inspect, and save.
- World dataA deterministic map shared by every path.
- Gameplay sceneRun the real camera, UI, simulation, and renderer.
- EvidenceFrames, logs, counters, diagnostics, and review.
Terrain rulesets are a good example of that arrangement. Categories such
as 3d_paint and 3d_terrain made the source of a
material explicit. The renderer could be tested against the requirement
that only provided ruleset textures appear, with no quiet fallback to a
generated color. Later, when material pages and atlases were introduced,
the content model did not have to be reinvented; the path from a named
terrain rule to pixels on the GPU changed beneath it.
The same philosophy entered the game itself. A bright zoning preview was not accepted as a decorative 2D brush pasted over the screen. The test contract required it to be a depth-tested 3D overlay, to follow the actual shore, to include only dry traversable cells, and to stop at water and the finite edge of the world. Building tools likewise had to select the real half-raised translucent construction model, show its dirt foundation, draw a white depth-tested outline, and open its container without a visible stall. Developer tooling and player interaction were converging on the same underlying world.
03. Make testing another developer on the team
The report archive behind this article is not a polished diary. It is a workshop floor: hundreds of benchmark and feature reports, more red than green, surrounded by logs, CSV files, JSON diagnostics, contact sheets, and more than twenty-seven thousand PNG evidence files. The repetition is the point. A distant-horizon fix was not “done” because one camera angle looked convincing. It had to survive movement, rotation, coastlines, inland views, warm-up, streaming, and the exact renderer intended for the game.
A typical feature run launched the normal game through its regular
run.sh path and opened a visible window. It required hardware
Vulkan on the NVIDIA test device instead of silently falling back to a
software renderer. Capture began only after the requested scene announced
that it was ready. The bridge then collected individual frames, a contact
sheet, functional events, visual statistics, renderer identity, evidence
JSON, and a concise status file.
The loop that turned a visual bug into evidence
Automation proved the route, hardware, frames, and budgets. A human still decided whether the result actually looked right.
- State the claimDescribe the visible behavior and measurable contract.
- Run the gameUse the real scene on the required Vulkan device.
- Capture evidenceRecord frames, logs, counters, and representative views.
- Apply gatesCheck scene, coverage, topology, frame budget, and resource churn.
- Review with eyesAccept, refine, or write the next, narrower test.
That last constraint prevented the harness from becoming a confidence machine. It could prove that twelve frames were nonblank, that they were 1920 by 1200, that color changed between captures, that the right scene was open, and that no fatal Vulkan message occurred. It could not decide that a beach looked natural, that a mountain chain had a believable rhythm, or that a texture transition felt intentional. The report said ready for review, and a person had to look.
Performance was treated with the same specificity. The recurring target was at least 60 frames per second, no wall frame above 16.667 milliseconds, and render work below 10 milliseconds. Benchmarks moved the camera with W, A, S, and D, rotated it with Q and E, and often fixed height, pitch, and roll so two implementations could be compared honestly. They tracked averages, but they also tracked the worst frame, GPU waits, readbacks, pipeline creation, buffer creation, texture creation, managed allocation, garbage collections, terrain coverage, missing nodes, and ring recreation.
That distinction mattered. A game may average 64 FPS and still feel bad if a building click produces a 70-millisecond pause. Many late reports are exactly that honest: a healthy average beside an unacceptable spike. The remaining optimization work is therefore less about making the large number larger and more about making rare bad frames disappear.
The filenames themselves became a record of thinking. Native terrain GPU culling reached a passing feature run on retry fifteen. One horizon-order investigation ran through fourteen benchmark versions. Another series moved through prewarm gates, backlog fixes, fail-closed behavior, hysteresis, prefetch order, water budgets, deduplication, pruning, overlap guards, depth order, and frame pacing. Each name is a hypothesis: perhaps this frame is late because the resident set is too narrow; perhaps the gap appears because a noncritical append won the budget; perhaps the ring is correct but its ocean ownership is not.
A red report was not a verdict on the project. It was a smaller search space for the next morning.
04. Implement the systems, not just the picture
While the evidence pipeline was growing, the game was accumulating the systems a larger world would need. Terrain generation moved through land points, scalar fields, irregular blobs, erosion, jittered sources, smooth coasts, narrow beaches, biomes, and several generations of mountains. Pointy mountains became spiky clusters, then taller chains, then brush-stamped chains with explicit spacing and climbable continuity. A terrain generator rewrite followed, because the combination of rules had become more important than any single clever noise function.
Water went through a similar education. An ocean was not merely a blue surface. It needed a stable level, correct depth order, continuity around active chunks, a distant representation, shoreline foam, a response to camera motion, and eventually finite-edge waterfalls. The reports contain separate investigations for opacity, flicker, chunk attachment, ocean anchors, GPU caching, parallel generation, land/ocean splitting, depth occlusion, foam stability, and the point at which the active ocean hands responsibility to the distance system.
Then came the life on top: objects, object scale, camera-direction culling, full-radius residency, night visibility, buildings, cursors, terrain foundations, zones, inventories, pause and new-game paths, time controls, day and night skies, stars in several sizes and colors, twinkle, a moving sun, clouds, and atmosphere received by terrain and water. Some of these arrived before the 3D migration, some during it, and some were restored afterwards. The important architectural choice was that they described game state rather than one renderer's favorite representation.
The simulation owns meaning; the renderer owns a view
Keeping those responsibilities separate is what made it possible to move gameplay more than once without rewriting every rule.
- Input & UISelect, place, paint, pause, and inspect.
- CommandsValidated actions with explicit terrain and water rules.
- SimulationPeople, buildings, resources, zones, time, and ownership.
- World snapshotStable terrain, object, material, and environment data.
- Rendering2D sprites, 3D meshes, billboards, water, sky, and overlays.
The building interaction tests show how concrete this became. A test fixture started with exactly 200 wood, 300 food, and 100 stone. Selecting a half-built residence had to open the real container, preserve those values, highlight the mesh through a depth-tested outline, show the construction raised partway from the soil, and keep the circular dirt foundation visible. A later placement contract separated the time spent collecting terrain samples, mutating paint tiles, publishing a snapshot, invalidating terrain caches, invalidating material pages, and suppressing nature. “Clicking a building froze the game” could now be divided into phases with millisecond budgets.
This is what we mean by implementation. A feature is not the visible model alone. It is the rule, data, editor path, runtime path, feedback, failure behavior, performance envelope, and evidence that all of those agree.
05. Move into 3D without losing the game
The reason to move was not that 3D was automatically more modern. Empires was asking the map to communicate things a flat board could only suggest: elevation that shaped movement, coastlines with physical presence, settlements tucked beneath ridges, weather crossing a visible landscape, and a sense that exploration continued beyond the edge of the current screen. Terrain needed to become a place rather than a background.
That decision changed nearly every hidden assumption. A 2D cell with an X and Y position became ground in X and Z with a sampled height in Y. A click became a ray from a perspective camera. A selection circle became geometry that had to follow the terrain and pass a depth test. Objects needed bounds, orientation, occlusion, and cheaper distant forms. The camera acquired pitch, altitude, clipping planes, focus, and a horizon. Even “draw this after terrain” became a render-graph dependency rather than a simple ordering convention.
The same cell gained height, depth, and a camera
The simulation could keep its identity while every interaction learned how to project into a spatial world.
The earliest results were appropriately ugly. Terrain existed, but an innocent height rule could extrude thousands of needle-like walls. A camera angle that hid the problem from above turned it into a canyon of overlapping geometry from the side. This was useful. It proved that the pipeline could generate and draw height before we invested in making that height beautiful.
The technology stack beneath the migration
Empires runs on a managed .NET codebase. Its benchmark commands still
reveal the history in the project name, Empires.Veldrid.csproj,
while the current high-performance route is a native Silk.NET Vulkan
backend. That migration let the game retain its C# simulation and tools
while taking direct ownership of GPU resources, command recording,
synchronization, indirect drawing, capture, and the rendering decisions
unique to a very large strategy world.
From a player command to Vulkan work
Each layer has a different reason to exist. The lower layers make scale possible; the upper layers make that scale meaningful.
PacketizedGpuCullDrawIndexedIndirectCountMaterialPage:
packed material groups, culled and submitted on the GPU through Vulkan.
On the CPU, the world selector decides which terrain nodes should exist at each detail tier and prepares stable packets. Material pages keep terrain appearance grouped without a draw call per tile. On the GPU, candidate packets can be culled and submitted through indexed indirect draws. Retained vertex and index rings avoid allocating new geometry every frame. A render graph orders terrain, water, sky, buildings, billboards, atmosphere receivers, overlays, UI, and final submission. The test harness watches for runtime pipeline or resource creation because a renderer that is fast only after hitching is not yet fast.
The managed runtime is part of the design, too. Passing reports use .NET's
SustainedLowLatency collection policy rather than pretending
garbage collection does not exist. Allocation is measured per frame, and
a long benchmark can fail if a change brings back collections or creates a
large allocation tail. The stack is not “C# versus native.” It is a C#
game and tool layer with a deliberately native rendering boundary.
06. Try the most literal world: a planet
Once terrain could rise, the most seductive version of scale was a whole planet. A finite spherical world promised continuity without an arbitrary rectangular edge. Zoomed out, the player could see continents and oceans. Zoomed in, the same surface could hold settlements. Atmosphere had a physical shell. A horizon came from curvature instead of a rendering trick. It was hard not to fall in love with the first globe.
The planet path used a cube-net-compatible world: six manageable faces projected into a sphere. This is a practical way to give a round surface addressable cells and textures, but the transformation does not erase the cube. Every face boundary becomes a contract. Heights must match. Normals must agree. Textures must sample the same world position. Objects must orient themselves to the local surface rather than global up. Selection overlays must cross a seam. The camera must remain aligned to a horizon whose “up” changes wherever it moves.
A surprising amount worked. World Maker reports validate planet-aligned billboards, cell hover and selection, finite water, a day-and-night shader, a skybox, terrain and ocean fog, atmospheric edge glow, and a camera descending through a defined altitude band while staying aligned with the horizon. Raise, smooth, and flatten tools edited thousands of vertices. The planet was not a mock-up. It was a functioning research branch.
It was also expensive. A long World Maker benchmark averaged 22.39 FPS against the 60 FPS gate, with an average render time of 42.33 milliseconds and a worst frame near 140 milliseconds. That run covered a very large planet and an editor workload, so the numbers are not a comparison with later Conquest gameplay. They are evidence of the tax: every ordinary terrain task became a six-face, curved-surface, seam-aware version of itself.
The cracks in these images are the clearest symptom, but not the only reason for the pivot. A strategy game asks the player to understand space, compare distances, plan across regions, and keep a stable mental map. A globe is wonderful for overview, but it continually moves parts of that map out of view and bends every tool around local orientation. Curvature was adding design cost as quickly as it added spectacle.
We did not declare the planet a failure. It taught us what atmosphere, horizon alignment, curved coordinate projection, depth-aware objects, finite water, and global seams actually cost. The spherical World Maker path remains valuable research. The Conquest game, however, needed a surface where its simulation and interactions could become deep before its topology became exotic. We chose to flatten the playable world on purpose.
07. Settle on a flat world, then rebuild it honestly
Going flat sounds like removing a problem. In practice it exposed the problems we actually needed to solve. Without curvature to provide a natural horizon, the renderer had to create convincing distance. Without six planetary faces, a world could be much wider, which made streaming unavoidable. Without the drama of a globe, coastlines, materials, hills, forests, and settlements had to carry the visual identity themselves.
The reset was literal. After experiments with world-scaled continents, irregular landmasses, beaches, biomes, and mountain rules, one report family is named flat dirt terrain reset. The team deliberately returned to a plain surface and rebuilt the generator as smaller contracts: chunk-level land and ocean, ocean-level rendering, white-flicker guards, land points, natural chunk edges, scalar fields, height continuity, erosion, coast smoothing, mountain brushes, material transitions, and a rewritten generator to coordinate them.
The bare mesh made ownership visible. Each rectangular unit could be generated, selected, loaded, retired, and tested. Camera movement no longer implied rebuilding a whole planet; it changed a neighborhood of resident terrain. The world became large because it could be divided predictably, not because every piece existed on the GPU at once.
Texturing was the next boundary. A terrain tile has a local material, but the player sees a landscape. Abrupt squares made the world read like a board; unconstrained blending made it muddy. The renderer evolved from simple vertex color and baked textures towards ruleset-driven atlases and material pages, with height, slope, contour, and ridge shading helping the same grass and dirt express form. Close terrain could use exact painted data while coarser levels retained the larger color structure.
The active-terrain contract
The settled design gives the camera a high-detail active region extending 12,000 world units, shaped as a 24,000-by-12,000 forward-looking draw footprint. Four levels of detail populate that region, with a selector cap of 512 nodes. A larger resident guard surrounds it so a small camera move does not immediately evict and recreate the terrain at the edge. Every benchmark checks that the selected nodes cover the required area without gaps, duplicates, or truncation.
This is a form of constrained attention. The player receives the most geometry and exact material data where decisions are being made. Farther away, fewer vertices describe larger pieces of ground. Retained GPU vertex and index rings are sized for the working set and reused after warm-up. A temporary safety surface can cover a not-yet-resident patch, but a test requires it to converge to exact terrain after movement. A world is not stable if the coarse fallback quietly becomes permanent.
The active ocean became its own stable surface at a fixed water height, with shoreline foam generated from the same world field that defined the coast. It had to own water near the camera without fighting terrain, then hand the view to a distant-ocean path without a visible line. At finite world edges, waterfalls provided a deliberate end rather than a missing quad. Flat did not mean infinite by accident; it meant the edge could be a design choice rather than a topology leak.
08. Teach a finite renderer to draw a distant horizon
A detailed active region is enough for interaction, but not for belief. Lift the camera and its edge becomes a moat around the simulation. The first horizon experiment solved the emotional problem before the technical one: it put recognizable hills beyond the active ground, and suddenly the map appeared to continue. The foreground water still ended in a box. The transition was crude. But the illusion had a pulse.
How the six-ring system works
Beyond the active terrain are six lower-detail rings. Their resolved grid spacings increase from 192 to 384, 512, 768, 1,536, and 2,048 world units. Each step trades local shape for reach. Together, the rings extend roughly 176,864 units forward and sideways and 164,864 units behind the camera, while overlapping the active terrain by 512 units. That overlap is small beside the full world and crucial at the seam.
Spend detail where play happens; spend coverage where belief happens
The drawing is schematic. The production layout is rectangular and view-biased, but the nesting shows how responsibility moves outward.
- Active terrain · 12K
- Four detailed LOD tiers, exact materials, objects, interactions, and a 512-node selection cap.
- Ownership overlap · 512
- Both systems cover the handoff so no uncovered strip appears between near and far.
- Six distant rings
- Increasing spacing covers more world with retained, lower-cost meshes and separate ocean ownership.
- Canonical world field
- Every level samples the same world-space terrain so colors and landforms remain locked while the camera moves.
The rings do not simply drag a giant texture beneath the camera. They sample a canonical 4,000-by-3,200 world field, snap their anchors to a stable grid, and preserve world-space invariants. Passing benchmarks demand zero non-periodic translation, zero scale error, zero witness-UV drift, and zero anchor-snap error. In plain language: the distant mountain should remain part of the world as the camera moves, not swim across the ground because a convenient mesh was recentered incorrectly.
The final distance representation uses quality segments for visible landforms and a cheaper floor to guarantee coverage. Land and ocean are split so water can maintain its own depth and lighting behavior. Directional shading makes coarse terrain retain form. Because the distant meshes are retained and world-locked, a moving camera can travel thousands of units without uploading them again.
The middle distance fought back
Near terrain could look correct. The far horizon could look correct. The strip between them could still be a disaster. Early transitions produced ghost shelves, toothed coastlines, overlapping levels, dark voids, and layers that occupied almost—but not quite—the same height. The camera made those tiny disagreements flicker as it moved.
Texture data added another class of failure. An incorrect atlas index or a sample requested before its page was resident did not produce a subtle color shift; it punched black rectangles through a continent. The terrain ruleset atlas black holes series needed repeated visual and benchmark passes. Later tests separated missing main-terrain tiles, horizon texture/ocean blending, land/ocean split, and seamless atlas sampling so each could fail for its own reason.
Even after the holes were filled, agreement remained a visual problem. A bright square of exact active grass could sit on a desaturated distant field like a carpet. The two systems were describing the same land with different material scales, lighting assumptions, and sample filters. The solution was not to blur the seam until nobody could point at it. It was to make both sides derive color and form from the same world data, then choose a transition wide enough to hide the necessary difference in resolution.
The fixes sound almost geological: crack fill, exact edge height, water-aware edge height, watertight side geometry, coarse-line seams, grid-core water, inland targets, world-locked rectangles, and distant-ocean depth occlusion. Beneath those names were streaming policies: prewarm what the camera is likely to need, prioritize required coverage, deduplicate requests, retain useful residents, use hysteresis so the boundary does not thrash, fail closed when exact data is not ready, and keep a bounded amount of work per frame.
The clearest turnaround came from the horizon-order benchmark. Its first recorded version averaged 10.78 FPS and contained a frame longer than one full second. After fourteen iterations, the same investigation passed across 4,096 measured frames at 63.99 FPS, with no frame over 16.67 milliseconds, a 2.20-millisecond average render time, no runtime GPU stalls, no runtime resource creation, and valid low and final refinement checks. The horizon did not become fast through one clever shader. It became fast because ownership, ordering, residency, reuse, and pacing finally agreed.
09. Bring the game—not only the renderer—into 3D
A beautiful terrain benchmark is not a strategy game. Once the flat-world and horizon contracts were stable enough, the next milestone was to restore the entire path from starting a game to acting inside it. The sequence ran through New Game world selection, Conquest terrain selection, banner setup, starter gameplay, pause behavior, and an end-to-end gameplay migration benchmark. Each menu capture mattered because a migration that only works through a developer command line is not complete.
The first full benchmark is one of our favorite red reports. It averaged 63.99 FPS. Its maximum wall frame was 15.63 milliseconds. It travelled the camera through the world with every required movement and yaw input. It created no runtime GPU resources. It still failed. The distant rings ended 512 world units short of the ownership contract: 176,352 units forward and sideways instead of 176,864, and 164,352 behind instead of 164,864.
That was not pedantry. The missing 512 was the exact overlap between the 12K active terrain and the first distance ring. At one camera angle the safety surface could disguise it; under another, it could become the strip where neither system took responsibility. The next attempt failed to start. The third included the overlap, reached the corrected extents, and passed.
Then the old verbs returned one by one. Terrain and horizon streaming were corrected around gameplay movement. Biomes and nature populated the ground. Coastal relief and grass softened the generator. Objects remained visible at night, adopted spatial streaming, and gained distant forms. Building UI attached to real world objects. Construction previews became partially raised translucent meshes. Foundation painting altered the terrain beneath them. Zones conformed to slopes and stopped at water. Pause, time, and menu state had to suspend or resume the same simulation the 2D prototype once controlled.
This is where the separation between simulation and presentation paid its debt. The player still understood wood, food, stone, a building container, an eligible piece of ground, a day passing, and a worker standing near a task. The renderer's job was to give those meanings depth without changing them. A zone was no longer a circle painted on the screen, but it was still a zone. A building was no longer a flat drawing, but opening it still had to feel immediate.
The frame had room for the game again
The bars show selected average CPU scopes from the passing run on a two-millisecond scale. They are nested measurements, not values to add.
Average CPU milliseconds; bars are scaled to 2.0 ms for legibility. GPU timestamp queries were not available in this report, so submission and presentation are covered by the wall-frame gate rather than these bars.
Passing that run did not make every later report green. Dense nature, object streaming, building commits, UI changes, and terrain refinement can still produce rare long frames. Recent builds often average between 63 and 64 FPS while failing on a handful of spikes. That is the honest state of the work: the architectural migration is proven, the world is integrated, and the remaining engineering is increasingly about consistency under real gameplay pressure.
10. Success—and the direction of Empires from here
We can finally say it plainly: the migration succeeded. Empires can enter Conquest through its real New Game path, create a world, render detailed active terrain into six world-locked distance rings, draw an ocean and its shoreline, move through a changing sky, populate the landscape, and run the settlement interactions that gave the original prototype its purpose. The current game is no longer a 2D simulation beside a 3D renderer. It is one playable 3D environment.
Success here does not mean “finished.” It means the foundation has stopped asking to be redesigned. The direction is now a wide, flat strategic world where the warmth and readability of pixel art meet physical terrain, weather, water, construction, and distance. The player should be able to understand a worker at a wood pile and, in the same frame, understand the mountain range that shapes the next stage of the settlement.
The next work goes deeper rather than wider: richer procedural biomes and landforms; more purposeful coasts, mountains, and landmarks; building, terrain, and zone tools that feel like fluent game mechanics; better object and nature streaming; exact terrain refinement after movement; retained UI work; and the removal of rare frame spikes. We are no longer trying to prove that the horizon can exist. We are deciding what the player will find on the way there.
After all the rewrites, the decisive question was not whether we could draw a planet or stream one more ring of terrain. It was whether Empires still felt like Empires. The first frame in which the answer became unmistakable is the one below.
The game came back—inside a much larger world.
Migration successful