If I were to make Golem now...
If I were to go back and remake Golem today, what would I do? Where would I start? As I have mentioned in previous entries, I would almost certainly use an engine now instead of rolling my own. (Although, to be fair, back then there wasn't nearly the wide range of available engines to do this stuff with, so rolling your own was almost a given.) Without having to worry about the low level details, I would be free to worry more about the stuff that makes it an actual game. I've become a better programmer, so I like to think that I would make fewer mistakes now, mistakes that would turn the game into spaghetti. Still, though, even with all that I've learned in the last couple decades about game making, I think I would probably start Golem now with the same thing I started with back then: drawing the ground.
Think about it: in an ARPG like Diablo, you spend a LOT of time looking at the ground. Camera above the ground looking down, dude walking around. The ground fills the frame nearly 100% of the time. To me, poring over screenshots of Diablo and Diablo 2, it seemed the natural place to start. Draw the ground, then figure out what kinds of other stuff to draw on top of it. In 1997, my options for drawing the ground were somewhat limited.
When I first read Designing Isometric Game Environments by Nate Goudie in a print issue of Dr. Dobbs Journal in 1997, I had already played Diablo 1. I had also already created a number of small prototype tile-based RPGs, starting in the late 80s. I had dipped into assembly language programming in the early 90s, to write "fast" tile blitting routines. I had a basic understanding of how tile maps were supposed to work, so I took what I knew and what I read in that isometric article, and I dove in.
Golem went through various different stages as I learned about tiles and tilemaps. From base tiles with no transitions, to transition permutations, to alpha-blended transitions for greater flexibility. I spent a lot of time looking at screenshots, playing with paint programs, trying to hand-draw some dungeon floors. I remember in the early 90s I had found a program for DOS called NeoPaint, and I was still using it in the late 90s to try to draw dungeon floors, right up until I discovered GIMP. I struggled to try to reproduce Diablo and especially Diablo 2, without really knowing or understanding how such things were done. At some point, I had the epiphany that they most likely created their tiles from photographic sources. Digital photography was starting to take off, and I remember stumbling on Mayang's textures in the early 2000s. Most of the tiles in the Golem screenshots still in existence were created from texture sources downloaded from Mayang's. I remember just being floored at the number of textures available there, and during that time I really worked on learning various editing techniques to make tiles from photo sources, to make them seamless and create transitions.
In the beginning, all of the render and blit operations were written in assembly. The first generation of Golem map rendering had its roots in a tile map system I wrote in the early 90s for DOS. At that time, my computing budget was limited. Hard drive space was at a premium, all drawing had to be done in assembly language to get the kind of performance a game required. With the switch to isometric in 97, I devised a very simple run-length encoding scheme to encode the graphic tiles. See, the isometric tiles are diamond shaped:
From the very first, I understood how wasteful this configuration was. All that empty space, all those transparent pixels. My early thought was to encode the image so that only the pixels (plus some book-keeping stuff for row offsets) were stored. That saved a lot of disk space, plus I wrote custom assembly routines to draw these RLE sprites with pretty decent performance.
The first iteration, I had no idea about transitions. I had played a lot of JRPGs on Nintendo systems, so I was pretty familiar with tile maps. All those first Golem tilemaps were transitionless. I don't have any of those screenshots anymore, but it was essentially like this:
Those are newer textures; the ones I made for Golem initially were... pretty terrible. I thrashed around a lot in those days, trying to figure out techniques and learn tricks. Eventually, I read about tilemap transitions (probably in the gamedev.net resource section) and started creating permutations. Dirt to grass, dirt to water, grass to water, etc... If you've ever done transition permutations like that, you know that the number of permutations can explode pretty rapidly. Thus, this later revision of Golem's map rendering had to carefully constrain terrain placement. Gone were the days when I could just throw whatever tilemap configuration at the renderer I wanted; I had to be careful in placing types so that, for example, I didn't end up with a dirt tile that bordered grass on one side and water on another. That just wouldn't work. Still, even given the limitations of tile permutations like that, the simple addition of transitions was a pretty good leap forward in quality. The result was something like this:
Eventually, though, that limitation started to really chafe. Just... you know, sometimes you really want to have a dirt tile with grass on one side and water on the other. You know? So I learned some more tricks, read some more articles. Somewhere around this time, I switched to DirectDraw for rendering, then moved on to Direct3D. We're talking early versions here. I kinda wanna say I started with DirectX 4. DirectX had been a thing for a few years, and I probably stuck with the old assembly stuff for far too long, but you gotta understand, kids. Back then, the internet was still mostly just sacks of bytes carried around on the backs of mules. You kids and your reddits and your facespaces, you just don't know what hardship is. Hardship is connecting to the World Wide Web with a dialup modem, hanging three T-shirts over your computer to try to muffle the connection noise because there's no volume control on it and your roommates are trying to sleep. Hardship is not even knowing that marvelous wonders such as DirectX or OpenGL even exist, because the only real reference you have is Michael Abrash's ponderous tome on graphics programming, with its chapters on Mode X, already a relic of a bygone era by that point.
Anyway, with the switch to modern APIs, things really changed. I could use alpha blending, something my old assembly routines didn't really allow. Now, I could create the transitions as alpha-blended decals overlaid on top of base tiles. Suddenly, I could have that mythical dirt tile bordered by grass and water, without having to create approximately 900,000 different terrain permutations. It was amazing!
Again, those early dev screens are lost. But here is a quick example of how that can look:
Any number of transitions could be overlaid upon one another to create as complex a transition as was required. Of course, this required me learning a few more tricks on tile creation. (Again, those early tiles were pretty garbage, though I was getting better by that point.)
It was around this time that I started branching out into a lot of different areas. I was building the character control stuff, combat stuff, inventory handling and management, etc... I was learning how to model in 3D, using the amazing Blender software that I had discovered. Blender was in its infancy, having just been released as open source by a crowd-funding campaign. But even then, it was pretty powerful and it opened up a LOT of options and avenues for me. I was learning how to create walls and gates and skulls and creatures. It was an amazing time.
I started to dislike how the tile transition schemes were plagued by the appearance of grid-based artifacts. You could see the tile-basedness of it. I let that ride for a long time, though. At some point later (after I had already abandoned Golem) I started experimenting with decal-based splatting systems that would splat terrain and terrain decorations down on top of a terrain, randomizing locations of splats to mitigate the grid constraints. I could lay down a base terrain, then splat decoration on top of it using alpha-masked splats.
With the rapidly expanding hard drive sizes and graphics card capabilities, the RLE system I had encoded my stuff in all along quickly became a liability. I didn't really need to optimize for hard drive space anymore, and it required an extraneous step of unpacking the encoded sprite to a OpenGL texture. I never did replace that system; I just worked around it. But since I had plenty of space, I could now do tile variations: different variations of a single terrain type that could be mixed and matched to eliminate the appearance of repetition. Even just having 2 variations of a given type made a large difference:
Adding more variations only made it better.
And that's pretty much where I left it all off. Using alpha-blended transitions or detail splats to hide repetition, texture variations, etc... I was able to make some pretty decent stuff, slightly approaching what Diablo 2 accomplished (if with nowhere near the artistic skill). Unfortunately, this was the end. The awkwardness of the graphics pipeline, combined with the general shittiness of the codebase, killed the project. Eventually, my old hardware was upgraded to new and the Golem was not copied over. Pretty soon, it was nothing but rotting bits on a disconnected harddrive in the bottom of a dusty, spider-webbed cardboard box.
So, back to the question of if I were creating Golem now, what would I do? First and foremost, I would ditch the tile-based transition scheme altogether. Using a custom shader to blend different terrain types together using a blend texture is the way I would go. It's what I've been using in my Goblinson Crusoe project for a long time now. Using such a scheme has quite a few advantages. The grid is no longer as large a problem. There is some repetition, due to using tiling textures, but the actual transition configurations are no longer tile-bound. A couple different base textures, a map to blend them together, and some revised ground terrain generation rules for the random generator and you're in business:
Couple it with the decal detail splatting to add some decorations, and you can get some really nice results with relatively low performance cost.
The base version allows 5 terrain types (black in the blend map is the base, R, G, B and A channels control the upper layers). But you could throw another blend texture in there for 9 types if desired. Texture arrays make it easy, since you can bind as many textures as you need.
I put together a quick test of it. The funny thing is that it only took me about an hour to get the framework up, and implement a quick randomly generated ground terrain and have it scroll around with the WASD keys. The power of a pre-existing engine, coupled with the countless hours I spent up to that point learning about how all this shit works and writing shaders and camera code for other projects. What took me literally years in the early days to accomplish, I can now accomplish in an afternoon and with better results besides. Such is progress.
If I were to make Golem now, this is how I would start.