Skip to content

fix(npc): start new custom npcs at the configured relationship delta - #376

Merged
ifBars merged 1 commit into
ifBars:stablefrom
DooDesch-Mods:fix/npc-relation-delta-new-save
Oct 30, 2026
Merged

ifBars merged 1 commit into
ifBars:stablefrom
DooDesch-Mods:fix/npc-relation-delta-new-save

Conversation

@DooDesch

Copy link
Copy Markdown

Linked issue

Fixes #375

Contributor checklist

  • I linked an issue opened before this PR, or explained an allowed exception above.
  • I checked existing issues and PRs for duplicate or overlapping work.
  • This PR addresses one focused problem or request.

Summary

A custom NPC that is new to an existing save now starts at the delta set with NPCRelationshipDataBuilder.WithDelta, not at the vanilla 2.0.

NPCRelationData.Init starts an NPC at NPCData.Relationship.DefaultRelationshipValue * 5. S1API left that value at the vanilla 0.4 and applied the configured delta only in FinalizeNetworkSpawn, which NPCNetworkBootstrap defers by a few seconds. Two Init calls ran before that and both started the NPC at 2.0:

  1. The S1API constructor (InitializeRelationshipData) on the registered NPC.
  2. Native Awake of the spawned instance.

NPCPrefabIdentity.ApplyDefaultRelationshipValue now writes clamp(delta, 0, 5) / 5 into the NPC data's DefaultRelationshipValue before both calls (constructor, and ApplyCriticalIdentityBeforeAwake in the Awake prefix). FinalizeNetworkSpawn still applies the full relationship defaults as before.

Compatibility

  • Public/protected API: no change. The new members are internal (NPCPrefabIdentity.ApplyDefaultRelationshipValue, NPCDataAccess.ApplyDefaultRelationshipValue, NPCRelationshipPersistencePolicy.ToNativeDefaultRelationshipValue).
  • Existing defaults and behavior: only NPCs with an NPCPrefabIdentity and a configured delta change. They start at the configured delta instead of 2.0 before spawn. NPCs without a configured delta keep the vanilla 0.4 / 2.0. The value written is the same delta FinalizeNetworkSpawn applies, clamped to 0 to 5 like the builder.
  • Stable IDs, saves, and network payloads: no change. Saved relationship data still replaces the default during load (checked in game, see below). DefaultRelationshipValue is on the per-NPC data copy S1API creates, not a shared preset.

Validation

Mono

  • dotnet build S1API.sln -c MonoMelon: 0 errors.
  • dotnet test -c MonoMelon: 825 passed, 0 failed.
  • Not run in game (no Mono test copy).

IL2CPP

  • dotnet build S1API.sln -c Il2CppMelon: 0 errors.
  • dotnet test -c Il2CppMelon: 788 passed, 0 failed.
  • New unit tests: ConfiguredDeltaMapsToNativeDefaultRelationshipValue, OutOfRangeDeltaIsClampedLikeTheBuilder.

Runtime evidence

Game 0.4.7f12, MelonLoader 0.7.3, IL2CPP. A local test pack adds three NPCs to an existing save that has never seen them: customer A (delta 2.5, unlocked), customer B (delta 2.5, locked behind connections), contact C (delta 3.5). Each NPC is read with a console dump right when the save reports ready.

Read stable (3.2.1) This PR
A at load relDelta=2 relDelta=2.5
B at load not read relDelta=2.5
C at load not read relDelta=3.5
A about 10 to 30 s later relDelta=2.5 relDelta=2.5

Save and reload: saved with A at 2.5, then changed A's configured delta to 4.0 and reloaded. A read 2.5 at load and 2.5 again 9 s later, so the saved value still wins. No [Relationship Data] warnings in the log.

Documentation

None. The documented behavior of WithDelta does not change; it now also holds before spawn.

NPCRelationData.Init starts an NPC at DefaultRelationshipValue * 5. S1API
left that at the vanilla 0.4 and applied the configured delta only in the
deferred FinalizeNetworkSpawn, so a new custom NPC read 2.0 for the first
seconds after load. Write delta / 5 into the NPC data before the constructor
Init and before native Awake. Saved relationship data still wins.

Fixes ifBars#375
@coderabbitai

coderabbitai Bot commented Oct 29, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 28 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 373d9a46-6197-4f17-9070-11b2525f60f4
Commits

Reviewing files that changed from the base of the PR and between c9ac103 and fddbe6c.

Files selected for processing: 5
  • S1API.Tests/Entities/NPCRelationshipPersistencePolicyTests.cs
  • S1API/Entities/NPC.cs
  • S1API/Internal/Entities/NPCDataAccess.cs
  • S1API/Internal/Entities/NPCPrefabIdentity.cs
  • S1API/Internal/Entities/NPCRelationshipPersistencePolicy.cs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@DooDesch

Copy link
Copy Markdown
Author

build-il2cpp and documentation fail before the build, in the assembly verify step: the game assemblies folder is empty.

A PR from a fork gets no secrets, so it can only use the game-assemblies-v4-main-* cache from stable. The last workflow run on stable was on 2026-10-19, and GitHub evicts a cache after 7 days without use. The only caches left are two empty ones from this PR's runs (281 and 306 bytes).

A manual run of the IL2CPP Build Check and the docs workflow on stable refills the cache. After that, a re-run here should get past this step.

@ifBars
ifBars merged commit fad9aab into ifBars:stable Oct 30, 2026
6 of 8 checks passed
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.

[BUG] New custom NPC starts at relationship delta 2.0 instead of the configured delta

2 participants