From c0dcb66f1cf5bd53b124e90aab90112ab725620e Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Tue, 29 Sep 2026 05:17:29 -0500 Subject: [PATCH] fix(physics): write the construction cheat block only when changed Live wrote the controllable-physics cheat block (gravity scale, speed multiplier) in a construction only when one of them differed from 1: 216 of 20,617 constructions had it (players at run speed 1.05 / 1.5 / 2.0 / 0.5, enemies with gravity 0), never 1 and 1. DLU wrote it in every construction. Serializations are unchanged. Test: ReplicaConstructionTest.ControllablePhysicsConstructionWritesCheatsOnlyWhenChanged. Check in game: with a second player watching, use a speed boost (or /setspeed) and zone in while boosted; the other player sees you move at the right speed. Enemies with gravity 0 (e.g. Sentinel Turret 6254) behave as before. Co-Authored-By: Claude Opus 5.5 --- .../ControllablePhysicsComponent.cpp | 6 ++-- .../ReplicaConstructionTests.cpp | 29 +++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/dGame/dComponents/ControllablePhysicsComponent.cpp b/dGame/dComponents/ControllablePhysicsComponent.cpp index 563380e73..b1285d6c6 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.cpp +++ b/dGame/dComponents/ControllablePhysicsComponent.cpp @@ -97,8 +97,10 @@ void ControllablePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bo outBitStream.Write(m_ImmuneToStunInteractCount); } - outBitStream.Write(m_DirtyCheats || bIsInitialUpdate); - if (m_DirtyCheats || bIsInitialUpdate) { + // Live wrote the cheat block on construction only when the gravity or speed was changed from 1. + const bool writeCheats = bIsInitialUpdate ? (m_GravityScale != 1.0f || m_SpeedMultiplier != 1.0f) : m_DirtyCheats; + outBitStream.Write(writeCheats); + if (writeCheats) { outBitStream.Write(m_GravityScale); outBitStream.Write(m_SpeedMultiplier); diff --git a/tests/dGameTests/dComponentsTests/ReplicaConstructionTests.cpp b/tests/dGameTests/dComponentsTests/ReplicaConstructionTests.cpp index 8729135fc..1824cf2e6 100644 --- a/tests/dGameTests/dComponentsTests/ReplicaConstructionTests.cpp +++ b/tests/dGameTests/dComponentsTests/ReplicaConstructionTests.cpp @@ -130,6 +130,35 @@ TEST_F(ReplicaConstructionTest, CharacterConstructionAlwaysWritesGmActivityAndSo player.SetCharacter(nullptr); } +// Live wrote the cheat block (gravity scale, speed multiplier) on construction only when one of them was changed: 216 +// of 20,617 controllable-physics constructions had it (players at run speed 1.05, enemies with gravity 0), never 1/1. +TEST_F(ReplicaConstructionTest, ControllablePhysicsConstructionWritesCheatsOnlyWhenChanged) { + Entity entity(15, info); + auto* const physics = entity.AddComponent(-1); + + const auto cheatBits = [physics]() { + RakNet::BitStream stream; + physics->Serialize(stream, true); + stream.IgnoreBits(1 + 1 + 7 * 32); // no jetpack, stun immunities + bool hasCheats{}; + EXPECT_TRUE(stream.Read(hasCheats)); + std::pair cheats{ -1.0f, -1.0f }; + if (hasCheats) { + EXPECT_TRUE(stream.Read(cheats.first)); + EXPECT_TRUE(stream.Read(cheats.second)); + } + return std::make_pair(hasCheats, cheats); + }; + + EXPECT_FALSE(cheatBits().first); + + physics->SetSpeedMultiplier(1.05f); + const auto [hasCheats, cheats] = cheatBits(); + EXPECT_TRUE(hasCheats); + EXPECT_FLOAT_EQ(cheats.first, 1.0f); + EXPECT_FLOAT_EQ(cheats.second, 1.05f); +} + class InventoryConstructionTest : public GameDependenciesTest { protected: // The items of the live sample below (CDClient 1.10.64 values)