Skip to content

Conversation

@xezon
Copy link

@xezon xezon commented Oct 11, 2025

Merge with Rebase

This change fixes crashing when launching the World Builder. The problem is the tools do not use the GameEngine class and therefore have no access to the new game time features.

The following tools use WW3D:

  • WorldBuilder
  • GUIEdit
  • W3DView

To accomodate the new game time features in tools, most game time related code in GameEngine class has been moved to a new GameTimer class. The logic is now reused in WorldBuilder and GUIEdit so in principle these should have the same capabilities to render WW3D steps independent of frame rate.

W3DView is not using the GameEngine module(!) at all (remember it is a Renegade tool) and therefore does not even have access to the new GameTimer class. But it seems it does not need it. W3DView animations look ok.

The simpler change here would have been to add a bunch of null checks for GameEngine but that would have been a hack.

TODO

  • Replicate in Generals
  • Add id to commits

@xezon xezon added Blocker Severity: Minor < Major < Critical < Blocker WorldBuilder Relates to World Builder Tools Affects Tools only Refactor Edits the code with insignificant behavior changes, is never user facing Crash This is a crash, very bad labels Oct 11, 2025
@xezon xezon force-pushed the xezon/fix-tools-render branch from 85c5a94 to 7a2bac8 Compare October 11, 2025 19:56
@xezon
Copy link
Author

xezon commented Oct 11, 2025

This will fail compile in Generals until replicated.

@xezon xezon added the ThisProject The issue was introduced by this project, or this task is specific to this project label Oct 12, 2025
@xezon
Copy link
Author

xezon commented Oct 14, 2025

Maybe rename GameTimer to FramePacer.

Copy link

@Skyaero42 Skyaero42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good.

With regards to naming I would go for RenderClock. My arguments:

  • The use of frame can be confusing as the logic steps also refer to frames
  • Pacer indicates more of a control-task which I don't find fitting
  • Timer is a consumer of time (usually with start/stop/reset)
  • Clock provides time, which is what the GameTimer currently does.

@xezon
Copy link
Author

xezon commented Oct 14, 2025

I don't like RenderClock. Because it is not Rendering specific but also is used for logic pacing. It intents to provide all functions to properly control the pacing of render and logic frames.

@xezon xezon force-pushed the xezon/fix-tools-render branch from 7a2bac8 to 00b8d39 Compare October 14, 2025 16:58
@xezon
Copy link
Author

xezon commented Oct 14, 2025

GameTimer renamed to FramePacer.

Replicated in Generals with conflicts.

Tested and worked in Generals Game Client and Generals World Builder.

$ git diff 403696c775dbd2311a2b514285b30923e3f74766..f69eb7cef0a474be183ffc03869f5576cc42a327 > changes.patch

$ git apply -p2 --directory=Generals --reject --whitespace=fix changes.patch
changes.patch:982: space before tab in indent.
        //
Checking patch Generals/GameEngine/CMakeLists.txt...
error: Generals/GameEngine/CMakeLists.txt: No such file or directory
Checking patch Generals/GameEngine/Include/Common/FramePacer.h...
Checking patch Generals/GameEngine/Source/Common/FramePacer.cpp...
Checking patch Generals/Code/GameEngine/Include/Common/GameEngine.h...
Hunk #3 succeeded at 101 (offset 1 line).
Checking patch Generals/Code/GameEngine/Source/Common/GameEngine.cpp...
Hunk #3 succeeded at 249 (offset 2 lines).
Hunk #4 succeeded at 298 (offset -1 lines).
Hunk #5 succeeded at 339 (offset -1 lines).
Hunk #6 succeeded at 490 (offset -164 lines).
Hunk #7 succeeded at 643 (offset -175 lines).
Hunk #8 succeeded at 656 (offset -175 lines).
Hunk #9 succeeded at 664 (offset -175 lines).
Hunk #10 succeeded at 672 (offset -175 lines).
Hunk #11 succeeded at 695 (offset -175 lines).
Hunk #12 succeeded at 738 (offset -175 lines).
Hunk #13 succeeded at 764 (offset -175 lines).
Hunk #14 succeeded at 832 (offset -175 lines).
Hunk #15 succeeded at 845 (offset -175 lines).
Checking patch Generals/Code/GameEngine/Source/Common/GameMain.cpp...
Checking patch Generals/Code/GameEngine/Source/GameClient/Drawable.cpp...
Hunk #1 succeeded at 35 (offset -1 lines).
Hunk #2 succeeded at 4785 (offset -757 lines).
Checking patch Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/QuitMenu.cpp...
Checking patch Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp...
Hunk #3 succeeded at 1888 (offset -56 lines).
Hunk #4 succeeded at 5870 (offset -173 lines).
Checking patch Generals/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp...
Hunk #2 succeeded at 187 (offset -3 lines).
Hunk #3 succeeded at 214 (offset -3 lines).
Hunk #4 succeeded at 234 (offset -3 lines).
Checking patch Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp...
Hunk #2 succeeded at 440 (offset 1 line).
Checking patch Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptActions.cpp...
Hunk #2 succeeded at 6583 (offset -546 lines).
Checking patch Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptEngine.cpp...
Hunk #2 succeeded at 4530 (offset -735 lines).
Checking patch Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp...
error: while searching for:
#include "Common/AudioHandleSpecialValues.h"
#include "Common/BuildAssistant.h"
#include "Common/CRCDebug.h"
#include "Common/GameAudio.h"
#include "Common/GameEngine.h"
#include "Common/GameLOD.h"

error: patch failed: Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp:33
Hunk #2 succeeded at 3718 (offset -554 lines).
Hunk #3 succeeded at 3758 (offset -554 lines).
Checking patch Generals/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp...
Hunk #2 succeeded at 428 (offset -9 lines).
Checking patch Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp...
error: while searching for:
                Int LOD = TheGlobalData->m_terrainLOD;
                //unibuffer.format( L"FPS: %.2f, %.2fms mapLOD=%d [cumu FPS=%.2f] draws: %.2f sort: %.2f", fps, ms, LOD, cumuFPS, drawsPerFrame,sortPolysPerFrame);
                if (TheGlobalData->m_useFpsLimit)
                                unibuffer.format( L"%.2f/%d FPS, ", fps, TheGameEngine->getFramesPerSecondLimit());
                else
                                unibuffer.format( L"%.2f FPS, ", fps);


error: patch failed: Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp:1025
Hunk #3 succeeded at 1673 (offset -81 lines).
Hunk #4 succeeded at 1709 (offset -81 lines).
Checking patch Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp...
error: while searching for:

        //WST 11/12/2002 New camera shaker system
        // TheSuperHackers @tweak The camera shaker is now decoupled from the render update.
        CameraShakerSystem.Timestep(TheGameEngine->getLogicTimeStepMilliseconds());
        CameraShakerSystem.Update_Camera_Shaker(sourcePos, &m_shakerAngles);
        transform->Rotate_X(m_shakerAngles.X);
        transform->Rotate_Y(m_shakerAngles.Y);

error: patch failed: Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp:399
Hunk #3 succeeded at 905 (offset -141 lines).
Hunk #4 succeeded at 1206 (offset -149 lines).
Hunk #5 succeeded at 1218 (offset -149 lines).
Checking patch Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWater.cpp...
Hunk #2 succeeded at 1187 (offset -23 lines).
Checking patch Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp...
error: while searching for:
#include "GameClient/InGameUI.h"
#include "GameClient/Water.h"
#include "GameLogic/TerrainLogic.h"
#include "Common/GameEngine.h"
#include "Common/GlobalData.h"
#include "Common/UnicodeString.h"
#include "Common/file.h"

error: patch failed: Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp:50
Hunk #2 succeeded at 293 (offset -3 lines).
Applied patch Generals/GameEngine/Include/Common/FramePacer.h cleanly.
Applied patch Generals/GameEngine/Source/Common/FramePacer.cpp cleanly.
Applied patch Generals/Code/GameEngine/Include/Common/GameEngine.h cleanly.
Applied patch Generals/Code/GameEngine/Source/Common/GameEngine.cpp cleanly.
Applied patch Generals/Code/GameEngine/Source/Common/GameMain.cpp cleanly.
Applied patch Generals/Code/GameEngine/Source/GameClient/Drawable.cpp cleanly.
Applied patch Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/QuitMenu.cpp cleanly.
Applied patch Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp cleanly.
Applied patch Generals/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp cleanly.
Applied patch Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp cleanly.
Applied patch Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptActions.cpp cleanly.
Applied patch Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptEngine.cpp cleanly.
Applying patch Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp with 1 reject...
Rejected hunk #1.
Hunk #2 applied cleanly.
Hunk #3 applied cleanly.
Applied patch Generals/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp cleanly.
Applying patch Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp with 1 reject...
Hunk #1 applied cleanly.
Rejected hunk #2.
Hunk #3 applied cleanly.
Hunk #4 applied cleanly.
Applying patch Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp with 1 reject...
Hunk #1 applied cleanly.
Rejected hunk #2.
Hunk #3 applied cleanly.
Hunk #4 applied cleanly.
Hunk #5 applied cleanly.
Applied patch Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWater.cpp cleanly.
Applying patch Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp with 1 reject...
Rejected hunk #1.
Hunk #2 applied cleanly.

$ git diff f69eb7cef0a474be183ffc03869f5576cc42a327..adac76bcd11da2b50a9a16c3634cb80cb4920c1d > changes.patch

$ git apply -p2 --directory=Generals --reject --whitespace=fix changes.patch                           Checking patch Generals/GameEngine/Include/Common/FramePacer.h...
error: Generals/GameEngine/Include/Common/FramePacer.h: No such file or directory
Checking patch Generals/GameEngine/Include/Common/FrameRateLimit.h...
error: Generals/GameEngine/Include/Common/FrameRateLimit.h: No such file or directory
Checking patch Generals/GameEngine/Source/Common/FramePacer.cpp...
error: Generals/GameEngine/Source/Common/FramePacer.cpp: No such file or directory
Checking patch Generals/GameEngine/Source/Common/FrameRateLimit.cpp...
error: Generals/GameEngine/Source/Common/FrameRateLimit.cpp: No such file or directory
Checking patch Generals/Libraries/Source/WWVegas/WWLib/WWCommon.h...
error: Generals/Libraries/Source/WWVegas/WWLib/WWCommon.h: No such file or directory
Checking patch Generals/Tools/W3DView/GraphicView.cpp...
error: Generals/Tools/W3DView/GraphicView.cpp: No such file or directory
Checking patch Generals/Code/GameEngine/Source/Common/GameMain.cpp...
Checking patch Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h...
Checking patch Generals/Code/Tools/GUIEdit/Source/EditWindow.cpp...
Hunk #2 succeeded at 1457 (offset -14 lines).
Hunk #3 succeeded at 1476 (offset -14 lines).
Checking patch Generals/Code/Tools/GUIEdit/Source/WinMain.cpp...
Checking patch Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp...
Hunk #2 succeeded at 339 (offset -12 lines).
error: while searching for:

        WorldHeightMapEdit::shutdown();

        delete TheFileSystem;
        TheFileSystem = NULL;


error: patch failed: Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp:654
Checking patch Generals/Code/Tools/WorldBuilder/src/wbview3d.cpp...
error: while searching for:
      m_showBoundingBoxes, m_showSightRanges, m_showWeaponRanges, m_showSoundCircles, m_highlightTestArt, m_showLetterbox);
        }

        WW3D::Sync( GetTickCount() );
        m_buildRedMultiplier += (GetTickCount()-m_time)/500.0f;
        if (m_buildRedMultiplier>4.0f || m_buildRedMultiplier<0) {
                m_buildRedMultiplier = 0;
        }
        render();
        m_time = ::GetTickCount();
}


error: patch failed: Generals/Code/Tools/WorldBuilder/src/wbview3d.cpp:2058
Applied patch Generals/Code/GameEngine/Source/Common/GameMain.cpp cleanly.
Applied patch Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h cleanly.
Applied patch Generals/Code/Tools/GUIEdit/Source/EditWindow.cpp cleanly.
Applied patch Generals/Code/Tools/GUIEdit/Source/WinMain.cpp cleanly.
Applying patch Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp with 1 reject...
Hunk #1 applied cleanly.
Hunk #2 applied cleanly.
Rejected hunk #3.
Applying patch Generals/Code/Tools/WorldBuilder/src/wbview3d.cpp with 1 reject...
Hunk #1 applied cleanly.
Hunk #2 applied cleanly.
Rejected hunk #3.

@xezon xezon merged commit c12bab6 into TheSuperHackers:main Oct 14, 2025
18 checks passed
@xezon xezon deleted the xezon/fix-tools-render branch October 14, 2025 17:13
@xezon xezon added this to the Decouple logic and rendering milestone Oct 16, 2025
fbraz3 pushed a commit to fbraz3/GeneralsX that referenced this pull request Nov 10, 2025
fbraz3 pushed a commit to fbraz3/GeneralsX that referenced this pull request Nov 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Blocker Severity: Minor < Major < Critical < Blocker Crash This is a crash, very bad Refactor Edits the code with insignificant behavior changes, is never user facing ThisProject The issue was introduced by this project, or this task is specific to this project Tools Affects Tools only WorldBuilder Relates to World Builder

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WorldBuilderZH crash on startup starting with weekly-2025-10-03

2 participants