Falling through the ground

We’ve had a lot of complaints of “falling through the ground” the past few weeks, and I finally decided to find a solution to that problem. It’ll be in the next update! The rest of this blog post is about why it happens, which is only interesting if you’re into the nuts and bolts of game development. You can stop reading now and I promise you’ll miss nothing.

Still here? Okay, let’s talk about why it happens.

We hadn’t had complaints of players falling through the ground since pre-alpha 1, back when it was common to fall through the world when you turned into a werewolf. But even though players have been immune, monsters have been routinely falling through the ground for ages, and recently players started falling too. Why?

In short: automatic movement. A couple weeks ago, I added the ability to automatically navigate to a spot by right-clicking on the ground. And if you use an ability while you’re out of range of your target, you automatically run to get closer. Very handy. Lots of reduced frustration.

To automatically move you, I use the Unity NavMesh system, short for “navigation mesh”. This is what moves monsters around, too, unless they’re very close to you.

Here’s what a section of Serbule looks like, with the navigation mesh visible. All the blue areas are spots that you can auto-navigate to:

NavMesh of Serbule. The little circles are places where it will auto-jump you to if need be.

But it’s not always rosy. Here’s a serious problem spot: a hill near a giant crystal.

NavMesh of forest area… note the holes.

You can see there’s big splotches of ground that don’t have any blue on them. But those areas should be perfectly walkable! And they are, sort of: the blue for those areas is just underneath the ground!

This is what happens if right-click to auto-walk on one of those areas:

Walking on NavMesh that’s under the ground.

As long as you’re automatically moving, you walk on top of the NavMesh, even if it’s under the ground. This can cause your legs to go right through land with no harm done. But as soon as you’re done auto-moving, you go back to regular movement, and then the game needs you to be above-ground, or else you fall to your doom.

These are clearly errors in the NavMesh calculator. Now a certain percentage of error is expected, in order to increase performance, but this goes way beyond the allowed margin of error. (Even if I tell it not to allow any margin of error, it happens.)

There’s an “advanced option” to generate a separate height mesh to fix this sort of thing, but it’s too expensive to use — it costs lots more CPU cycles to move people that way, and it only partially fixes the problem anyway.

Eventually I fixed it with a hack: as soon as you stop auto-moving, I shoot an imaginary ray from your head to your feet. If there’s ground in between your head and feet, I shove you upwards so you aren’t falling through.

This looks glitchy, though: you’ll be running right through the ground until suddenly poof, you’re atop the ground. But for now, it’s the best I can do. Monsters will now use this trick, too — in the next update we’ll see if it adequately addresses the issue. (It worked in my testing, but players get into a lot of weird situations.)

Unity Issues

I’ve blogged about problems with Unity’s NavMesh system a while back, and I searched for a replacement system, but… available replacements are tons of work to use within Unity. Not really reasonable in my time frame, I’ve got gameplay code to write! And Unity finally got around to documenting the NavMesh system, which made it dramatically easier to use.

But it’s still full of all kinds of bugs. This isn’t even the most egregious bug I’ve had to work around.

And that really gets to my gripe with Unity. Unity is key to making this game, because it’s just so much more powerful than other cost-comparable engines that it’s crazy. And I really like using Unity, and have built a whole engine layer on top of it. Completely committed to this toolchain, can’t change now.

But I wish they didn’t ignore bugs for years on end. The NavMesh bugs aren’t even the high-priority ones to fix. My personal-peeve bug is that the entire streaming-audio feature doesn’t work on desktop OSes or browsers. The whole feature is totally bugged! Streaming .OGG files causes all kinds of warping and distortion and cutting and skipping. It’s awful. How did they ever allow this feature to go out like this? My guess is that it worked when it was released, but later it broke, and they’re not willing to spend the time to fix it.

An even more obvious problem can be found on Macs: if you have two monitors with different resolutions, and you play a Unity game in a window, one of the monitors will report the wrong mouse coordinates, making it basically impossible to click on any GUI elements. This is a huge embarrassing issue that’s trivially reproducible, and it’s been in my bug-submission queue with them for maybe eight months now. So I don’t have much hope for more nuanced bugs, like the NavMesh issues, getting fixed soon.

Unity’s still pretty much the only game in town for indies making 3D games in reasonable timelines, so they can get away with prioritizing bugs any way they want. For the past six months it seems they’ve only bothered to fix major iOS/Android bugs, not bugs on desktop OSes. That’s very frustrating. If they keep this up, they’ll allow room for a competing engine to usurp them eventually.

9 Responses to Falling through the ground

I understand that you are now fully entrenched in Unity and can’t turn back now, but given the number of different bugs and difficulties you’ve had with the engine, would you still choose Unity if you could go back and start it all again?

@Timulus – if I started over 3+ years ago? No question about it, I’d still go with Unity. If I started over today, … probably I’d still go with Unity, but I’d look at recent options more carefully. There’s going to be a ton of annoyances with any engine — I’ve never used one that didn’t have grievances like this — and Unity’s workflow tools and cross-OS compatibility are still really hard to beat. But if I were starting a few years in the future, who knows.

@Sinistralis – the NavMesh system actually moves you along the mesh automatically, so if I tried to move you too, you’d ping pong up and down at a high frequency. There’s a way to turn off the automatic movement, and do it by hand, but it doesn’t seem to have been thought out very well… it will need new hacks to make work, basically. That’s probably the eventual solution, but will take a lot of fiddling and frustration, so I’m putting that off.

You can’t exactly manipulate the NavMeshes in real time — the stuff in the pictures above is hard-coded. You can place “obstacles” in the scene dynamically, though, so I could put little filler boxes everywhere there’s a problem, or something like that.

However, navigating lots of dynamic obstacles costs CPU power, which is my bottleneck for the AI servers. So that makes that option less exciting to experiment with.

I’m initially surprised by this bug: I would think that the first thing to do would be to use the navmesh to derive a path and use that path to generate movement-control inputs, so the character is subject to normal collision with the ground.

On second thought, I can see that that’s more expensive, harder to implement in a generic engine, and would cause occasional hanging up on small obstacles. But perhaps doing it that way would be straightforward enough to be a satisfactory fix for players intersecting the ground while (as opposed to after) automoving?

(Players only, not monsters, since it would be less noticeable and more expensive for monsters, and since, if it gets hung up, players can compensate intelligently and see it as a minor glitch compared to monsters getting stuck and being sitting ducks.)

Redirecting everything through something that parses distance and calculates a “run time to location” and turns/runs sounds like a brilliant way to fix this problem. The only issue with it would be that you lose the built in pathing, and having to account for maneuvering around small obstacles/turns etc I feel like would be exceptionally expensive, as stated above.

Cool idea, although this is something I’d be leery of just band-aiding. I feel like this would just be an issue waiting to pop up at another point but I don’t know much about Unity, so maybe not.