This is a submission for DEV's Summer Bug Smash: Smash Stories powered by Sentry.
Prefer Watching Instead?
If reading isn't your thing,...
For further actions, you may consider blocking this person and/or reporting abuse
240hz isnt even the limit tbh, with 1kHz monitors, the new 'standard' for gaming monitors being up from 144hz to 240hz, with the 'high refresh rate' being 300hz+, it's a bit of a tricky one. My advice, always decouple rendering from the gameloop, else you end up with issues like the old Bionicle game, where if you werent running on a potato, it runs at unplayable speeds.
For perspective, with my current endeavor on the gaming front, I am building Dwarven Stronghold (Think Dwarf Fortress, but written in Rust, so it's not so slow and heavy to run), One of the first things I did, was build the framework for the game, specifically separating the render loop from the simulation loop, so the simulation loop runs as fast as it wants, with the game-loop running at a fixed 'game time : wall clock time', so the sub-second simulations are variable depending on the overhead, while keeping the rendering separate, so the rendering isnt limited by the game's loop. So you can keep 240hz or even 1000hz, even if the game drops it's simulation to 10 TPS. The separation of concerns allows the game to stay smooth, even when the gameloop fluctuates.
Think COD, if you play online and your network drops, you still run around, still shoot, etc. Then disconnect after it times, so it doesnt interrupt the gameplay for minor stutters.
Totally agree. Decoupling render loop from sim loop is the way to go for high refresh rates.
240hz/1000hz monitors are useless if your game logic is tied to FPS.
Fixed timestep for simulation + variable render = smooth gameplay even at 10 TPS.
Great example with Dwarven Stronghold in Rust!
That makes sense 💯
Such an insightful comment. That just opens up more things to research for me as a beginner in the game development area.
Thanks a lot!🙏
Anytime, if you're looking in to game-states, I'd highly recommend looking up merkle roots and how you can use them to track state propagations. It makes sure that anomalies are pruned and that the state is always preserved. If you use hardware AES processing, it's also practically free, because it uses a part of the processor games dont generally use. Just be mindful of how dense you make it, keep it transactional with pointers, not full-on state dumping, else you'll hit OOM in no time.
This is great. Next time I’ll decide to write a game, I’ll definitely get back to your comments!
I remember this one! This is the one where I didnt realize I actually had to shift to move. Haha!
I totally remember your comment. I was like: “oh no, do I have a bug somewhere?”😄
Then I realized it was by design😄
😂😂😂
Same path here - backend habits, no game-dev background, and I also ship a browser game. Although it's just a chat, no fancy visuals. The same bug shape lives one layer up though: the game is tuned against specific AI models, a provider ships a new version, and the bots behave differently on identical code.
The game looks awesome. After the re-tune, does it still feel like the game you built, or are you driving a slightly different car on your own 165Hz now?
Good to know I’m not the only one.
It feels fine now, but it took quite a lot of tuning and testing. Totally worth it, though.
Hi, there!
I am looking for a partner to collaborate with by sharing an account.
In return, you will receive a 20–30% share;
I hope this collaboration leads to a long-term partnership.
WhatsApp: +1 (910) 852-7435
Telegram: @bytepil0t
Good technical content. I'd love to see more exploration of the edge cases and failure modes — understanding when and why these patterns break down is often more valuable than knowing how to implement them.
Thanks a lot. It really had me dive DEEP into some low-level stuff.
It's great idea using articles as a billboard and I enjoyed night driving 🚘
I know, it’s real fun! 🚗
So cool! 😍
Great job!
Thank you!😊
Great write-up, the part most "just multiply by dt" tutorials skip is exactly the part you nailed: decay and lerp need Math.pow, not linear scaling. The 0.97 * dt = 1.94 example makes the failure mode click instantly.
Thanks a lot. At first I just went for the dt multiplication but I quickly realized it wasn’t gonna cut it.
Hi, there!
I am looking for a partner to collaborate with by sharing an account.
In return, you will receive a 20–30% share;
I hope this collaboration leads to a long-term partnership.
WhatsApp: +1 (910) 852-7435
Telegram: @bytepil0t
Interesting game, definitely worth playing! 😆
Thanks! Enjoy!😄
Hi, there!
I am looking for a partner to collaborate with by sharing an account.
In return, you will receive a 20–30% share;
I hope this collaboration leads to a long-term partnership.
WhatsApp: +1 (910) 852-7435
Telegram: @bytepil0t
The interesting part is that the bug wasn't really in the physics formula, it was in an unstated assumption about the environment. That's a pattern that shows up far beyond games: hardware, browser behavior, timing, concurrency, and configuration can quietly become dependencies. Making those assumptions explicit and testing across them is often what separates "works locally" from software that's actually portable.
Exactly! And that’s the reason why game development is so complicated and tricky. I mean this one was a simple game, nothing complicated in it conceptually, but still, a major issue showed up. Granted, I’m still a rookie in this regard, but still.
This is exactly why I like weekend challenges. 😄 The goal isn’t always to build something perfect, it’s to force yourself into territory you normally wouldn’t touch. A backend engineer deciding to build a browser game in two days sounds like the perfect recipe for chaos and learning. Looking forward to seeing how this turned out!
It really was pretty chaotic😄 I almost failed to finish it😄
Really enjoyed this deep dive. The “my monitor was secretly a system dependency” part made me laugh, but the technical lesson is actually a great one.
I especially liked the distinction between value += rate * dt, exponential decay with Math.pow(factor, dt), and frame-rate-independent lerp. It’s easy to think “just multiply everything by delta time” solves the problem, but smoothing and decay require a bit more care.
This is also a good reminder that performance bugs aren’t always obvious bugs — sometimes the code works perfectly on the developer’s machine while behaving like a completely different application elsewhere. Great write-up!
Thanks a lot. This is another reminder that sometimes things turn out to be way more complex than they seem.
This is a really clean explanation of delta time, the lerp formula
especially, most people just do alpha * dt and don't realize it breaks
down at higher dt values.
Bookmarking this for the next time I touch anything with requestAnimationFrame.
Thanks a lot! I tried my best.🙏
This is such a relatable “works on my machine” bug 😂 The 165Hz monitor secretly becoming a system requirement is hilarious, but the explanation of delta time and why simply adding * dt isn’t enough makes this genuinely useful. Great write-up!
Thank you!😄
The exponential decay one is the part worth the whole article and i think its sharper than you let on.
you say the naive fix, speed *= 0.97 * dt, is wrong. it is, but its a worse class of wrong than the bug it replaces. the original bug was at least monotonic. everybody got a slower car than you intended, consistently, scaled by their refresh rate. annoying but predictable. the naive fix flips the sign. at dt of 2 you get 1.94 and the car accelerates when it drives off road, so a 30fps player gets the opposite of the mechanic. you didnt just fail to fix it, you built a machine that behaves backwards on the exact hardware that was already suffering most.
and thats the trap in the pattern, its that * dt genuinely works on case one. you learn the rule from the linear case, it rewards you, then you carry it into the multiplier case and it quietly inverts. a fix that works the first three times you try it is how you end up shipping the fourth one without checking.
good writeup. the fact that your own monitor was an untracked variable in every test you ran is the part id put on a sticker.
Hm… interesting insight I’ll have another look sometime in the future. Thank you!
Great Game!
Thanks a lot!🙏
😍😍
✨✨
this sound like 'to the mad' ''p
is purely, i like that,, new stuff is now overclock for an idea own who missed a support to work, i take it c[_]
Hi, there!
I am looking for a partner to collaborate with by sharing an account.
In return, you will receive a 20–30% share;
I hope this collaboration leads to a long-term partnership.
WhatsApp: +1 (910) 852-7435
Telegram: @bytepil0t