Skip to content

fix: persist custom NPC deals and relationships - #262

Merged
ifBars merged 2 commits into
stablefrom
diffuin/260-d1a3bdda
Aug 12, 2026
Merged

fix: persist custom NPC deals and relationships#262
ifBars merged 2 commits into
stablefrom
diffuin/260-d1a3bdda

Conversation

@diffuin

@diffuin diffuin Bot commented Aug 12, 2026

Copy link
Copy Markdown

Requested by @ifBars in #260.

Diffuin response

Confidence: Medium

The worktree is ready for a PR: new custom NPC deals use stable native GUIDs, and saved relationship values survive the deferred spawn lifecycle. Existing contracts created with the old random GUID cannot be repaired from their save payload, so this PR should not close #260 until that migration limit is accepted or addressed.

Recommended next steps

  1. No public APIs, save fields, or existing durable IDs changed.
  2. Prepared NPCs remain inactive until the existing deferred network-spawn path runs.
  3. A pre-fix contract cannot be mapped safely because it contains a random customer GUID but no stable custom NPC ID.
Evidence and validation

Evidence inspected

  • Native ContractData persists CustomerGUID, while NPCData persists only the NPC ID. The old random custom NPC GUID therefore could not resolve after reload.
  • S1API now derives a versioned SHA-256 GUID from the existing NPC identity ID, registers inactive custom NPCs before QuestsLoader restores contracts, and lets NPCsLoader hydrate and later queue those same instances.
  • Finite saved relationship deltas, including zero, are retained and reapplied before and after the existing network-spawn preparation path.
  • Focused tests cover deterministic GUID normalization, distinction, and missing identity handling.

Validation performed

Runtime validation remaining

  • dotnet is not installed in this checkout, so the MonoMelon and Il2CppMelon builds and tests did not run.
  • Validate a newly scheduled custom-NPC deal across save/reload in IL2CPP and Mono.
  • Validate saved relationship values of zero and nonzero across save/reload in IL2CPP and Mono.
  • Validate multiplayer reconnect and late join after restoring custom-NPC contracts and relationships.
Diffuin run details
  • Provider: codex
  • Model: gpt-5.6-terra
  • Reasoning: high (Luna advisor: complexity (high); baseline bounded implementation)
  • Elapsed: 532s
  • Codex thread: 019ff4fe-5fce-7531-8248-15655413371d

AI notice: Generated with AI assistance and not guaranteed accurate. Verify findings and plans against the current source and runtime.


Diffuin job: d1a3bdda-fd74-4273-aa32-1f1ccbfb1ac9
Commit: 23cf7a4099a66e8b8a5ce2db1a01014297bdb5be

@ifBars ifBars self-assigned this Aug 12, 2026
@ifBars ifBars added the bug Something isn't working label Aug 12, 2026

@ifBars ifBars left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified and approved after completing the persistence path on the PR branch.

The original head established deterministic custom-NPC GUIDs and prepared NPCs before QuestsLoader, but live testing exposed two remaining loader-order defects:

  • NPCsLoader's legacy path constructed a second custom NPC after QuestsLoader had prepared one, allowing prefab defaults to win during later save serialization.
  • IL2CPP contract restoration reached Customer.AssignContract before the inactive custom customer's deal-attendance cache was initialized.

Commit 693c5d6 reuses the exact prepared NPC instance and initializes customer runtime state before contract restoration.

Validation:

  • Mono: build succeeded with 0 warnings/errors; 575/575 tests passed.
  • IL2CPP: build succeeded with 0 warnings/errors; 564/564 tests passed.
  • Live Mono and IL2CPP: strict three-load smoke passed for a custom customer and custom dealer. Non-default relationship values and unlock state persisted, an accepted contract restored to the same deterministic customer GUID, Customer.CurrentContract was assigned, and an explicit zero relationship persisted through another save/reload.
  • AssetRipper/native inspection confirmed vanilla NPC prefabs use stable baked GUIDs while the custom BaseEmployee template has no baked GUID, matching the runtime registration approach.
  • Refreshed hosted IL2CPP build, coverage, and both documentation checks passed.

Existing saves containing contracts written with the pre-fix random custom-NPC GUID cannot be migrated because ContractData stores only CustomerGUID, not the custom NPC identity ID. Newly saved and future custom-NPC contracts persist correctly.

@ifBars
ifBars merged commit dab5bd3 into stable Aug 12, 2026
6 checks passed
@ifBars
ifBars deleted the diffuin/260-d1a3bdda branch August 12, 2026 09:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Custom NPC relationships and scheduled deals reset after save reload

1 participant