Skip to content

Commit 906166e

Browse files
committed
fix: spectator consistency check
1 parent b30cfa5 commit 906166e

25 files changed

+357
-182
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="SpaceWar (sync-test)" type="DotNetProject" factoryName=".NET Project">
3+
<option name="EXE_PATH" value="$PROJECT_DIR$/SpaceWar/bin/Debug/net8.0/SpaceWar.exe" />
4+
<option name="PROGRAM_PARAMETERS" value="0 1 sync-test" />
5+
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/SpaceWar/bin/Debug/net8.0" />
6+
<option name="PASS_PARENT_ENVS" value="1" />
7+
<option name="USE_EXTERNAL_CONSOLE" value="0" />
8+
<option name="USE_MONO" value="0" />
9+
<option name="RUNTIME_ARGUMENTS" value="" />
10+
<option name="PROJECT_PATH" value="$PROJECT_DIR$/SpaceWar/SpaceWar.csproj" />
11+
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
12+
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
13+
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
14+
<option name="PROJECT_KIND" value="DotNetCore" />
15+
<option name="PROJECT_TFM" value="net8.0" />
16+
<method v="2">
17+
<option name="Build" />
18+
</method>
19+
</configuration>
20+
</component>

samples/SpaceWar.Shared/GameSession.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ public void TimeSync(FrameSpan framesAhead)
9191
void UpdateStats()
9292
{
9393
nonGameState.RollbackFrames = session.RollbackFrames;
94+
95+
var saved = session.GetCurrentSavedFrame();
96+
nonGameState.StateChecksum = saved.Checksum;
97+
nonGameState.StateSize = saved.Size;
98+
9499
for (var i = 0; i < nonGameState.Players.Length; i++)
95100
{
96101
ref var player = ref nonGameState.Players[i];
@@ -103,8 +108,8 @@ void UpdateStats()
103108
public void OnPeerEvent(PlayerHandle player, PeerEventInfo evt)
104109
{
105110
Console.WriteLine($"{DateTime.Now:o} => PEER EVENT: {evt} from {player}");
106-
if (player.IsSpectator())
107-
return;
111+
if (player.IsSpectator()) return;
112+
108113
switch (evt.Type)
109114
{
110115
case PeerEvent.Connected:

samples/SpaceWar.Shared/Logic/GameState.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,15 @@ public void Init(int numberOfPlayers)
3939

4040
public void SaveState(ref readonly BinaryBufferWriter writer)
4141
{
42-
writer.Write(in Bounds);
4342
writer.Write(in FrameNumber);
44-
writer.Write(in Ships);
43+
writer.Write(in Bounds);
44+
writer.Write(Ships);
4545
}
4646

4747
public void LoadState(ref readonly BinaryBufferReader reader)
4848
{
49-
reader.Read(ref Bounds);
5049
reader.Read(ref FrameNumber);
50+
reader.Read(ref Bounds);
5151
reader.Read(Ships);
5252
}
5353

samples/SpaceWar.Shared/Logic/NonGameState.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ public class NonGameState(int numberOfPlayers)
3636
public bool Sleeping => SleepTime > TimeSpan.Zero;
3737
public int NumberOfPlayers => numberOfPlayers;
3838
public FrameSpan RollbackFrames;
39+
public uint StateChecksum;
40+
public ByteSize StateSize;
3941

4042
public bool TryGetPlayer(PlayerHandle handle, out PlayerConnectionInfo state)
4143
{

samples/SpaceWar.Shared/Logic/Renderer.cs

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ SpriteBatch spriteBatch
88
)
99
{
1010
readonly StringBuilder statsString = new();
11+
readonly StringBuilder stateInfoString = new();
1112
readonly StringBuilder scoreString = new();
1213

1314
public void Draw(GameState gs, NonGameState ngs)
1415
{
1516
DrawBackground(ngs.Background);
17+
1618
for (var i = 0; i < gs.NumberOfShips; i++)
1719
{
1820
DrawShip(i, gs, ngs);
@@ -171,6 +173,7 @@ void DrawHud(GameState gs, NonGameState ngs)
171173
{
172174
for (var i = 0; i < gs.NumberOfShips; i++)
173175
DrawScore(i, gs, ngs);
176+
174177
if (ngs.StatusText.Length > 0)
175178
{
176179
var statusSize = gameAssets.MainFont.MeasureString(ngs.StatusText);
@@ -185,7 +188,8 @@ void DrawHud(GameState gs, NonGameState ngs)
185188
Color.Yellow, 0, Vector2.Zero, 1, SpriteEffects.None, 0);
186189
}
187190

188-
DrawStats(gs, ngs);
191+
DrawConnectionStats(gs, ngs);
192+
DrawStateStats(gs, ngs);
189193
}
190194

191195
void DrawScore(int num, GameState gs, NonGameState ngs)
@@ -236,8 +240,11 @@ void DrawBar(Rectangle position, Color color, float actual, float total, int pad
236240
0, Vector2.Zero, SpriteEffects.None, 0);
237241
}
238242

239-
void DrawStats(GameState gs, NonGameState ngs)
243+
void DrawConnectionStats(GameState gs, NonGameState ngs)
240244
{
245+
const float statsScale = 0.6f;
246+
const int statsPadding = 2;
247+
241248
var maxPing = TimeSpan.Zero;
242249
for (var i = 0; i < gs.NumberOfShips; i++)
243250
{
@@ -250,21 +257,41 @@ void DrawStats(GameState gs, NonGameState ngs)
250257
statsString.Clear();
251258
statsString.Append($"ping: {maxPing.TotalMilliseconds:f2} ms ");
252259
statsString.Append($"rollback: {ngs.RollbackFrames.FrameCount}");
253-
const float scale = 0.6f;
254-
const int padding = 2;
255-
var statsSize = gameAssets.MainFont.MeasureString(statsString) * scale;
260+
var statsSize = gameAssets.MainFont.MeasureString(statsString) * statsScale;
256261
Vector2 statsPos = new(
257262
(gs.Bounds.Width - statsSize.X) / 2,
258-
gs.Bounds.Bottom + Config.WindowPadding - padding - statsSize.Y
263+
gs.Bounds.Bottom + Config.WindowPadding - statsPadding - statsSize.Y
259264
);
260265
Rectangle statsBox = new(statsPos.ToPoint(), statsSize.ToPoint());
261-
statsBox.Inflate(padding * 2, padding);
262-
statsBox.Offset(-padding / 2, padding);
266+
statsBox.Inflate(statsPadding * 2, statsPadding);
267+
statsBox.Offset(-statsPadding / 2, statsPadding);
263268
spriteBatch.Draw(gameAssets.Blank, statsBox, null,
264269
new(0x303030),
265270
0, Vector2.Zero, SpriteEffects.None, 0);
266271
spriteBatch.DrawString(gameAssets.MainFont, statsString, statsPos, Color.White,
267-
0, Vector2.Zero, scale, SpriteEffects.None, 0);
272+
0, Vector2.Zero, statsScale, SpriteEffects.None, 0);
273+
}
274+
275+
void DrawStateStats(GameState gs, NonGameState ngs)
276+
{
277+
const float statsScale = 0.5f;
278+
const int statsPadding = 2;
279+
280+
stateInfoString.Clear();
281+
stateInfoString.Append($"State: {ngs.StateChecksum:x8} {ngs.StateSize}");
282+
var size = gameAssets.MainFont.MeasureString(stateInfoString) * statsScale;
283+
284+
Vector2 pos = new((gs.Bounds.Width - size.X) / 2, gs.Bounds.Top - Config.WindowPadding);
285+
Rectangle box = new(pos.ToPoint(), size.ToPoint());
286+
287+
box.Inflate(statsPadding * 2, statsPadding);
288+
box.Offset(-statsPadding / 2, statsPadding);
289+
290+
spriteBatch.Draw(gameAssets.Blank, box, null,
291+
new(0x303030), 0, Vector2.Zero, SpriteEffects.None, 0);
292+
293+
spriteBatch.DrawString(gameAssets.MainFont, stateInfoString, pos, Color.White,
294+
0, Vector2.Zero, statsScale, SpriteEffects.None, 0);
268295
}
269296

270297
static readonly Rectangle[] missileExplosionSpriteMap =

samples/SpaceWar/Game1.cs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,17 +165,26 @@ protected override void Update(GameTime gameTime)
165165

166166
void HandleReplayKeys()
167167
{
168-
if (rollbackSession.Mode is not SessionMode.Replaying)
168+
if (rollbackSession.Mode is SessionMode.Remote or SessionMode.Spectating)
169169
return;
170170

171-
if (keyboard.IsKeyPressed(Keys.Space))
172-
replayControls.TogglePause();
171+
if (rollbackSession.Mode is SessionMode.Replaying)
172+
{
173+
if (keyboard.IsKeyPressed(Keys.Space))
174+
replayControls.TogglePause();
175+
176+
if (keyboard.IsKeyPressed(Keys.Right))
177+
replayControls.Play();
173178

174-
if (keyboard.IsKeyPressed(Keys.Right))
175-
replayControls.Play();
179+
if (keyboard.IsKeyPressed(Keys.Left))
180+
replayControls.Play(isBackwards: true);
181+
}
176182

177-
if (keyboard.IsKeyPressed(Keys.Left))
178-
replayControls.Play(backwards: true);
183+
if (keyboard.IsKeyPressed(Keys.Back))
184+
{
185+
rollbackSession.LoadFrame(rollbackSession.CurrentFrame - 10);
186+
replayControls.Pause();
187+
}
179188
}
180189

181190
protected override void Draw(GameTime gameTime)

0 commit comments

Comments
 (0)