The
ultima underworld engine always fascinated me. In many ways it were way ahead of its
time giving the player non-orthogonal walls, sloped floors, bridges, water, 3d doors
etc. etc.
Add to that a huge selection of items and monsters stuffed into creatively made levels
and a genious plot - and you got an underworld game.
Update: Until recently I believed that the Underworld engine was a so-called
ray-casting engine like Wolfenstein, Doom and many other games from that early era
of the first person shooter. In a raycasting engine the levels are basicly 2d maps
and the player is then fooled into believing that the world is 3d by some scaling
tricks. I believed this because the levels ARE stored mostly as 2d maps with the exception
of certain items in the world.
However Doug Church was so kind to email me to clear up some things on this matter.
Doug was one of the programmers on both the UW1 and UW2 team (and actually project
leader on UW2 - good work there Doug!!) so I guess I better believe him :) Here are
the facts in his own words :
" However, let me second what Dan Schmidt said in the guestbook back in August about
the description of the UW engine you guys have up on the page. Namely, UW _was not_
a raycasting engine. While UW did use a tilemap to store the world, that has nothing
to do with the rendering model. In general, I'd suggest that the "world rep" and "rendering
engine" be considered separate things when discussing game technology, because they
very often are. In UW, we had a tile based world. The renderer used the tiles to explore
the view cone and do a high level cull operation. From the list of visible tiles,
we generated full 3d polygons, in the traditional XYZ sense, and handed them off to
a rendering back end and rendered each poly in 3d as is. That is also how the 3d models
like the ankh shrines or benches were done, which clearly aren't "raycast" model 3d
objects. Now, in practice, many of our 3d primitives did things like normal checks
first, and then chose which algorithim to rasterize with based on scale/normal/etc
of the surface being rendered."
Well, thanks for clearing that up Doug.
What I have done is that I have made a program which converts the 2d maps into real
3d meshes of triangles. This 3d data is more suited for the modern hardware accellerated
3d graphics cards. Because the levels are now real 3d you also get full freedom of
movement which means that you can move and look in any direction in the world.
My viewer also loads the original 8bit textures and converts them to 24bit using the
original pallette from the game. Then it automatically generates a set of mip-maps
for each texture using a cubic filter which ensures that flickering in the 3d graphics
will be kept at a minimum.
I have made a crude collision detection algorithm to clip the player against the walls.
I warn you in advance that this is not a perfect algorithm, but I dont want to spend
any more time on this project so I just threw it in to provide SOME realism ;)