You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Hangar Perimeter: Tech Li stalls after elevator, blocking progression #184
A script softlock occurs on the "Hangar Perimeter". After riding the large elevator platform down to the lower sub-level, Tech Li completely freezes in place at the edge of the elevator. He fails to step off the platform, entirely blocking campaign progression.
I tried to reproduce this on openQ4 0.14.000 by staging the Viper Squad elevator sequence in hangar1 (the lift with Tech Li, Hayes and Mahler). The lift stopped at the right height every time. Tech Li stood at the edge of the platform for about 7–10 seconds after it arrived, while the other two walked off straight away, but he then followed the others. I couldn't get him to stay stuck, so there's probably something about your game state that my test doesn't recreate (fighting near the top of the lift, for example).
Could you help with a few details?
Your openQ4 version. It's on the main menu, or in VERSION.txt next to the executable.
A save from just before the elevator, or from while Tech Li is stuck if that's all you have. Saves are in %LOCALAPPDATA%\openQ4\baseoq4\savegames. Each slot is a set of files with the same name (.save, .txt and, if present, .tga). Please zip all of them for that slot and attach the zip here.
Did you load a save during this level, or play straight through?
Were there enemies alive near the top of the lift when it stopped?
Does it happen every time you reload that save, or only sometimes?
If you wait a few minutes, does he eventually move? We've seen him stand at the edge much longer than he should and then walk off, so it would help to know whether this is a very long delay or a permanent stop.
If you can, your log file. Open the console, enter seta logFile 2, reproduce the freeze, then quit and attach %LOCALAPPDATA%\openQ4\baseoq4\qconsole.log.
A save is the most useful of these, because it lets me load your exact situation.
changed the title [-]Script softlock in Hangar Perimeter[/-][+]Hangar Perimeter: Tech Li stalls after elevator, blocking progression[/+]on Oct 18, 2026
Linked this progression blocker to Q4-02 in the roadmap and to #189. That PR adds recovery when a medic/tech cannot reach a patient; its code review is approved and the branch has been updated for fresh CI after the unrelated test-harness fixes.
This issue stays open: the contributor's unreachable-patient test is useful, but it has not reproduced your exact lift state. The save requested above remains the best way to confirm whether that fix resolves your progression blocker.
@ipfsd-acc Thank you, the save made this traceable.
Reproduced. I loaded Quicksave2 in the official 0.13.2 Windows build (and in a current main build) and sampled Tech Li (entity elgar) every 10 seconds for two minutes with aiDumpState. He never moves on either build. Each sample shows the same thing: still scripted (aifl.scripted = true, state Wait_ScriptedDone), playing a looping scripted idle, still looking at target_elevFaceUp, with no heal patient.
What's holding him. It's a race between two threads in the stock hangar1 map script (scripts/maps/hangar1.script):
marinesUseLift starts elgarSwitch in its own thread 3.25 s into the lift ride. That thread stands Li up, turns him to face target_elevFaceUp (aiScriptedAnimWait / aiScriptedFaceWait), then starts an endless scripted idle loop and sets his look target.
After the lift and gate, marinesUseLift releases him: lookAt( $null_entity ), then aiScriptedStop( $elgar ).
aiScriptedWait only polls scriptedDone(), and aiScriptedStop makes that true. If elgarSwitch is still waiting when the release comes, the release ends its wait, and it goes on to start the endless idle loop after he was released. Nothing stops him again.
His state in your save matches that ending exactly.
This is a different problem from the one #189 addresses. #189 recovers a medic or tech stuck approaching a patient it can't reach, and Li has no patient here, so it wouldn't help with this save.
Still open: why elgarSwitch sometimes takes longer than the roughly 5 seconds it has. The likely suspects are the scripted turn toward target_elevFaceUp not counting as finished while he rides the moving lift, or a save and load during the ride. I'm looking into that next, together with a fix that also releases Li in saves already stuck like yours. A save from just before you step onto the lift would help a lot if you have one (or a quicksave taken on the lift during the ride). Also, did you save or load at any point during the ride?
@ipfsd-acc Found the trigger: Turbo mode. Your save has the lift's stored move time at exactly half its authored value (3504 ms instead of the map's 7000), which is what g_turboMode 1 does to movers.
Turbo doubles mover speeds, but the hangar1 lift script times Tech Li against the lift's normal 7-second ride: it waits a fixed 3 seconds before standing him up and turning him, and his animations run at normal speed. With the ride halved, the script releases him about 4.75 s into the sequence, before his stand-and-turn finishes at about 5.15 s. The release cancels that wait, the rest of his sequence then starts an endless idle loop, and nothing releases him again.
Reproduced on current main from a fresh hangar1, running the real lift trigger:
g_turboMode 0: Tech Li is released after the lift, every time.
g_turboMode 1: Tech Li is stuck (Wait_ScriptedDone, still looking at target_elevFaceUp), every time.
Workaround for now: turn Turbo off (or seta g_turboMode 0) and load a save from before you step onto the lift. A save where he's already stuck can't be recovered by changing the setting, because his frozen state is stored in the save.
I'm preparing a fix that keeps script-choreographed movers (func_mover, like this lift) at their authored speed in Turbo mode, since map scripts time their waits against them. Doors and platforms you operate yourself stay fast.
The supplied save and Turbo timing analysis are now linked to #198, which preserves the authored timing of script-controlled movers. I have removed the awaiting-reporter label. #189 remains a separate unreachable-patient recovery improvement and is not the fix for this save.
I am reviewing #198 and its checks. The existing workaround remains: turn Turbo off and load a save from before the lift. The proposed change prevents the race on a fresh sequence; it does not repair a save that already stores Tech Li's stuck scripted state.
Activity
akacross commentedon Oct 18, 2026
Thanks for the report and the screenshot.
I tried to reproduce this on openQ4 0.14.000 by staging the Viper Squad elevator sequence in hangar1 (the lift with Tech Li, Hayes and Mahler). The lift stopped at the right height every time. Tech Li stood at the edge of the platform for about 7–10 seconds after it arrived, while the other two walked off straight away, but he then followed the others. I couldn't get him to stay stuck, so there's probably something about your game state that my test doesn't recreate (fighting near the top of the lift, for example).
Could you help with a few details?
VERSION.txtnext to the executable.%LOCALAPPDATA%\openQ4\baseoq4\savegames. Each slot is a set of files with the same name (.save,.txtand, if present,.tga). Please zip all of them for that slot and attach the zip here.seta logFile 2, reproduce the freeze, then quit and attach%LOCALAPPDATA%\openQ4\baseoq4\qconsole.log.A save is the most useful of these, because it lets me load your exact situation.
[-]Script softlock in Hangar Perimeter[/-][+]Hangar Perimeter: Tech Li stalls after elevator, blocking progression[/+]themuffinator commentedon Oct 18, 2026
Linked this progression blocker to Q4-02 in the roadmap and to #189. That PR adds recovery when a medic/tech cannot reach a patient; its code review is approved and the branch has been updated for fresh CI after the unrelated test-harness fixes.
This issue stays open: the contributor's unreachable-patient test is useful, but it has not reproduced your exact lift state. The save requested above remains the best way to confirm whether that fix resolves your progression blocker.
ipfsd-acc commentedon Oct 20, 2026
@akacross I tried to reproduce the bug again, and it worked, which means the bug isn’t a one‑off or rare.
The console doesn’t say anything about the stuck issue.
.save file: Quicksave2.zip
.log file: qconsole.log
akacross commentedon Oct 21, 2026
@ipfsd-acc Thank you, the save made this traceable.
Reproduced. I loaded
Quicksave2in the official 0.13.2 Windows build (and in a currentmainbuild) and sampled Tech Li (entityelgar) every 10 seconds for two minutes withaiDumpState. He never moves on either build. Each sample shows the same thing: still scripted (aifl.scripted = true, stateWait_ScriptedDone), playing a looping scriptedidle, still looking attarget_elevFaceUp, with no heal patient.What's holding him. It's a race between two threads in the stock
hangar1map script (scripts/maps/hangar1.script):marinesUseLiftstartselgarSwitchin its own thread 3.25 s into the lift ride. That thread stands Li up, turns him to facetarget_elevFaceUp(aiScriptedAnimWait/aiScriptedFaceWait), then starts an endless scriptedidleloop and sets his look target.marinesUseLiftreleases him:lookAt( $null_entity ), thenaiScriptedStop( $elgar ).aiScriptedWaitonly pollsscriptedDone(), andaiScriptedStopmakes that true. IfelgarSwitchis still waiting when the release comes, the release ends its wait, and it goes on to start the endless idle loop after he was released. Nothing stops him again.His state in your save matches that ending exactly.
This is a different problem from the one #189 addresses. #189 recovers a medic or tech stuck approaching a patient it can't reach, and Li has no patient here, so it wouldn't help with this save.
Still open: why
elgarSwitchsometimes takes longer than the roughly 5 seconds it has. The likely suspects are the scripted turn towardtarget_elevFaceUpnot counting as finished while he rides the moving lift, or a save and load during the ride. I'm looking into that next, together with a fix that also releases Li in saves already stuck like yours. A save from just before you step onto the lift would help a lot if you have one (or a quicksave taken on the lift during the ride). Also, did you save or load at any point during the ride?akacross commentedon Oct 21, 2026
@ipfsd-acc Found the trigger: Turbo mode. Your save has the lift's stored move time at exactly half its authored value (3504 ms instead of the map's 7000), which is what
g_turboMode 1does to movers.Turbo doubles mover speeds, but the
hangar1lift script times Tech Li against the lift's normal 7-second ride: it waits a fixed 3 seconds before standing him up and turning him, and his animations run at normal speed. With the ride halved, the script releases him about 4.75 s into the sequence, before his stand-and-turn finishes at about 5.15 s. The release cancels that wait, the rest of his sequence then starts an endless idle loop, and nothing releases him again.Reproduced on current
mainfrom a freshhangar1, running the real lift trigger:g_turboMode 0: Tech Li is released after the lift, every time.g_turboMode 1: Tech Li is stuck (Wait_ScriptedDone, still looking attarget_elevFaceUp), every time.Workaround for now: turn Turbo off (or
seta g_turboMode 0) and load a save from before you step onto the lift. A save where he's already stuck can't be recovered by changing the setting, because his frozen state is stored in the save.I'm preparing a fix that keeps script-choreographed movers (
func_mover, like this lift) at their authored speed in Turbo mode, since map scripts time their waits against them. Doors and platforms you operate yourself stay fast.themuffinator commentedon Oct 21, 2026
The supplied save and Turbo timing analysis are now linked to #198, which preserves the authored timing of script-controlled movers. I have removed the awaiting-reporter label. #189 remains a separate unreachable-patient recovery improvement and is not the fix for this save.
I am reviewing #198 and its checks. The existing workaround remains: turn Turbo off and load a save from before the lift. The proposed change prevents the race on a fresh sequence; it does not repair a save that already stores Tech Li's stuck scripted state.