Files
Sylpheed/docs
Sylpheed RE agent 0cf75f998f re: phase coroutines are started by a per-frame timer table
sub_822748D0, called from ScriptPhase::Update every frame, walks the table at
[phase+240]: stride 24, each record carrying a coroutine offset (rec+4), an f32
threshold (rec+12) and a timer index (rec+20). It compares the previous and
current copies of the 32-entry float register file ([phase+104] and [phase+88])
and starts the coroutine at codebase+off on a RISING EDGE, prev <= t < cur, so
each fires once. Verified instruction by instruction.

The table comes from the mission-level begin_phase opcode 0x83's fourth operand
(the fifth is the phase end-event); sub_82270DF8 stores them at [phase+240] and
[phase+236]. On disc it is tagged constants -- 0x819 int, 0x81A float, both past
the ISL dispatcher's bound so they never execute. Verified on Stage 02: counts
25/13/18 with the tag triple correct in every record. Only timers 0 (1-1170s,
mission clock) and 5 (0-5s, phase intro) are used corpus-wide.

This explains the poke results. Two experiments set a squadron to 'destroyed'
and nothing happened; the leading explanation was that the condition coroutine
is not polling. It is not -- coroutines are started on a schedule by timer
crossings, so state written between firings is read by nobody.

It also reframes the arrival timetable: the routes' t=170 and these thresholds
are the same kind of thing. The mission is substantially a timeline, with unit
predicates deciding what happens at each scheduled point rather than when.

Open: which built-in arms or resets each timer.
2026-08-25 20:37:37 +00:00
..