Two Bright Readings
One in the morning
Saturday had finished at one in the morning. Anthropic had given everyone an extra usage reset with the launch of Opus 5.5, and James had spent the night using as much of it as he could, so Sunday started at nine. Two sausages, beans, an omelette and a coffee.
He went to the gym and ran. By the time he got back it had rained hard enough to cancel the barbecue his parents had been hoping for. They were home from Rotterdam, three weeks with his brother and the new baby, and dinner was moving indoors.
Before he left he gave Claude Code Opus 5.5 a list, and the list was about the dark. The street lamps came on too late. A storm needed lightning. The petrol pumps, which had been scenery for a month, needed to work. The work was split across several sessions, and by the evening seven or eight of them were sharing one open editor, taking turns to press play by sending each other messages.
That is the argument this entry makes, and it is the British one. GTA 6 is set in a sunny version of Miami. Second Chance is set in a Midlands town at the end of September, which means the question of when the street lamps come on is not a small one. It gets dark before tea. It rains on the barbecue. Rockstar have people for this. James had a Sunday, with a Sunday dinner in the middle of it.
Coming on too late
His complaint was specific. The lamps in Radworth came on at a fixed point in the sun's descent, and by then it was already too dark to see the road. Late at night the game was unplayable. He asked for them to work the way real ones do: on the light, not the clock, and early enough that a player can still find the kerb, and the jitty at the end of the terrace.
The agent read the lamp Blueprints before it touched them, and came back with a finding that changed the job. Moving the switch-on earlier, it said, would change nothing the player could see. The game pinned its camera exposure to daytime until the sun was two degrees above the horizon, so the whole of dusk was being metered as if it were noon. A lit lamp throws tens of lux onto a pavement. Under a daytime exposure that sits about seven stops below anything the screen shows. The lamps had been coming on. They had been invisible.
So there were two jobs, and the agent did them in the order the builder scripts on this project always run: VARS first, then the logic. VARS is its shorthand for variables, the named values a Blueprint keeps hold of - a speed, a cash total, a flag saying the lamp is on. James had heard the word enough over two days to ask what it meant. Say it to his dad and he hears VAR, the video referee, because his dad is a Forest fan. It had come up again that afternoon.
Each lamp now carries its own photocell. Every fifteen seconds it reads how much sunlight is reaching the street, and when that drops past a threshold the lamp comes on. The threshold is nudged slightly for every lamp by its position, so a street does not snap on at once. It comes on in a ripple, the way a real one does. The camera's exposure listens to the same reading and starts adapting as the light goes, one stop gained for each stop the sun loses, which is what the lamps needed to be visible at all.

There was one detail the agent put in for a reason that belonged to a different session. A lamp goes on after a single dark reading but only goes off after two bright ones. The weather system brightens the sun thirteen times over for a lightning flash, and without the second reading every lamp in a storm would flick off and back on with each strike.
In play, standing on Radworth Road with 56 lamps in range, it held. Just after ten in the morning, in rain, none were on. Jumped to twelve minutes to eight in the evening, all 56 were. At seven the next morning, after two bright readings, all 56 were off again. On a clear midsummer evening they now come on between 20:25 and 20:39 instead of all at once at 20:57, and under heavy rain from about seven.
Then James asked for five screenshots of the streets at night, and the shoot found the next problem. Along the horizon, behind the trees on three of the five streets, sat hard white shapes that had no business being there. A trace along one sight line hit the primary school at 248 metres. The agent logged it as unproven and did not touch it. The graphics card was reading 7.35 GB of its 8 before anyone pressed play, so the shots were taken at Medium.
Dinner
His parents' house, BBQ pork cooked indoors, veg and gravy. Mr Bean on the telly. His parents had had a good time in Rotterdam. He had been reading an argument on X that morning, artists on one side and AI on the other. That can wait.
When he got back to the desk the lamps were built and the lightning was half done.
Out of a dark cloud
The lightning had a rule before it had a mesh. James had laid it down early: lightning on a sunny day is extremely rare, it comes out of a dark cloud. So a visible bolt only appears when the cloud cover is at least nine tenths and the rain is heavy, and the channel starts 400 metres inside the cloud deck. Strikes come every four to twelve seconds in a full storm. Near ones, from 150 metres to two and a half kilometres, are drawn. Each strike plays its own thunder at the speed of sound, so one 3.49 km away rumbles about ten seconds after the flash.
The bolts themselves were built in Blender, eight of them, with the brightness of each branch packed into a spare set of texture coordinates so one material could light the main channel hard and the forks softly. The first render test drew nothing at all. The mesh imported at the right size. The material compiled. Every readback the agent took came back green, and there was no bolt.
It took a probe script to find out why. Somewhere between Blender, FBX and Unreal, the vertical texture coordinate is turned upside down, so a value of 1 arrives as 0. The main channel, the brightest part of the bolt, was being told to emit nothing. One subtraction in the material fixed it.
The second fault was bigger and easier to see.

The flash that goes with each strike is a point light, and the agent had placed it twelve per cent of the way up the channel. On a bolt 2.6 km long that put it 312 metres above the street. From there it lit only what faced upwards: roofs, sills, the tops of walls, and the wet road, which is glossy enough to mirror it. The street looked as though it had snowed. It was gone midnight.

At 60 metres the light fell on the house fronts instead. The agent capped the height there, and wrote the fix into the build at 00:34. The fixed version is written and is next to be seen in play.
How bright the flash should be turned out to be something stills cannot answer. The agent shot it at 40 million candela, then four, then two, then 300,000, and the four frames came back nearly the same. The camera's auto exposure had re-adapted in the seconds between the setup and the shot. A real flash lasts under three quarters of a second, too short for the eye to adapt, so a near strike at the built strength would white out the whole screen. That one goes to James, in play, in real time.
Twelve times brighter
The pumps were the other thing working that evening. Radworth Services has eight of them and 48 nozzles, unleaded in green, diesel in black, super in yellow, at 144.0p, 149.0p and 158.0p a litre. Lift one with E and the hose pays out from 120 cm to 380. Walk away with it and it stops you three and a half metres from the pump. U puts it in the car's filler, U again starts it, and it pumps at 1.2 litres a second: 24.73 litres in 20.61 seconds cost £35.61, and the player's cash went from £500 to £464.39. The wrong grade does not fit. The nozzle bumps off the filler and there is no message, because a real one does not come with one either.
There were no drivable cars on the map to test with, and scripts cannot put one into a game that is already running. So the agent put two unsaved test cars on the forecourt in the editor, a petrol and a diesel, played, and took them away afterwards. Mid-fill on the diesel it drove the car six metres. The pump stopped, billed £11.56 for the 7.76 litres already in the tank, and the nozzle sprang back to its holster.
The screen was the fault.

The display is a widget component: a piece of ordinary game interface stuck onto the pump as a screen. The material it was drawn with reacts to the lights around it, and a pump under a forecourt canopy is in shade. The text was there and correct, and dark grey on black. The agent turned up the widget's tint in the running game. Twelve times was readable. Twenty-five was barely any brighter.

It baked in twelve and wrote down that the proper fix is a material that ignores the lighting altogether, the way a real screen does. The plan is for an attendant to fill the car for you in the daytime. At night it is self-service.
The storm test finished at fourteen minutes past midnight. It was Monday by then.
The fault
Street lamps switch on at dusk but the street is still black in Unreal Engine 5.8
The lamps switched on from the sun's angle, and moving that earlier would have changed nothing. Exposure was pinned to the daytime value (EV100 8.0 to 8.8) until the sun was 2 degrees above the horizon, so dusk was metered as noon. A lamp's tens of lux sit about 7 stops under that. The lamps were on and invisible.
The fix
Switch the lamps on light level, and let the exposure follow the same reading
Each lamp reads the lux on the street every 15 s: sun intensity × the sine of its elevation. On below a threshold, off only after two bright readings in a row, so a lightning flash (sun ×13) cannot blink it off. A fixed per-lamp bias of 0.85 to 1.12 makes a street light in a ripple. The night post-process weight now also rises with lost light, one EV per stop past the first, capped at 3.7 EV.
The guard: a light that is on is not a light you can see. Check exposure before moving a switch-on time.
The fault
Lightning bolt mesh from Blender imports invisible in Unreal Engine 5.8
Brightness was packed into a second UV channel's V. Blender to FBX to Unreal flips V (v becomes 1 - v), so the main channel, brightness 1, arrived as 0 and emitted nothing. Size, material and compile all read back green. U is untouched.
The fix
Read any value packed into V as 1 - V
One subtraction in the material's emissive expression. Any data packed into a UV's V needs 1 - v after this import path.
The fault
Lightning flash point light turns every roof and road white like snow
The flash sat 12 % up a 2.6 km channel, 312 m above the strike, so it lit only upward faces. A wet road at roughness 0.02 mirrored it.
The fix
Clamp the flash to 60 m along the channel
Flash position = strike point + channel × the smaller of 12 % and 60 m. Short bolts keep 12 %. Judge intensity in real time: auto exposure re-adapts between setup and a still, so 40 M and 300 k candela shot alike.
The fault
WidgetComponent screen text almost invisible on a 3D object in Unreal Engine 5.8
The pump display used Widget3DPassThrough_Masked_OneSided, which is lit. Under a canopy the correct text rendered dark grey on black.
The fix
Tint the widget ×12 now, an unlit widget material next
TintColorAndOpacity ×12 is readable; ×25 is barely brighter. The real fix is an unlit, emissive widget material. Also: in 5.8 Python, widget_space, draw_size and two_sided are setters (set_draw_size), not properties.
The kit
| Tool | Why this one |
|---|---|
| Claude Code Opus 5.5 | seven or eight sessions sharing one editor, taking turns at PIE by message |
| Unreal Engine 5.8 | Blueprint lamps, weather, strike and pumps, all tested in PIE |
| Blender | the eight lightning bolt meshes, with brightness packed into a UV channel |
| A UV probe script | proved the V flip when every other readback was green |
Plain English
| Term | What it means |
|---|---|
| variable | A named value a Blueprint keeps hold of - a speed, a cash total, a yes/no flag saying the lamp is on. Shortened to "vars" in the agent's reports, and a builder script's VARS step is the stage that creates them before any logic is written. |
| Blueprint | Unreal's visual scripting. Logic built by wiring boxes together with lines instead of typing code. This whole game is built in it. |
| photocell | A small light sensor on a street lamp that switches it on when the daylight fails and off when it returns, instead of on a clock. The lamps in Second Chance each have a simulated one. |
| 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. |
| debounce | Waiting for a reading to stay the same for a moment before acting on it, so one freak reading - a lightning flash - does not flick a lamp off and on. |
| post process volume | A box in the level that changes how the final image looks inside it - exposure, colour, contrast. |
| 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. |
| UV | The flat pattern that says which part of a 2D image lands on which part of a 3D model. Wrong UVs mean the texture arrives stretched or in the wrong place. |
| FBX | The interchange file format used to move models and animation between Blender and Unreal. |
| emissive | The part of a material that gives off light - a screen, a bulb, a neon sign. |
| point light | A light that shines out in every direction from a single spot, like a bare bulb. Where you put it matters as much as how bright it is. |
| candela | A unit of how bright a light looks from one direction. A candle is about one; a lightning strike is millions. |
| widget component | A piece of on-screen interface, like a readout or a menu, pasted onto an object in the 3D world so it shows up as a screen on that object - a pump display, a till, a phone. |
| lit material | A lit material reacts to the lights around it and goes dark in shadow; an unlit one shows its own colour whatever the lighting, which is what a glowing screen needs. |
| VRAM | Memory on the graphics card. This project has 8 GB of it, and that ceiling shapes most of the decisions in the devlog. |
Things we still need to fix tomorrow:
- James watches a near strike in play and picks the flash strength.
- See the 60 m flash in play, then the flicker.
- The sky stays black in a strike. The whole deck going lilac needs its own path.
- Find what draws the white shapes on the night horizon, then reshoot two of the five streets.
- A look at dusk in play: is 20:15 to 21:30 readable?
- Fill a car with less money than the fuel costs.
- The unlit screen material for the pumps, and the thin white line along the screen's top edge.