Besides constructing horrible puns, I’ve been working on adding Daggerfall’s enemies into the toolkit. My first idea was to add something fast, but it turned into one of those rabbit-hole situations.
Sure it would be easy to just add basic monster templates, but wouldn’t it be great to actually import the correct enemies? Not just the fixed monsters like that first rat or imp in Privateer’s Hold, but support proper random encounter tables like those outlined in the Daggerfall Chronicles guide. And it all had to be easy to change once inside Unity, not just static information pulled from Daggerfall’s files.
The first thing I needed to work out was how did Daggerfall know which monster to spawn where? There are basically two kinds of enemy spawns, fixed and random. Both have an editor marker flat (from TEXTURE.199) in RDB blocks, so this was a good place to start. Fortunately, there’s only a few bytes of data in the record defining these flats, and for fixed monsters this was easy to find. The FactionID in flat resource structures also defines a monster (or mobile) ID. Basically, (FactionID & 0xFF) = MobileID. Range 0-42 are monsters like rat, imp, spriggan, etc. Range 128-146 are enemy adventurer types like Mage, Spellsword, etc.
Just to be sure I had this right, I wrote a quick tool to change IDs of every monster in S0000999.RDB (central dungeon block of Privateer’s Hold) then started a new game. As hoped, the first rat (ID=0) was now an Ancient Lich (ID=33), which promptly ate my level one character for breakfast. I tried not to think about all the ancient liches between myself and the dungeon exit.
I then documented everything into a spreadsheet by spawning each ID in turn, checking them in-game. This allowed me to build a starting template for each and every enemy’s texture file (male and female), animations, behaviour, affinity, corpse marker, and so on. The end result is EnemyBasics.cs where mobile enemies are simply defined. There are also new enumerations in DaggerfallUnityEnums.cs for MobileEnemies, MobileStates, MobileBehaviour, and MobileAffinity. This will be my foundation for adding enemy mobiles to the toolkit moving forward. I’m trying to keep everything just simple enough to get the job done. It’s up to you to build on from here.
I have added a new enemy name field to the DaggerfallBillboard editor script when you have a fixed enemy editor marker selected.
Next, I turned my sights on random encounters. Any Daggerfall nut knows about the various dungeon types (Crypt, Human Stronghold, Vampire Haunt, and so on), and that each dungeon type has a random encounter table described in the Daggerfall Chronicles guide book. I just had to work out which value defined the dungeon type.
Fortunately this was easy to find also. The upper 8 bits of the “Unknown2” value in a location’s MapTable data actually defines the dungeon type. It follows the same order as listed in the Chronicles, with Crypt=0x0033, Orc Stronghold=0x0133, Human Stronghold=0x0233 and so on. You can just shift right by 8 bits (DungeonType >> 8) to get the index. I’ve added this information back to the API in DFRegion.cs and MapsFile.cs so it’s all read in for you when loading a location. I have also added a field to the DaggerfallLocation editor script to display the dungeon type in your Inspector.
With that squared away, I created a basic set of random encounter tables, one per dungeon type, matching those described in Daggerfall Chronicles. This can be found in RandomEncounters.cs.
There’s obviously more to this, as the player’s level is also used to determine which monsters spawn from the encounter table, but this should be a good start and easy to build on. Like the enemy mobiles, my goal here is to make something just functional enough for you to build on with Unity. The more independent you are of the game files, the better.
Now that Daggerfall Tools for Unity has a good foundation of enemy definitions and encounter tables, I’ll be adding a foundation mobile type to the toolkit for ready-made enemies. When starting play mode (or instancing a dungeon from code) the editor markers will spawn an appropriate monster in-place. I’m going to help with this by setting up all the initial animation smarts, but it’s up to you to extend with spells, AI behaviours, pathfinding, and so on. The good news is that you can use all the typical Unity features and there’s a ton of great resources for scripting enemies in the Unity tutorials and on the Asset Store.
Time to wrap this post up. I’ll show more of Daggerfall Tools for Unity very soon, once the above data starts becoming visual.