Skip to content

Commit 020f6a6

Browse files
bruno-dasilvaMearman
authored andcommitted
feat: Add GetPrevFrameChecksum() to the Lua API
# Purpose Trying to expose the sim frame checksum information to lua so we can update the fightertest widget/gadget combo to grab it every sim frame and dump it to a file at the end of each fightertest run.
1 parent b614e35 commit 020f6a6

5 files changed

Lines changed: 49 additions & 0 deletions

File tree

rts/Lua/LuaSyncedRead.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
#include "System/FileSystem/FileHandler.h"
8080
#include "System/FileSystem/FileSystem.h"
8181
#include "System/StringUtil.h"
82+
#include "System/Sync/SyncChecker.h"
8283

8384
#include <cctype>
8485
#include <functional>
@@ -121,6 +122,7 @@ bool LuaSyncedRead::PushEntries(lua_State* L)
121122

122123
REGISTER_LUA_CFUNC(GetGameFrame);
123124
REGISTER_LUA_CFUNC(GetGameSeconds);
125+
REGISTER_LUA_CFUNC(GetPrevFrameChecksum);
124126

125127
REGISTER_LUA_CFUNC(GetGameRulesParam);
126128
REGISTER_LUA_CFUNC(GetGameRulesParams);
@@ -931,6 +933,38 @@ int LuaSyncedRead::GetGameSeconds(lua_State* L)
931933
}
932934

933935

936+
/***
937+
*
938+
* Returns the engine's final sync checksum for the previous simulation
939+
* frame as an 8-character lowercase hex string (e.g. `"fade1eaf"`).
940+
* The value is stable for the entire duration of the current frame
941+
* (independent of gadget/callin ordering) and is identical across all
942+
* in-sync clients, so it can be folded into a deterministic per-run
943+
* artifact for sync testing (e.g. fightertest).
944+
*
945+
* Returned as a string rather than a number because Spring's Lua is
946+
* built with `LUA_NUMBER = float`, which cannot represent a 32-bit
947+
* checksum losslessly.
948+
*
949+
* Returns `nil` on builds without `SYNCCHECK`.
950+
*
951+
* @function Spring.GetPrevFrameChecksum
952+
*
953+
* @return string|nil checksum
954+
*/
955+
int LuaSyncedRead::GetPrevFrameChecksum(lua_State* L)
956+
{
957+
#ifdef SYNCCHECK
958+
char buf[16];
959+
snprintf(buf, sizeof(buf), "%08x", CSyncChecker::GetPrevChecksum());
960+
lua_pushstring(L, buf);
961+
#else
962+
lua_pushnil(L);
963+
#endif
964+
return 1;
965+
}
966+
967+
934968
/******************************************************************************
935969
* Environment
936970
* @section environment

rts/Lua/LuaSyncedRead.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class LuaSyncedRead {
4545

4646
static int GetGameFrame(lua_State* L);
4747
static int GetGameSeconds(lua_State* L);
48+
static int GetPrevFrameChecksum(lua_State* L);
4849

4950
static int GetGameRulesParam(lua_State* L);
5051
static int GetGameRulesParams(lua_State* L);

rts/Net/NetCommands.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,12 @@ void CGame::ClientReadNet()
623623
ASSERT_SYNCED(CSyncChecker::GetChecksum());
624624
clientNet->Send(CBaseNetProtocol::Get().SendSyncResponse(gu->myPlayerNum, gs->frameNum, CSyncChecker::GetChecksum()));
625625

626+
// Cache the just-sent, frame-closed checksum so Lua gadgets
627+
// running in the NEXT sim frame can read a stable value via
628+
// Spring.GetPrevFrameChecksum(). Must happen before the
629+
// 4096-frame reset below so we capture the pre-reset value.
630+
CSyncChecker::SetPrevChecksum(CSyncChecker::GetChecksum());
631+
626632
// buffer all checksums, so we can check sync later between demo & local
627633
if (haveServerDemo)
628634
localSyncChecksums[gs->frameNum] = CSyncChecker::GetChecksum();

rts/System/Sync/SyncChecker.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212

1313
unsigned CSyncChecker::g_checksum;
14+
unsigned CSyncChecker::g_prevChecksum;
1415
int CSyncChecker::inSyncedCode;
1516

1617
void CSyncChecker::NewFrame()

rts/System/Sync/SyncChecker.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class CSyncChecker {
3131
* Keeps a running checksum over all assignments to synced variables.
3232
*/
3333
static unsigned GetChecksum() { return g_checksum; }
34+
static unsigned GetPrevChecksum() { return g_prevChecksum; }
35+
static void SetPrevChecksum(unsigned v) { g_prevChecksum = v; }
3436
static void NewFrame();
3537
static void debugSyncCheckThreading();
3638
static void Sync(uint32_t val);
@@ -48,6 +50,11 @@ class CSyncChecker {
4850
*/
4951
static unsigned g_checksum;
5052

53+
/**
54+
* Final checksum of the previous simulation frame.
55+
*/
56+
static unsigned g_prevChecksum;
57+
5158
/**
5259
* @brief in synced code
5360
*

0 commit comments

Comments
 (0)