5 ms·
Seeing stuff like this on here fills me with nostalgia. I basically learned to code thanks to a few helpful and extremely patient IRC members in the Spring RTS
by Centigonal 4y ago
Seeing stuff like this on here fills me with nostalgia.
I basically learned to code thanks to a few helpful and extremely patient IRC members in the Spring RTS engine[1] community (some of whom I spot in these comment sections on occasion - hi!), and deterministic lockstep simulation for online play was one of the first ideas that totally blew my mind when I learned about it ("b-but that means all the "random" numbers on every computer need to be the same! and so do all the floating point calculations across different hardware!"). Of course, to me at the time, that was deep magic that I thought I'd never be able to fully understand.
[1] see https://springrts.com/ https://springrts.com/ - or check out http://zero-k.info/ http://zero-k.info/ and https://www.beyondallreason.info/ https://www.beyondallreason.info/ for games on the engine that are still pretty active
- paulryanrogers 4y agoIf the randomness is deterministic doesn't that mean players could peek into the future?
- Centigonal 4y agoGenerally (I hope I get this explanation right), the PRNGs on all players' computers are the same algorithm, with the same seed, executing the same player commands in the same order. So as soon as the game starts, you can predict what all future calls to random() will return. However, you can't predict the other players' actions, and those actions can insert an arbitrary (and unpredictable) number of random() calls between now and when your next action executes, so practically there is no gameplay advantage you can get from that avenue (AFAIK).
- taberiand 4y agoI'm gonna take an uneducated guess that though the simulation is in lockstep, the order of inputs from all players is not known ahead of time so you can't peek too far. Though maybe a cheat engine could simulate a few branches of possible inputs a few steps ahead and adjust inputs when it discovers split-second advantages?
- hot_gril 4y agoEveryone waits for your client's next step. Your client can basically pause the game whenever it wants, giving you time to do something. But there are bigger exploits. IIRC, the client sends separate actions for buying a unit/tech/building and paying resources, and the other clients don't enforce that they go together. This allows malicious clients to buy without paying. It's been seen a few times even in the ranked mode of the Definitive Edition remake. https://www.reddit.com/r/aoe2/comments/fjjudp/cheaters_are_a_thing_in_de_apparently/ https://www.reddit.com/r/aoe2/comments/fjjudp/cheaters_are_a... This way of doing things made sense for the time, and the execution was impressive. It was pretty reliable, nobody wanted to cheat anyway, and yes lag was a big problem but there wasn't another good way to do it back then. Nowadays they should have something else IMO.
- ComputerGuru 4y ago> Nowadays they should have something else IMO. Finally found a genuine use for the blockchain, since the server is only used for the lobby! Mine virtual AoE gold and record it in the distributed ledger. Primitive path finding is also AI, so now you just need some investors!
- hot_gril 4y agoDE seems to use a relay server. Old version relied on P1 setting up port forwarding and always being present in the game, not an issue anymore.
- lolinder 4y agoThat problem doesn't seem inherent to the model, it's a flaw in the selection of client steps. Is there any reason transactions like building and paying couldn't be atomic?
- hot_gril 4y agoI don't know why it's that way. My guess would be complexity. Yeah, they could fix that later, but they can't fix the fog of war cheat, which would also be pretty powerful.
- Jare 4y agoYes - and this can be AWESOME. In a deterministic engine, anything not affected by player input can be forecast accurately - by the computer, not the human user. For NBA Inside Drive 2000, I developed all the ball physics to be deterministic and "reasonably" accurate (25 years ago, in a world without physics engines). This meant that after a player made a shot and the ball left their hands, the trajectory, scoring or bouncing off the rim, was purely controlled by deterministic physics. This in turn meant that we could foresee what was going to happen, and feed the player AI with that while the ball was in flight. Obvious use was to move characters with high rebounds stats towards the place where the ball would bounce after not scoring, so they're more likely to pick the rebound. [edit: for shooting the ball, the instant the ball would leave the player's hands I computed the perfect trajectory to hit a shot, and then based on the player stats, I'd nudge the trajectory off center. It was then purely up to the physics to determine if the ball went in or what]
- qikInNdOutReply 4y agoYou can reseed with player inputs every cycle
- Emjayen 4y agoNot to any meaningful degree -- inputs (from humans) permutate the state. You can, however, compute say the initial world state, revealing the map/resources/ect. Ofcourse in this case you'd may aswell just look for some sort of maphack.
- visualphoenix 4y agoYup. That’s how networking basically worked for Army of Two. We only sent controller input over the network. Everything else was deterministic.
- Galanwe 4y agoThat was more or less the case for Starcraft 1 as well. It made for incredibly funny replay of matches if you happened to own a newer version of the map, as the game starts to diverge from reality and enter some parallel universe where players do nonsense actions and movements.
- foldor 4y agoJust showing my appreciation for Army of Two. It was a cheesy, weird game, but my friend and I loved playing it regardless. The online multiplayer worked great!
- anderspitman 4y agoOh man I discovered Spring about 15 years ago. Never dug into the engine but wrote a couple Lia scripts. Great engine. Good times.
- qikInNdOutReply 4y agoYou are not by chance the guy responsible for the commando-sneak widget? Computes the view circles of know units, sneaks a whole army single file into enemy territory by chosing a out of sight route?
- anderspitman 4y agoNo but that sounds fun! The best one I made was a really hacky script called followmouse that would constantly tell selected units to move towards the cursor. It was for microing around defenses and whatnot.
- eloff 4y agoThe random numbers I understand, because I’ve used a similar principle to make tests deterministic. The trick is to make the same number of calls to the generator and use the same seed. The floats are really thorny though, differing subtly across CPUs. Did they just rely strategically on rounding? Make heavier use of integers?
- simmonmt 4y agoDon't use floats (it wasn't a 3D game) or if you have to, make sure every float is derived from an integer that's kept in sync. And don't do anything that affects simulation state based on those floats.
- bsorbo 4y agoAge of Empires 2: Definitive Edition consistently de-syncs when playing across a M1 Mac (using Windows 11 Arm or Crossover) and an x86 machine, and I suspect the difference in floating point behavior described here is the culprit: https://developer.apple.com/documentation/apple-silicon/addressing-architectural-differences-in-your-macos-code https://developer.apple.com/documentation/apple-silicon/addr...
- magicalhippo 4y agoDoesn't sound unlikely. LHC@Home had big issues[1] with AMD and Intel machines giving very different results to the same work unit. They traced it down to the exp() function behaving different, and ended up using a library[2] for anything more fancy than basic arithmetic. [1] https://lhcathome.web.cern.ch/sites/default/files/OPENshort.pdf https://lhcathome.web.cern.ch/sites/default/files/OPENshort.... [2]: https://github.com/SixTrack/crlibm https://github.com/SixTrack/crlibm
- eloff 4y agoAnother reason for me to stay clear of the M1 for now. It’s really fascinating, but it’s not quite there yet. I’ll let others work the rough edges away before I give it a try.
- 4y ago
- capitainenemo 4y agoHedgewars also uses deterministic lockstep. But due to the floating point problem, the main developer elected to write custom fixed point math instead. It works since the game doesn't use a lot of physics.