Ultima Online terrain
This was a Reddit thread reply in 2019, an answer to the question “Anyone know how the Ultima Online terrain effect was achieved?”
Hi, original lead designer on the game here. The answer by /u/ZaneDubya is very good. The technical term for the redrawing is “dirty rectangles,” and you can find lots of references on the Net for methods to do that.
The original first pass at 3d terrain was done by me, actually — I simply grabbed the terrain tiles and made alternate sets that were lighter and darker and created the optical illusion of multiple heights of terrain. Similar to, but different from, the original Legacy of Kain, or lots of JRPGs. This was well before the alpha, actually while we were still in our first office in the building (of many) so that would place it in the first few weeks I worked there, probably late 1995.
When Rick Delashmit saw what I was doing, he said “I bet I can actually give you real 3d terrain,” and went off and wrote the texture mapping routine. Then he and I worked on setting things like the 4 pixel interval, which took some experimenting (clipping and performance issues meant we had to be careful about stuff off the bottom edge of the screen being too high and causing visual artifacts).
I had to do the tech art solve for terrain embankments, and I am pretty sure that’s how we ended up picking the left/right split for the quads. The embankment textures in the game are still the ones I made later by combining the dirt and grass tiles and drawing “runnels” on them with a burn tool in Photoshop.
This of course introduced the question of working with objects on top of the now-varied terrain. Objects had a Z and were sorted appropriately for drawing based on an anchor point that was the center of the bottom row of pixels in the sprite. If you were in a tile with another object that had a higher Z than a point roughly around your head, were simply didn’t draw those things. That’s how “roof popping” worked.
This did mean you had to be careful given the way the screen was drawn: back to front, then left to right, then bottom Z to top Z within a tile’s x and y. It was easy to create things that clipped through, particularly given that many sprites were wider than one tile.
Later on, when doing the jungle environments, this was addressed to a degree by making very wide sprites into multiple 44px-wide strips, and placing them one next to the other. Much much later, in Metaplace, I had the client programmer make this process automatic for all extra-wide tiles. Doesn’t solve every case, but it solves a lot.
In order to do walls, we developed a system that had the most efficient tileset we could make for the sake of networking traffic, and which also by its nature prevented players from standing in a corner that occluded them entirely. Richard Garriott was very impressed that we had developed a more efficient wall tileset than any he’d seen in 2d games before.
Objects could be tagged as a surface, and they could be tagged as “stairs.” I actually did the tech art design on stairs too; our artists couldn’t figure it out at the time. The terrain was defaulted to a surface. Players were snapped to the first surface below their Z anchor point at their feet. The stair tag allowed you to walk up and down surfaces, and excessive gaps between Z heights were deemed impassable by the pathfinding routine. Impassability was defined on a tile art basis.
Important to point out that these flags stuff was in the object definition, and not a separate pathing map! This way everything worked consistently. We did not build path graphs at all, they were basically procedurally read from the tile and object map.
We simply didn’t render anything above your head’s Z anytime you were in a tile with an objects whose Z was above your head. The result was that as soon as you stepped “under” a floor (aka a ceiling), the upper floors of the building “popped.” Because of this, we had to set a defined Z height for “next floor” and make it an art standard for all walls in the game.
Because of how Z worked, you could actually place surface object tiles under the terrain as well. We had a special terrain tile that was solid black and a “cave” entrance, that didn’t cause you to snap, allowing you to walk from the terrain surface to underneath the terrain — whereupon all terrain above would stop being rendered. Doing entire dungeons this way was an issue, though, because we wanted to do dungeons that didn’t actually fit under the terrain! So we would use the cave entrances as a fakeout, then teleport you to a different location on the map altogether, where the terrain was solid black. The result was that players thought they were going underground when in fact they were on the surface!
I worked with Rick to develop a tool suite for terrain painting and elevation painting, which allowed you to have a resizable rectangular brush (you could resize it independently on either axis, so you could make “strip” shaped brushes). You then had a set of basic tools including raise, lower, smooth, roughen (basically, add noise), and flatten. But for the alpha map (so E3 1996) this was still way too much handcrafting of the terrain. We found ourselves making vast swaths of forest dead flat with nothing interesting, because the tools didn’t scale.
The quick solution, literally written the night before the alpha test opened, was a terrible little scripting language called escript. Rick wrote it, it had horrible syntax because he didn’t have time to make a nice parser (every variable had to be enclosed in ##, every statement in @@, and the like), it literally ran off disk — not memory — and I learned it that night. Basically, it let me automate basic processes like query a tile’s id or Z, raise, lower, etc, plus also place objects by id. I then wrote a quick set of scripts that could do things like place trees randomly on forest terrain tiles, slightly rumple the terrain, etc.
These tools ended up being how all of UO was built. Later on, Rick extended the API for the game scripting language (wombat) to be able to call escripts. I wrote a set of generic tiny escripts, and a big wombat front-end to it all that was a menu driven system. “Select all forest tiles from this X/Y coordinate to this X/Y coordinate. Apply a gentle slope from this end to that end, roughening, then smoothing. Then search through all tiles adjacent to forest and place the correct half-forest half-grass tile around the edges.” (We didn’t have tile blending — every two different tiles needed a hand placed transition tile between them.)
This tool is still in use today, twenty years later, the current team tells me.
This is part of why UO’s mountains are so poor, by the way. The designer in charge of the mountain biome was supposed to have it full of wedding cake tiers, interesting spaces, etc. Instead, he painted it all impassable, drew a few mountain passes between areas, painted the passes with dirt, and left it at that. A lot of the mountains were in fact dead flat! We had a whole set of pines, mountain creatures, etc, which were supposed to be up there. Instead, it cost us almost 1/3 of the total continental surface!
In a desperate effort to make it at least look OK, I took the mountain rock tiles and made some dramatically darker versions, and randomly salted them across the mountains to add visual contrast and “hard edges.”
Second Age’s map much more fully leveraged these tools, which is why it is so “wedding cake” like. The entire map was painted flat first, using dummy tiles, then automated processes went across it raising up tiers, randomizing tile variety, adding smoothing and slopes, processing tile transitions, and so on. The only parts that had to be hand-edited were tight passages and ramps between elevation tiers. This is very noticeable if you wander that map.
Ah, good times. 🙂
All creatures/players/gear were 3d models rendered on turntables to generate all the angles.
Much terrain tile art existed as both a terrain tile (basically, a texture map) and as an object (a diamond shaped flat object). This was so that we could use it for visual effects. It was wasteful to make wooden flooring on the terrain be objects — that would incur two draw calls. So you would have wood terrain that you had to make sure was flat, and you’d have separate wood flooring for when it needed to be mid-air. When you walk from the ground to a dock over water in UO, you are walking from terrain wood to object wood seamlessly.