Skip to content

Fix Smarter Construction compat for 1.6 cache refactor (#598)#600

Draft
M-r-A wants to merge 1 commit into
rwmt:masterfrom
M-r-A:issue-598-smarter-construction
Draft

Fix Smarter Construction compat for 1.6 cache refactor (#598)#600
M-r-A wants to merge 1 commit into
rwmt:masterfrom
M-r-A:issue-598-smarter-construction

Conversation

@M-r-A

@M-r-A M-r-A commented Jun 27, 2026

Copy link
Copy Markdown

Summary

Smarter Construction 1.6 refactored its internal caches from static fields to per-map MapComponents. The existing compat patch in SmarterConstruction.cs still resolved ClosedRegionDetector.cache and other static bindings via AccessTools.StaticFieldRefAccess. On current SC 1.6 builds those fields no longer exist, so DeclaredField returns null and compat init throws:

MPCompat :: Exception loading dhultgren.smarterconstruction: System.ArgumentNullException: Value cannot be null.
Parameter name: fieldInfo
  at HarmonyLib.AccessTools.StaticFieldRefAccess[F] ...
  at Multiplayer.Compat.SmarterConstruction..ctor(ModContentPack mod)

Reported in #598.

Approach

Detect which layout is loaded at init time instead of inferring from a missing static field:

private static bool UsesMapComponentLayout()
{
    var encloseThingsCacheType = AccessTools.TypeByName("SmarterConstruction.Core.EncloseThingsCache");
    return encloseThingsCacheType != null
        && typeof(MapComponent).IsAssignableFrom(encloseThingsCacheType)
        && AccessTools.Method(encloseThingsCacheType, "GetCache", new[] { typeof(Map) }) != null;
}
  • 1.6+ path: resolve GetCache(Map) on EncloseThingsCache / PawnPositionCache, clear _cache / _positionCache per map in Find.Maps, reset _lastCacheCleanup to 0.
  • Pre-1.6 path: keep existing static field refs (ClosedRegionDetector.cache → nested EncloseThingsCache.cache, static PawnPositionCache fields).
  • Assign clearSecondaryCaches once at init (ClearMapComponentCaches or ClearStaticCaches) so GameComponentUtility.FinalizeInit clearing stays branch-free.

Field name fallbacks (_cache / cache, _positionCache / positionCache) retained for minor renames within each layout.

Trade-off

Still uses reflection into private cache fields rather than an upstream SC API (e.g. Compatibility.ClearCachesForMultiplayer()). Acceptable for MP Compat; a public clear hook in rimworld-smarter-construction would be more stable long-term but is out of scope here.

Test plan

  • Builds cleanly (Multiplayer_Compat.sln, Debug)
  • Game load: log shows MPCompat :: Initialized compatibility for dhultgren.smarterconstruction (no ArgumentNullException)
  • MP: start/load colony with Smarter Construction enabled; no compat errors on FinalizeInit
  • MP: host + client load same save after a prior session (cache clear on FinalizeInit does not break construction priority / enclose checks)

…t#598)

Smarter Construction 1.6 moved enclose/pawn caches from static fields
to per-map MapComponents. The compat layer still looked up
ClosedRegionDetector.cache and failed with ArgumentNullException.

Detect layout via EncloseThingsCache : MapComponent + GetCache(Map),
clear per-map caches on older builds, and keep the pre-1.6 static path.

Fixes rwmt#598
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.

1 participant