Frontend menu + settings + saves foundation

Netcode frontend pattern: UITK main menu / pause / settings (MenuUi + controllers), on-demand world lifecycle (WorldLauncher/SessionRunner), GameBootstrap menu branch; Graphics/Audio settings (SettingsService/GameVolume); single-slot save foundation (SaveData/SaveService, born-correct load at director spawn, autosave on Siege->Calm + quit); RuntimePanelSettings + theme; BuildTool menu; 10 EditMode tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-06 15:05:36 -07:00
parent f3f65bccbf
commit f31ffe910b
56 changed files with 1744 additions and 8 deletions
@@ -0,0 +1,32 @@
using System.Collections;
using UnityEngine;
namespace ProjectM.Client
{
/// <summary>
/// Persistent (<c>DontDestroyOnLoad</c>) MonoBehaviour that hosts the world-lifecycle coroutines for
/// <see cref="WorldLauncher"/>. World create/dispose + scene loads must run at a FRAME BOUNDARY (never
/// inside an ECS system update — that crashes), and must survive the MainMenu&lt;-&gt;Game scene swap, so a
/// single long-lived runner owns them. Created lazily on first use.
/// </summary>
public class SessionRunner : MonoBehaviour
{
static SessionRunner _instance;
static SessionRunner Instance
{
get
{
if (_instance == null)
{
var go = new GameObject("~SessionRunner");
DontDestroyOnLoad(go);
_instance = go.AddComponent<SessionRunner>();
}
return _instance;
}
}
public static void Run(IEnumerator routine) => Instance.StartCoroutine(routine);
}
}