
Ioannis Koukourakis
@JKoukourakis • 2,184 subscribers
Game Programmer/Designer. #AmnesiaTheBunker #AmnesiaRebirth #ONTOS #LetheEp1 #PhantomLine. Creator of @detis_engine.
Shorts
Videos

Lua might feel ugly next to the C++ engine core, but to be fair, the iteration freedom it provides for gameplay is absolutely unmatched. Many might disagree, but imho, engine and gameplay programming are two entirely different beasts requiring entirely different approaches.
Ioannis Koukourakis63,030 views • 6 months ago

Why the character movement in my custom game engine felt janky and how I fixed it. In a game engine, most often, a character moves using the physics engine. Meaning, the player is not just a coordinate in space but a physical body. It has velocity, it handles collisions, and it interacts with the world. Now, as you might know, physics engines need stability. If you run them at variable framerates, things start breaking. Objects phase through walls or fly off into space because the math becomes unpredictable. This is why most game engines lock their physics loop to a 60Hz fixed rate. But here’s the problem: If you have a high-end system, you don't want to limit it at 60 FPS. That's a waste of good hardware. Now, that said, if the GPU is rendering at 144 FPS but the player's position (physics driven) only updates 60 times a second, it creates a micro-stutter that ruins the "smooth" feel of the game. A good way to fix this is to treat the character as two separate things: 1. The Physics Body (Invisible part): This is the "real" character. It lives in the 60Hz physics world, it moves the player and handles collisions. 2. The Visual Model and Camera (Visible part): This is what the player actually sees. It doesn't care about collisions, its only job is to look nice and smooth at whatever framerate the GPU is pushing. Once you have this separation, you can use interpolation to keep them in sync. Every time the physics clock ticks, you save the previous position of the invisible body before moving it to the new one. Between those ticks, calculate how far we are between the last physics update and the next one. By using this to drive the visible parts of the game, the stutters disappear. The physics loop stays fixed behind the scenes, while the visuals slide smoothly between the snapshots. Example: - Right after a tick: blend_weight= 0.0 (The visual model stays at the old physics position). - Halfway to the next: blend_weight= 0.5 (The visual model slides to the middle point). - Just before the next: blend_weight= 0.9 (The visual model is almost at the new physics position). Pro-Tip A critical mistake I made initially, and one many devs make, is parenting the camera and visible parts directly to the player body. If you do this, the camera inherits the discrete 60Hz physics movement by default. In that setup, interpolation won't work because the camera is "stuck" to the physics clock. For this fix to work you must decouple the camera and visuals from the body and move them separately. Player movement processing in Detis Engine: - fixed_process: Physics runs at 60Hz. Handles collisions and raw movement. - process: Variable rate. Mainly used for player input caching in the player case. - late_process: Variable rate. Handles interpolated camera movement after physics and everything else is done being processed. - render. Submits the final interpolated transforms to the GPU. The test environment in the video is running on an old 2070-based laptop. Hopefully the video compression won't introduce any stutter... I’m sharing this in hopes it helps a fellow dev. Cheers.
Ioannis Koukourakis48,497 views • 5 months ago
No more content to load