diff --git a/build-windows-visual-studio/sm64ex.vcxproj b/build-windows-visual-studio/sm64ex.vcxproj
index c46d3bb6..ead60679 100644
--- a/build-windows-visual-studio/sm64ex.vcxproj
+++ b/build-windows-visual-studio/sm64ex.vcxproj
@@ -4009,6 +4009,7 @@
+
diff --git a/build-windows-visual-studio/sm64ex.vcxproj.filters b/build-windows-visual-studio/sm64ex.vcxproj.filters
index 717e5aea..ad3260ae 100644
--- a/build-windows-visual-studio/sm64ex.vcxproj.filters
+++ b/build-windows-visual-studio/sm64ex.vcxproj.filters
@@ -15285,6 +15285,9 @@
Source Files\actors
+
+ Source Files\src\pc\network\packets
+
diff --git a/src/pc/network/packets/packet.c b/src/pc/network/packets/packet.c
index d43bbed0..0200077d 100644
--- a/src/pc/network/packets/packet.c
+++ b/src/pc/network/packets/packet.c
@@ -45,7 +45,7 @@ void packet_process(struct Packet* p) {
case PACKET_COLLECT_COIN: network_receive_collect_coin(p); break;
case PACKET_COLLECT_ITEM: network_receive_collect_item(p); break;
case PACKET_UNUSED1: break;
- case PACKET_UNUSED2: break;
+ case PACKET_DEBUG_SYNC: network_receive_debug_sync(p); break;
case PACKET_JOIN_REQUEST: network_receive_join_request(p); break;
case PACKET_JOIN: network_receive_join(p); break;
case PACKET_CHAT: network_receive_chat(p); break;
diff --git a/src/pc/network/packets/packet.h b/src/pc/network/packets/packet.h
index ae458d0f..d5c3c035 100644
--- a/src/pc/network/packets/packet.h
+++ b/src/pc/network/packets/packet.h
@@ -23,7 +23,7 @@ enum PacketType {
PACKET_COLLECT_COIN,
PACKET_COLLECT_ITEM,
PACKET_UNUSED1,
- PACKET_UNUSED2,
+ PACKET_DEBUG_SYNC,
PACKET_JOIN_REQUEST,
PACKET_JOIN,
PACKET_CHAT,
@@ -271,4 +271,8 @@ void network_receive_reservation_use(struct Packet* p);
void network_send_reservation_release(u8 syncId);
void network_receive_reservation_release(struct Packet* p);
+// packet_debug_sync.c
+void network_send_debug_sync(void);
+void network_receive_debug_sync(struct Packet* p);
+
#endif
diff --git a/src/pc/network/packets/packet_debug_sync.c b/src/pc/network/packets/packet_debug_sync.c
new file mode 100644
index 00000000..4ab1d855
--- /dev/null
+++ b/src/pc/network/packets/packet_debug_sync.c
@@ -0,0 +1,66 @@
+#include "../network.h"
+#include "behavior_table.h"
+#include "pc/debuglog.h"
+
+static void print_sync_object_table(void) {
+ LOG_INFO("Sync Object Table");
+ for (int i = 0; i < MAX_SYNC_OBJECTS; i++) {
+ if (gSyncObjects[i].o == NULL) { continue; }
+ u16 behaviorId = get_id_from_behavior(gSyncObjects[i].behavior);
+ LOG_INFO("%03d: %04X", i, behaviorId);
+ }
+ LOG_INFO(" ");
+}
+
+void network_send_debug_sync(void) {
+ u8 objectCount = 0;
+ for (int i = 0; i < MAX_SYNC_OBJECTS; i++) {
+ if (gSyncObjects[i].o == NULL) { continue; }
+ objectCount++;
+ }
+
+ struct Packet p;
+ packet_init(&p, PACKET_DEBUG_SYNC, true, PLMT_AREA);
+ packet_write(&p, &objectCount, sizeof(u8));
+ for (int i = 0; i < MAX_SYNC_OBJECTS; i++) {
+ if (gSyncObjects[i].o == NULL) { continue; }
+ u16 behaviorId = get_id_from_behavior(gSyncObjects[i].behavior);
+ packet_write(&p, &i, sizeof(u8));
+ packet_write(&p, &behaviorId, sizeof(u16));
+ }
+ network_send(&p);
+}
+
+void network_receive_debug_sync(struct Packet* p) {
+ u8 objectCount = 0;
+ u16 remoteBehaviorIds[MAX_SYNC_OBJECTS] = { 0 };
+
+ packet_read(p, &objectCount, sizeof(u8));
+ for (int i = 0; i < objectCount; i++) {
+ u8 j;
+ u16 behaviorId;
+ packet_read(p, &j, sizeof(u8));
+ packet_read(p, &behaviorId, sizeof(u16));
+ remoteBehaviorIds[j] = behaviorId;
+ }
+
+ bool hasMismatch = false;
+ for (int i = 0; i < MAX_SYNC_OBJECTS; i++) {
+ u16 localBehaviorId = (gSyncObjects[i].o == NULL) ? 0 : get_id_from_behavior(gSyncObjects[i].behavior);
+ u16 remoteBehaviorId = remoteBehaviorIds[i];
+ if (localBehaviorId != remoteBehaviorId) {
+ hasMismatch = true;
+ break;
+ }
+ }
+ if (!hasMismatch) { return; }
+
+ LOG_INFO(" ");
+ LOG_INFO("Sync Object Table Mismatch");
+ for (int i = 0; i < MAX_SYNC_OBJECTS; i++) {
+ u16 localBehaviorId = (gSyncObjects[i].o == NULL) ? 0 : get_id_from_behavior(gSyncObjects[i].behavior);
+ u16 remoteBehaviorId = remoteBehaviorIds[i];
+ if (localBehaviorId == 0 && remoteBehaviorId == 0) { continue; }
+ LOG_INFO("%03d: %04X %04X %s", i, localBehaviorId, remoteBehaviorId, (localBehaviorId == remoteBehaviorId) ? " " : "<<<");
+ }
+}
diff --git a/src/pc/network/packets/packet_object.c b/src/pc/network/packets/packet_object.c
index cc26c85c..3e97a6d0 100644
--- a/src/pc/network/packets/packet_object.c
+++ b/src/pc/network/packets/packet_object.c
@@ -630,6 +630,14 @@ void network_update_objects(void) {
network_delayed_packet_object_execute();
}
+#ifdef DEVELOPMENT
+ static f32 lastDebugSync = 0;
+ if (clock_elapsed() - lastDebugSync >= 1) {
+ network_send_debug_sync();
+ lastDebugSync = clock_elapsed();
+ }
+#endif
+
for (u32 i = 1; i < MAX_SYNC_OBJECTS; i++) {
struct SyncObject* so = &gSyncObjects[i];
if (so->o == NULL) { continue; }