Collapsed to a Point
Six in the morning, and the takeaway fan
The session had been left running overnight, building twelve cars.
They are fictional to the badge, generated by a Python script in Blender rather than bought in, and they are modelled off 323 photographs of real second-hand adverts, which is how you end up with right-hand drive, a proper cowl, and doors and boots that open. The whole set builds and exports headless in about thirty-one seconds. James went to bed with his eyes gone from reference images and left it to it.
What woke him at six was the extractor fan on the takeaway outside, not the cars. He checked them anyway. They had come out well, well enough that he spent breakfast giving notes rather than starting again, and the notes came fast: the dashboard too big, the front seats sitting too far back, the rear headrests poking up through the back windscreen, the parcel shelf standing still while the tailgate lifted over it. He wanted the shelf on its strings, the way it is in a real hatchback. He also wanted twelve different interiors rather than one interior twelve times, which is fair, because a fleet of identical cabins reads as wallpaper the moment you look through two windscreens at once.

The agent, Claude Code Opus 5, working through two editor servers, took all of it and rebuilt the packaging around a standard set of measurements instead of a slab across the cabin: wheel centre behind the cowl, hip point derived from knee room, backrest hinge landing on the B-pillar. Then a table of per-car cabins, read off the advert galleries. Fabric or leather. Hooded binnacle or flat fascia or a tablet stuck on top. Manual, automatic or a rotary selector. Rear bench or two buckets. It was the right answer and it was answering the wrong question, but that would not surface for another two hours.
The handle that was not connected to anything
One of the notes was that the interior door handle was not attached to the door.
That reads like a placement problem, and it was treated as one. The armrest and the pull were made to measure the door's local depth at their own height, because the tumblehome, the way a car's sides lean inward towards the roof, had been leaving them floating an inch clear of the trim. That fix was real and it was needed.
It was not the fault. The door card, the trim panel on the inside of the door, did not exist. None of them did.

Blender's mesh library gives a newly created vertex an index of minus one until something tells it otherwise. There is an obvious-looking call for this, and it is the wrong one: ensuring the lookup table does not assign indices. Updating the index does. The copy routine that builds every inner liner in the car read the index straight off the new vertices, got minus one for all of them, and welded each liner onto a single point. Every door card, every tailgate liner, the whole boot tub. Twenty-seven thousand of the interior's thirty-seven thousand triangles had no area at all.
It survived because nothing complained. The build ran clean. The renders looked fine, because what is not there does not draw. Nine other liners did come out correct, and that was the confusing part until it was not: those parts happen to have a mesh operation run over them on the way through, and an operation assigns indices as a side effect. The ones that went straight from creation to export were the ones that vanished.
What caught it was a guard nobody had put there for this. Unreal drops zero-area triangles on import, so the imported bounds came back four to eight per cent smaller than the figures the exporter had written down for the same mesh, and the import script compares those two numbers as a matter of course. A car being four per cent smaller than its own manifest is not a plausible rounding error. That is the whole detection story. Rockstar have somebody whose job is to open the asset and look at it. Here the asset is checked by a script written for a different reason on a different day.
What Rockstar's people are not allowed to say
After breakfast he read X, and X was full of GTA 6. A large quantity of the game's assets had leaked, and Rockstar had posted a reminder to the people who built it that they are not to mention their involvement until 19 November. Then a video from somebody who had been to a preview at Rockstar HQ, going through the open questions. No casino has been mentioned. No job you can clock on to has appeared in anything released or leaked. Hunting for profit is confirmed. The fishing is catch and release.
That is the sort of thing that decides a Sunday.

The jobs line is the one worth arguing, because it is the one Second Chance already answers. There is a refuse and fly-tipping shift you clock on to and get paid for, and a job at the pub. There is a council bin lorry working a terraced street with two loaders on the kerbs, their lift technique corrected by a man who does it for a living. The e-bike for the takeaway delivery gig is finished, down to the charge lights on the battery, and the gig itself is being built around it. A world where you are out on a release programme and can go and do a day's work in it is a different proposition from a world where the work is a cutscene about somebody else's life.

And the NDA is the other half of it, which is James's own observation and the best line he has had in a fortnight: the people who built the biggest game in the medium are under orders to say nothing about it for two months. This one publishes every week, screenshots and faults included, and would be delighted if more people talked about it. Being small is why the whole build can go out in public. Nobody has to approve it.
A colour that had never been set
The gambler at the roulette table had been wearing clothes made by hand in Blender. They came off, and customised Fab garments went on. The other man got customised MetaHuman clothing, and looks considerably better for it.
Then the trainers, which took the rest of the evening. James set their colour in the MetaHuman editor, came back to them later, and reported that it had reverted.
It had not reverted. It had never arrived.

A material instance in Unreal can inherit every value from its parent and hold none of its own. This one held none of its own: zero overrides on the whole instance. A script had read the colours off it, saved them, read them back identical and reported success, and all of that was true and none of it meant anything, because the readback returns the inherited value and cannot distinguish "set to this" from "never set at all". The character edit had gone onto the character at ten to five. The outfit assets it should have reached had been built at twenty past four, half an hour earlier, and nothing rewrote them.
The sole was a separate fault and a better one. Black went on the upper and the sole stayed white, and two confident explanations came and went: one parameter turned out to control the laces, and flipping another moved the sole by 3.7 sRGB, which is nothing. The actual cause was a painted wear overlay shipping at 0.95 strength, washing the sole pale regardless of what colour it was told to be. Taking it to zero dropped the sole band by 21.6 sRGB with the upper unmoved.

The method is the reusable part, and it is duller than looking: crop the same box out of the before and after frames and take the mean. A 3.7 difference and a 21.6 difference look identical on a screen.
The capture script that produced those frames had raised the editor to Epic quality and never put it back, which is why the room was reporting itself 1.5 to 2.2 GB over the video memory budget on an 8 GB card for the rest of the session. Pair every override with its restore, in the same script.
An eye eleven millimetres inside a head
The gym was the middle of the day. A mile running, then half an hour in the pool, which was warm. Outside it was warm and windy, and they were putting the fair up on the recreation ground next door, so there were people stood watching the trucks come in with the rollercoaster.
The animals got the afternoon, for the same reason as the trainers: they are seen close up now. A long-lens rig was built so each species can be photographed properly instead of squinted at across a field, and the first otter through it had no eye. Just fur where the eye should be.
Every mammal eye in the set was seated inside its own head. The otter's was eleven millimetres in, the vole's eight, the fox's flush with the skin. Eye centres are now pushed out to sit at 45 per cent of their radius inside the surface, and the builder prints where it put each one. While it was open: the legs had been built with seven sides, and a seven-sided tube has 51 degree corners, which is over the 46 degree threshold at which the renderer stops smoothing. Ten sides, and they are legs again.

A light that spawned with its collision on
The last of it was the delivery job, and it produced the cleanest lie of the day.
A small movable light needed to be spawned into the world while the game is running, and it needed no collision. Setting it to none persisted. The write echoed the new value back. Read the template afterwards and it still said none. Spawn the thing and it comes up with collision fully enabled.
Unreal stores that setting inside a structure that also holds the collision profile by name, and writing to the structure merges rather than replaces, so the old profile survived the edit untouched. On spawn the profile reapplies its own setting over the raw one. The template genuinely did hold the right value. It was overwritten a moment after the actor existed.

The fix is to set the profile by name in the same structure, which is the only way to reach it, because the profile field cannot be written on its own. The wider point is the one that cost the round: for anything created while the game is running, a template readback is not evidence. Spawn it, read the live thing, destroy it.
That was Sunday. The cars are in the engine and the boots open. The snooker went up on YouTube.
The fault
A mesh imports into Unreal Engine 5.8 with smaller bounds than the file it came from
Nothing errors. The exporter reports a clean build, the renders look correct, and the imported static mesh reads four to eight per cent under the dimensions recorded for it at export.
Cause: in Blender's mesh library a vertex created with verts.new() carries index -1 until something assigns one. ensure_lookup_table() does not assign indices; index_update() does. A copy routine reading v.index therefore welds every new vertex onto element zero, and the whole part collapses to a single point.
The collapsed parts do not disappear from the file. They export as zero-area triangles, which Unreal drops on import, which is where the missing volume goes. In this build 27,000 of an interior's 37,000 triangles were zero-area, every inner liner was gone, and the visible symptom was "the interior door handle is not connected to the door", because the panel the handle mounts to did not exist.
☠ Parts that survived did so by accident: any bmesh operation run over a part assigns indices as a side effect, so a routine that calls recalc_face_normals or an extrude happens to be safe and one that goes straight from creation to export is not.
The fix
Call index_update() before reading any vertex index, and compare imported bounds against the exporter's manifest
Two changes, and the second is the one that will catch the next unrelated version of this:
- The copy routine calls
index_update()before it readsv.index, and the triangulated
export copy drops zero-area triangles rather than shipping them.
- The exporter writes each mesh's dimensions into a manifest, and the import script asserts
the imported bounds against it. A four per cent discrepancy is not a tolerance, it is missing geometry.
The guard: a geometry fault that produces zero-area triangles is invisible to every check that counts objects, materials or file sizes. Dimensions are the cheapest thing that notices.
The fault
A material instance readback returns the value you asked for and the instance overrides nothing
A colour is set on a character, saved, read back identical, and reported verified. On screen the old colour is still there, and the report will come back as "it reverted".
Cause: get_material_instance_vector_parameter_value() returns the inherited value from the parent material when the instance holds no override of its own. It cannot distinguish "set to this" from "never set". A save-and-readback of an inherited value passes perfectly with nothing behind it.
Second fault in the same afternoon, same character: a region that ignores every colour parameter you can reach. M_shs_casualsneakers ships WearMaskStrength at 0.95 with painted wear enabled, which washes the sole pale whatever tint it is given.
The fix
Count the instance's own overrides, and measure the pixels instead of looking
Read what the instance asserts, not what it answers:
mi.get_editor_property("vector_parameter_values") # count this
A count of 0 means every "verified" value on that instance is the parent's. The colour script now asserts the count before and after and faults if a parameter is not present as a real override. Overrides went 0 to 3, and the colour arrived.
For the wear overlay: WearMaskStrength 0.95 to 0.0 moved the sole band 21.6 sRGB with the upper unchanged, against 3.7 for the hypothesis that felt right. Crop the identical box out of the before and after frames and take the mean. By eye those two results look the same.
The guard: if a character's built outfit assets predate a wardrobe edit, that edit is not in them. Compare the folder timestamps before trusting anything downstream.
The fault
A component set to NoCollision spawns at runtime with collision enabled
set_component_property BodyInstance = "(CollisionEnabled=NoCollision)" returns persisted: true, echoes the new value, and a read of the template afterwards agrees. The spawned actor comes up QUERY_AND_PHYSICS.
Cause: BodyInstance also carries CollisionProfileName, and a struct write is a merge, so the untouched profile (BlockAllDynamic) survives inside the same struct. On spawn the profile reapplies its own collision setting over the raw enum. The template really did hold NoCollision; it was overwritten after the actor existed.
The fix
Set the profile by name inside the same struct, and verify by spawning
Write the whole thing at once:
(CollisionProfileName="NoCollision",CollisionEnabled=NoCollision,ObjectType=ECC_WorldDynamic)
CollisionProfileName is not settable on its own. set_component_property answers "Property 'CollisionProfileName' not found on StaticMeshComponent", because it lives inside BodyInstance.
The guard: a component template readback is not a spawn readback. For anything created while the game is running, spawn it, read the live component, destroy it, and wrap that probe in try/finally or a raised exception leaves the actor in the map.
The kit
| Tool | Why this one |
|---|---|
| Blender, driven headless | twelve cars build and export in about 31 seconds with no editor open and nothing to wedge. The interactive route had already run a UV unwrap for four hours and locked up. |
| Unreal Engine 5.8 | where the collapsed liners, the inherited colours and the collision profile were all visible, and none of them visible anywhere else |
| An exporter manifest of per-mesh dimensions | the only thing that noticed the geometry was missing |
| A crop-and-mean pixel comparison | settled a colour question that two confident readings had got wrong |
| 323 photographs of real second-hand car adverts | the source for every profile number, cabin layout and trim choice in the twelve |
Plain English
| Term | What it means |
|---|---|
| static mesh | A 3D model that does not bend - a wall, a bin, a bottle. It can be moved as a whole, but its shape is fixed. |
| material instance | A copy of a material with some settings changed. Cheap to make and cheap to render, so most surfaces are instances rather than originals. |
| bounds | The invisible box the engine considers an object to occupy. Streaming and culling decisions are made on the box, not on the model, so an object with a box the size of the map can never be streamed out. |
| tri count | How many triangles a model is made of. The basic measure of how expensive it is to draw. |
| pivot | The point a model rotates and scales around, and the point it sits on when placed. A pivot in the wrong place makes an object float or sink. |
| FBX | The interchange file format used to move models and animation between Blender and Unreal. |
| actor | Anything placed in the game world - a lamp post, a person, a trigger volume, a camera. If it sits in the level, it is an actor. |
| MetaHuman | Epic's system for realistic human characters - face, body, hair and clothing, ready to animate. Every named person in the game is one. |
| VRAM | Memory on the graphics card. This project has 8 GB of it, and that ceiling shapes most of the decisions in the devlog. |
| 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. |
| 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. |
| MCP server | A bridge that lets an AI agent drive another program directly. Here, two of them let the agent operate the Unreal editor. |
Things we still need to fix tomorrow:
- The parcel shelf lifting with the tailgate is built and the next job is pressing it in play
and watching it swing.
- The twelve cars are about 167,000 triangles each at full detail against a target of 80,000
to 120,000. The boot tub liner is most of it.
- The interior plastic reads pale tan under full sun. Check the material's own base colour
before blaming the lighting.
- The badger's ear is a flat black coin, the rabbit's hind legs are tubes that want haunches,
and the pigeon's wing bars still read as stickers. Nine more species to photograph.
- Loading the main map twice in one editor session took the editor down with a D3D12 fatal
error twice yesterday. Order a session as assets first, then one load of the world.
- The refuse induction film and the snooker are up. The delivery gig is the next thing being
built.