I’ve been working away for the last few weeks, which has meant that my development has had to take into account that it is being done primarily in bars an restaurants. I know many of you are waiting for the latest version of The Lords of Midnight, but although I have spent some time fixing bugs and adding a few new features, I am not in a position to Build a release version. I have to have access to my desktop to do that, and the few days I’ve spent at home with my family, I hope you can understand that spending time in my study on my computer is not the highest order of the day.
After declaring an end to any changes to Lords of Midnight, I spent some time merging the codebases of the different versions that have been branched out over the the year. Namely, Mobile version, Desktop Version, and Doomdark’s Revenge. I now have a unified code base which means that when I release a update for LoM soon, it can be across all formats.
Once the merge was complete I decided to spend some time working on Doomdark’s Revenge. I am hoping to release a test version soon. The night AI will not be activated but you will be able to wander around the map, above and below ground. And generally check out the UI differences between the games etc. This will then give me a good base to slowly turn on AI features and test them thoroughly up to release later this year. For the record that would be in about 12 weeks!
Once area that I have been working on this week, is tunnels. Tunnels are one of the new features that Doomdark’s Revenge implemented. So I have been slowly working my way through the code base, adding in all the little things that need to be there in order for them to work.
It’s a little different with The Midnight Engine, ( which by the way is the underlying code that powers both The Lords of Midnight and Doomdark’s Revenge ), over the original games, in that there is one code base. Doomdark’s Revenge was released as completely new game, and therefore much of what didn’t remain of The Lords of Midnight was just removed and the new code was added. This is a big issue with my codebase, as my original brief for creating The Midnight Engine was to be able to play both games and in theory create a game that mixes the features from both LoM and DDR. So, if we take tunnels as an example, I could just turn tunnels on in LoM, and everything would just work.
Now, let me try and give you an example of why that thought process gives me a nightmare when implementing something like tunnels.
In LoM a map location is split up into [ Terrain, Area, Object, Flags ], in DDR it is just [ Terrain, Flags ] – both area and object are generated. TME uses an expanded format [ Terrain, Variant, Area, Climate, Flags, Object ]. So the generated areas in DDR are stored, as are the objects. ( For the record, objects change every night ). For both, objects are classed as things you find or things you see. So Guidance, Cup of Dreams, Dragons, etc…
Now tunnels are a flag. A location has a tunnel beneath it or it doesn’t. If the terrain is GATE, PIT, PALACE, CITY, then the tunnel is an entrance/exit. If the terrain is PLAINS, FOREST, HILLS, MOUNTAINS, then it is considered a passageway. Now, this is where things start to get messy.
A tunnel location can only have a critter ( dragon, wolf, skulkrin, trolls ), when it is a passageway. And the location directly above ground can only have a critter when there isn’t a passageway below. So affectively you have two locations sharing the same space but only one critter at the location who could be in either of the two locations.
It seems a pretty straight forward thing to think about, but when your code base works on the concept of a single location, suddenly everything changes.
When drawing the landscape, the frontend asks the backend for the information about a given location. It draws the terrain graphics and any critter imagery that is required. The backend has just told the front end that there is a critter at this location. However, now it has to consider if we are above or below ground, and the type of below ground we are on. Based on that information the frontend can decide if that critter is visible or not.
When at a given location the frontend asks the backend for all the lords that are at a given location. But now it has to consider if that lord is above or below ground. The list of these types of checks goes on and I’ve found myself having to work through the engine making sure that I am always using the correct context. More importantly I am trying to make sure that any logic is in the backend and not in the frontend. Therefore the backend now returns the information in the form of, here is the information at the location requested, this critter is above ground and this critter is below ground. It doesn’t matter that there can’t be a critter in both, that is a backend problem not a frontend one.
A similar thing happens with the discovery map. There are flags on a location to say that it has been seen, looked at, or visited. Seen is a distance thing. Two locations away may have been seen, and you know what terrain is there because you can see it on the landscaping view in front of you, but you might not know what it is called. Looked at is for locations directly in front. You know the terrain and the name. Finally, visited is exactly that, you have stood on that piece of ground. But, you might not have stood under that piece of ground. So now we have to introduce the concept of tunnel visited and tunnel looked at. How about, we have walked down a tunnel and got to the end, and we know the tunnel finishes, as opposed to not quite making it to the end, so we have looked at the tunnel location in front, but because we didn’t visit it, we don’t know if the location after that continues as a tunnel, or this is indeed the end of the tunnel.
That one bit flag in DDR ‘tunnel’ suddenly becomes so much more when you are trying to keep a flexible engine. That one bit flag also creates limitations. Two tunnels adjacent to each other must be connected. You can’t run a tunnel under a palace because a palace is always an exit/entrance. This is used to create a one way tunnel in the game.
I have considered removing the bit flag, and replacing it with the concept of layered maps. You would then have a map for all the terrain above ground and then a map for all the terrain below ground. Following that approach would me that the limitations could be removed and it would allow things like different critters above ground than below. Or types of tunnels. But for now, I’ll leave well alone!
Other things have crawled out of the subterranean landscape… For example, two characters at the same location are not actually at the same location when one is above ground and one is below ground. Thus, the newly added grouping functionality suddenly needs to take into account tunnels!
My brain hurts just reading this!
Ready to start testing whenever you are – I still have test flight installed from last time.
It’s always a delight for me to read this kind of stories. 🙂 As a hobbyist game programmer, I really feel identified with these troubles.
I have a question, tough. Why did you keep dragging that ultrapacked data representation of the game world for all this time? It made sense in the Spectrum when Mike had only 48KB of RAM. But not now. Not even when you remade it for PC in the 90’s!
Why you tie your hands so tight by keeping that data structure all this time, while your final build weights more than 20MB because of the uncompressed graphics? Isn’t it kind of contradictory?
I haven’t kept the compressed data. The map in TME is 8 bytes per location. It handles 1024 areas compared to 64. 127 terrain types with 8 variants each. A climate control byte. 28 flags etc…
All lord data is expanded and limitations removed.
This issues has occurred purely because I have only just started thinking about tunnels. And im hurtling toward a release date. If I allowed myself more time I would completely refactor the way tunnels work.
Chris
Can’t wait to try it chief! But don’t forget some you time pal!
Thanks for the update!
It sounds like you have a lot to consider to make a generic engine to suit both games. Having experience in the games industry, I’ve witnessed first hand the conflict between back-end and front-end; sometimes there just isn’t a “beautiful” answer that keeps the compartmentalisation but gives you full flexibility. I feel your pain!
The screenshots you’ve posted up look absolutely stunning – DDR was one of my most treasured games as a kid – I still have a the map torn from a Crash magazine (drawn by the magical Oli Frey) – it’s full of my annotations and tunnel routes. The mere thought of being able to use it again fills me with childish exuberance – something I would struggle to put into words. In essence you’re giving me back my childhood and I couldn’t wish for a better present.
Thank you for taking on this incredible project.
Interesting read even though I didnt understand much of it!
What kind of updates for LoM can we look forward to in the near future? I mean, I’m sure there will be various bug fixes and tweaks. But in an earlier comment you mentioned alternate difficulty levels, new scenarios, and graphical updates. Is there anything like that coming up anytime soon?
I don’t know yet. I need to get DDR out and then take stock…
Funnily enough Chris I was reading down thinking “just go for a separate terrain map for each level” and then you could even have future maps (a dream?) with more complete subterranean features. You’ve obviously shelved that because of the immediacies of the DDR release date but I think that’s probably the way to go. It would also be pretty simple in terms of your data structures: level/altitude/elevation/etc. That would allow for later flying cities, underdeeps, etc.
Look forward to the DDR in whatever form though.
Cheers
Charlie
Yes, the problem is compatibility. There are a couple of things that I could/should have done with expanding before the LoM release. To change so now would risk breaking the code for LoM and without a lot of test, I just couldn’t feel secure. However once DDR is out, I can take stock. Especially should anyone else like to use the engine.
I’ve actually changed to the concept of a layered map in the interface between the frontend and the backend. The map structure stays the same, but there is now a couple of variables that pertain only to the tunnel. This way the fronted doesn’t need to think about the whole above ground nonsense. It just says, if in tunnel, use the tunnel values.
So, it’s a little way in the right direction.