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 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. ;)
(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.
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.