feat(battlenode): inject SessionBattleEngine into BattleSession in pure shadow (Phase 2 N1 exit)
The engine is constructed per session, seated once from the master seed + both shuffled decks (F-N-5), and fed each frame via ShadowIngest — all inside a try/catch in ComputeFrames so a shadow failure can never break live dispatch (ND1/ND6). Routes still come from the existing handlers: wire output is byte-for-byte unchanged. FrameDispatchContext gains the Engine ref for N2+. csproj: PrivateAssets=compile on the engine ref so its global-namespace type surface (MessagePackSerializer, UserConfig, UserCard, ChallengeConfig, ...) does not leak transitively into SVSim.EmulatedEntrypoint (which references BattleNode) and collide with that project's own types; the runtime DLL still flows. All 238 BattleNode unit tests pass; EmulatedEntrypoint builds clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,12 @@ internal sealed class FrameDispatchContext
|
||||
internal required string BattleId { get; init; }
|
||||
internal required BattleSessionState State { get; init; }
|
||||
|
||||
/// <summary>The session's shadow engine (design ND2/F-N-6). In Phase-2 N1 it is fed in pure shadow
|
||||
/// and read by no handler; N2+ handlers source opponent-facing fields from it. Always non-null;
|
||||
/// <see cref="Engine.SessionBattleEngine.IsReady"/> is false until the engine is set up (and stays
|
||||
/// false if headless setup is unavailable in the host — the shadow then no-ops).</summary>
|
||||
internal required Engine.SessionBattleEngine Engine { get; init; }
|
||||
|
||||
/// <summary>The opponent is an AI-passive (ack-only) bot: it runs no handshake — no
|
||||
/// <see cref="IHasHandshakePhase"/> — and receives no relayed frames (the client drives its own
|
||||
/// AI; the server only acks). This is the participant property that replaces the per-handler
|
||||
|
||||
Reference in New Issue
Block a user