Skip to content

Add Strange Terrain (Nokris strike) - #3

Draft
Confetti3 wants to merge 19 commits into
stanuwu:mainfrom
Confetti3:strike-nokris
Draft

Confetti3 wants to merge 19 commits into
stanuwu:mainfrom
Confetti3:strike-nokris

Conversation

@Confetti3

@Confetti3 Confetti3 commented Sep 18, 2026 •

Copy link
Copy Markdown

Draft until stanuwu/Sunrise#128 is merged. The script calls API that only exists on that branch (set_squad_attachment, set_mission_effect, set_volume_active, release_native_phase, complete_native_encounter, on_event_trigger_state, on_event_native_reaction, bind_combatant_to_squad), so it won't run on current master. It also needs that branch to report replicated squad damage to Lua as on_event_damage_state; without it the boss never leaves phase 1.

This adds Strange Terrain, the Nokris strike, as strike_nokris/. It follows the 0.5 layout: strike_nokris/strike_nokris.lua is the entry point and everything else is required as strike_nokris.<module>. Nothing outside that folder is touched.

What's in it

  • Opening, the tunnels and the summoning room, with the relic knight and the crystal objectives.
  • The gauntlet and the arena, including the ogre's shield hop-on and the crystal beams.
  • Nokris: portal entry, the three protected phases with their crystal carriers and adds, and the kill. The boss only takes damage past each health gate once the script has cleared that phase and released it.
  • Phases start from the boss's replicated health, not from a client hook. Gates are compared as 10-bit levels (880/614/338 of 1023), since the clamp holds the boss at a level, not at the authored fraction. A crossing seen mid-release is held and started on the next settle.
  • Directives, dialogue cues and the populations along the route. A lot of the squads are wired as optional so a missing or renamed one in the SDK doesn't take the whole mission down.
  • Two Lua tests under strike_nokris/tests/: the optional entry population, and the phase provider replayed against a recorded fight's health timeline (NOKRIS_HEALTH_CSV).

Not done

  • Music isn't wired yet; I haven't worked out the section indices.
  • No rewards. Completion just records that the native defeat was accepted.
  • Defeat still comes from squad alive_count; the last health sample in a fight is well above zero.
  • Only played solo.

Testing

Ran it in game on build 86657 against the Sunrise branch above, most recently a full strike with all three phases starting server-side. Both Lua tests pass offline. I'll re-run once that PR settles and its API names are final, then take this out of draft.

strike_nokris/strike_nokris.lua drives the Nokris strike: opening crystals and
relic knight, ritual gauntlet, arena carrier rounds, portal, three shielded
boss phases and the chest. Helpers load as strike_nokris.<module>.

The completion model ends at the accepted result; no reward or exit commands
follow it, and MISSION COMPLETE is raised through context:complete_mission.
objective.assign maps the script's integer task group onto the generated
mission.TaskGroup handles and the squad's slot; revisions are gated natively.
objective.count reads the authored group count from those handles.
0.5.0 replaces the visible directive entry in place and clears it with
clear_directives(); the lane rotation and the disabled former entry drew a
stray marker under the new type-68 layout.
The type-30 occupancy monitor on slot 43 never reports a change under
the 0.5 DLL, so SQ_TUNNEL_START never spawned and the tunnel support
and ogre room never populated behind it.
0.5.0 slot handles carry no objective_count, so the assert raised a Lua
error the moment the arena entrance admitted the first carrier round and
the VM stopped; no carrier knight was ever placed.
Same 0.5.0 slot-handle difference as the serial carriers: the field is
absent, so the assert would have faulted the VM at the first shield phase.
A re-placed squad slot's second lifetime reports no alive field on 0.5, so
round 3 was never adopted and round 4 was never placed.
A re-placed carrier slot reports no alive count on 0.5 and keeps objective
revision 1. The first report of the replacement lifetime blocked the fight
with carrier_population_unknown, so a lost relic ended the boss encounter.
Place the same-wave sibling squads the reconstruction left out (gauntlet,
tunnel, arena acolytes and carrier escorts, third arena support wave), run
arena carrier rounds three and four on their own fresh slots, and summon
the boss-room G squads on each return to damage. Every added squad is
optional: an unresolvable or refused one is skipped, never a route block.

Dialogue gains the intel line, the opening relic hint, the chant reaction
and Nokris's four taunts.
Records each gate the server sees in nokris.server_phase; the native reaction
still drives the fight. Gates compare ten-bit levels because the clamp holds the
boss at the first level at or above each floor.
The provider admits a phase when the boss squad's damage state reaches the clamp
level for the next floor (880/614/338 of 1023). The client hook's reaction is now
a fallback: it is held for 1.5 s and starts a phase only if the server never
reported it, since a dropped lane-2 frame at a gate would otherwise stall the
fight. The portal opens from either source and takes the boss generation from
the model. nokris.phase_source records which source started each phase.

Defeat, completion and the gate release stay with the native owner.
Phases and their portals start only from the server's replicated boss health.
The hook's gate reaction is ignored; it keeps the capture sequence current for
its death event. A gate sample that arrives before the model can take it is held,
because the clamp keeps the level flat and the sample never repeats.
Scene spawns bind the combatant first, so the entry population now takes a
combatants list and commits the binding a frame ahead of the type-1 placement.
Atom and ability programs need the squad-bound actor. The damage-state wrap is
diagnostic: on 86657 the client sends one type-2 Sense at spawn and never
republishes, so it records nothing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant