"The singleton pattern that removes reference-wiring"
You're dragging Component references across the inspector for every system that needs the clock, player, UI state, or world builder — and hotloads / runtime spawns break those links.
s&box scenes and runtime-built worlds don't need a DI container for "one of these exists." A static Instance published at Awake is enough for singleplayer / host-local managers. The trap is publishing too late (OnStart) or forgetting to clear on destroy so a destroyed GO still looks "alive."
public sealed class GameClock : Component
{
public static GameClock Instance { get; private set; }
protected override void OnAwake() => Instance = this;
protected override void OnDestroy()
{
if (Instance == this)
Instance = null;
}
}Consumers:
var clock = GameClock.Instance;
if (clock is null) return;
// ...Create managers first in bootstrap so OnAwake has published .Instance before world/state components run (component-lifecycle-onawake-onstart).
For networked shared host truth (day/night, run stats), prefer [Sync(SyncFlags.FromHost)] + host mutation guards over assuming every peer's singleton is authoritative — see owner-simulated-networking.
OnAwake runs synchronously at Components.Create, so the Instance pointer is valid before the next bootstrap line. Clearing only when Instance == this avoids a newer replacement being nulled by an older destroy. Null-guards keep hotload / teardown races from throwing instead of no-opping for a frame.