Skip to content

fix: the contacts app's wait for custom NPCs survives a broken NPC in the scene - #337

Merged
ifBars merged 2 commits into
ifBars:betafrom
r-melvin:fix/contacts-wait-for-npcs
Oct 2, 2026
Merged

ifBars merged 2 commits into
ifBars:betafrom
r-melvin:fix/contacts-wait-for-npcs

Conversation

@r-melvin

@r-melvin r-melvin commented Oct 1, 2026 •

Copy link
Copy Markdown

Summary

ContactsAppPatches.WaitForNPCs checked every frame that each physical custom NPC was in the scene. It did this by reading NPC.ID for every result of FindObjectsOfType<NPC>(true). Some of the game's own NPCs throw from ID on IL2CPP: the pooled NPCs/SpecialCustomers/SpecialCustomerNPC(Clone) and SpecialCustomerLeaderNPC(Clone). One throw fails the whole check. On the second load of a session the wait is still running once they exist, so it threw every frame for the rest of the session:

[ERROR] [Il2CppInterop] Exception in IL2CPP-to-Managed trampoline ... NullReferenceException
  at Il2CppScheduleOne.NPCs.NPC.get_ID()
  at S1API.Internal.Patches.ContactsAppPatches.<>c__DisplayClass9_2.<WaitForNPCs>b__6(NPC sn)

That was 1,222 errors in 47 s in one run.

The change.

  • Skip broken NPCs: an NPC whose ID throws is skipped. It's never one of the custom NPCs being waited for.
  • No nested search: IDs are matched through a set.
  • Less often: the check runs four times a second instead of every frame, since it searches the whole scene, inactive objects included.

Compatibility

  • Public/protected API: none changed.
  • Existing defaults and behavior: the relation circles are added under the same conditions, up to 0.25 s later, and now also when such an NPC is in the scene.
  • Stable IDs, saves, and network payloads: none touched.

Validation

Mono

dotnet build S1API.sln -c MonoMelon --no-restore -p:AutomateLocalDeployment=false: 0 errors, 0 warnings. dotnet test ... -c MonoMelon: 743 passed (740 on beta plus 3 new: a throwing NPC id is skipped, a missing NPC is still waited for).

IL2CPP

dotnet build S1API.sln -c Il2CppMelon --no-restore -p:AutomateLocalDeployment=false: 0 errors, 0 warnings. dotnet test ... -c Il2CppMelon: 723 passed (720 plus 3 new).

Runtime evidence

How it was tested. Automated runs on 0.4.7f7 load a save, teleport to each custom NPC, record whether its model is shown and its network state, return to the menu and load again. They used a combined build of #332 to #339.

  • Same mods on both runtimes: IL2CPP and Mono "Alternate", with BigWillyMod, The Big Pimpin, Drug Expansion, S1MAPI and SteamNetworkLib. IL2CPP ran without Polyfill, on the game's own interop assembly.
  • IL2CPP with about 60 mods: including Polyfill, Siesta and S1UMF.
  • Saves: an early save and a late one where The Big Pimpin's intro is played through.

I also played the IL2CPP case by hand.

Before/after on IL2CPP without Polyfill or S1UMF (S1UMF guards NPC.ID itself, which hides the bug). The before build is all of #332 to #339 except this one; the after build is all of them. The probe counted the relation circles in the contacts app.

First load Second load Errors
Without this change circles for Big Willy and Disco Davey none 1,560 trampoline errors from WaitForNPCs
With this change circles for both circles for both none

On Mono there were no errors either way.

Documentation

None needed.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 260c0e71-7091-4857-990c-485aa7f4c593

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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.

… the scene

WaitForNPCs polled FindObjectsOfType<NPC>(true) every frame and read each one's ID. On IL2CPP, on the
second load of a session, one inactive NPC in the scene throws from NPC.ID (its data object is gone), so
every poll threw: 1,222 "Exception in IL2CPP-to-Managed trampoline" errors in 47 s in one run. The
predicate never returned true for the rest of the session.

The check now skips an NPC whose ID throws, matches IDs through a set instead of a nested search, and
runs four times a second instead of every frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@r-melvin
r-melvin force-pushed the fix/contacts-wait-for-npcs branch from da4b3c1 to e353ecf Compare October 1, 2026 23:16
@r-melvin
r-melvin marked this pull request as ready for review October 1, 2026 23:34
@ifBars ifBars added beta A game update on the beta & alternate-beta steam branches bug Something isn't working npcs Native game NPC system labels Oct 2, 2026
@ifBars

ifBars commented Oct 2, 2026

Copy link
Copy Markdown
Owner

I pushed 9ec0598 to remove the comment that repeated the throwing-ID test. Kept the runtime scan-throttling explanation and XML docs. No runtime changes in this follow-up. Full builds and suites pass: 743 Mono, 723 IL2CPP.

@ifBars

ifBars commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

Tested on 0.4.7f7 Mono and IL2CPP. Dealer and supplier contacts initialized on the first load and after reloading, even with nine scene NPCs throwing when their ID was read.

CI passed. The combined build of #332, #333, #334, #336 and #337 also passed all 770 Mono and 744 IL2CPP tests. Merged into beta.

@ifBars
ifBars merged commit beed831 into ifBars:beta Oct 2, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

beta A game update on the beta & alternate-beta steam branches bug Something isn't working npcs Native game NPC system

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants