missions: CM8 Ashfall under pressure - #8578
Closed
keithharvey wants to merge 2 commits into
Closed
Conversation
Contributor
Integration Test Results23 tests +2 8 ✅ ±0 16s ⏱️ ±0s For more details on these failures, see this check. Results for commit 52f7acc. ± Comparison against base commit 4484c4c. ♻️ This comment has been updated with latest results. |
keithharvey
force-pushed
the
cm8-ashfall-pressure
branch
from
August 1, 2026 18:28
8ac453b to
caf420a
Compare
The first mission built on the framework, and the reason the roster is a
DSL rather than a table: a unit is declared once, with the team it
belongs to and the name triggers refer to it by, so a trigger file says
Unit("outpost_command_hub") and a typo is a load error rather than a
condition that silently never fires.
Mission mode comes with it. Triggers own the verdict, so engine
elimination must not end the match — that is standing configuration, not
something a trigger can assert mid-game, and it belongs in the mode the
lobby picks.
The editor learns the two probes a roster makes possible: whether a
named unit is dead or has been spotted. Both read latches the loader
publishes, which is why they arrive with the roster rather than with the
editor.
The mission gains scavenger waves, and everything the mission needed in order to ask for them. The pressure arc is four beats in cm8_ashfall/triggers/waves.lua: open quiet half a minute in, climb when the outpost is relieved, spike when the enclave is found, and stop when the commander dies. It names a pack — scavengers.skirmish — and the missions module resolves it through the scavengers module's mission vocabulary, so a mission gets the same wave director a multiplayer game runs, at a tenth of the intensity, with no bot on the field to activate it. .After(seconds) is new, and is what makes the opening beat possible. A trigger holds its effects until its conditions have gone on being true for that long, re-arming each time it fires so a repeating trigger reads as a rate limit. Seconds, never frames: MissionSeconds is a declared alias, so every editor deriving slots from the types can name the unit instead of showing a bare number. Transfer.Give is repaired here because CM8 is what proved it broken. Its contract is that no policy question is asked — the game moving a base, not a team choosing to share — but the move goes through Spring.TransferUnit, which fires AllowUnitTransfer, which the controller answers from the same sharing policy as any ordinary share. So the bypass bypassed nothing, and the policy gave the right answer to the wrong question: Gaia is nobody's ally, refuse. The opening beat of this mission is "you inherit this failing base"; what the player actually inherited was six structures that never moved and an enclave that shot at them. The give now announces itself for the duration of the move, the same way /take already did, and a rules param rather than an upvalue because VFS.Include is uncached and the controller and the caller hold different copies of api.lua. The editor learns to watch. A trigger publishes that it has FIRED — not that its condition is true, which would flicker back off on a once-trigger — and both editors shade a card that has fired, which is the difference between a list of rules and a visible run through them. Wave progress is published the same way, so a director's clocks are readable from a panel. And a guard the combat module needed for the same reason waves did: the gadget handler defers its callin-list updates while iterating but nils the method field immediately, so unhooking from inside a callin takes the whole gadget down on the next frame. CM8 needs an enemy team to arm at all, which the shared headless startscript does not have, so the scenario brings its own: luaui/Tests/cm8_ashfall/test_waves.lua drives the whole arc bot-free, and test_outpost.lua is the one that fails for thirty seconds without the Give fix. Both self-skip everywhere else.
keithharvey
force-pushed
the
cm8-ashfall-pressure
branch
from
August 2, 2026 14:16
caf420a to
52f7acc
Compare
keithharvey
force-pushed
the
cm8-ashfall
branch
from
August 2, 2026 14:22
53828b7 to
b0f9f91
Compare
Collaborator
Author
|
Folded into #8494 — CM8 Ashfall is now one commit covering both the roster and the pressure arc, on the same |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The mission gains scavenger waves, and everything the mission needed in order to ask for them.
The pressure arc
Four beats in
cm8_ashfall/triggers/waves.lua: open quiet half a minute in, climb when the outpost is relieved, spike when the enclave is found, stop when the commander dies. It names a pack —scavengers.skirmish— and the missions module resolves it through the scavengers module's mission vocabulary, so a mission gets the same wave director a multiplayer game runs, at a tenth of the intensity, with no bot on the field to activate it..After(seconds)New, and what makes the opening beat possible. A trigger holds its effects until its conditions have gone on being true for that long, re-arming each time it fires so a repeating trigger reads as a rate limit. Seconds, never frames:
MissionSecondsis a declared alias, so every editor deriving slots from the types can name the unit instead of showing a bare number.Transfer.Giveis repaired here, because CM8 is what proved it brokenIts contract is that no policy question is asked — the game moving a base, not a team choosing to share. But the move goes through
Spring.TransferUnit, which firesAllowUnitTransfer, which the controller answers from the same sharing policy as any ordinary share. So the bypass bypassed nothing, and the policy gave the right answer to the wrong question: Gaia is nobody's ally, refuse.The opening beat of this mission is "you inherit this failing base". What the player actually inherited was six structures that never moved and an enclave that shot at them. The give now announces itself for the duration of the move, the same way
/takealready did — a rules param rather than an upvalue, becauseVFS.Includeis uncached and the controller and the caller hold different copies ofapi.lua.The editor learns to watch
A trigger publishes that it has FIRED — not that its condition is true, which would flicker back off on a once-trigger — and both editors shade a card that has fired. That is the difference between a list of rules and a visible run through them. Wave progress is published the same way, so a director's clocks are readable from a panel.
One guard the combat module needed for the same reason waves did
The gadget handler defers its callin-list updates while iterating but nils the method field immediately, so unhooking from inside a callin takes the whole gadget down on the next frame.
Tests
CM8 needs an enemy team to arm at all, which the shared headless startscript does not have, so the scenario brings its own.
test_waves.luadrives the whole arc bot-free;test_outpost.luais the one that fails for thirty seconds without the Give fix. Both self-skip everywhere else.Stacked on #8577 (
scavengers) → #8576 (waves) → #8494 (cm8-ashfall).Note for review: this commit bundles more than its title suggests — the
Transfer.Givefix,.After/MissionSeconds, the fired-trigger shading and the combat callin guard are all separable if you would rather they landed as their own units.