famous blog post “fix your timestep” written in 2004, written again in 2024

https://www.gafferongames.com/post/fix_your_timestep/

I first read this gamedev post somewhere near 2004. I have been doing game engine development for the portion of my adult life, and in 2024, the current revision of my “fix your timestep” code, are as follows:

In my network viewer, this is the code:

try {

	using namespace std::chrono;
	using namespace std::chrono_literals;

	setup();
	setGameMode(initial);

	nanoseconds lag(0), timeElapsed(0s);
	steady_clock::time_point nowTime, fpsStartTime
		, oldTime = steady_clock::now(), fpsEndTime = oldTime;

	std::uint32_t frameCount = 0, tickCount = 0;

	do {
		nowTime = high_resolution_clock::now();
		timeElapsed = duration_cast<nanoseconds>(nowTime - oldTime);
		oldTime = nowTime;

		lag += timeElapsed;
		while (lag >= mLengthOfStep) {

			mGameMode->step();

			lag -= mLengthOfStep;

			++tickCount;
		}

		fpsStartTime = high_resolution_clock::now();

		doEvents(); //this will call cef::render in addition to handling input
		render();

		++frameCount;

		nanoseconds fpsElapsedTime(duration_cast<nanoseconds>(fpsStartTime - fpsEndTime));
		if (fpsElapsedTime >= 1s) {

			fpsEndTime = fpsStartTime;

			mGameMode->updateSecondStatus(tickCount,frameCount);

			frameCount = 0;
			tickCount = 0;
		}
	} while (mPlaying);
}
catch (std::exception& e) {
	MessageBoxA(NULL, e.what(), "Error", MB_OK);
}

setGameMode(nullptr);
shutdown();

This is the code from my rts game server which is an evolution:

try {

	using namespace std::chrono;
	using namespace std::chrono_literals;

	Managers::get().setup(&mGraphics, &mPlayerManager, &mUnitManager, &mBuildingManager, &mControlGroupManager);

	setup();
	setGameMode(initial);

	nanoseconds lag(0), timeElapsed(0s);
	steady_clock::time_point nowTime, fpsStartTime
		, oldTime = steady_clock::now(), fpsEndTime = oldTime;

	std::uint32_t tickCount = 0;

	steady_clock::time_point serverUpTimeStart = steady_clock::now();
	minutes serverDieIfNotAliveTime(5);
	setAlive(false);

	do {
		nowTime = high_resolution_clock::now();
		timeElapsed = duration_cast<nanoseconds>(nowTime - oldTime);
		oldTime = nowTime;

		lag += timeElapsed;

		while (lag >= mLengthOfStep) {

			mGameMode->step();

			lag -= mLengthOfStep;

			++tickCount;
			
		}
		//rather than working to render - instead, sleep until next tick is due

		auto availableSleepTime = mLengthOfStep - lag;
		availableRunTime(availableSleepTime);
		

		fpsStartTime = high_resolution_clock::now();
		nanoseconds fpsElapsedTime(duration_cast<nanoseconds>(fpsStartTime - fpsEndTime));
		if (fpsElapsedTime >= 1s) {

			fpsEndTime = fpsStartTime;

			updateSecondStatus(tickCount);

			tickCount = 0;

			mServerUpTime = duration_cast<seconds>(fpsStartTime - serverUpTimeStart);
			
			if (!isAlive() && mServerUpTime >= serverDieIfNotAliveTime)
				mPlaying = false;
		}
	} while (mPlaying);
}
catch (std::exception& e) {
	MessageBoxA(NULL, e.what(), "Error", MB_OK);
}

setGameMode(nullptr);
shutdown();

What is your time step code in 2024?

Leave a comment