Просмотр исходного кода

Publish ending cinematic records in the held Apex world

Millie 3 дней назад
Родитель
Сommit
5e476d6aac

+ 6 - 4
Sunrise/src/server/bap/encrypted/push/activity/activity_mission_seed_roster.cpp

@@ -498,10 +498,12 @@ MissionSeedRosterResult append_initial_mission_seed(Session& session,
             publicRegion = isPublic;
         }
     }
-    const bool transitionPublication =
-        !lease.fullSetPublished
-        && ((!lease.scriptSelected && !publicRegion) || heldRegion < 0
-            || static_cast<std::uint32_t>(heldRegion) != selectedRegion);
+    // Arrival was already accepted for a sibling state above. Apply that same rule to
+    // the content subset, or the lease commits without ever registering its movie controller.
+    const bool transitionPublication = mission_seed_transition_subset_only(
+        lease.fullSetPublished, lease.scriptSelected, publicRegion,
+        heldRegion, selectedRegion, summary.sliceSetIndex,
+        middleware::content::packages::tables::kSliceSetIndexFactor);
     for (std::size_t source = 0; source < foldGroupCount; ++source) {
         const layouts::RosterGroup& candidate = materialized[source];
         if (!layouts::valid_roster_group(candidate)) {

+ 11 - 0
Sunrise/src/server/bap/encrypted/push/activity/mission_seed_world_change.h

@@ -72,4 +72,15 @@ mission_seed_arrival_window_closed(std::int32_t heldRegion,
         && !mission_seed_arrival_window_closed(heldRegion, newRegion, newSliceSet, factor);
 }
 
+/** State-local records may publish once the containing world is held, including sibling movies. */
+[[nodiscard]] constexpr bool mission_seed_transition_subset_only(
+    bool fullSetPublished, bool scriptSelected, bool publicRegion,
+    std::int32_t heldRegion, std::uint32_t selectedRegion,
+    std::uint32_t selectedSliceSet, std::uint32_t factor) noexcept {
+    return !fullSetPublished
+        && ((!scriptSelected && !publicRegion)
+            || !mission_seed_arrival_window_closed(
+                heldRegion, selectedRegion, selectedSliceSet, factor));
+}
+
 } // namespace sunrise::server::bap::encrypted::push::activity

+ 8 - 0
docs/mission-ember-apex-cooling-and-scorch.md

@@ -12,3 +12,11 @@ Package evidence correction: config 80B3D494 (ship) and 80B3D497 (sunburn) both
 Validation: all five mission Lua suites pass. Route peak: 235 variables, 61 intents per callback, three concurrent timers, 13,000 Lua instructions including the mock. Tests cover cooling command order, beam presence, deferred ship activation, duplicate ship receipts, and disabling the extra escape burn.
 
 Still unresolved: exact native ending-readiness failure and full-screen surge distortion. The diagnostic DLL commit fe45d11 improves visibility but does not itself fix cinematic playback. Do not reinstate the reverted cinematic-region ordinal encoding: it caused Lime.
+
+## Ending roster correction
+
+The 15:52:37 stalled-run capture contains 491 allocated sync records and no type-6 cinematic record. All allocated records have byte 20 set to 1; its exact native readiness meaning is not established. This capture does not demonstrate Omega's 19-unseeded-record condition.
+
+The roster's transitionPublication predicate still compared heldRegion directly against selectedRegion. Thus held Apex region 0 / selected bookend region 1 withheld state-local groups even after the separate arrival-window check accepted the shared world. Apply the shared-world arrival rule to the roster subset too. Both bookends may then publish while the player holds Apex; genuine world changes and unknown held-world state still defer local records.
+
+This is isolated from the reverted global-message state-byte experiment. Global state encoding is unchanged. Release build and all 22 portable tests pass, including the production subset predicate. Native movie creation and playback need a live test; do not treat server cinematic_staged as proof of playback.

+ 9 - 0
tests/mission_seed_world_change_test.cpp

@@ -107,6 +107,15 @@ void arrival_window_stays_open_across_a_real_slice_set_change() {
 } // namespace
 
 int main() {
+    // Closing the arrival lease alone is insufficient: the roster must include the
+    // state-local cinematic groups while the client still reports Apex gameplay.
+    assert(!seed::mission_seed_transition_subset_only(false, true, false, 0, 1, 0, 8));
+    assert(!seed::mission_seed_transition_subset_only(false, true, false, 0, 2, 0, 8));
+    assert(seed::mission_seed_transition_subset_only(false, true, false, 40, 1, 0, 8));
+    assert(seed::mission_seed_transition_subset_only(false, true, false, -1, 1, 0, 8));
+    assert(seed::mission_seed_transition_subset_only(false, false, false, 0, 1, 0, 8));
+    assert(!seed::mission_seed_transition_subset_only(false, false, true, 0, 1, 0, 8));
+    assert(!seed::mission_seed_transition_subset_only(true, true, false, 40, 1, 0, 8));
     // Real full-mission case: the last explicit seed is the landing, but ordinary
     // traversal already brought the player to Apex before selecting its ending.
     assert(!seed::mission_seed_selection_needs_arrival(64, 64, 0, 1, 0, 8));