sub_8225FEF8's only caller is sub_82260568, which looks like a derived
ctor calling its base -- i.e. every phase is a Demo, which would make
the built-in dispatch inert. Reading the constructor refutes it: it
allocates 10216 bytes and runs SilphScriptPhase's ctor on object A,
then initialises a second object B and stamps the Demo vptr on it.
They land at Y+4 and Y+8, which is why the load path resolves the
ScriptPhase through Y+4.
The Demo class's 109 overrides all point at three no-op stubs; only
slot 15, slot 111 (Update = sub_82275800), slot 112 and the destructor
survive. DEMO is the corpus's established cutscene text family, so the
cutscene-runner reading is recorded as a reading, not a result.
Also notes a new handle for the stalled X+12 question: the kind is
passed straight into sub_82260568 as its third argument.
Docs only; artefacts byte-identical.