Home Lights
Keep twenty-five first
It was a Monday, so James was at work, and most of what he put into the day arrived as short typed replies. Install and build. Keep 25 first. Mark the doors. Do all of it. yes gate links. The rest of it was done by agents.
He had handed it to the Projects feature in Claude Code, which is in beta. A planner takes the job and hands pieces of it out to several agents running Opus 5.5, each in its own session, each reporting back up the chain. The job was a hundred people. Second Chance already has thirty named townsfolk with their own week - Baz at the bar by one most days, Shirley opening the post office at seven - but the plan is a whole town's worth: a hundred residents in households, with jobs, school runs, cars and bus fares, all of it running whether the player is watching or not.
The part that does the thinking had been written as a C++ plugin, which is a first for a project that has been Blueprint-only since the day it started. It came down to his machine as a zip of 181 files. The first agent of the morning - Claude Code Opus 5.5, like the rest of them - was given one instruction: make it compile, and do not touch anything else in the game. Then James was asked how much of it to switch on. He chose to keep the existing thirty-odd citizens visible and let the hundred run in the background, unseen, until the plumbing between the two was proven. That was the sensible answer. It also meant that by the end of the day there would be a hundred people going about their day in Radworth that nobody could see.
GTA 6 has been built by a studio the size of a small town. This town had a Monday and some agents.
Nineteen errors and a roundabout
The first build stopped in the header tool, which refused a type alias inside a property it was meant to expose to the editor. The second got further and stopped on nineteen errors across ten files. None of them were mysterious. Every one was the engine having moved since the code was written: a getter that Epic have made private in 5.8, a weak pointer that can no longer be tested like a true-or-false value, a navmesh function that now takes one argument and returns the answer instead of filling one in, a maths constant that does not exist under the name the code used. The agent fixed them in the plugin source, logged every change in a table, and had a clean build by quarter past eight. It kept a patch of the differences so the copy the other agents work from could be brought into line.
Then it pressed play, and the editor fell over 23 seconds later.
The assert was the kind that tells you exactly what happened and not why it matters. The road system builds itself from the level's road splines when the world starts. Where a road is a loop, it closes the loop by adding the first point to the end of the list - and it did that by handing the list a reference to its own first element while the list was growing. Unreal checks for that in the editor and stops dead. Radworth has roundabouts. So every play session crashed before a single citizen moved.
The fix was one line, twice: copy the point first, then add the copy. The same mistake was sitting in the bus route code, waiting for the first looping route. The rebuild was refused by the machine's permission check, and it sat there until James typed rebuild ok from wherever he was. By ten past one the game ran.
Six of six citizens spawned within a second of the intro being skipped. That mattered more than it sounds. In August a playtest had found none at all. It did not reproduce. They spawn when the player is within 70 metres of their home, which the August test had not been.
Ian and Paul then walked out to their front doors and stood there. Both doors read locked. Only five houses in the whole estate had ever been marked as a citizen's home. The agent proved it with a trick it could only do in a running game - it moved Paul four steps past his own door, and he set off for the market at a steady walk - and then asked. James said mark the doors. Twenty-three were marked. Two more were held back, because there is a furnished burglary set behind each of them, and that is a different conversation.
The sun in somebody's front room
The brief asked for screenshots of the street. The screenshots came back black.

The agent's first theory was shaders still compiling after a restart. Its second was exposure, and it switched the camera's eye adaptation off from the console to get a fixed brightness. That made the shots white instead of black. It also did something that took four and a half hours to come to light: a show flag set from the console is not a setting on a camera, it is a global override, and it outlives the play session. James's own editor viewport stayed blown out to white from quarter past one until quarter to six, when it was found and put back. The value that means "default" is 2. Setting it to 1 does not put it back; it forces it on.
The sun was found mid-afternoon, and it was the best fault of the day.
One of the plugin's systems gives every house a life of its own after dark: lights on in the front room, off again at bedtime, off in the day when nobody needs them. To know which lights belong to which house, it draws a box round each one and adopts every movable light inside it, filtered by name. Unreal puts the sun at the very centre of the world unless you move it. In Radworth, the very centre of the world is beside 13 and 15 Brickyard Close. So the house adopted the sun, and at about 41 seconds into each session, finding it was daytime, it turned the big light off.

There were two fixes and James said do all of it, so both went in: the sun's own kind of light is now on the house system's ignore list in the settings, and the code that adopts lights now skips a directional light outright, whatever it is called. After the rebuild the sun held for seven minutes and counting.
Over the garden wall
At twenty to four James sent a message that had nothing to do with the sun. Charlie was going out of his front door and stepping over the low garden wall instead of using the gap in it in front of the door. Nobody does that. He wanted them to use the gate.
The cause was a number. The navmesh had been set to let walkers climb up to 60 centimetres, weeks earlier, to get people up a kerb onto a raised road platform. The terrace garden walls are 60 and 61 centimetres. So the pathfinder was happy to route straight over them, and the citizens, who can climb rather less than that, wedged.
The agent's written investigation suggested 55 would bring the effective climb down to 50. It tested 55. Every one of 1,638 probe results came back identical to 60. The engine rounds the step up to a whole number of 10-centimetre cells, and 55 rounds up to six. So it went to 50, added seven nav links through the garden gates where the lower step left a doorstep stranded, ran its checks that nothing else in the town had lost a route, and saved the navmesh. Routes that crossed more than 45 centimetres of something went from 186 to 14.
The fresh load found two new ones. Pete and Baz both live in mirrored houses, where the door swings the other way, and the path out now ran tight along the hinge line and straight into their own opened door. They stood just inside their hallways for eighty seconds with a complete path in front of them. That is where it was left.
Nobody works here
At half five James asked for something different: watch a whole day, seven till ten, and see where people go and what they do when they get there.
At twenty-four minutes past twelve Baz walked to Boss Man's corner shop and stopped against the side wall, by the window. James said he was going to work. The schedule said Shopping. It also said nobody works at Boss Man's at all. The marker for the shop had been put on the wall line, with the shelves on the other side of the bricks, and when Baz reached it there was nothing more for him to do. James's answer was to put him behind the counter for now.
The chippy at dinner was worse, or funnier.

Nine citizens go to the chippy at one on weekdays. The four nearest the player turned up, walked to the marker, and huddled against a blank wall round the corner from the door. The counter is inside, the three chairs are inside, and the navmesh reaches all of them. What is missing is anything telling a citizen what to do on arrival. Of all the places in the town, only the pub has that, and it shows.

James also said the bricks on that side of Boss Man's were flashing. The agent went looking for two faces fighting over the same spot and did not find one: no brick sits on brick anywhere on the shop. What it did find is the window glass, 5 millimetres behind the brick face, poking through in thin strips round every frame. A two-frame comparison from a fixed camera showed no flicker on the plain brick at all. It wrote down both explanations and sent the question back - is it at the window edges or in the middle of the wall? - which is the right question and not an answer.
From six minutes past six James had the camera himself, flying round the town in the free view. The agent's screenshots from then on were of whatever James was looking at. It said so in the report.
A phone you have to buy
Halfway through the evening James made a call that changes the opening of the game. The player no longer starts with a phone. He comes out on the release programme with nothing, and the phone is something he buys.
Every GTA since the fourth one has put a phone in your pocket in the first hour, because the story needs to be able to ring you. There is no story here that needs to ring you. So there are two places to get one. Boss Man sells a burner from behind his counter for £50. He takes £40 if you push, and refuses £30. Baz will sell you the same phone in the pub, at the same prices, in his own words. Once you have one, neither of them sells again.

The lines on the Boss Man side are James's own, word for word, and the build script refuses to run if they drift. It was tested with Baz in the running game: press U to talk, ask for less, take forty. Cash went from 100 to 60 and the phone came on. Everything that uses a phone - the texts, the delivery app, the phone on the e-bike handlebars - now checks first whether you have one.
The children
The town's hundred include children. In the simulation there are households with children in them, the under-elevens walked to school by an adult, and Radworth Primary running from quarter to nine to quarter past three. They live through the day like everybody else. Until the second batch builds the bridge between the simulation and the screen, they do it out of sight.

Three child characters are built and dressed - a hoodie and joggers, a tee and cargo trousers - in free Fab clothing chosen against what a British high street is actually selling to kids this autumn. The next job is making them walk like children. Adult clips on a 99-centimetre body carry an adult stride, and that is exactly the sort of thing a British player would clock in half a second.
Three of the agents on this thread ran out of room before they finished, and each handed over to the next with a written note: what was done, what was proven, the exact next action. Just before one in the morning the last of them sent Ian to work for the first time. At twenty-four minutes past five, game time, he put a hi-vis on and walked to the depot.
The fault
A C++ plugin fails to compile in Unreal Engine 5.8: UHT "Unable to find" and 19 errors
A third-party gameplay plugin, installed into a Blueprint-only project. Two builds before it linked.
- UHT:
Unable to find ... 'FTownPlaceId'- ausingalias used as aUPROPERTYtype. The header tool cannot resolve aliases. - C2248
USkeletalMeshComponentBudgeted::GetAnimationBudgetHandleis private in 5.8. - C2280
TWeakObjectPtrhas no usableoperator boolin 5.8. - C2660
ARecastNavMesh::GetPolyAreaIDtakes a different number of arguments. - C2039
TNumericLimits<double>::Quiet_NaNdoes not exist. - C2397 brace-init narrowing double to float (large world coordinates make
Dist2DandRotation().Yawdoubles). - C2365/C2440 an enumerator and a struct member with the same name,
Node. - C2275
UNavigationSystemV1::GetCurrent<...>used as an expression. - C4458 a local called
OwnerhidingAActor::Owner, as warning-as-error.
The fix
Port the plugin to the 5.8 API, one error at a time, and keep a patch
- Alias: use
int32in theUPROPERTY; keep the alias for C++ only. - Budget handle: drop the getter check.
FAnimationBudgetAllocator::RegisterComponent/UnregisterComponentalready ignore a repeat. - Weak pointer:
.IsValid(). GetPolyAreaID:uint32 AreaId = GetPolyAreaID(Ref). It returnsRECAST_DEFAULT_AREAon failure.- NaN:
std::numeric_limits<double>::quiet_NaN(). - Narrowing:
static_cast<float>. UNavigationSystemV1::GetCurrent<...>as an expression:FNavigationSystem::GetCurrent<UNavigationSystemV1>(World).
The guard: log every change in a table and regenerate a unified diff against the pristine zip, so the copy the other agents work from can be patched. Keep LF line endings; a Python write_text on Windows writes CRLF and turns every file into a diff.
The fault
PIE crash: "Attempting to use a container element which already comes from the container being modified"
Full assert: Addr < GetData() || Addr >= (GetData() + ArrayMax), SizeofElement 24. Fired 23 s into every PIE on a map with a looped road spline. Points.Add(Points[0]) passes a reference into the array being grown; if Add reallocates, the reference dangles, and the editor build asserts on it.
The fix
Copy the element before adding it
const FVector First = R.Points[0]; R.Points.Add(First); The same pattern was in the bus-route code (Stops.Add(Stops[0])). The guard: a regex sweep for X.Add/Push/Insert/AddUnique/Emplace(X[...]) across the plugin; it found those two and no more.
The fault
DirectionalLight hidden about 41 seconds into PIE, streets render black
The sun was in the level, movable, and visible in the editor. In PIE it went off at about 41 s. A home-lights system adopted every movable ALight inside each house's search box, matched by name, and switched house lights off by day. The sun sat at world origin, which in this level is beside two terraced houses.
Wrong turn on the way: ShowFlag.EyeAdaptation 0 to get a fixed exposure for the screenshots. Show flags set from the console are global overrides that outlive PIE. The editor viewport stayed blown out white for four and a half hours.
The fix
Skip directional lights in the light binder, and restore show flags with 2
- Settings: the house system's ignore-by-name list gained
directionallight(alongside street, skylight and sun), written to the project's ini so it survives a restart. - Code: the bind step returns early for a
UDirectionalLightComponent, whatever it is named. - Show flags: 0 forces off, 1 forces on, 2 is default. Restore with 2, never 1.
Verified: after a fresh launch the ignore list reads four entries and the PIE sun stayed on for seven minutes.
The fault
Navmesh routes step over 60 cm garden walls, and AgentMaxStepHeight 55 changes nothing
With AgentMaxStepHeight 60 the pathfinder routed citizens over 60-61 cm terrace garden walls that their capsule could not climb; they wedged. 55 produced 1,638 probe results identical to 60. Recast computes walkableClimb = CeilToInt(AgentMaxStepHeight / CellHeight), and with 10 cm cells 55 rounds up to 6 cells, which is 60.
The fix
Step 50, gate nav links, and a full nav gate before saving
AgentMaxStepHeight 50 on all three resolution settings (5 cells), plus re-seated nav links through the garden gates where the lower step stranded a doorstep. Before the save: 453/453 terrace doors routed to the street, 81/81 citizen routes, the loo and house-6 route probes unchanged. Routes crossing more than 45 cm of geometry fell from 186 to 14. Backups of the navmesh were taken first; it is a level actor and there is no undo.
The kit
| Tool | Why this one |
|---|---|
| Claude Code Projects (beta) | a planner splitting one large job across several Opus 5.5 agents, with James's choices relayed down as short replies |
| Unreal Build Tool, from the command line | the project has no Visual Studio solution; Build.bat UnrealEditor Win64 Development -Project=... builds the plugin on its own |
| Monolith MCP | starting and stopping PIE, running the editor Python probes, firing HighResShot |
| A written handover per session | three agents hit the context limit on the same thread; each picked up from the note |
Plain English
| Term | What it means |
|---|---|
| plugin | A self-contained bundle of extra code and settings that drops into an Unreal project and adds features to it, here a whole town simulation written in C++. |
| Unreal Header Tool | The program that reads a C++ plugin's headers before the compiler does, to work out which parts the editor and Blueprints are allowed to see; if it rejects something, nothing gets compiled at all. |
| PIE | "Play In Editor" - pressing play inside the editor to test the game without building it first. Fast, and it behaves subtly differently from the real build. |
| navmesh | An invisible map of walkable ground that characters use to work out routes. No navmesh, no walking. |
| nav link | A hand-placed bridge that tells the pathfinder two patches of navmesh are joined, for gaps it cannot see across on its own - a narrow doorway, a jump, a ladder. Both ends snap to the nearest walkable floor, which is right until the nearest floor is the one below. |
| step height | The tallest ledge a walker is allowed to step straight up; the navmesh and the character each have their own, and when they disagree, people get routed over walls they cannot climb. |
| directional light | The light that stands in for the sun: it shines the same way everywhere in the level, from infinitely far away. |
| show flag | A console switch that turns one kind of rendering on or off, such as fog or auto-exposure; set from the console it overrides every view in the editor until it is put back. |
| exposure | How bright the virtual camera treats the scene, like a real camera's aperture and shutter. A higher EV100 number darkens the picture. This project pins it per building so a room does not slowly brighten while you stand in it. |
| citizen director | The part of the game that brings townspeople into being near the player and puts them away again when the player leaves, so a whole town can run without every person existing at once. |
| MetaHuman | Epic's system for realistic human characters - face, body, hair and clothing, ready to animate. Every named person in the game is one. |
| z-fighting | What happens when two surfaces sit in exactly the same place, both facing the same way: the renderer has no way to decide which is in front, so it picks differently from frame to frame and the wall flickers. On this project it is a photosensitivity requirement rather than a polish one, so the geometry is measured for it rather than eyeballed. |
| context window | How much of a conversation an AI model can hold in mind at once; when a session fills it, the work has to be written down and handed to a fresh one. |
Things we still need to fix tomorrow:
- Pete and Baz stand behind their own open front doors in the mirrored houses. The door links sit on the hinge line; moving them off it is next.
- Fourteen routes still cross a garden wall, and three citizens can only get partway to the health centre from the back-garden pockets they start in.
- An arrival routine for every venue: in through the door, queue at the counter, buy, sit or take away. The chippy first.
- Baz behind Boss Man's counter, the club's bouncer and barmaid, and the Palace staff whose bodies sit 57-60 cm above their seats.
- Boss Man's side wall: window edges or plain brick. James to say which.
- The bridge that puts the hundred on screen, children and school run included. Child walk and idle clips, and hair, are needed first.