( with apologies to zefrank )
Tonight I’ll be trying to optimize the loading of the map so I don’t wind up with over ten thousand rendered objects for just the terrain with no characters or anything. I’ve already sketched out a couple of things to try, and made an initial attempt that gave me some confusing results.
But first some context:
What?
In the mid-1980s there was a commercially successful, text-graphics MMO hosted on CompuServe. A few years back I was amazed to stumble across an open-source emulator, and cloned the repository in anticipation of having time to contribute. It’s since gone back to closed-source, so that’s the latest code I have. It’s a frankly awesome piece of work, and a great starting point for me to do some technology learning and experimentation while also satisfying my nostalgia.
The first thing I’m doing is making a visualizer for a running server, giving a bird’s eye view of the map. This gives me an excuse to play around more in Unity, and since the server code was already in C#, it is fairly easy to leverage.
Let’s do some stuff
So I put together a Unity project with a cube prefab and some hand-made ugly textures, brought in the DS code (commenting out the parts that expect a live database), and threw together something to render the map (Map and Cell are classes from the DS code):
|
|
It’s pretty awkward, especially the way we have to maintain parallel arrays to match up display strings to Materials (that’s just so I could easily mess w/it in the Unity editor). But it does get us this:
From this angle you can see the town of Kesmai and several of the dungeon levels underneath.
As you can see, I couldn’t make up my mind about the textures: retro green-on-black ASCII or something more representative?
First naive optimization

Having 11945 individual cubes just for the map seems a little wasteful. As a first pass, maybe we can just have a double-wide block if we encounter the same cell string twice in a row:
|
|
Seems simple enough: If there’s a block already instantiated to our left (x - 1), check its material. If it’s the same as I’m about to use, just shove that one over by a half unit and make it a unit wider (and don’t bother to instantiate the current one). What could go wrong?
7991 blocks for 11945 cells
8003 blocks for 11945 cells
7990 blocks for 11945 cells
Three runs in quick succession actually give us three different counts for what we’ve instantiated. Maybe we’re in a race with Unity, checking out the previous block’s renderer before it’s quite ready. Let’s figure out what’s going on…
Well, that was a timesink. Not an issue with Unity’s renderers, not a C# collection oddity, it turns out there is some randomness in the original map-loading code that affects the cell graphic string, e.g.:
|
|
Randomness is all well and good, but I can’t have that if I’m to be comparing optimizations. I don’t want to start messing with that code yet, so luckily the random number generator already had an alternate constructor that takes a seed (the default one uses the clock):
|
|
Setting the seed to 1, I get the consistent results I was expecting.
Even this simple attempt gets us almost a one-third savings in actual objects to instantiate. Tomorrow we’ll try some real ideas.