Entry 330
"scene does not sleep the event task: the pass runs on in its frame, disabled"
Filescrates/piney-event/src/vm/exec.rscrates/piney-event/src/host.rscrates/piney-game/src/area_host.rscrates/piney-game/src/field_host.rscrates/piney-game/src/world.rstools/test_event_vm.pycrates/piney-event/tests/vm_fixture.txtdocs/engine/event-vm.mddocs/engine/field-walk.md
74 read from the thread code that the event task, put to sleep inside
scene, wakes on the next frame. It left that unchecked against the game.
It does not sleep at all. All addresses are INF SLUS_202.67.
Why
ChangeScene (0x00167380) ends in ChangeRequest(6, 7) (0x001671e0).
That calls ccDisableThEvent, then ccSleepNoSleepThread(1, 1)
(0x0015a200), which does two things:
- it raises the sleep count of every thread whose flags (+0x10) lack bit 0;
- it puts the calling thread to sleep (flag 0x20,
SleepThread) only if its flags lack bit 1 (andi 0x2at 0x0015a27c).
ccThEvent sets both bits on itself as it starts (flags |= 3,
0x001b5a8c). So ChangeRequest returns into Execute, whose scene case
(0x001b01d8) goes straight back to the loop head. Nothing there or in
eventSub (0x001b5ef0, all 62 blocks) tests the phase. The rest of the
block and the rest of the pass run in the same frame, with
eventMng.phase at -1. Blocks with a phase condition then fail
CheckOpen; blocks with none still run.
mode was already modelled this way (ChangeRequest(num, 7), then the
next instruction). Every instruction that follows a scene in any
volume's scripts is bookkeeping, with no wait: end_event,
gate_unmark, mail, bbs_post, news_add, menu_clear, set_block.
The port
The interpreter had scene wait (Wait::ChangeRequest) until the next
mode's host answered no. The rest of the block then ran a frame later, in
the next area. It also left the phase at 4 until the frame's end, when the
host disabled it.
Now scene calls Host::change_scene and disables the VM, and the pass
goes on. Wait::ChangeRequest and the hosts' answers to it are gone.
Two tests show the difference:
event_2_plays_to_the_scene_change(world.rs) now ends with event 2 closed (CLOSED | 0b111), no block playing, and the play pass done, all in frame 2295, thescene's frame.event_21_elk_walks_up_in_mac_anufirst failed with only the disable missing. Event 21's block 1 ends inscene -2 ...(the same town again). With the phase still 4, block 4 (phase >= 4) opened in the old town and walked Elk in the new town's set-up, before his entry ("not done"). With the disable, block 4 waits for the new town's play, as in the game.
The checks' harness
tools/test_event_vm.py stubbed ChangeScene out entirely, so the game
side never disabled the task. It is now hooked to do what its
ChangeRequest does to the event manager (phase -1), without the scene.
vm_fixture.txt is regenerated from it.
nothing about the frame. The rest of [[74]]'s list (the battle pieces, pc_command's walks, Kite held, the party back in Mac Anu) is unchanged.