Skip to content

SDK: record scene event keys and counter directive elements, carry directive progress - #122

Merged
stanuwu merged 6 commits into
stanuwu:masterfrom
Fozkais:sdk-scene-keys-and-directive-elements
Sep 27, 2026
Merged

stanuwu merged 6 commits into
stanuwu:masterfrom
Fozkais:sdk-scene-keys-and-directive-elements

Conversation

@Fozkais

@Fozkais Fozkais commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • records, in the SDK pack, the event gates of every authored scene's graph: one row per gate, carrying the event key the server publishes with set_scene_events and the gate's ordinal in the scene's progression. A graph that cannot be read or does not have the expected shape leaves the scene without keys and is logged, never refused.
  • records the directive elements authored with a progress label and no description. The generator required a description and dropped the counter variant of a directive; an element is now kept when it has a title and either text, and its progress label, source tags and authored flag word travel with the row.
  • carries progress values in the directive lane set_directive publishes. The type-68 encoder wrote the four signed lane values as zero, so a counter could only show 0 / 0.
  • exposes all of it to Lua: event_keys on each scene symbol, progress and counter on each mission.Directive entry, and progress = { current, maximum } on set_directive. event_keys is the authored set scene:send_event{ key } accepts for that scene; the call itself only bounds the key.
  • bumps the pack version so existing packs regenerate.

Files Modified

Pack Format

Sunrise/src/state/activity_sdk/format.h
  • Adds the authoredSceneEventKeys section at the end of the section index, with its row AuthoredSceneEventKey (scene slot, resource tag, graph tag, gate offset, ordinal, key, flags), and the graph layout: the graph field of a resource, the typed array marker, the gate array and element classes, the element size, the key and ordinal offsets, and a gate bound.
  • Adds the packed directive table layout (table, entry and element classes, sizes and field offsets) and the counter bit. DirectiveElement gains progress, its source tags and flags.
  • Moves the pack version from 40 to 41.
Sunrise/src/state/activity_sdk/activity_sdk_loader.cpp
Sunrise/src/state/activity_sdk/generation/pack_writer.h
Sunrise/src/state/activity_sdk/generation/activity_sdk_pack_writer.cpp
  • Register the event key row stride on both sides and carry the section through the writer tables.
Sunrise/src/state/activity_sdk/runtime.h
Sunrise/src/state/activity_sdk/activity_sdk_catalog.cpp
  • Add Catalog::authored_scene_event_keys() and slot_authored_scene_event_keys(), which returns one contiguous range per type-43 slot and relies on the section's slot ordering, as the resource accessor does.
Sunrise/src/state/activity_sdk/activity_sdk_relation_validation.cpp
Sunrise/src/state/activity_sdk/activity_sdk_structure_validation.cpp
  • Add the authored_scene_event_keys check: every row names a type-43 slot that holds exactly one resource of the stated tag, flags are exact, key and graph are set, and rows come in slot then gate order without repeats.
  • Relax the directive checks: a description or a progress label is required, not both; an authored field has both source tags and an absent one has neither.

SDK Generation

Sunrise/src/client/content/activity/activity_sdk_authored_scene_inventory.h
Sunrise/src/client/content/activity/activity_sdk_authored_scene_internal.h
Sunrise/src/client/content/activity/activity_sdk_authored_scene_inventory.cpp
Sunrise/src/client/content/activity/activity_sdk_authored_scene_validation.cpp
  • Follow a resource to its graph, require exactly one typed array of gate elements, check that every element opens with the graph's own tag and the gate class, and record its key and ordinal. A graph that is unreferenced, unreadable, without a gate array, over the gate bound, or with a malformed gate is logged and yields no keys; only a topology inconsistency fails the build.
  • Validate the rows before composition: each belongs to a resourced scene with the same resource tag, its identity recomputes to the stored one, and the order is strict.
Sunrise/src/client/content/activity/activity_sdk_native_pack_text.cpp
  • Reads the three localized references and the flag word of a packed element with the named layout instead of literal offsets; a reference is checked only when present. Keeps an element with a title and a description or a progress label, and logs the ones it leaves out at debug.
Sunrise/src/client/content/activity/activity_sdk_pack_composer.h
Sunrise/src/client/content/activity/activity_sdk_pack_composer.cpp
Sunrise/src/client/content/activity/activity_sdk_pack_composer_rows.cpp
Sunrise/src/client/content/activity/activity_sdk_pack_composer_validate.cpp
Sunrise/src/client/content/activity/activity_sdk_native_pack_pipeline.cpp
  • Link and convert the new rows and fields, bound the section and pass it to the Lua source, as for the other authored scene sections.
Sunrise/src/client/content/activity/activity_sdk_lua_artifacts.h
Sunrise/src/client/content/activity/activity_sdk_lua_publish.cpp
Sunrise/src/client/content/activity/activity_sdk_lua_contract.cpp
Sunrise/src/client/content/activity/activity_sdk_lua_catalog_contract.cpp
Sunrise/src/client/content/activity/activity_sdk_lua_missions.cpp
  • Publish event_keys = { ... } in gate order on each scene symbol and the section count in the manifest.
  • Publish progress and counter on a mission.Directive entry when authored; a counter element takes its key from its progress label, since it shares its title with the described one. Declares SunriseDirective and the progress argument in the Lua contract and the new directive fields in the catalog contract.

Server

Sunrise/src/middleware/bap/activity_message/scriptable_auth_body.h
Sunrise/src/middleware/bap/activity_message/activity_scriptable_auth_mission_body_codec.cpp
  • Type68Preset carries the four signed lane values; the encoder writes them as given for the active lane and zero for the inactive ones. The body keeps its shape. write_directive_entry takes them after the navpoint name and bubble hashes and the waypoint reference.
Sunrise/src/server/activity/mission/mission_script_vm.h
Sunrise/src/server/activity/mission/mission_script_sdk_bridge.cpp
Sunrise/src/server/activity/mission/mission_script_lua_presentation_api.cpp
  • The resolved element definition carries the authored flag word. set_directive accepts progress, one to four int32 values, beside the other named arguments, and refuses it on an element that declares no counter, since the HUD would ignore the values.
Sunrise/src/server/ui/activity_host/activity_host_sdk_mission_view.cpp
  • Shows the progress label and marks counter elements.

Validation

  • Release x64 build of e581d0b passed.
  • clang-format passed on all 29 affected sources and headers; the configured clang-tidy passed on all 20 affected translation units.
  • Pack regenerated from the installed content: 5310 event key rows; every scene with a resource received its keys and no activity_sdk_scene_graph result was logged. For scenes whose graphs were decoded by hand from their packages, the exported keys match in count, value and order, including the shared opening gate (ordinal -1) and scenes with 1, 3, 5 and 10 gates.
  • Directive elements went from 14932 to 15076. The 144 added rows are exactly the rows with an empty description, and every one of them carries a progress label; every element the previous reader kept is still present.
  • Live, on a counter element with no description: set_directive{ directive = ..., progress = { 0, 3 } } shows the element's title once with " 0 / 3"; re-sending it with { 1, 3 } updates the counter in place without a new banner.

Notes

@Fozkais

Fozkais commented Sep 18, 2026

Copy link
Copy Markdown
Contributor Author

updated to match/adapt with 0.5.0 changes

@Fozkais
Fozkais force-pushed the sdk-scene-keys-and-directive-elements branch from 8c0d27c to 83bf426 Compare September 21, 2026 14:18
Fozkais and others added 6 commits September 27, 2026 17:53
A scene resource references its event graph; the graph holds the gates the server
publishes with set_scene_events, each carrying an event key and its ordinal in the
scene's progression. The pack now carries one row per gate, ordered by scene slot
then gate, with the resource and graph tags the row was read from.

The catalog exposes the section and a per-slot range, and relation validation
refuses a pack whose keys do not belong to a type-43 slot with exactly one
resource of the stated tag. Format version 39.
The generator follows each scene resource to its graph, requires exactly one
typed array of gate elements, checks every element opens with the graph's tag
and the gate class, and records its key and ordinal. A graph that cannot be
read, or a malformed one, is logged and leaves the scene without keys; only a
topology inconsistency fails the build.

Rows are checked against the inventory before composition and published to Lua
as event_keys on each scene symbol, with the count in the manifest.
…iption

A packed type-68 element is four localized string references and a flag word.
The generator required a description and dropped the counter variant of a
directive, authored with a progress label and no description. An element is
now kept when it has a title and either text; the progress label, its source
tags and the authored flag word travel with the row, and the counter bit is
exposed to Lua as `counter` beside `progress`.
The type-68 encoder wrote the four signed lane values as zero, so a counter
element could only show 0 / 0. The preset now carries them and the encoder
writes them as authored; the inactive lanes stay at zero and the body keeps its
shape. set_directive accepts `progress = { current, maximum, ... }`, one to four
int32 values, and refuses it on an element whose authored flags declare no
counter, since the HUD would ignore the values. The resolved element definition
carries the flag word for that check.
The page walked every directive element of the pack for each occurrence of the
state, and resolved the binding, the lease and the scriptable route again for
every element it kept; each of those resolutions then scanned the whole element
section once more to check the element's identity. With the counter elements
now in the section the page dropped the game to 12 fps.

Elements are written in slot, name hash then element order without repeats; the
relation check now requires it, and slot_directive_elements returns one slot's
elements by binary search. The page walks the type-68 slots of the state's
objects, resolves each slot once with directives_availability and draws its
elements from that range. prepare_directive checks the identity in the same
range. A description or progress label is drawn only when authored; the missing
marker was printed before.
Reach the gate table through the graph's own field instead of scanning the blob, and check
the graph's class on the way.
Drop a scene's keys when one gate is malformed, so a misread graph yields no keys.
Log a scene with no graph at debug; it is not a fault.
Key a directive by its progress label only when it has no description, so shipped scripts
keep their title keys.
Publish a scene's event keys from the sorted section range instead of a full scan.
Move the key collector into the file's anonymous namespace and give build() its comment back.
Delete the per-slot event key accessor nothing calls.
Bump the pack version to 42; 41 is taken on master.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@stanuwu
stanuwu force-pushed the sdk-scene-keys-and-directive-elements branch from 83bf426 to ab796ea Compare September 27, 2026 16:10
@stanuwu
stanuwu merged commit 3a8cb6a into stanuwu:master Sep 27, 2026
1 check passed
@stanuwu

stanuwu commented Sep 27, 2026

Copy link
Copy Markdown
Owner

Merged, thanks.

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.

2 participants