Why video game doors are so hard to get right [video]
youtube.com
youtube.com
In UE4, this is handled with 2 different network synchronization mechanisms: 1) multicast events (for animations) and 2) replicated state (for authoritative state). When player 1 opens the door, the server fires a multicast event to all clients within the network relevancy radius that says "play door animation." Multicast events only play once, and only to clients who were listening at the time of it firing. At the end of the door animation, the server sets the authoritative state to "opened." This authoritative state propagates to all clients, current and future clients. This allows player 2, who was outside the radius when the door was opened, to see the door as opened as they get closer, without seeing the animation playing.
Where network replication matters a lot more though is on things like movement and shooting in competitive games. There is a great short series of blog posts by Gabriel Gambetta that covers different problems and solutions, but everything is a tradeoff https://www.gabrielgambetta.com/client-server-game-architect...
One thing it doesn't mention, but that I thought of and implemented a protection against, is a malicious client sitting there and listening to game states, then send a bunch of inputs with timestamps in the past that would put the player into an advantageous position. I eliminated this by coding the server to reject any inputs that are older than 500 ms, and since the server was authoritative, the client had to just deal with it and put the player where it was up to 500 ms ago. The server would even tell the client "You are lagging and I ignored your input" when this happened, so legit clients could deal with it.
While yes, this could create a negative player experience as a player who is dealing with a lot of latency or packet loss would frequently get teleported back, that player would already be having a negative experience due to everyone else jumping around. Even with interpolation between predicted states and authoritative states, at 500 ms latency, you're going to have a bad time in a real-time multiplayer game when latency matters.
Desync is common and is caused by packet loss in UDP games. It's not usually worth while to compare your state with the authoritative state, because that requires a round-trip from client->server. Instead, the server can rank each piece of the state as important (has been altered recently is a good measure of importance), and just spam out a bunch of redundant game state packets hoping some of them arrive.
You can build a guaranteed delivery packet system on top of UDP, but a guarantee has to come from the client meaning you're waiting on round-trips to confirm that the states are fully in-sync. Most games (especially fast paced shooters) don't need this level of assurance, and heavy packet loss over a long period of time should just result in a disconnect for that player.
Each game packet is typically packed (and compressed) with other game packets to maximize bandwidth and acknowledgment data for the reliable packets is also compressed into the data stream. Reliable packets take very little additional bandwidth (assuming your UDP connection is not going to lose many packets in normal use). Players will pull ethernet cables for a second to force packet loss if the unreliable packets give them an advantage (ie to allow them to interpolate through a wall or to not register shot hits).
Half of games networking is finding out what you can "get away with" from an impact/user perception. Ex: play hit effects, sounds in a de-synched way locally but have major game events be authoritatively acked by the server, the local events also do a good job of masking the latency. The other half is really cool tricks like dead-reckoning or lock-step[1] which uses a completely deterministic game state to sync hundreds of entities over latent connections.
It's a really fun design space that's leverages heavily both the game design(designs where players "predict" are easier to keep in sync/fun), a level of deception to hide latency and cool technical approaches to hard problems in a non-deterministic environment.
If doors synchronize closer than a player's sniper rifle range then a player can either stand just behind a door (that is open for them) and shoot people at range (who see the door as closed). Or the door defaults to open and a closed door that seems like cover allows you to get sniped.
While the ideal is to synchronize everything at the same distance, if you have 100+ players on a single map and a sniper rifle with 500m range you can be synchronizing the stage of hundreds of doors per player and eating bandwidth that would (usually) be better used synchronizing player position state. In practice you end up doing some amount of 'automatic' synchronization and some based on context... and a server that has the definitive world state that can 'undo' shots through closed doors etc.
Building rendering distances can also be an issue with doors, generally you switch to simpler building models as they get further from the player's camera. But you can't include doors in the lower level of detail models until you are at a distance that enemy players are also not visible. So while a building can be a 200 triangle shell at 400m it still has to have doorways and network synchronized doors, even if the doorway is 4 on-screen pixels it should still be possible to see a player move behind that open doorway (or not see them if the door is closed).
This is all kind of wrong. You want players to see the door opening IFF they can see the door at all. If incompetent developers can't achieve that and come up with some other solution and a lame excuse to go with it, that does not change the desire from a player perspective.
I think narrowing it to “seeing” the door might produce a limited result that closes a lot of doors on proper multiplayer handling of other game mechanics.
That is typically one of the conditions encompassed by "network relevancy".
1 - https://www.youtube.com/watch?v=9kzu2Y33yKM
(edit: it looks like digipen also posted that talk themselves, and theirs doesn't have the ~10-15 minute gap the VNN one has, but theirs seems to not have the slides. Take your pick! https://www.youtube.com/watch?v=8OWjxGL8PDM0)
Poking a gun through, or quickly tossing a grenade and then closing the door again felt so natural.
https://www.ign.com/articles/turns-out-hardest-part-making-g...
Reminds me of Zelda: OoT. At the final boss fight, Ganon knocks the sword out of your hand, the only point in the game where you're without a sword equipped as an adult. In early versions of the game, if you saved and reloaded at that point, you would end up with the sword unequipped, resulting in some glitchy behavior. For example you could now use any equipped item on horseback. The hookshot could be abused to allow you to move Link pretty much freely in 3D space.
Even in later versions, you can get to this behavior by never picking up the first sword and lifting the left side of the cartridge ever so slightly when Mido blocks the way to the first dungeon until you have a sword, allowing you to pass through him. The no-sword OoT challenge is just challenging enough to be fun.
https://youtu.be/OKSWkpC_SC4?t=946 Link starts at where the master sword gets knocked off but the premise of the speedrun is interesting on its own.
To be fair, it was _saving_ after having performed the glitch that persisted glitched data to the save RAM, but I only figured that out seven years later.
Great way to play tricks on friends.
I can't blame the devs for taking shortcuts like that, but still a bit weird to call that one out as an impressive example.
Everything else about the doors in TLOU2 is impressive, though. I don't think there's any game that exists that has doors that are as well engineered as TLOU2 that also properly swing in only one direction.
Can you imagine running away from the zombies, you reach for the door, move to back up and realize you didn't quite grab the handle? Or the other version where you do grab the handle and realize you need to let go of it to start shooting, but are stuck in an animation.
Personally, I'm cool with worlds with no doors and outsized doorways. Ideally the scenery between my character and the camera fades out, so the camera only has to move to follow, not to get a better angle. I do admire the effort that goes into it making the doors look good.
Well, the clips from Last of us seemed to be the only ones where the character put their hand on the doorhandle, and kept it there for the duration of the door opening. And the door didn't visibly clip through anything on the other side.
The clips from Fortnite and Hitman, in contrast, didn't show the player character using the door handle at all.
Next I’d love to see, “Why online checkout forms are so hard to get right.”
Software is hard.
Ha. This is an amusing claim given that redstone, the whole complicated circuitry used in advanced Minecraft machines, was arguably added for the purpose of powering doors. Years of work have gone into all of the community-made piston doors of various sizes and features. And all interactive components like buttons and pressure plates have to have their signal duration balanced against how long it takes to walk through a door.
Even ignoring redstone, though, doors are complicated to design in the exact same ways. Which way do they swing open? Depends how you’re facing when you place them… unless the game detects double doors, and reverses the second one to match. And each door has to have a corresponding vertical trap door, which can either be flush with a floor or with a ceiling. Which way do trap doors open? Well, whichever way works best with the ladder below them. Oh, which means trap doors must also act like ladders. In fact, you can climb a wall of nothing but trap doors in the game.
What about water? Trap doors can be waterlogged, and that’s a common way to hide irrigation. But normal doors intentionally aren’t. Why? Because doors are the most common early-game tool for scuba diving - a placed door becomes a free pocket of air. Does it seem realistic? No, and maybe they could fix it, but then that would affect anyone who uses doors as entrances to underwater houses, as well as make scuba diving more difficult.
Players argue about the use of doors for diving; they argue about whether they should be able to shoot arrows through the windows in doors; they argue about whether every new tree should bring a new type of wood, and thus a new type of door.
Doors are hard, no matter how simple the game.
Redstone: The surprising complexity of a redstone torch does not confer complexity to a minecraft door, even though you could use that torch to open or close a door. A minecraft door has one binary state relating to redstone, powered or unpowered. That's it. The redstone functionality a minecraft door has is very simple by the standards of many other redstone-capable blocks in the game.
Piston doors: Can be arbitrarily complex, but these do not confer complexity to regular minecraft doors.
Placement: Minecraft doors are not the simplest block in this regard, but they are far from the most complex. Just compare them to stairs. Stairs have four attributes: facing[east,west,north,south], half[bottom,top], shape[inner_left,inner_right,outer_left,outer_right,straight]. There are 80 ways any stair block can be configured. There are only 64 configurations of a door block in minecraft (as far as the player need be concerned, it's only half of that since half a door implies the other half, similar to an extended piston.) Incidentally, there are 9 materials a door can be made out of, but 48 materials stairs can be made out of. And 8 of those 48 stairs have the special behavior of turning into other material, while only one of the 9 door materials has special behavior.
Waterlogging: Regular minecraft doors have never waterlogged. Waterlogging is complexity added to other blocks in the aquatic update, but doors were not changed. There was no complexity added here. And doors are not the only blocks which weren't updated for waterlogging; there are dozens of other blocks like this.
Trapdoors: Are more complex than regular minecraft doors. Trapdoors being complex does not mean that regular minecraft doors complex.
Players wishing doors had more complexity: Is not doors being complex.
> Doors are hard, no matter how simple the game.
Doors are extremely complex in some games, and significantly less complex in others. Complexity is not a binary trait. I claimed that minecraft doors are comparably simple, particularly when compared to the doors in TLOU2. I stand by that.
Given the current Java waterlogging mechanisms, even if doors acted like slabs and trapdoors, they would still hold out water source blocks present on one face. It would still break scuba diving though.
Another example from beenBoutIT: The Last of Us and its sequel have the same sort of style. The sequel has superior doors but is generally considered an inferior game. The quality of the doors really doesn't seem to be a major factor in how these games were received.
Minecraft itself: minecraft doors having no animation was not a foregone conclusion derived from the broader style of the game. Minecraft pistons do have animations when extending or retracting. I've never heard a player complain that minecraft doors are lack what minecraft pistons have.
I think that most video game players are accepting of doors behaving in unrealistic ways. Simple doors don't actually bother most players, and complex doors usually go unappreciated by most players. Contrary to what the video claims, doors can 'just magically fly open', and players don't care.
See https://bugs.mojang.com/browse/MC-149060 "Villagers "spam" doors by opening and closing them really fast"
Or https://bugs.mojang.com/browse/MC-69281?jql=text%20~%20%22do... to see the 6000+ bug reports related to doors.
Or watch https://www.youtube.com/watch?v=aiEq0bJcAz0 "Villager door spam"
Why would someone spend day after day carefully modelling things that no one seems to notice anyway?
For example the way in which dead leaves accumulate in a specific corner of my balcony.
If those beings that created the simulation are so advanced that they created this amazing word, why were they at the same time so stupid that they didn't do any optimisation and instead decided to model and refine things that almost no one notices anyway?
If those intelligent beings decided to spend less time on that aspect, and leaves accumulated on my balcony in a less complicated pattern, I wouldn't notice anything weird anyway, because I would be accustomed to that other less complicated pattern. So there would be no reason to make an effort on that.
and what, specifically, do you think you would notice if it was in some way simplified? how can you be certain about the leaves on your balcony? you have no objective frame of reference to compare "full detail" simulation.
basically the argument I was trying to make is: if it wasn't simulated I wouldn't be looking at it, and I wouldn't find it strange at all because I would be living in a world where that thing doesn't exist
> and what, specifically, do you think you would notice if it was in some way simplified?
exactly, I wouldn't notice anything.
My argument is: if those beings are so smart that they created this awesome simulation, how could they be so dumb that they wasted time simulating unneeded details?
why do you think this isn’t constantly happening?
>how could they be so dumb that they wasted time simulating unneeded details?
if it’s within your perception, it’s needed detail.
More convincingly though, if leaves didn't behave that way, the entire rest of the world would have to be designed in a consistent way. Fluid dynamics would have to work differently - and consistently with everything else or we'd notice.
You certainly noticed.
These concerns are less pronounced on PC because fine adjustments are simplified by the input method. With gamepads, precise movements are possible but more challenging than with a mouse, and any player momentum amplifies the challenge.
The preprocessor divides the entire inside of the level into convex areas and builds a graph that expresses where they touch. So for movement, if you just make sure that you can only go from one area into another that according to the graph touches it, there simply is no way to move out of bounds because the out of bounds area is not in the graph at all.
This does mean though that you have a world that is mostly static, that consists only of indoor spaces and has a limited amount of complexity because otherwise the preprocessing results in an unmanageable amount of data. There is just no way you can preprocess the whole world like that in a modern open world game.
I am not a game dev, so at first look a level editor that is mostly drag and drop should solve this for the level designers, but for some reason you can still fall through floors.
- you have a 1m thick floor in your video game.
- your video game has physics in it (like gravity, collisions, etc).
- your game runs at 60 fps
Given these assumptions, if any in-game object ever exceeds a velocity 60 m/s then on one frame it will be above the floor and on the next frame it will be below the floor without ever triggering a collision. Oops.
Let me guess: "Just make the floor infinitely thick". Sure that would work but it sort of limits the kinds of maps and terrain you can make if the floor is always infinitely thick.
One way to solve it without infinitely thick floors is to draw an imaginary line between your current position and previous position every frame and check if the line would have collided with anything . If it does - do something (make the player die, move them back above the floor, etc.). It gets more complex when it's not just the floor you have to worry about clipping through but the wall and the ceiling and all other objects.
Otherwise though, the 'trigger' code you suggest ends up generally being some kind of math (ie physics, regardless of whether it's via a physics engine layer or a game/state layer); you essentially have to figure out "where" on the plane the object is, convert that to the proper coordinate system for your overall level, and then 'sample' the underlying terrain/mesh/ground covering to figure out if you're in a legal position.
Typically this ends up being implemented as a "clamp" of sorts; you will pretty rapidly end up with oddities, floating point precision quirks, and the like.
The "best solution" will vary, often drastically, from game to game.
FWIW, I've been doing game-dev for almost 10 years now & have almost exclusively done "AI/NPC" agents. We've faced what I would classify as pretty much the same issue with AI agents, especially when you want them to follow nice, smooth paths while also realistically 'bumping into' each-other -- yet ensuring that they will never, ever, ever go through a wall. It sounds so stupidly-simple but, I can assure you, it is not! If you had unlimited resources (read: CPU), then it's not so bad, you can calculate for "optimal" every frame -- in reality, you never have unlimited resources, and seemingly-simple calculations like this have to run extremely fast and they cannot be allowed to fail (there's nothing more frustrating & game-breaking than NPCs that get 'stuck' behind a wall or in an area that they cannot vacate, etc). You can write code for agents to "detect stuck + get un-stuck" but, similarly, doing that fast is non-trivial; and ideally you don't want them stuck to begin with!!
It's a massive can of worms. ;)
The correct approach is to not model the floor as thin sheet geometry but instead to model it as solid objects, e.g. the CSG approach used in Quake, Half-Life 1 and Unreal 1 & 2. I believe those games didn't have any falling through bugs.
While I never actually did any level editing, I did read a guide to the Unreal Tournament level editor, which said that UT was unusual in that a blank level was filled with mass and the level creation process involved subtracting that away to create empty space, rather than adding objects to an empty void.
Related?
The Unreal approach makes it easy to create levels with a waterproof outer hull which allows you to use certain optimizations (such as portals in the BSP tree) to reduce what you need to draw.
But even without that, CSG usually produces only geometry that has a thickness, and that's what helps with the sliding through floors in the first place.
But since the Unreal approach makes it very easy to query if a point is inside the valid space of the level, or not, that's also used as a shortcut for determining if things did fall through somewhere.
So yes, the "blank filled with mass" approach further reduces the problem but no, it's not strictly necessary.
(I used to work on ragdoll physics.)
Here’s a game developer talking about the problem and how they solved it in The Witness, but note well the limitations he describes. It’s not directly useful if the player can jump, for instance.
Edit: mentioned in the end of the video, of course :)
Whereas the physics engine and real-world realism aspects are what the video talks about.
If the problem is that doors are inherently difficult to design, the counterpoint is that these questions have already been answered in multiple ways over the past 30+ years of video game history. It's easier today than ever to answer these questions by drawing on previous games.
https://en.wikipedia.org/wiki/Inverse_kinematics#Inverse_kin...
Stylistically it works when in a fantasy setting, or in some science fiction "tech base". But it wouldn't, if you had ordinary everyday objects like doors, beds or kitchens around.
If you've made Quake maps, you also notice that to make it playable, you should avoid things like protruding door frames, or the player easily and annoyingly gets stuck on the wrong side of it. The mapper must place clip brushes so the player smoothly flows over these obstacles. The player never notices these "nudges".