Skip to content

3.2.1-beta.2 on 0.4.7f6: plain custom NPCs fail to construct, legacy and ConfigurePrefab paths alike ("The custom NPC prefab has no framework data object") #309

Description

@madjagstudios

Environment

  • Schedule I 0.4.7f6, Steam beta branch, Steam build 25439817 (the 2026-09-21 beta update), IL2CPP
  • MelonLoader 0.7.3
  • S1API (Forked by Bars) 3.2.1-beta.2 (+9d9d07706762ab943f548091b6b313b00bdb5514), S1MAPI 2.0.0
  • No other mods loaded: a minimal repro mod (below) with S1API and S1MAPI only reproduces it

What happens

Two phone-only custom NPCs, subclasses of S1API.Entities.NPC built with the deprecated 4-argument constructor (base(id, firstName, lastName, null), which the [Obsolete] message describes as the supported path for non-physical NPCs), fail to instantiate on every attempt when a save is loaded:

[WARNING] [NPCPatches] [S1API] Failed to instantiate custom NPC type '<Type>' before contract loading:
  System.Reflection.TargetInvocationException ---> System.InvalidOperationException:
  The custom NPC prefab has no framework data object.
   at S1API.Internal.Entities.NPCDataAccess.InitializeCurrentDataForConstruction(NPC npc)
   at S1API.Entities.NPC..ctor()
   at S1API.Entities.NPC..ctor(String id, String firstName, String lastName, Sprite icon)
   at <Type>..ctor()
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean wrapExceptions)
   at S1API.Internal.Patches.NPCPatches.PrepareCustomNpcsForContractLoad()

The same failure repeats for each save ID and at "with default data", four attempts per type, so the contacts never exist.

Where it comes from

NPC() calls NPCDataAccess.InitializeCurrentDataForConstruction(prefabNpc), which throws when GetDataObject(npc) is null. NPCDataAccess.AssignNewData (which creates and attaches the NPCDataObject) is only called on the base-employee fallback path (when the source NPC component is replaced) and the dealer/supplier paths. As far as we can read from source (not verified at runtime), a plain NPC template where sourceNpc == replacementNpc never gets a data object attached, which would make both the parameterless path and the legacy constructor fail.

We don't know whether this also fails on 0.4.7f5 (the build 3.2.1-beta.2 was validated on) or only on f6. The f5→f6 code diff shows no NPC-framework changes, so the template's data object would be asset-side if anything.

Minimal repro result

With only S1API, S1MAPI and the repro mod below installed, loading a save logs the same exception for both contacts: the legacy 4-arg constructor and the recommended parameterless constructor with ConfigurePrefab + WithIdentity. After load, NPC.Get(id) returns null for both (REPRO RESULT ...: MISSING). The modern path throws from NPC..ctor() directly, so this is not specific to the deprecated constructor.

Expected

Non-physical NPCs created through the legacy constructor (or the parameterless one with no ConfigurePrefab override) get a framework data object, the same as on 3.2.0.

Repro

public sealed class ReproLegacyContact : S1API.Entities.NPC
{
#pragma warning disable CS0618
    public ReproLegacyContact() : base("repro_legacy_contact", "Legacy", "Repro", null) { }
#pragma warning restore CS0618
}

public sealed class ReproModernContact : S1API.Entities.NPC
{
    public ReproModernContact() : base() { }
    protected override void ConfigurePrefab(S1API.Entities.NPCPrefabBuilder builder) =>
        builder.WithIdentity("repro_modern_contact", "Modern", "Repro");
}

Load any save on 0.4.7f6 with 3.2.1-beta.2 installed. Both types fail in PrepareCustomNpcsForContractLoad with the exception above, and neither exists after load. The full MelonLoader log from the repro run is available on request.

Happy to test a fix build.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions