[ODE] ODE in Myst V: A Postmortem

Colin Bonstead colin at cyan.com
Tue Jun 21 15:58:17 MST 2005

I've pretty much wrapped up the physics work in Myst V, so I figured I'd 
send out an email to the list with the details of what kind of issues I 
ran into.

For our previous game, Uru, we used the Havok 1 engine for our physics.  
The characters were simulated as 3 different size spheres stacked on top 
of each other.  Movement was accomplished by just setting the linear 
velocity based on the player animation.  This worked well since Havok 
resolved all collisions each frame, so there wasn't any "jittering" when 
you pushed yourself into a wall.  We had some physical objects scattered 
around that you could push, but no real fancy physical interaction.

When we were reworking the engine for Myst V though, we decided to drop 
Havok and go with ODE.  The main reasons were that we wanted to ship on 
Mac, which Havok didn't support (thus killing the Uru Mac port we were 
going to do), and ODE was free.  We had evaluated ODE during Uru, but at 
that time it didn't support trimeshes, which was a deal breaker.

Going from Havok to ODE, the main issues were the lack of convex hull 
support and the fact that collisions weren't completely resolved each 
step.  In Uru, pretty much all detectors were made from convex hulls.  
Since they have a definite inside and outside they can detect when 
another physical is completely inside them, unlike a trimesh.  Since ODE 
doesn't have hulls I had to make the artists use either box or sphere 
detectors, or use a trimesh and make sure the object that's going to be 
inside them will always be touching a triangle.  That was unfortunate, 
but they adapted to those restrictions.

The bigger problem was the collision resolution.  Since ODE uses the ERP 
to resolve collisions over multiple steps you can run into cases where 
an object being forced into some static geometry will push in and out 
instead of stopping dead.  In Havok the penetrations were always 
resolved, so our character controller was much simpler.

For the Myst V avatar I used a capped cylinder.  In Havok we kept our 
characters upright by setting an inertial tensor that was wacked out 
enough to make it impossible to get any angular rotation.  (Then for 
turning we would just manually set the rotation.)  That didn't work in 
ODE so I initially tried making a joint that would disallow any rotation 
in the x and y.  That worked, but after scooting around a little the 
character would begin slowly tipping over.  It was a problem I ran into 
more than once, where a joint just wasn't stable.  So, I gave up on the 
idea of a joint and went with what Alen from Croteam suggested and just 
created a flag in ODE that would prevent a body from ever getting 
angular velocity.  (I just added a few checks in the step for the flag 
and didn't add angular velocity in those cases.)

Moving the avatar by setting the linear velocity directly, like we did 
in Havok, didn't work too well.  I don't remember exactly what happened, 
but I do remember that everyone on the mailing list said it was a bad 
idea.  Again I went with Alen's suggestion here and made a custom joint 
that set the x and y linear velocity.  That worked fine but due to the 
collision joint sponginess I needed an additional check to keep the 
avatar from running full force into walls.  I added an additional capped 
cylinder that was slightly bigger than the collision one and it just 
detected collisions without making any contact joints.  Then I took the 
normals from all the contacts and decided if we were about to run into a 
wall.  If so, I would redirect the velocity to slide along the wall, or 
just kill it if there was nowhere to go.

To get good contact normals from the trimesh I had to add another 
special flag to only return normals.  By default you'll get the best 
separating axis, which isn't necessarily the normal of the triangle you 
hit (for instance, if you're on an edge).  In addition, to clean up the 
amount of contacts I implemented the contact reduction method from Game 
Gems 4(?), which is checked into the unstable tree.

The main problem I ran into was with the instability of the ODE joints.  
I run our simulation at a fixed 100 Hz, and clamp the per-frame delta to 
a max of 100 ms (so we don't kill the framerate even more by doing too 
many steps during a slow frame).  That works great on fast machines, but 
on slow ones (ie dropping below 10 fps at times) the joints tend to get 
unreliable.  The avatar can run pretty fast (around 20 feet per second I 
believe) and we ran into a problem near the end of development where in 
low framerate situations the avatar would sometimes pass through boxes.  
Changing those to trimeshes fixed the problem, I think because they 
generate more contacts.  I did a lot of work playing with different ERP 
values, step sizes, stepping methods, etc, but nothing fully cured the 

Overall I'm fairly happy with ODE, in the sense that the price is right 
and it allowed us to do a Mac version.  However, I wouldn't recommend it 
to any other commercial game developers.  The community is pretty 
helpful, but it just isn't the same as having support from a commercial 
physics engine.  Also, development is pretty stagnant right now.  The 
biggest reason I'd recommend against it though is the fact that Novodex 
is basically being given away for free if you commit to using a decent 
amount of physics in your game.  Ageia wants to create a market for its 
physics accelerators, and they're willing to take a bath on Novodex to 
do that.  I'm sure Havok is not happy about that.

Anyway, if anyone has any questions or comments I'll be happy to reply.

Colin Bonstead
Lead Engine Programmer
Cyan Worlds

More information about the ODE mailing list