Hacker News new | ask | show | jobs
by jvanderbot 1368 days ago
> Removing all uses of undefined behaviour is probably a fool's errand, as it would require significant changes throughout the code that would take time and come with a performance impact, all for no immediate practical benefit. So I just hunted down the undefined behaviour cases that actually broke determinism. This was easy enough, as we have plenty of tools we use to test determinism. By comparing the game state CRC for every tick of every test (we have 2,417 tests) between x86 and ARM, I believe I got a pretty good coverage of potential issues.

Holy hell.

4 comments

This kind of determinism testing is a fairly common approach in games that implement shared-state multiplayer, and I think that's why it was implemented for Factorio as well. Otherwise you get drift between clients that breaks the game.
One alternative is to run everything on the server, but that introduces another set of problems.
IIRC that's what Satisfactory does and it causes all sorts of synchronization issues and glitches - non-hosting players not seeing buildings or stuff on belts or even glitching into/colliding with things that were not there a split second ago, as they loaded from the server too slowly.

That won't really happen in Factorio due to the shared state & makes possible insanely complex layouts that all players can see an interact with exactly the same. The downside usually is that eventually - just after you got that 20 GW nuclear power plant with trucked water & and steam going - the slowest player starts to have issues as his hardware no longer can keep with the complexity of the simulation.

Then you either start shedding players or call it a day and start again with a different objective or mod.

I built a similar system for a Doom port--compatibility was an important issue for me, and conveniently I was adding client/server multiplayer with state deltas, so I had all the infra built to do a full dump every tic. It sounds wild, but if your game is already deterministic and you support saving, you're 80% of the way there.
Automated testing is great! More game developers should get serious about using it, even if you're not doing full coverage unit testing like business software.
Yes! Automated testing is a super power. I haven’t had a single bug in production for 5+ years because of automated tests.
Whats CRC?
I'm guessing cyclic redundancy check. You turn the game state in each tick into a number, then play the exact same game on both platforms. If you get the same stream of numbers, you can be pretty sure the game is behaving correctly.
It's likely a hash of the game state. They save input and playback recordings of the game, expecting to always receive the same hash for the game state every frame.

Just this week I started on a similar system for a game engine I work on (Zelda Classic). Main reason was for testing purposes, but another benefit is that it is SO cool to see the game replayed for you. Like those self playing pianos.

cyclic redundancy check