diff --git a/SVSim.BattleNode/Protocol/Bodies/PlayActionsBroadcastBody.cs b/SVSim.BattleNode/Protocol/Bodies/PlayActionsBroadcastBody.cs
index 5280322..c639733 100644
--- a/SVSim.BattleNode/Protocol/Bodies/PlayActionsBroadcastBody.cs
+++ b/SVSim.BattleNode/Protocol/Bodies/PlayActionsBroadcastBody.cs
@@ -8,18 +8,15 @@ namespace SVSim.BattleNode.Protocol.Bodies;
/// (independent of KnownList — a targeted hand play carries both). KeyAction forwards a
/// choice/Discover play's {type,cardId} so the opponent renders the choice-token generation;
/// the pick (selectCard) is stripped for a hidden (open:0) draw-to-hand choice. UList
-/// forwards the sender's unapproved-movement list (deck-sourced summons/fetches) verbatim. Spin
-/// is the count of hidden, non-reproduced shared-RNG draws in THIS frame (real-spin design §3.2,
-/// per-frame delivery); null/omitted = 0 (the client's assumed default). All are omitted when null
-/// via the envelope's WhenWritingNull policy (a vanilla play carries none).
+/// forwards the sender's unapproved-movement list (deck-sourced summons/fetches) verbatim. All are
+/// omitted when null via the envelope's WhenWritingNull policy (a vanilla play carries none).
public sealed record PlayActionsBroadcastBody(
[property: JsonPropertyName("playIdx")] int PlayIdx,
[property: JsonPropertyName("type")] int Type,
[property: JsonPropertyName("knownList")] IReadOnlyList? KnownList,
[property: JsonPropertyName("oppoTargetList")] IReadOnlyList? OppoTargetList,
[property: JsonPropertyName("uList")] IReadOnlyList? UList = null,
- [property: JsonPropertyName("keyAction")] IReadOnlyList? KeyAction = null,
- [property: JsonPropertyName("spin")] int? Spin = null) : IMsgBody;
+ [property: JsonPropertyName("keyAction")] IReadOnlyList? KeyAction = null) : IMsgBody;
/// Opponent-facing keyAction entry for a choice/Discover play. type/cardId
/// (the GENERATING card) pass through so the opponent re-derives the candidate pool from that card's
diff --git a/SVSim.BattleNode/Sessions/Dispatch/Handlers/PlayActionsHandler.cs b/SVSim.BattleNode/Sessions/Dispatch/Handlers/PlayActionsHandler.cs
index 6c60083..346e09c 100644
--- a/SVSim.BattleNode/Sessions/Dispatch/Handlers/PlayActionsHandler.cs
+++ b/SVSim.BattleNode/Sessions/Dispatch/Handlers/PlayActionsHandler.cs
@@ -48,17 +48,6 @@ internal sealed class PlayActionsHandler : IFrameHandler
// knownList in the same frame (capture line 75).
var uList = KnownListBuilder.RelayUList(entries.GetValueOrDefault("uList"));
- // Hidden shared-RNG draws (a random deck→hand fetch the opponent can't reproduce) advance the
- // sender's shared _stableRandom; the receiver doesn't re-run them, so it needs a spin crank to
- // stay aligned for later visible randoms. Per-frame delivery (real-spin design §3.2): the count
- // rides THIS PlayActions. A fetch we relay with an identity (uList cardId present) is already
- // known to the opponent — exclude its idxs so it isn't counted. 0 → null (omitted; client
- // assumes spin:0).
- var revealed = uList is null
- ? (IReadOnlySet)new HashSet()
- : uList.Where(u => u.CardId is not null).SelectMany(u => u.IdxList).ToHashSet();
- var spin = KnownListBuilder.CountHiddenDraws(orderList, playIdx, revealed);
-
var body = new PlayActionsBroadcastBody(
PlayIdx: playIdx,
Type: type,
@@ -67,8 +56,7 @@ internal sealed class PlayActionsHandler : IFrameHandler
UList: uList,
// {type,cardId} forwarded so the opponent renders the choice token; selectCard dropped
// when open==0 (hidden draw-to-hand pick). Null for a vanilla play (no keyAction).
- KeyAction: KnownListBuilder.StripKeyActionForOpponent(keyAction),
- Spin: spin > 0 ? spin : null);
+ KeyAction: KnownListBuilder.StripKeyActionForOpponent(keyAction));
var frame = ctx.Env with { Body = body };
return new[] { new DispatchRoute(ctx.Other, frame, false) };
diff --git a/SVSim.BattleNode/Sessions/Dispatch/KnownListBuilder.cs b/SVSim.BattleNode/Sessions/Dispatch/KnownListBuilder.cs
index 2df5637..9ec92c0 100644
--- a/SVSim.BattleNode/Sessions/Dispatch/KnownListBuilder.cs
+++ b/SVSim.BattleNode/Sessions/Dispatch/KnownListBuilder.cs
@@ -42,41 +42,6 @@ internal static class KnownListBuilder
return null;
}
- /// Count hidden, non-reproduced shared-RNG draws implied by an orderList: move ops
- /// from Deck(0) to Hand(10) for a non-played, unrevealed card (a random fetch the opponent can't
- /// reproduce — it can't enumerate the active player's deck). Each such moved card = one crank the
- /// receiver must apply (spin += 1). Skips: the played card's own move (idx == playIdx);
- /// any idx in (its identity is already on the wire — a revealed uList
- /// fetch); and lot-based randoms (a move op carrying a rand array — the receiver
- /// reproduces those by re-rolling, so counting would double-crank). An ordinary card DRAW also
- /// surfaces as a hidden move(0→10) but is a deterministic top-of-deck pop (no shared-stream
- /// roll) and must NOT be counted — distinguishing it from a random fetch on the wire is the open
- /// capture (real-spin design §3.1; the spec's Task 0). Base 0; see the real-spin design doc.
- public static int CountHiddenDraws(object? orderList, int playIdx, IReadOnlySet revealed)
- {
- if (orderList is not IEnumerable