The player stands up off a chair in Unreal Engine 5.8 and still cannot move with WASD
An appointment nobody could walk to
The plan for Wednesday was small and it was overdue. Second Chance has a job centre on Bestholme Boulevard — two storeys, a hall of desks, an advisor called Denise who is fully voiced and gates both of the game's jobs — and nobody had ever played the sign-on from the front door to the handshake. James wanted to walk in, take a seat, do the appointment, and come out with a job. That was the whole ask.
He got as far as the pavement outside and could not move.

Not sluggish, not fighting the camera. Nothing. Keyboard dead, mouse dead. The agent — Claude Code Opus 5, which does most of the driving here — said the intro sequence was holding control, because pressing SPACE by hand still skipped the intro and that looked like proof the input system was alive. It was not proof of anything of the sort. James pressed SPACE himself, the intro skipped, and the pawn was still deaf. That killed the theory in about four seconds and cost the best part of an hour before it died.
The real answer was that BP_PlayerCharacter would not compile. A Blueprint with unresolved compile errors is still possessed and still ticks, so it looks alive from the outside — but none of its events ever fire, so Move, Look, Sprint and Interact all die together in the same instant. SPACE survived because the intro director polls that key itself rather than going through the pawn, which is exactly why it is the most misleading tell in the game.
Twenty-five compile errors, all from one root, and the root was a bin lorry. BP_BinLorry had been deleted and rebuilt from scratch at some earlier point by its own builder script, which makes a brand new class wearing the same name. Every reference to it on the player character went stale at once: a variable quietly degraded to a bare object, two function calls lost their binding, an actor lookup had its class pin cleared. None of the error text mentions the bin round. One of the errors reads Object Reference is not compatible with Object Reference — the same four words twice, which is what two different classes sharing a display name looks like in print.
The lorry itself was undamaged. All thirty-seven of its functions were present. The damage was entirely on the side of the thing doing the referring, which is the opposite of where anybody looks first.
Rockstar have a build system that would have caught that before it reached a person. He had a Wednesday evening.
The chair he had given up on
With input back, he walked in, took a chair in the waiting room, and got stuck in it.
James recognised it immediately, because it was the same thing that happens in the Slag & Slurry. His words for it were flat: this is the same bug in the pub, I gave up trying to fix it there to move on with the jobs. It had been sitting on the pub's fault list for weeks under the assumption that something about pub chairs was wrong.

Nothing about pub chairs was wrong. Both faults were on the player character, so both of them were in every seat in the game, and both fixes land everywhere at once.
The first one is the better story. To stand up you have to look down — the game reads where your eyes are pointing and stands you up when you glance at the floor. The check was reading the wrong output pin. GetActorEyesViewPoint returns two things, a location and a rotation, and the wire came off the location. So the game was taking the player's eye position in the world — a number in the tens of thousands, because the town is large — treating it as a direction, and asking whether that pointed downwards. Normalised, it comes out at about −0.009. Essentially horizontal, wherever you actually look. The gate wanted −0.72. It was never going to be true, at any camera angle, on any seat, anywhere in the game.
What makes that one worth publishing is why it read as deliberate. Drag a wire from a location pin onto a rotation pin in Unreal and the editor silently inserts a conversion node for you, Rotation From X Vector, and everything compiles clean. So the graph does not look broken. It looks like somebody chose to convert a vector into a rotator on purpose, and a pin-level trace done six days earlier stopped one node short of it and concluded the threshold was simply too harsh. That left a week of planning a fix that would not have worked, aimed at a number that was doing nothing at all.
Then fixing it exposed the second fault, which had been hiding behind the first the entire time — while standing was impossible, the code that misplaces you had never once run. Standing up called SetActorLocation on wherever you were standing when you sat down. Sit, stand, and you go back to your own footprints. The trouble is that if one stand ever drops you inside the chair, that spot is now the saved spot, and every subsequent stand puts you back inside the chair for the rest of the session. Self-perpetuating, and it survives until you quit.
That is also the answer to the symptom in the title, which is the one James kept reporting: I am stood up off the chair and still cannot move with WASD, I can look around with the mouse. Sitting down tells the game to ignore movement input and only standing up turns it back on. So while standing was impossible, movement input stayed ignored for the rest of the session while the mouse kept working perfectly. Every flag read correct. Not seated, not ignoring input, walking mode. The pawn was simply wedged inside a chair, 0.0 cm from it, with a capsule overlapping the mesh. A collision problem wearing an input problem's clothes.
Standing up now puts you in front of the chair, worked out from the chair's own transform every time, so nothing can poison it. That half is saved and has not been played yet.
The comment that swore it was fine
Somewhere in the middle of all that, James looked round the job centre hall and said the building, the chairs and the desks all had the inside-out bug.
He was right, and he had been right the last time as well. That report had been dismissed once before with an argument that sounded solid: the materials are not two-sided, so inverted faces would be culled and we would see holes, and there are no holes. That reasoning is simply wrong. With single-sided materials the near faces are the ones culled, so you see the far interior from behind and the object still reads as a solid box. It just takes its light from the wrong side and goes flat. Nothing is missing. It only looks dull, and dull is very easy to blame on the lighting.
The sweep across two hundred and thirty meshes found fifty-two of them inside out. Ten generators were carrying it. Eight kits were fixed at source, re-exported and re-imported — the job centre, the police station, the nightclub, the chip shop, the lane fence that appears a hundred and forty-six times along one road, pub wall art, the parade of shops and the pub shell, and a tower block. Afterwards, five meshes were still flagged.
The cause was a repair from July that only went half way. One box-building function in the shared kit had its top and bottom faces fixed and all four sides left wound inward, and the note explaining that the winding was now correct got copied word for word into four more kits as they were written. The claim was true about the top face and false about the sides in every single file. The confident comment is the reason it spread. All of them have been deleted.
The instrument nearly cost the day too. The first winding checker derived a face direction with a cross product using the right-hand rule, and Unreal is a left-handed engine, so it scored the engine's own primitive cube as one hundred per cent inside out. That is the second time a test in this project has failed that exact way. The rule now is that any winding test prints the engine's own cube first and its verdict is void if that cube does not come back clean.
All of it is measured. None of it has been playtested, and that distinction matters here more than usual, because measurement is what got this wrong twice already.
Eighteen centimetres, twice
Running alongside all of that — including overnight, unattended, at James's own instruction to carry on until six in the morning — was the carvery at the Working Men's Club. It is a proper one: a stainless serving run with the veg in bain-marie wells, gravy after the veg and the three sauce pots last, in the order a person actually collects them, which was a ruling James made in one sentence and which turned out to expose two bugs on its own.

Then the hero of the whole thing: the carve itself. A knife makes two descending draws through the joint, the joint's mesh advances a stage so it visibly shortens, and a floppy three-segment slice is released at the end of each draw. The stroke was proved sample by sample against the maths rather than by eye, and it returns to its rest position to the last decimal place, which matters because a stroke that finishes half a centimetre off its start creeps and nobody notices for weeks.
The arithmetic was perfect and the result was wrong.

Slices were being created wherever the knife was at the moment of release. At the end of a draw the blade has travelled eighteen centimetres past the joint's centre line. The joints sit eighteen centimetres apart. So every slice landed neatly in front of the next joint along, and it looked like a working carvery right up until you noticed which meat the slices were under.
No amount of checking the numbers would have found it. A screenshot found it in a second.

The fix is a marker component parked where a slice ought to appear, and slices are born at its position instead of the knife's. The general form is worth keeping: spawn it where the moving thing is is only correct if the moving thing is where you think it is at the moment you spawn.
What a job centre is for
There is no job centre in GTA 6. There is no reason there would be — it is a story about somebody else, and you are along for the ride. Second Chance is a first-person town where you are yourself, out on a release programme, and the rent is due on a day you can see coming. So you walk to Bestholme Boulevard, you take a ticket, you sit on a plastic chair among other people who are also waiting, and you have an appointment with a woman who has thirty recorded lines and three vacancies to pitch at you. Nobody makes you go. The rent does.
That is the argument, and Wednesday is also what it costs: to have a chair worth sitting on you need a sit-and-stand system, and a sit-and-stand system can wedge you inside the chair for the rest of the session while every diagnostic reads green.
Being small is why the job centre is enterable in the first place. Nobody had to be persuaded.
The fault
The player stands up off a chair and still cannot move with WASD, but the mouse look still works
Reported at the pub for weeks and reproduced at a job centre waiting-room chair. Two independent faults on BP_PlayerCharacter, one hiding the other.
Fault 1 — the stand-up gate could never be true. SeatTick read GetActorEyesViewPoint's OutLocation where it wanted OutRotation:
GetActorEyesViewPoint.OutLocation -> [Rotation From X Vector] -> GetForwardVector -> Dot(·,(0,0,1))
GetActorEyesViewPoint.OutRotation -> (nothing)
So the player's eye world position — a vector around (27794, 11193, −280) — was being used as a look direction. Normalised its Z is about −0.009, against a gate of < −0.72. Never true, on any seat, at any camera angle.
☠ It compiles clean and reads as deliberate maths. Dragging from a location pin onto a rotator pin makes Unreal silently auto-insert Rotation From X Vector. A pin-level trace made six days earlier saw the dot product and the threshold, stopped one node short of the conversion, and diagnosed a value that needed relaxing.
The visible symptom is a consequence, not a third bug. SitAtChair calls SetIgnoreMoveInput(true) and only the stand-up path calls ResetIgnoreMoveInput, so with standing impossible, movement input stayed ignored for the whole session while look input kept working.
Fault 2, exposed by fixing fault 1. SeatStandBack was SetActorLocation(PreSit) — restoring wherever you were standing when you sat. One stand that lands inside the chair poisons that saved point and every later stand puts you back inside it. Read live off a stuck session: PreSit was exactly the chair's location, the pawn sat 0.0 cm from it with its capsule inside the mesh, and every seat flag read clean — not seated, input not ignored, MOVE_WALKING.
The fix
Wire the rotation pin, and compute the stand-off point from the seat rather than from history
Fault 1: delete the auto-inserted Rotation From X Vector and wire OutRotation → GetForwardVector. Verified both directions of the gate in PIE — level look still refuses, 60° down stands you up and returns Seated=False, MOVE_WALKING, move input no longer ignored.
Fault 2: compute the stand-off point from the seat's own transform every time so no stored value can be poisoned. Built and saved; not yet played.
The guards, and both are general:
- ☠ An auto-inserted conversion node is a smell. It very often means a wire landed on the
neighbouring pin. Unreal inserts it without comment, so the graph looks intentional.
- ☠ A clean set of input flags does not mean the pawn can move. Measure the pawn's distance
to nearby static meshes before believing any input diagnosis. Here the capsule was simply wedged in a chair.
The fault
Every keyboard and mouse input dies at once, but SPACE still skips the intro
BP_PlayerCharacter would not compile. A Blueprint with unresolved compile errors is still possessed and still ticks, but none of its events fire — so Move, Look, Sprint and Interact go together.
Cause: BP_BinLorry had been deleted and recreated by its own builder script, which makes a new class, and four kinds of reference to it on the player character went stale at once — 25 errors from one root.
Three tells, and two of them mislead:
| Tell | What it means |
|---|---|
| SPACE still skips the intro | ☠ Not an intro bug. The intro director polls that key itself, so it is the one input that survives a dead pawn graph. Some input works, all of the pawn's input does not is the fingerprint of a compile failure |
list_errored_blueprints returns count: 0 | ☠ Not proof. It only catches Blueprints flagged for the PIE compile warning. Run compile_blueprint on the pawn — that returned 25 |
Could not find a function named "BLTryHook" | A cascade, not a missing function. With the target type gone the self pin falls back to self. The function was on the lorry all along |
The signature error is Object Reference is not compatible with Object Reference — the same words twice, which is two different classes sharing a display name.
The fault
Buildings, chairs and desks are inside out but there are no holes, so it reads as flat lighting
52 of 230 meshes across the level were wound inward. Ten generators carried it.
☠ The argument that dismissed this once is false: the materials are not two-sided, so inverted faces would be culled and we would see holes. With single-sided materials the near faces are culled, so you see the far interior from behind and the object still reads as solid. It only takes its light from the wrong side and goes flat, which is easy to blame on lighting.
Cause: a July repair to one shared box-building function fixed the top and bottom faces and left all four sides wound inward — and the note asserting the winding was now correct was copied verbatim into four more kits. True about the top face, false about the sides, in all five files.
The fix
Fix the winding at the generator, and make every winding test prove itself on the engine's own cube
Eight kits fixed at source, re-exported and re-imported. 52 inverted down to 5 flagged.
☠☠ The instrument lied first, for the second time in this project. A checker that derives a face direction with a right-handed cross product scores /Engine/BasicShapes/Cube at 100% inside out, because Unreal is left-handed. The fix is not to flip the sign — it is to stop deriving a direction at all, since the engine already ships a vertex normal in its own convention.
The guard: any winding test prints the engine's own cube first and its verdict is void if that cube is not clean.
Three more things the pass paid for, all of which pass a check while wrong:
recalc_face_normalsmust be gated on closed islands. It orients an island outward, which
is meaningless for an open one, so it is free to flip correct geometry — a roof slab authored as a top and an underside, for example.
- Exporting with
FBX_SCALE_NONEinstead of the kit'sFBX_SCALE_UNITSlanded six meshes at
100× in Unreal while Blender re-read its own file at exactly the right size, drift 0.000000. Only Unreal acts on the unit declaration in the header. Verify the span in Unreal, and gate on "is it 100×", never on a drift tolerance — a real geometry fix moves bounds.
- A re-import silently reverts a material. Slots rematch by name, so a lane fence went back
from its grained timber to a flat tint with no check firing, because the slot name never changed.
☠ Delete any comment that asserts a winding is correct. Say what measured it instead.
The fault
Carved slices spawn in front of the wrong joint
Slices were created at the knife's world location, which needs no local-to-world arithmetic and was wrong for a reason arithmetic could not catch. At the moment of release the blade has drawn 18 cm past the joint's centre line, and the joints sit 18 cm apart, so every slice landed in front of the next joint along.
The stroke itself was correct and had been proved sample by sample against the model — including returning to its authored rest pose to the last decimal. A screenshot found this in a second.
The fix
Spawn from a marker component, not from the moving thing
Park a bare SceneComponent where the slice should appear — in front of the cut face, on the joint's own centre line, 4 cm above the board — and spawn at its world location. It reuses node types already proven in that graph and adds nothing new to get wrong.
☠ The tempting alternative, releasing the slice mid-draw where the blade happens to cross the centre line, is one number and it is a fudge: the slice would appear before the cut finished, and the code would say end of draw while meaning something else.
The guard: spawn it where the moving thing is is only correct if the moving thing is where you think it is at the moment you spawn. Here the knife's position was right, the spawn was right, and the result was wrong.
The kit
What actually did the work
- Unreal Engine 5.8, Blueprint only — no C++ in this project at all.
- Blender, headless, driven from a script. Every building kit in the town is a generator
file, which is why one bad box function reached five buildings and why fixing it once fixed all of them.
- Two editor MCP servers, which let the agent compile Blueprints, read pins, drive PIE and
take viewport captures without a person at the keyboard. The overnight carvery session ran unattended on them at James's instruction.
- A screenshot. Two of Wednesday's four faults were found by looking at a picture after
every number had already come back green.
Plain English
| Term | What it means |
|---|---|
| Blueprint | Unreal's visual scripting. Logic built by wiring boxes together with lines instead of typing code. This whole game is built in it. |
| pawn | The thing in the world the player is actually driving — the body the camera is attached to. When the pawn stops responding, nothing the player presses does anything. |
| event graph | The Blueprint logic that runs while the game is actually being played. |
| tick | Code that runs every single frame. Cheap once, ruinous sixty times a second across a thousand actors. |
| 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. |
| 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. |
| 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. |
| normals | The direction each face of a model is considered to be pointing. Get them backwards and the model renders inside out — you see through the front and the inside is solid. |
| face winding | The order the corners of a triangle are listed in. That order is what decides which way the face points, so a model built with its corners listed the wrong way round comes out inside out. |
| 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. |
| collision hull | The invisible simplified shape used for bumping into things. It is not the shape you can see, which is why invisible walls happen. |
| 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 stand-in-front-of-the-chair fix is built and saved but never played. Sit in a pub
chair, a job centre chair and a canteen chair and stand up from all three.
- The stand-up gate still asks for a 46° look down and nothing on screen says so. A natural
glance is about 20°. That is a design call, not a bug, and it has not been made.
- The whole inside-out repair is measured and not playtested. Look at the job centre, the
police station, the club, the chip shop and the pub in game. Twice now James has caught this class of fault before any instrument did.
- Five meshes are still flagged as inverted.
- The carvery has no press-to-carve yet — the knife runs, nobody can start it. No queue, no
plate, no gravy, no eating.
- The carved slices read too pale against the joint's own cut face, and they are too small: 9 cm
across off a joint about 15 cm wide. A real slice is as wide as the joint.
- The sprout is still not a sprout. Three attempts bought a smooth green pear.
- The job centre's check-in ticket dispenser is modelled and still not imported, and the notice
board tells you to check in at a screen that is not there yet.
- Denise's head now turns to follow the player, proven end to end in PIE — but only tested with
the player parked 9.7 m away and off to one side, which is not where anybody sits.
- There is still no video of the bin round, and it has been finished for over a week.