Commissioning
Twenty threads, one editor
It was Saturday, so the gym and then the whole day on the game, and for once the work did not have to fit round anything. By the end of it the roadmap had become a timetable.
The roadmap is the file where every intended feature of Second Chance sits in one of four tiers: built, in flight, planned, or only an idea. By the afternoon the planned tier had thirty-five rows in it, eleven of them added that same day, and James had asked for the obvious thing. Build them. The agent, Claude Code Opus 5.5, did not try to build thirty-five features at once. It wrote a brief for each group of rows and sorted them into twenty sessions in four waves, small and offline first, big and blocked last, so that only a few threads would be fighting for the editor at any one time.
That last part is the whole problem. There is one copy of Unreal Engine 5.8 open on one machine with one 8 GB graphics card, and only one thing can press play in it at once. So a coordinator thread hands out the editor in turns. A thread does everything it can offline, writes its scripts and dry-runs them, and then waits for a go. Every brief carried the same rules at the top: never Save All, back up before saving, and load the big town once per editor launch, because a second load crashes the graphics driver.
Rockstar have a building full of people for GTA VI and, presumably, more than one copy of the editor. Here it was a queue.
The day did not go to one feature. It went to a wind farm, a graphics setting that had been wrongly turned down a few days earlier, and a car that left one tyre track in the snow instead of two. The toilets got a ruling from James at twenty past six, and a fresh thread started on cigarette smoke the wind can blow about. Neither of those reached the editor before the day ran out.
A promise somebody keeps
The town in Second Chance has a council election in its calendar. The player is out of prison on a release programme, getting on with his life, and the vote happens round him. Most games would hang a cut scene off the result. James wanted the winner's main promise to actually happen in the world, so that a vote has a consequence you can see from the end of your street. One candidate promises a wind farm on the hills outside town: construction starts the next day, the turbines go up one at a time on cranes, and once it is switched on the player's electricity bill drops to nothing.
The code for that had existed for days and nothing was in the world. The turbine, the crawler crane and the tower sections had been modelled in Blender and exported, and they sat there as nineteen files. On Saturday the agent imported fourteen meshes at true size, a 200 m turbine to the tip of its blade, and placed the farm in the town.
The first import went wrong in a way that took a while to see. The agent read the size of the rotor from its height in Blender and assumed the height was two blade lengths, one up and one down. It is not. Three blades sit 120 degrees apart, so one points straight up and the other two point down and out, and the lowest tip sits only half a blade below the hub. The rotor's height is one and a half blade lengths. The agent "corrected" the rotor by a factor of 1.356, which made it a third too big, and then carried the same factor on to the next meshes as if it were a property of the export. It was a property of the rotor. Every mesh was re-read on its own, and the fix stopped travelling.

The editor preview can scrub the build through its stages, so the agent took stills, mid-build and finished. That was where the second problem turned up. The turbine sites had been chosen weeks ago from a height map of the hills, by picking summits, and the height map knew nothing about anything built since. One turbine stood 50 m inside the new upmarket estate. Two more were within 200 to 340 m of Kelsthorpe, the steel-framed estate that went up the week before. The agent wrote a read-only finder that looked for local summits at least 500 m from anything built, moved the three, and noted in the handover that the finder has to run again after any new building goes up near the farm.
James looked at the stills and said yes, it looks good.

Then the bill. The electricity bill in Second Chance is not a number on a menu. The cellar grow on the crime path runs real lamps on a real meter: the LEDs over the plants clock up units, the meter charges 26p a unit with £4.20 a week on top, and every Monday a text arrives and the money comes out of the player's cash. Run the lamps longer and the bill shows it, which is the point. Cutting the bill to nothing took one multiply node, placed where the meter works out the week's charge. That one number feeds the text and the debit both, so one change covered both.
A £0.00 bill counts as collected even when the player has no money at all, which is the right answer for the wrong reason. The text still says the weekly bill has been collected, with no mention of a wind farm, because changing the wording means recompiling the game instance, the object that holds the player's money, and on this machine that has a habit of running out of memory and taking the editor down.
The farm is in the world. Whether it builds itself in play - the cranes standing down, the rotors turning, a Monday with the bill at nothing - is the next test, and it needs the wind farm candidate forced to win and the clock pushed on several days.
The orange was the street lights
The morning had started on something else: a decision that had been made on bad evidence.
Earlier in the week the game had been running out of video memory at its top quality setting, Epic. Ray tracing is a big lever. Turning it off had saved about a gigabyte in an earlier test, which was the only single change that had ever brought Epic under the 8 GB card's budget. It had been rejected. The night still with ray tracing off came back drenched in orange, the street lamps smeared into fog and the sky glowing, and the agent had put the orange down to the missing ray tracing.
On Saturday morning it took the same night still with ray tracing on, in the current build. That was drenched in orange too. The orange was not ray tracing. The older still it had been compared against came from an older build, before the night fog had been retuned, so two things had changed between the pictures and the agent had blamed the wrong one. At twenty to twelve James settled the rest: the orange is meant to be there. Sodium street lamps in fog look like that, and anyone who grew up under them knows it.

So it was run again properly, as a fair pair: same build, a fresh process each, Epic, rain, no residents. At night, ray tracing on used 7,349 MB and ran at 12.8 frames a second; off, 6,393 MB and 13.7. In daylight it was 7,364 MB at 5.6 against 6,129 MB at 7.5. The two daytime frames were the same picture apart from one reflection in a car windscreen. Ray tracing went off in the game and stayed on in the editor, where the offline path tracer still needs it.
Two other ideas closed the same morning: trimming what ray tracing could see saved almost nothing, and forcing hair cards saved no memory, because the strand data stays loaded either way. A verified run after lunch had Epic at roughly 6 GB and 13.3 frames a second, and the bottleneck had moved. It was no longer the graphics card. It was the game thread, at 75 ms a frame, all the small Blueprint jobs every object does every frame: seventeen toilet cubicle doors, twenty toilet pans, sixty-eight bird controllers. By the evening the whole town's traffic had been switched on, and with 100 residents in the rain it was 7.7 frames a second.
That is a long way short of 30. The next lever is the per-frame Blueprint work, and it needs its own turn in the editor.
One track or two
At ten to five James was looking at snow, and he said what anybody would say who had ever followed a car down a snowy street. The tyres were only leaving one track. There should be two, left and right.
The agent's first finding was worse than his. The tracks are a Niagara effect: four thin strips of particles laid flat on the road, one per wheel, driven by a director object that keeps a table of which vehicles get tracks and where their wheels are. That table had been written in September for the older traffic. The new resident cars, the ones the town's traffic system had started spawning the day before, each have their own class, and none of those classes was in the table. The commonest cars on the road were leaving no tracks at all.
Adding them did not finish it. With the twelve new car models in the table, the agent measured where each wheel actually touched the road, and the resident cars ride about 4 cm lower than the older traffic. On one side of a car that was enough to put the strip under the snow surface. The track was being drawn. It was drawn under the snow. That was James's one track: the other one was there, buried. The contact height on the new rows went up to 12 cm and both tracks appeared, at the car's own wheel spacing.

Two smaller things went in with it. Parked cars were filling the slots meant for moving ones, so the new rows only track a car moving faster than 30 cm a second, and the number of cars tracked at once went from 16 to 24. And James asked a second question three minutes after the first: does fresh snow cover the old tracks, and when it melts do they go? The melt was already right. The cover was not built. The tracks just vanished when their 90 seconds ran out. Now each strip is stamped with the time it was laid and a shared snow cover value rises while snow falls, so an old track fades under new snow while a fresh one stays sharp. The play test that evening showed both, the older track visibly thinner fifty seconds later, and when the snow stopped and thawed every track was gone and every one of the effects had been destroyed within 105 seconds.
What it comes to
A wind farm stands on the hills, sited round two estates that did not exist when the sites were picked, and a bill can drop to nothing because of who won the vote. GTA VI is set in a version of Miami. This is a Midlands town, and that is the argument: a place with a council, a bin round, a bill on a Monday, and a vote that can change the skyline.
The snow got its second track because somebody looked at a road and knew what a road in snow looks like.
The cigarette smoke is next in the queue.
The fault
Snow tyre tracks show only one wheel track in Unreal Engine 5.8 (Niagara ribbon under the snow surface)
- Cars left one track in snow instead of two, and some cars left none at all.
- Cause 1: the track director's per-class table predated the new resident car classes, so the commonest traffic was never registered.
- Cause 2: the new cars ride about 4 cm lower than the old traffic. The ribbon is drawn at a fixed height above the wheel's contact point, and on one side of the car that put it below the snow surface. Measured on one model, the two left wheels touched at -0.7 and -0.6 cm: that side's ribbon was buried.
The fix
Two tracks at the car's own wheel spacing, covered by new snow and cleared on thaw
- Added a row per resident car model, with wheel positions and wheelbase read from the car's own components, plus a catch-all row for the parent class. Contact height 12 cm on the new rows.
- New per-row minimum speed, 30 cm a second, so parked cars do not take the tracking slots. Tracked cars 16 to 24.
- Fresh-snow cover: a shared
TrackCovervalue in a material parameter collection rises while snow falls; each ribbon is stamped with its own cover and age when laid, and the material fades it as the difference grows. - Guard: in play, check the wheel contact height per vehicle class with a probe before trusting a track table. A ribbon under the surface draws and is invisible.
The fault
Ray tracing off rejected because the night still turned orange - comparing stills from two different builds
- The ray-tracing-off night capture came back orange and fogged; it was compared against an older ray-tracing-on still and the orange was blamed on ray tracing.
- The older still predated a night fog change. The current build is orange with ray tracing on as well, and the orange is intended: sodium lamps in fog.
- Cost: the only change that had ever brought Epic under the 8 GB budget sat rejected for several days.
The fix
A fair A/B pair, then ray tracing off in game only
- Same build, a fresh process for each, Epic, rain, no residents. Night: 7,349 MB / 12.8 fps on, 6,393 MB / 13.7 off. Day: 7,364 MB / 5.6 on, 6,129 MB / 7.5 off. Frames identical bar one windscreen reflection.
[SystemSettings]:r.RayTracing.Enable=0,r.MegaLights.DefaultShadowMethod=1.[SystemSettingsEditor]:r.RayTracing.Enable=1,r.MegaLights.DefaultShadowMethod=0, so the editor and its path tracer keep it.- Verified on the plain ini: about 6 GB, 13.3 fps, game thread 75.1 ms against 17.9 ms GPU. Epic is now game-thread bound.
- Guard: never compare a capture from today's build against an old one. Re-shoot both sides.
The fault
Blender wind turbine rotor imports at 1.356x scale in Unreal Engine 5.8 after a "size fix"
- The rotor's diameter was worked out as its height, on the assumption that height is two blade lengths.
- With three blades at 0, 120 and 240 degrees the lowest tip is half a blade below the hub, so the height is 1.5 blade lengths. The "fix" scaled the rotor up by a third.
- The same factor was then carried on to the following meshes.
The fix
Measure every mesh against its own real dimension
- The rotor was re-imported at true size, and each mesh was checked against its own real-world measurement, never against a factor found on another mesh.
- In 5.8 Python, a C++ actor's construction script reruns on
set_editor_property;rerun_construction_scriptsis not exposed for it. - Guard: a scale correction belongs to one mesh. Never carry it forward.
The kit
- Unreal Engine 5.8: Niagara ribbons, a material parameter collection, a Blueprint director that keeps the track table.
- Blender for the turbine, crawler crane and tower sections, exported as FBX.
- A C++ wind farm actor in the town's own plugin, driven by the election's schedule.
- A height map of the hills for the first siting, and a read-only Python finder for the re-siting.
- Claude Code Opus 5.5: a coordinator and threads taking turns on one editor.
Plain English
| Term | What it means |
|---|---|
| ray tracing | Working out light and shadow by firing rays through the scene on the graphics card; it looks right and it costs video memory for its own copy of the world. |
| A/B comparison | Two captures that differ in exactly one setting, so any difference between them can only come from that setting. |
| scalability settings | The engine's quality dials - shadows, textures, effects, anti-aliasing - each of which can be set independently. Turning one up can cost far more than turning the rest up together. |
| VRAM | Memory on the graphics card. This project has 8 GB of it, and that ceiling shapes most of the decisions in the devlog. |
| game thread | The part of the engine that runs the game's own logic - every Blueprint, every tick - one thing after another. If it takes 90 milliseconds, nothing else matters: the frame cannot finish sooner. |
| Niagara | Unreal's particle system - rain, smoke, sparks, dust, fizz on a pint. |
| ribbon | A particle effect drawn as one continuous strip joining its particles in order, which is how a tyre track or a sword trail is made. |
| material parameter collection | A small shared set of numbers that many materials read at once, so one change - how much snow has fallen, say - reaches every surface together. |
| FBX | The interchange file format used to move models and animation between Blender and Unreal. |
| construction script | Blueprint logic that runs when an object is placed or changed in the editor, rather than while the game is running. |
| 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. |
Things we still need to fix tomorrow:
- The wind farm in play: force the wind farm candidate to win, push the clock on, and watch the cranes, the rotors and a Monday bill at £0.00.
- The bill text names the wind farm. Needs a compile of the central save object, so it waits for a fresh editor.
- Pads and laydown areas are flat slabs with a skirt, which reads as cut-and-fill on the slopes. They need shaping to the hills.
- Epic at 100 residents is 7.7 fps. The per-frame Blueprint work goes next: the toilet doors, the pans and the bird controllers.
- Snow track contrast and cover speed, judged in play. The player's own car still uses the generic track row.
- The car sitting 25 cm under the roundabout goes to the traffic thread.
- Enclosed toilets with doors in the leisure centre and the mosque, and the flushing minigame in the police cell. Wind-blown cigarette smoke after that.