Status

2025-12-03: This is on hold for now. I moved from Windows 11 to Linux and haven’t rebuilt my game-dev setup yet. The big unknown is the Unreal Engine toolchain: I still need to confirm it will build and compile cleanly on Linux for this project.

First, some videos

Basic city gen working, lots of decorations: https://www.youtube.com/watch?v=M50FAsi7-1w

A more playable demo: https://www.youtube.com/watch?v=4u57CENYcI4

Game overview

Perpetual City is an open-world game set in a procedural city with no edge. Walk long enough in any direction and new districts keep forming. The vibe shifts as you move, so the city never settles into something you can fully “learn.”

Tonally, I keep thinking about Worm and the uneasy, reality-bending mood of Control. For Control it is not in a copy-the-plot way, more in the “something is off, and it might be watching you back” sense. For Worm, I’m tempted to just copy the plot… or at least how powers interact.

I’m planning for kind of rough like. Death is part of the loop, not rare. When you die, you return to a safe location with what you learned intact. You come back as another super-powered individual.

NPC behavior is intended to feel emergent instead of fully scripted. The world would react across runs: help one faction and another may turn hostile; a small intervention can kick off a bigger conflict; consequences can carry forward even when parts of the environment reshuffle.

I also want this to stay open-ended. It’s a hobby project I can keep growing without a finish line.

Key features

Dynamic exploration

Interactive NPC transformations

Narrative and lore

Respawns and memory threads

Strategic, variable gameplay

Perpetual City blends procedural exploration, a death-driven progression loop, and an evolving faction ecosystem inside an infinite city.

Attribute system: CREST

Characters are described through CREST. (Yes, I ripped this idea off Fallout.) I wanted a stat set that covers mind, weird power, physical grit, luck, and social pull without turning into a spreadsheet simulator.

Factions and world dynamics

The city has factions with distinct goals:

Gameplay experience

Coding details

PerpCity uses the UE5 runtime system: generate terrain and urban structure around the player as they move, with no pre-baked map. The target use case is an always-extending world for the project. Start anywhere, go any direction, and the environment forms on demand.

The system is three layers:

A guiding idea that kept paying off: treat most layout as 2D geometry work (polygons, offsets, boolean operations), then lift it into 3D meshes only when it’s time to render.

What it produces at runtime

As you play, it generates:

This is what I’ve spent most of my time on.

Editor setup (no code access needed)

The tile-based runtime path is the current approach.

  1. Enable the PerpCity plugin.
  2. Place the World Manager actor in the level (this runs the system).
  3. Assign an auto-material for terrain (optionally with a scalar parameter used for tile fade/opacity).
  4. Press Play.

Key controls on the manager:

Those knobs exist because the system is always balancing two competing goals: react quickly to player movement, and avoid frame spikes from doing too much geometry work at once.

How it works at runtime

1) The manager keeps tiles around the player

On a repeating cadence:

Tile work is budgeted. Higher-detail work costs more, so you can keep responsiveness while keeping frame time from going off a cliff.

2) Each tile generates terrain, then evaluates buildability

When a tile initializes or changes LOD:

This is what stops roads from happily marching up cliffs or fragmenting into isolated patches.

3) Roads grow through scored candidates

The score mixes things like:

In practice, this tends to create networks that “organize” instead of spraying random lines.

4) Blocks and buildings come from roads (still early)

Right now, block extraction is simple:

5) Buildings start from a 2D footprint polygon

Given a footprint:

Each floor can then spawn interior logic: subdivision into rooms, walls/doors, decoration.

6) Rooms place objects while protecting walkable space

Interior decoration is treated like a constraint problem in 2D:

Instead of building a full pathfinding graph for each attempt, the system uses polygon operations and offsets to test connectivity.

The geometry problems and the choices I made

PerpCity leans hard on 2D polygon math. The basic idea is: make layout decisions with robust geometric operations, then translate the result into meshes.

Polygon cleaning and consistency

Procedural inputs are messy: near-duplicates, collinear runs, self-crossings, inconsistent winding order. Utilities exist to:

Without this, offsets/booleans/triangulation get unstable.

Boolean ops and offsets that don’t fall apart on concave shapes

Hand-rolled clipping failed quickly. A robust polygon library handles:

One practical detail: the library operates on integer coordinates. World units get converted into integer space. That improves robustness in some ways, but it introduces precision/tolerance headaches around intersections.

Holes, partitioning, triangulation

Offsets and booleans often create holes. Rendering wants something simpler.

A partitioning/triangulation library helps:

This makes “complex footprint to renderable mesh” workable without reinventing polygon decomposition.

Collision testing for footprints and placement

For frequent checks like “does footprint A collide with B?”, a Separating Axis Theorem (SAT) approach works fast:

It’s fast enough for repeated checks, especially after the cleaning pass makes shapes closer to convex.

Walkability as polygon connectivity

One of my more proud tricks is traversability via polygon math geometry:

This answers “is the room still usable?” without constant nav-meshing.

Sliding an object until it hits something

For snug placement against walls without complex constraint solving:

Non-geometry issues I ran into and what I did about them

Stable frame time while generating heavy geometry

Procedural mesh creation, road growth, and interior decoration can spike. To address this I have dynamic frame budgets setup:

Result: the system stays (mostly) interactive while streaming content.

I’m sure every AAA game has a way of doing this, and that I’m not really doing state-of-the-art… but most AAA games don’t dynamically create their meshes and interiors.

Road intersections: “touch” vs “cross”

Problem: junction logic is full of edge cases:

Approach:

Status: better than the initial version, but splitting still gets noisy in edge cases.

LOD blending flicker during transitions

Problem: opacity-based LOD transitions flickered.

Approach:

This is a boring choice, but stable visuals beat fancy transitions that look broken.

Concave footprints and center-based assumptions

Problem: some footprint operations assume there’s a meaningful “center.” Concave and L-shaped polygons break that.

Approach:


What’s unfinished

Tile-based roads and blocks

Buildings and interiors

Persistence

Playability

This isn’t actually a game yet. I have a bunch of game-like abilities (nav-map, NPC AI including shooting, bullet penetration simulation, superpowers)… but these are mostly just to entertain myself between coding.


Third-party and adapted components

PerpCity uses:

To-Do