diff --git a/SVSim.BattleNode/Lifecycle/ScriptedLifecycle.cs b/SVSim.BattleNode/Lifecycle/ScriptedLifecycle.cs
index 801d90b..d8ec94c 100644
--- a/SVSim.BattleNode/Lifecycle/ScriptedLifecycle.cs
+++ b/SVSim.BattleNode/Lifecycle/ScriptedLifecycle.cs
@@ -107,6 +107,15 @@ public static class ScriptedLifecycle
EnvelopeForPush(NetworkBattleUri.TurnStart,
new OpponentTurnStartBody(Spin: ScriptedProfiles.OpponentTurnStartSpin));
+ ///
+ /// Server-pushed TurnEnd transition that closes the opponent's turn and hands control
+ /// back to the player. Paired with in the v1.1 loop.
+ /// Wire shape from prod capture battle-traffic_tk2_regular.ndjson L18:
+ /// {"uri":"TurnEnd","turnState":0,"resultCode":1,"playSeq":N}.
+ ///
+ public static MsgEnvelope BuildOpponentTurnEnd() =>
+ EnvelopeForPush(NetworkBattleUri.TurnEnd, new TurnEndBody(TurnState: 0));
+
private static IReadOnlyList BuildPosIdxList(IReadOnlyList hand)
{
var list = new List(hand.Count);
diff --git a/SVSim.UnitTests/BattleNode/Lifecycle/ScriptedLifecycleTests.cs b/SVSim.UnitTests/BattleNode/Lifecycle/ScriptedLifecycleTests.cs
index f78257a..c4c3881 100644
--- a/SVSim.UnitTests/BattleNode/Lifecycle/ScriptedLifecycleTests.cs
+++ b/SVSim.UnitTests/BattleNode/Lifecycle/ScriptedLifecycleTests.cs
@@ -153,6 +153,19 @@ public class ScriptedLifecycleTests
Assert.That(body.Spin, Is.EqualTo(100));
}
+ [Test]
+ public void BuildOpponentTurnEnd_emits_TurnEnd_uri_with_turn_state_zero()
+ {
+ var env = ScriptedLifecycle.BuildOpponentTurnEnd();
+
+ Assert.That(env.Uri, Is.EqualTo(NetworkBattleUri.TurnEnd));
+ Assert.That(env.ViewerId, Is.EqualTo(ScriptedLifecycle.FakeOpponentViewerId));
+ Assert.That(env.Cat, Is.EqualTo(EmitCategory.Battle));
+ var body = (TurnEndBody)env.Body;
+ Assert.That(body.TurnState, Is.EqualTo(0));
+ Assert.That(body.ResultCode, Is.EqualTo(1));
+ }
+
private static MatchContext FixtureCtx(IReadOnlyList? deck = null) => new(
SelfDeckCardIds: deck ?? Enumerable.Range(1, 30).Select(i => 100_011_010L).ToList(),
ClassId: "1", CharaId: "1", CardMasterName: "card_master_node_10015",