In the mouth of a broad tunnel, they paused to look one more time upon the fair land of Midnight.

Here is something that I have been working on in the background – Tunnels in The Lords of Midnight. It’s not something that is going to be used in the main game, but I am hoping to have a new scenario released later this year, early next at the latest.

For those of you who have read Drew’s novelisation, then the need for tunnels will make sense. For those of you who haven’t, well something for your list…

Normal Tunnels

Now, you’d think that adding tunnels to LoM would be pretty straight forward. It is as you may know from following my posts, the same codebase as Doomdark’s Revenge, having been unified a few years back. However, there are some issues.

Firstly, even though they are the same engine, and use the same data structures etc, the games are built conditionally as separate projects. This means certain part of the engine is not compiled depending on the games. For example, tunnels, mist, AI lords, special objects, are not part of LoM. Regiments, Ice Fear, and Waypoints, are not part of DDR. There are other little things like critters and battles working differently, and small UI changes.

The engine is written in c++ and most of these features are turned on or off using preprocessor macros like this..

            if ( !IsDead() ) {
#if defined(_DDR_)
                flags.Reset ( cf_inbattle|cf_wonbattle|cf_preparesbattle);
#endif
#if defined(_LOM_)
                flags.Reset ( cf_inbattle|cf_wonbattle );
#endif

Some of it is handled with c++ object inheritance.

Some of it is not handled very well. The code base, like many projects has morphed and evolved over the years. I as a 30+ year veteran software developer, understand the vast gulf of academic based code structure, and real world getting it done with deadlines. And it’s no surprise that the engine has many of these pitfalls.

The following piece of code makes sure that two characters tunnel status is the same. ie: These two characters can only see each other if they are both either in, or both out of the tunnel.

#if defined(_DDR_)
            // they both need to be in or out of a tunnel
            if ( c->IsInTunnel() != IsInTunnel() )
                return false;
#endif

The thing you will notice is that the preprocessor check that will include this code is _DDR_ which means, it only gets compiled when I build Doomdark’s Revenge. Ideally this code should either be governed with a _TUNNELS_ feature preprocessor macro or better still, a feature check based on the capabilities of the scenario. So, that was the first thing I had to do and it took a few iterations to get it right.

The landscaping view for DDR is different as it has a header, therefore the tunnel view needed to be modified.

New graphics were used to distinguish the two.

Text had to change. The DDR strings database has ways of describing that a character is in a tunnel, or can see and entrance. LoM did not.

I found a bug on the think page that is in DDR in that it will show you information about a character in a location that does not have the same tunnel status. There were a couple of other UI issues specific to LoM for showing characters or armies in a tunnel. These just come out of different code paths.

Narrow tunnels

You will notice in the above image, a slightly different tunnel view. This is for narrow tunnels. The novel explicitly has Farflame not entering the tunnels when Morkin does even though they are together, and this is because he is too large. This is a story specific plot device, but that makes no sense when we consider the tunnels in DDR. So the change I made to accommodate this was to have normal and narrow tunnels. In this instance Farflame can enter the tunnels, but there are some important areas that he cannot go because they are too narrow, and the game indicates this with the slightly different layout. Narrow tunnels will also be extended to armies, and too many characters in one location.

Something else I have done with the tunnels is to tweak the concept of entrance and exit. In DDR these are always one of four terrain types – Palace, Pit, Gate, and Temple. However using the mapping software you can now override this and mark any location as an exit, an entrance, or both.

Tunnel view in mapping tools

And finally, while I was make changes for the mapping I extended two other features. Firstly impassable mountains. This was added as a rule recently to help make games optionally harder or just different and it was locked to just mountains. However, I have now added a feature to allow any location on the map to be marked as impassable. In this instance it will be used for all the mountains around Ushgarak. This means that the only way to enter the plains of despair is to take Kor and Grarg. The slight pass at Vorgath as been closed off but I am having to think this through a little more because of the consequences to a western attack.

And finally, respawning of things. In DDR critters and things (claws, thorns, springs, etc) regenerate randomly. I am planning on adding this to LoM as a rule, but for the next scenario I am also adding it as a mapping feature so that certain locations can respawn. In this instance I am using it for critters in the tunnels.

Tunnel Exit

There will be more information about the Novel Campaign later as I work my way through it.

If there were vague fears for the future itching in the depths of men’s minds…

The following is the list of outstanding items that are currently on my feature list. The intention is to add all of these over the next few releases. They all have a varying level of difficulty to implement and some will be quick wins. I’m not going to commit to an order or when as much will depend on me being on a roll or not, but I will place a marker against the ones I original intended for the Summer Solstice release. If you would like to discuss the items in any more detail, please feel free to following the links to my GitHub page for each item.

panel_select, panel_think – Add Next/Previous buttons for Desktop – Summer Solstice

panel_select and panel_think need an additional Next/Previous buttons for moving through the pages. The mobile pager is not always obvious.

Option – Don’t swap after successful approach – Summer Solstice

Give the option to stop the auto switch to the newly recruited lord after an approach. Maybe this could be Enable / Disable / Ask with default being Enabled.

Option – Auto Seek – Summer Solstice

Add option to auto seek when entering a location. Doomdark’s Revenge already does this as seek is not a player action. Maybe it could be?

Option – Auto Approach – Summer Solstice

Add an option to auto approach when entering a location in LoM or when trying to move in to a location DDR.

Game Difficulty – LOM/DDR – battle algorithms

Adjust battle algorithms to give Doomguard more success. This would be a difficulty option.

Game Difficulty – LOM – Armies

Add more armies tracking Luxor, Morkin in LoM. This would be a difficulty option.

Game Difficulty – LOM – IceFear / Moonring

The ice fear is calculated based on Morkin’s distance from the Ice Crown and the distance from the warm glow of luxor. The ice fear is then fed in to other calculations.

increase the falling rate of Invigorated/tired, bold/afraid, + effect on + distance to Moon ring. This would be a difficulty option.

LOM: Campaign for Novel

Create a campaign that would mirror changes made for the Novel.

  • Lord of Silence
  • Tarithel the Fey
  • Utarg changing sides
  • Tunnel to the Tower of Doom

LOM: Gameplay Rule – Varied start positions

Allow various different start positions for the lords. Needs some thought to whom this should affect.

LOM: Gameplay Rule – Replenish Cup of Dreams

LoM – Locations that have a Cup of Dreams have the ability to respawn after x amount of time. This could be altered by the difficulty mode. Other ‘things’ could also be respawned. This would not be dissimilar to how DDR works.

DDR: Gameplay Rule – Armies continue to fight after attacking.

Currently in Doomdark’s Revenge AI Lords have the habit of leaving a fight. This option would make them act like LoM and stay until death or other lords leave. Another potential option would be for them to leave if they consider they are losing… Could also be linked to difficulty.

DDR: Gameplay Rule – Armies attack when near an enemy

Currently AI lords have the habit of not attacking enemies that are close by, unlike LoM. This feature would make them act more like LoM. Could also be linked to difficulty.

DDR: Gameplay Rule – Adjust lord death rules – Summer Solstice

In Doomdark’s Revenge the death rules for Lords should be tweaked to be more like LoM, meaning that can’t die until their army is wiped out. And not if attacking a critter with an army.

panel_map: Add Pinch and Zoom

  1. Add Pinch and Zoom to map for Mobile
  2. Add Shift and Mouse move for Desktop

Add guide and novella to embedded browser

Rather than open in a external browser, open the novella and guide in a embedded browser.

The Icemark was indeed a changed place

An interesting thing came from fixing the battle code in Doomdark’s Revenge, it highlighted a bug that is in the original code, that I can’t tell if ever caused an outward problem.

It is all to do with loyalty.

Loyalty in DDR is about race. Which race are you loyal to: Giants, Dwarves, Hearstealer, Moonprince… etc. When a lord recruits another lord, they become their liege and the new vassal becomes loyal to the same loyalty race.

When a AI lord moves in to a location, they check the loyalty of any lords present and if there is a difference in loyalty, they may attempt to recruit.

The problem is – if a lord who has vassals is recruited the loyalty of the vassals does not change, but the loyalty of the lord does. The liege of the vassals does not change either. So these lords have a liege of a lord who is not loyal to the same race as them. And they will potentially attempt to follow them or follow the same instructions. Even though they are technically the enemy.

Should the vassals ever find themselves in the same location as their liege, they are no longer the same loyalty so they will attempt to recruit them. In this instance the, the vassals becomes the liege of their liege, but their own liege does not change. Confused yet?

What we have here, is circular lieges.

Example:

Glormeon the Giant’s liege is Imagrorn the Giant, and Imagrorn’s liege is Varagrim. But let’s say Imagrorn is recruited by Carormand the Barbarian, then Imagorn’s liege is now Carormand, and his loyalty is to the Barbarians. But Glormeon’s liege is still Imagrorn, however his loyalty is still to the Giants.

The first problem here is that these two lords now see themselves as enemies or potential recruits. So they could fight or recruit. But also Glormeon will follow orders of Imagrorn even though they are enemies. Which may be tracking him down or following his enemies, or liege… and should Glormeon enter a location with Imagrorn he may attempt to recruit them. If this is successful then Glormeon’s liege would be Imagrorn and Imagrorn’s liege would be Glormeon.

In the original this situation would occur. Which I think really just messes with the AI. But in the remake, I traverse the liege tree to work out who is the overall lord in charge, and if we have a circular liege then the game crashes!

So the question is – how to fix.

So I remove the liege traversal and allow the original messy AI or do I break the liege link as soon as recruitment happens… ie: When Imagrorn is recruited and his liege changes to Carormand, then Glormeon’s new liege becomes Varagrim. Or should Glormeon remain loyal to Imagrorn and change his race loyalty to the Barbarians?

As a bug fix the first seems the quickest and keeps the gameplay the same. The other two options the potentially becomes gameplay rules.

This also doesn’t take in to account that the human player, ultimately The Moonprince, may be the loyalty race of some of these lords.

I am tracking the bug here on the GitHub repos for anyone interested.