Daggerfall Unity Now Playable Start to End

That’s right! The main story quest in Daggerfall Unity is now completely playable from start to end. I’ve spent the last couple of months playing through the story quest, building out engine support, and fixing all the major bugs I could find. It’s true this game still has a distance to travel (spell system is next major journey) but this is a huge milestone in the project’s life cycle. It’s no longer fair to say Daggerfall Unity “isn’t playable yet”, that’s not even close to accurate anymore. And thanks to regular contributors like Nystul, Allofich, Hazelnut, and Lypyl, some of the later features on the roadmap are building out ahead of schedule.

The quest system has consumed around a year of my development time to bring to this point. It represents the single largest group of features in the project so far, and drives almost every other gameplay system forwards. I feel confident in saying the magic system probably won’t be anywhere near as challenging. And once we pass that milestone, everything else is on the downhill run.

 

Getting Started

After you grab the latest DragonBreak build from Live Builds page, there are two ways you can play through the main quest. You can either start a new character and play normally (using quests offered by any Fighters Guild to help level up between main quests) or use the “setmqstage n” console command to force the game to a specific point along the main quest process. There are 7 total quest stages, thus “setmqstage 1” through “setmqstage 7” are supported. Each stage is a chain of around two to six quests that represent a particular story arc in the game. If and when new problems are found with main quest, testers can quickly restart and test just that stage without playing through the whole game from the beginning.

If you want to play the game as normally as possible, start a new character. Playing the game from start to end normally is also an important and time-consuming part of the testing process, so your time here is valuable, even if something breaks and you need to start again. But if you want to perform focused testing of the main quest, grab a high level character save and use the “setmqstage n” console commands. I’ll post more details in this forum thread as time allows. Please offer feedback in that thread or ask general questions, and post to Bug Reports forums with obvious bugs.

 

Stable Builds

The next step from here is to work towards a DragonBreak stable build and complete the 0.4 cycle. This might take several weeks as the main quest is a massive and complex system, there’s no telling what problems testers might run into. Once the stable build is ready, work will proceed on the spell system and 0.5.

 

Thank You

I also want to thank all of Daggerfall Unity’s contributors, supporters, mod-creators, and community members. You are all responsible for this project’s momentum, and for keeping morale high during those bleak periods of solid development where nothing visible seems to be happening. I am very excited for the future of Daggerfall Unity and the community building around it.

Cheers everyone!

 

For more frequent updates on Daggerfall Unity, follow me on Twitter @gav_clayton.

 

Dust of Restful Death

The main story quest in Daggerfall Unity is cracking along lately. The more problems I solve, the faster I can pass new quests. This has created a cumulative effect where things are snowballing towards the finish line. Today, I feel I’ve reached an important milestone with the main quest passing up to “The Dust of Restful Death”, only a few short steps from the end.

In this quest, the player briefly soothes the tormented bones of King Lysandus to learn why he requires vengeance. From a technical front, this is not only the result of a long chain of earlier quests, but required some new interaction between the world and quest system, and is the first quest to play an in-game cinematic.

There are bound to be problems and bugs to fix as the full story quest rolls out to testers, but for now let’s just enjoy this one quest where Lysandus has his big moment.

Vengeance Build 81

New builds are now available on the Live Builds page, bringing us up to build #81 across all platforms. A lot has happened over the last month, with steady contributions from long-time Daggerfall Unity developers Lypyl, Allofich, TheLacus, and Nystul. I would also like everyone to welcome on board new developer Hazelnut, who has built many valuable updates over the last month.

I’ll post a more complete list of updates towards the end of this post, but want to start with the big visual stuff that’s changed since last update.

 

Main Quest

The complete main story quest is now offered when starting a new level 1 character. Please keep in mind this is still under construction, so you are likely to reach a point where you cannot continue and may need to start fresh later (or use a console cheat). It could be another few months before all main quests are in a passing state, but I felt it was important to start offering to new players.

 

Main Quest Testing – Stage 3

I’ve pulled the wraps off stage 3 of main quest for testers. This includes a quest from Prince Helseth to blackmail Lord Castellian (S0000002) which follows onto recovering an unauthorised biography for Queen Barenziah (S0000011). This tome can be stolen by the necromancers if you don’t recover from Orsinium in time, leading to player needing to strike a deal with Gortwog for recovery. Will the player return the book to Barenziah as planned, or betray her and deliver the book to Gortwog instead?

  

 

 

 

 

 

 

Transport Menu

Hazelnut has implemented the transport menu for player to switch between Foot, Horse, Cart, and Ship. Until full shops are implemented, all level 1 characters will begin with a free horse, cart, and ship to play with. It’s a great feeling to tear around towns and the wilderness on a horse at long last. But as player housing is not yet implemented, you cannot store loot on your ship. Please keep this mind or anything you drop to the ship will be lost when you leave!

 

Item Info & Player Status Popups

Another Hazelnut update. He has implemented inventory info popups and world status popups. What you can’t see easily is this required a fairly large back-end system to expand context macros correctly across various systems. This work is also being used in several other places now.

 

Banking

The third big update from Hazelnut builds on earlier groundwork by Lypyl. Banks are now mostly operational. You can deposit and withdraw gold, convert gold to letters of credit, and even take out loans!

 

Selling & Repairing

If you’ve played one of the earlier interim builds, you might have noticed player encumbrance and weapon condition has been implemented. To complement this, Hazelnut has added selling and repairing items at stores. The selling and repairing gold values match classic very closely thanks to additional work by Allofich. Now you can finally tip out that wagon and profit from all your dungeon crawling.

 

Real-time Info Panel & Enhanced Item Lists

The final big-ticket item from Hazelnut is a real-time info panel for items which displays details as player moves mouse over an item. This is optional, but currently enabled by default for testing. A second option, which must be enabled in settings.ini (EnableEnhancedItemLists=True) will show an item grid of 16x tiles instead of the default 4x. This is excellent work that brings the UI forwards while maintaining classic style.

 

Enhanced Mod Support & Post-Processing

TheLacus has built out texture injection to support wilderness flat replacements, and added post-processing support for effects like SSAO, bloom, vignette, anti-aliasing, and more! Post-processing is currently available in mod form. Check out this thread on the forums for more information.

 

Talk Window & Discovery

Last but certainly not least is the NPC talk interface by Nystul. You can now bother town NPCs to ask for directions to local shops, with more features on the way. A huge thanks goes to Nystul for all of his amazing work on this system.

The talk window also complements my location and building discovery, as NPCs can direct you to nearby businesses if they like you enough (and know the place). Please keep in mind this system is still under development and NPCs cannot yet offer all the topics available in classic at this time.

 

More Gameplay

One of the most under-represented contributors by screenshot is Allofich. He contributes a great deal to the back-end formulas, reverse engineering, and general flow of game systems. These are all very hard to show in screenshot form, so make sure you have a skim through the patch notes to find more of his work. Some of the features he’s added recently include fixes to activation, residence greetings, and shop opening hours.

 

Conclusion

There’s no doubt that Daggerfall Unity is barrelling forwards. Thanks to contributors, new systems are starting to be built ahead of my original schedule. If this trend continues, some of the later gameplay elements are likely to be ready concurrently with upcoming work on spell system. Bundle this with all of the amazing mod work being done over in the Community Workshop forums. It’s just not possible to highlight everyone here, so please take the time to read through mod creator’s threads and give them feedback on their work.

Detailed patch notes follow for build #81. If you want more frequent micro-updates, please follow @gav_clayton on Twitter. Thank you for reading!

  • Shop opening hours and greetings. (Allofich)
  • Show up to 16x inventory tiles per list instead of 4x. Currently off by default. (Hazelnut)
  • Realtime info panel in inventory. Currently on by default. (Hazelnut)
  • Texture injection improvements and fixes. (TheLacus)
  • Main quest is now offered to new level 1 characters. (Interkarma)
  • Can now “start quest” by quest filename. (Interkarma)
  • Quest resources are now culled when placing them to a second location. This can happen when quest want to move item from one dungeon to another. (Interkarma)
  • Fixes to face display of static NPCs. (Nystul)
  • Fixes to quest execution flow. (Interkarma)
  • Cycle quest debugger display from Off/Minimum/Full (default is Minimum) using LeftShift+Tab. Off will also disable place markers on HUD. (Interkarma)
  • Quests will now always have a minimum of one day travel time. (Interkarma)
  • Implemented QuestSuccess flag. This is raised when quest calls “give pc” action. (Interkarma)
  • Can no longer remove quest items to remote container, except when item must be dropped as part of quest. (Interkarma)
  • Quest items are now removed when quest is tombstoned. Orphaned quest items in saves are purged on load. (Interkarma)
  • Soul gems with trapped souls now read from classic saves and displayed correctly in inventory. (Hazelnut)
  • Banks are mostly operational now. Can deposit, withdraw, take out loans, and convert gold to letters of credit. (Lypyl/Hazelnut)
  • Fix for quest item stacking issue. (Hazelnut)
  • Fix for bucklers stacking with two-handed weapons on paper doll (Allofich)
  • Boots and shoes now count as leather armour. (Hazelnut)
  • Cost calculations for selling and repairing. (Allofich)
  • Holiday text now displays when player enters a town during a holiday. (Allofich)
  • Slightly increased interior ambient light at night.
  • Post processing stack now available for camera effects like SSAO, bloom, etc. (TheLacus)
  • Initial talk window for mobile NPC interaction, ask for directions, etc. (Nystul)
  • Partial fix for mobile NPC precision issue causing them to glide north at spawn (Interkarma)
  • Fix for faction data pollution from bad saves.
  • Main quest stage 3 ‘setmqstage 3’ now enabled. (Interkarma)
  • Enemy names are now saved with corpse loot container. (Allofich)
  • Most shops now support selling and repair of equipment. (Hazelnut)
  • Implemented weapon material effectiveness vs. specific foes, e.g. silver to hit werewolves. (Allofich)
  • Prohibited equipment now restricted based on class settings. (Allofich)
  • Back-end tracking for starting crime guild quests Thieves and Dark Brotherhood. Quest line currently disabled. (Allofich)
  • Mobile town NPCs are now killable. No blood splash at this time. (Allofich)
  • Info click now supported on dead enemy mobiles. (Allofich)
  • Inventory weight and encumbrance. (Hazelnut)
  • Click distance check and fix activating through walls. (Allofich)
  • Improved artifact handling (Hazelnut)
  • Fix for starting Mynisera’s Letters. You should now be able to complete this quest, rounding out Stage 2 with only some bug fixes required (see below).
  • Improved enemy equipment calculations (humans and orcs will use their own armour and weapons for combat purposes). (Allofich)
  • Improved loot tables by dungeon type. (Allofich)
  • Location and building discovery like classic. Player will now need to discover locations through quests or exploration. Buildings are discovered as player interacts with them.
  • Exterior automap and travel map updated to support discovery. (Nystul)
  • Improved player movement speed calculation based on attributes. (Allofich)
  • New texture import support for billboard batches. This should allow mod authors to replace all foliage sprites in world. (TheLacus)
  • Fast travel countdown on travel map and fix for borders showing on zoom. (Nystul)
  • Transport menu: Foot, Horse, Cart, Ship now supported. (Hazelnut)
  • nfo popups based on item type and improved text macro support. (Hazelnut)
  • Fix for bucklers and two-handed weapons. (Allofich)
  • Fix to prevent fast travel with enemies nearby. (Allofich)
  • More combat sounds. (Allofich)

The “Fighters” Update

The Fighters Guild awaits

A whole new cycle of Live Builds is now underway for Daggerfall Unity 0.4. Here are some of the new features you’ll find in the latest “Fighters” update.

 

Quest System

The quest system is now open! Visit any Fighters Guild and speak to the usual quest giver to receive a random guild quest. Be sure to bring your strongest character, because quests span everything the Fighters Guild has on offer, from rats to liches.

Mordane Yeomham has work for you

 

While still incomplete, the quest system in Daggerfall Unity manages to kick things up a notch over classic:

  • No more binary QBN/QRC files and command line compilers! Quest scripts can be created with a simple text editor like Notepad and are based on Donald Tipton’s TEMPLATE v1.11 scripting language, the de facto standard for creating Daggerfall quests. If you’ve written Daggerfall quests before, you already have the skills needed to write quests in Daggerfall Unity.
  • Quests scripts are JIT (just in time) compiled by Daggerfall Unity. This means you can write new quest scripts and test them while the game is running.
  • Daggerfall’s classic quests have already been migrated to the new scripting language and many quests are perfectly playable in Daggerfall Unity now.
  • New features! Daggerfall Unity is already extending the capabilities of the quest system beyond what’s possible in classic, such as using location exteriors in quests. It’s even possible to write new quest actions in C# and extend quest system through mods.
  • The Quest Debugger lets you see what your quest is doing at any time by displaying the internal Task states and Timers, and helping you find buildings quickly. This debugger will continue to grow in power as the quest system develops. Note: Quest Debugger is always enabled in “Fighters” update. A toggle will be added once quest system passes tests.

 

Real Skills

Be prepared! Daggerfall Unity now has real combat formulas, including weapon and armour checks, dodging, critical strike, and more. If you take on a vastly more powerful enemy, you might not land a single blow.

How do you like me now?

 

Skill and level progression are now working. Your character will grow in power by playing the game and be able to level up at last. Skills like dodging and critical strike will be checked during combat, and skills like medical are checked during rest. Daggerfall’s level-up formula is applied on travel and rest, and you’ll go up in level once your skills have been raised enough.

Practice makes perfect

 

You can now set your interaction mode using F1-F4 (default keys). Use Info mode to find an NPC or building name, and use Steal mode to try your luck at picking locks. This even checks your Lockpicking skill against the lock using Daggerfall’s lockpick formula.

Maybe a more direct approach is needed

 

New UI Windows

The exterior automap will help you navigate around town locations. Named buildings are marked automatically for now, and the Quest Debugger will direct you to quest buildings until the discovery and “talk” systems are implemented. Like the dungeon automap, you can zoom, pan, and rotate the map. It’s great dragging the map around with left mouse button rather than using arrow keys.

Now, where was I?

 

The keybind interface will help you bind keys just like in Daggerfall.

No more editing text files

 

Wandering NPCs

Mobile NPCs now wander the streets during daylight hours across all climates in Illiac Bay. Meet Nords, Redguard, and Bretons in your travels.

Excuse me, do you know where I can sell all this orc blood?

 

The “talk” system has not yet been implemented in Daggerfall Unity, so you can’t yet speak to these wandering people to ask for directions, rumours, and so on. This will be coming sometime in 0.5 update cycle.

 

More Mods

All the mods that were previously integrated with Daggerfall Unity now have standalone updated versions from their creators. Available mods are on the Released Mods page of the forums. Please let the creator know if you encounter a problem with their mod.

You can now create art replacement mods for Daggerfall Unity. Check out the new Modding pages for more details on how to replace textures, sprites, models, sounds, and movies. A few great-looking art mods are already in the works, such as the Terrain Flats art mod by jman0war. He is hand-painting all new terrain art and it looks amazing.

 

And in case you didn’t know already, Daggerfall Unity has a runtime C# compiler, mod packager, and mod loader. This has been available for a while, but not a lot of people seem to know about it yet. Check out this page on the forums for more information on creating a Hello World styled mod in C# for Daggerfall Unity. You could even make a mod that adds custom actions to the quest system!

 

Get Involved

You can find the latest builds on the Live Builds page as usual.

For conversations, please use the following forum thread for all talk and bug reports for now. More information will be found in that thread to help you run quests.

 

Credits

I have the following people to thank for their contributions to the above features, in no particular order:

Allofich – For tirelessly working on skills, formulas, level ups, and researching classic save format. Some of the real gameplay features in this release would not have been ready without his efforts.

TheLacus – For creating the asset swap capabilities, documenting everything, and supporting people in their efforts to mod Daggerfall Unity.

Nystul – For the incredible automap user interfaces and mods he creates.

Lypyl – For the runtime C# compiler, mod packager, and mod loader. Also for his help with reverse engineering building data during early stages of the quest system.

JustinS – For his perfect keybind interface.

And thank you to everyone else who has contributed smaller fixes and patches on GitHub: muderbeard, midopa, electrorobobody, and more. Daggerfall Unity has only come so far thanks to the ingenuity and generosity of contributors. The combination of open source and a brilliant community will take this project a long way in the future.

Cheers!

Town Populations

I’ve had my head in the quest system for several months and really needed a short break. I also happened to need a solution for spawning enemies outdoors in cities (for example, the ghosts and wraiths in Daggerfall at night) and noted there was a good amount of overlap between spawning enemies and NPCs in town environments because they all need to avoid placement inside building geometry. And whatever solution I use for placement could probably be used for navigation as well. I had scheduled wandering NPCs for 0.5 cycle, but decided to make an early start on this while solving town placement and navigation. And what better way to test this solution than to actually watch NPCs walk around?

The first problem I had was how to find an appropriate placement position. My initial idea was to use the foliage placement array in exterior data. This formed a nice grid over each block, but it also marched over water and under buildings. That would not be suitable. I considered just dropping in mobiles and using a combination of rays and colliders to refine their position until they found open space, but that approach seemed way too messy and inefficient.

That’s when I had a eureka moment thinking about how perfectly automap image data lined up with the game world. Take the below screenshot as an example. In game, I’m standing outside the Odd Blades looking at the entrance door. On the automap, once unit conversions are done, I’m in exactly the same place.

 

So Daggerfall’s automap perfectly skins building footprints. This should mean I can take the inverse of automap data to work out which parts of the environment are open. I quickly prototype by placing white cubes on open environment and avoiding the building footprints. Take a look at the results.

 

This is beyond perfect. The automap doesn’t just contain data for building footprints, but for flat placement and decorative geometry as well. I have a strong suspicion Daggerfall also uses the automap data in this manner, it’s just too precise and detailed to be a coincidence.

With a solution in mind, I now have to execute the idea. I create a new class called CityNavigation which is added to the location GameObject at scene layout time by StreamingWorld. This constructs a navigation grid at the same time location and automap data is read so only a small amount of additional processing is done per location. With the inverse of automap blocked out, we get the following:

This is good – the white areas can be used for placement and navigation, but it’s not perfect. It also needs to account for tilemap under location. We can’t place NPCs on water tiles, and they should try to avoid those tiles when walking around. Rather than just block out unwalkable tiles, I take this one step further and allocate each tile a specific weight, where a higher weight means the tile is more favourable. Here’s the final navgrid where black areas are “no-go” and brighter areas are preferred over darker areas. You can probably see right away this creates a strong preference for the road network:

 

What you can’t see in the above image is that each weight occupies the upper 4 bits of a single byte. The lower 4 bits are reserved for a flag system, giving me up to 4 bits to control NPC behaviours. This will be important later in this article.

Now that I have a nice procedurally generated map of any exterior location, the next problem is converting between all the different coordinate systems. If you’ve ever tried to make a big world in Unity, you’ll know that precision problems kick in after a few thousand scene units or so from origin (position 0,0,0 in world). This manifests itself through jittery movement and shadows, imprecise feeling of control, and issues with physics system. The game map in Daggerfall rocks in over 819,000 x 409,000 scene units, way beyond what Unity can handle with fine floating-point precision. I overcame this challenge very early on by using a fixed point coordinate system for the world (Daggerfall units) and normal floating point units for the scene (Unity units). The world is built around the player in chunks close to origin, and when player runs too far in one direction, the whole world is brought back towards origin. To the player it feels like they are running continuously through a huge open world, when in fact the world is being constructed around them one chunk at a time. The player never moves more than 1000 units from origin in the X-Z plane.

What does all of this have to do with the navgrid above? Well, now I have yet another coordinate system to glue together. I have not only the Daggerfall units and Unity units, but the X,Y position inside the navgrid array where any virtual mobile objects have to move around. So the next thing I do is write some helpers in CityNavigation to convert from navgrids to world space, world space to scene space, and back again, and so on. This chewed up a solid chunk of Sunday to get working properly, and there’s still a few precision issues due to the large differences in scale. Something to refine down the track.

With all the math out of the way, I can now start placing mobile NPCs into the world. One problem though, I hadn’t written any code to render wandering NPCs yet. So I started with these guys just to confirm the navgrid through scene conversions were working. Sometimes in game development, you have to bust out some programmer art to get the job done.

 

With placement working, next came the process of building the mobile NPC billboard properly – including that stop-and-stare thing they do when you get too close to them.

Town NPC Billboards

With rendering done, I can start moving them around the navgrid using a simple motor. They will generally follow roads when encountered (because roads have a higher weight), but there’s enough randomness to let them change directions and wander around elsewhere on the grid.

And do you remember me mentioning the navgrid can store flags in the lower 4 bits? The first flag I created is an “occupied” bit that lets a mobile claim a navgrid tile before walking into it. This prevents two or more NPCs trying to occupy the same tile at a time. The next clip shows the mobile movement, path following, and dynamic avoidance of each other. I’ve cranked up the spawn count and movement speeds because it helps me observe the behaviour (and it’s kind of fun to watch).

Mobile Pathing and Dynamic Avoidance

Despite everything accomplished, I still have more to do. The next step is working out which races are placed in which towns. I put my travelling boots on and tracked around classic Daggerfall’s world until I found which races appeared in which climate zones. I built this into the helper which returns climate data for texture swaps, etc. and now the correct NPC races (either Redguard, Nord, or Breton) will appear across the game world.

 

The final step was to build a PopulationManager class. This code handles spawning/despawning of NPCs around player as you move through town environments so the location feels populated. After a bit of experimentation, I used a population index per 16 RMB blocks so that small towns feel like they have a smaller overall population than large cities. One of my challenges here is the draw distances in Daggerfall Unity are huge compared to classic Daggerfall. While classic can place NPCs safely in the fog out of sight, in Daggerfall Unity you can see two full city sizes distant across the map. This means that hiding pop-in and pop-out of NPCs is a little trickier. For now, I mitigate this by trying to only show or hide NPCs when player is not looking directly at them (as Daggerfall does) and only allow them to pop-in when a certain distance from player.

There’s still a few bugs to iron out. You can still catch them pop-in nearby if you happen to look in the right direction at the right time, and they sometimes glide slightly in the wrong direction on spawn due to precision issues as they align to the grid. And of course you can’t talk to them yet, because the “talk” system won’t be introduced until 0.5 sometime. But overall, the feeling of crowds is quite satisfactory and Daggerfall-ish, and it’s wonderful to finally see these sprite people bustling around cities.

I hope you enjoyed reading about some of the work that goes into creating even a small feature like this one. If you’d like to read more, I try to post regular micro-updates to my Twitter feed @gav_clayton.

 

Closing The Loop On Quests

For the first time yesterday, I was able to run a full quest in Daggerfall Unity from start to finish, and I’m very happy to say that a sizeable chunk of the quest system is now implemented. Following is another quick visual diary on what I’ve been working on lately. Where possible, I’ll share some information on what the quest system is doing in the background. There’s also a new video at the end.

 

Guild Quests

I have partially implemented guild quests with their usual service providers. Visit the quest-giver NPC in any Fighters or Mages Guild across Illiac Bay to receive a quest from a curated pool that is “mostly working” in Daggerfall Unity. This system helps me set the scope for testers, and introduce new quests over time as more of the quest system is built. Let’s take a look at this in action by following a quest from start to finish.

 

If you have  a sharp eye for Daggerfall quests, or have ever written one yourself, you’ll notice a lot is happening in the screenshots above:

  • Quest-giver NPC is identified by faction ID and the guild service window shows “Get Quest” as it should for that NPC.
  • The quest offer process is in place for you to accept or refuse job offered.
  • Many text macros are expanded automatically – such as random monster name, target location, player’s race, current region, and so on.
  • Reward is being randomly generated based on quest script.
  • Travel time is calculated from world using same logic as travel map, ensuring player has enough time to travel there, find the item, and return back.
  • The quest log information is generated and stored in the journal with current date, return location, quest-giver NPC, target monster, and how long you have to complete quest.
  • The quest-giver (Mordyval Moorhart) has also been tagged as the Questor NPC for this job. The quest system will keep track of your clicks on this person to know when you’ve returned with the wrappings.

If you travel to the named dungeon and explore it thoroughly, you will eventually find the mummy who is the target of this quest. If you don’t want to search you can use the ‘tele2qspawn’ and ‘tele2qitem’ console commands to teleport directly to the target spawn or item markers in dungeon. However you find it, kill the mummy and the target quest item is placed in its inventory for you to loot along with other randomly generated treasure.

Here are some of the things the quest system is doing under the hood in the above screenshots:

  • Tracking when player visits target dungeon and injecting the mummy into world.
  • Capturing script events like “injured foe” and “killed foe”. In this particular the quest, the mummy wrappings are placed on the monster when you injure it.
  • Tracking quest items, setting their background green, and displaying scripted text after picking up the mummy wrappings.

Now it’s time to return to Mordyval Moorhart for our reward.

In this step, the following stuff happens in the background:

  • Quest script detects you have clicked on the Questor NPC with the target item.
  • The QuestCompleted text is shown for a successful outing.
  • A loot container opens with your agreed-upon reward.

In classic Daggerfall, if you accidentally close the loot window without getting your reward that item is lost. I’ve made a small change where the reward is placed into a dropped loot container at your feet if you forget to collect it. This at least gives you a second chance to pickup your loot.

 

With all of the above working, this closes the loop on the quest process for a whole bunch of quests. It’s not just mummy wrappings, a lot of quests involving item hunts and killing monsters all operate inside this same framework. Where things fall down right now is with some of the special script actions that add flavour and complexity to quests. These remaining quest actions and conditions will be built out over time until quest system is at 100%.

 

Escort Quests

Sometimes a quest will ask you to take an NPC somewhere, such as rescuing the below person from a giant slain as part of a Fighters Guild quest. It seems the giant had been keeping this person for a snack.

A lot is happening in the above side-quest:

  • The quest script selects at random from a victim NPC, a map reward, or no map and no victim. In this case, the victim NPC was selected.
  • The random NPC Lysausa Gaerwing and her home town of Crosswold Borough are generated, giving her a bit of a backstory.
  • According the quest log, she wants to be delivered to Lord Mordoryan’s Wares, a shop in Oxville. Note the %g2 pronoun macro isn’t working yet. This is on my todo list.
  • When accepting the escort, a portrait (which usually does not resemble NPC flat in world) is added to your HUD to show this person is journeying with you.
  • The quest system tracks when player enters target building, displays the scripted popup, and removes NPC from your HUD.

 

Artifacts

A smaller task than above, but still necessary for the quest system is the ability to spawn artifact items. These special items are created by merging two sets of template data together to form one very powerful item with a larger than usual number of enchantments. While magic system isn’t in the game yet, certain groundwork still needs to be implemented. Because I’m looking at spells and effects in the update chain immediately after quests, now is a good time to start thinking about this stuff. Artifacts are still at a very early stage, and I might not return to them for a while.

The character above is holding Chrysamere from a quest script intended only to test these items can be generated by quest system. A big thanks to all the people who sent me their saves so I could test artifact import and creation. I still have some bugs to fix, but I’ve made a good start on this.

 

Conclusion

The quest system is doing great. It’s still a ways from being finished, but all the hard problems have been solved and now I’m just building out support for remaining actions and conditions, and fixing bugs along the way. The next items on my list are multi-spawn foes (e.g. kill 6 rats in a house) and more work on text support (like the %g family of pronoun macros). There’s bound to be a few more articles to go before I can call quests complete.

If all goes well, I should have the first real test build with the quest system in current state available in 2-3 weeks. This will have the Fighters and Mages Guild quest system in place for testers to run through available quests and help me find bugs. You’ll also be able to use ‘startquest’ console command to launch whatever quest you wish, even quests you write yourself, but things might not work properly if you go too far off grid for now. I’ll post more about the test build once it’s ready, including any limitations in the build at the time.

Thank you for reading! If you would rather watch quests in action, following is a pure gameplay video of Daggerfall Unity, except I’m using the console cheats to teleport to objectives in dungeons for the sake of brevity.

For more frequent updates on Daggerfall Unity, follow me on Twitter @gav_clayton.

NPCs, Items, Enemies, Quest Debugger

I’ve been hard at work the last couple of weeks, finally making serious inroads into the real meat of the quest system. Here’s a quick diary of my progress since last post. If you follow me on Twitter, you’ve already seen most of this, although there’s a new video at the end you might enjoy.

In the last post, I talked about using buildings as quest sites. This has allowed me to start work on placing NPCs, items, and enemies as part of quests, and to support branching quest execution based on where player is in world.

When a named NPC is reserved by quest system, Daggerfall Unity handles all the book-keeping to move that NPC to the quest site. I tested this out using King Gothryd at first. Once the new quest site is determined and Gothryd is reserved, scene builders will no longer deploy him at the usual home location – unless the quest specifies the atHome flag at time of NPC reservation. In screenshot below, Gothryd has already left for the quest site.

 

The quest system then generates a SiteLink between target Place and Person resources. When the player visits the target location, scene builders need to place Gothryd at that location. Here’s Gothryd at the end of his journey.

 

I wanted to take a short break from NPCs and moved onto items briefly. There’s a few different ways Daggerfall uses Item resources in quests. They might added directly to your inventory, placed in a dungeon, or used as a permanent reward. Different quest conditions will also trigger based on whether player is carrying a certain item or not. I still have a lot to do here, but have made a start on the first case – adding an item directly to player inventory. The parchment with a green background below is the first real quest item in Daggerfall Unity. Specifically, it’s the letter from Brisienna.

 

At this point the quest engine is getting advanced enough that I need more detail on what’s happening under the hood at any time. I put together a quest debugger that shows the various Task and Timer states for a running quest. I plan to make this capable of step-through execution in the short term. The debugger shows which tasks are active/inactive and which timers are pending/running/complete. After setting this up, I could finally resolve many bugs in execution flow. I also added proper support for persist-until tasks, global variable links, and rearming tasks designed to switch on and off.

 

I’m pleased to say the quest system is all coming together rather quickly now. There’s still a huge amount of work to do, but most of the hard problems have been solved now and I’m just building out action support and fixing bugs. Here’s a little video of the current state of the quest system. Some of the early quests are working nicely now.

As a bonus, this video also shows the new skill tracking and player levelling by Allofich. Yep, it’s possible to level-up in Daggerfall Unity now thanks to his efforts. Great work Allofich!

Quest Buildings And PcAt Condition

Now that buildings and NPCs can be identified in the game world, I can finally start linking together parts of quest system to world. The clearest starting point is quest buildings, as a majority of quests in Daggerfall will send player to a building somewhere in the world.

If you’ve been following my progress on quest system for a while, you already know a lot of technical progress has been made on the back-end. Without forcing you to recap on past articles, here’s a brief summary of quest system in its current state:

  • Quest scripts are generated by Template v1.11 by Donald Tipton. This has long been the go-to solution for adding new quests to classic Daggerfall. By adopting this scripting format, it becomes possible to compile scripts between both Daggerfall and Daggerfall Unity for testing. And it means anyone with experience writing quests for Daggerfall can already write quests for Daggerfall Unity.
  • Daggerfall Unity has a JIT quest compiler which builds quest scripts at runtime. This means you can edit, start, and stop quests without once closing the game. This will be even more useful once the Quest Inspector UI is ready.
  • The QuestMachine execution environment runs compiled quests like small virtual machines inside your game session. It interfaces with the world and does all the necessary housekeeping for running quests.
  • Quests are made up of resources (Place, Person, Item, etc.) and Actions (perform some task). Some actions are also conditional (do task when condition is true). Almost all of Daggerfall’s high-level gameplay is driven by the quest system. Even some things you might not expect (such as Lysandus screaming VENGEANCE! at night) are accomplished by quests.

 

When adding building selection to game, one of my first problems was how do I locate the building in whatever town player is in. Daggerfall Unity doesn’t have wandering NPCs to mark buildings on your map quite yet. Not a problem for named buildings like taverns and shops because these are visible on the automap, but what about some random residence in town? How do I get the player there for testing?

The solution I landed on was to add a simple quest compass on the HUD. This will show the direction, name, and distance to target door. Fortunately, I already track building entrances in the world. What’s needed is to build a set of marker positions based on active quests. I start by just adding a test sphere on quest target doors.

 

That blob above sits perfectly on the door to my quest building. Now I need to show that as text and distance. The HUD text overlay below align with doors in camera space and show distance to multiple targets.

 

And finally the building name. This marker can direct quest developers straight to all active quest sites in their current location. Of course, anyone will be able to turn this on from the quest inspector UI if they would like a quest compass. I’m almost certainly going to expand this system out for quest items in dungeons and other targets in the future.

 

I can now enable the quest journal, something Lypyl implemented perfectly some time back. I wire up the keybinds and UI to allow player to open quest journal, and find logged quest information sitting there as expected.

 

What you can’t easily see above is that some text macro support has been added as well. For example, %pcn resolves to player’s full character name, _buildingSymbol_ expands to building name, __buildingSymbol_ expands to location name, and ____buildingSymbol_ expands to region name. This is all part of the text engine inside Daggerfall I’ve had to reimplement in Daggerfall Unity.

With local building support out of the way, the next step is remote buildings elsewhere in the same region. This involves a bit more work, but in a few hours it’s possible to send player anywhere in the game world.

 

The final piece is to implement PcAt conditional action, which detects when player has entered target building and does something. In this test quest, I just display a popup and end the quest.

 

This is an important milestone for questing in Daggerfall Unity. It means a lot of the hard groundwork has been completed and the real work, the stuff visible to the player, can commence. This is a huge relief for me because I can finally show off my progress in a meaningful way with screenshots and videos. As important as all the code back-end is to outcome, its been very difficult to show progress which sometimes makes it feel like nothing is happening.

To celebrate visible progress, here’s the first video of Daggerfall Unity’s fledgling quest system in action.

 

For more frequent updates on Daggerfall Unity, follow me on Twitter @gav_clayton.

Identifying Buildings And NPCs

In my last post, I talked about the “Place” quest resource and merging map-level data down to block-level. The next step from here is to propagate this information to scene-level where the player ultimately lives. I decided to tackle this along with a start on Daggerfall’s interaction modes, i.e. Steal, Grab, Info, Talk which are by default bound to keys F1-F4. What I’m most interested in here is the ability to perform an info click directly on a building to discover its name.

First step was to quickly implement the mode switch itself. Key-kinds were already in place inside the InputManager class, all I needed were a few more lines of code to track which mode player was in and a new HUD label to present switch to user. After several minutes it was possible to flip between the 4 interaction modes.

 

Next, I needed a way of detecting when player clicks on a building. I already track player clicks in PlayerActivate class, and can detect clicks on static scenery and doors, but not on the building model itself. I go to work looking for an efficient way to manage this. Each Daggerfall model contains a radius value stating the overall size from its centre point. This seemed like a good place to start, so I overlay the radius as a sphere collider on test buildings.

 

Keep in mind that I’m not storing individual building models at scene level, the entire block of buildings above is combined into one large model. This is more efficient for rendering and results in fewer draw calls to the graphics card. So I don’t know which building player has clicked on – I just know they’ve clicked a combined block model and I need to resolve that back to a specific building. The sphere colliders would do the job, but they unfortunately suffer from a lot of overlap. Depending on where player is standing and where they clicked on the building, it’s possible for that target point to be inside two or three different building spheres. There are ways of handling this of course, but I decided to go with box colliders instead that will tightly wrap Daggerfall’s little box houses.

Before I can implement boxes, I had to go right back to the procedural mesh builders that extract data from ARCH3D.BSA (Daggerfall’s 3D model archive). During the vertex conversion process, I added some tracking for minimum and maximum vertex positions from origin to get the overall size of models in X, Y, Z space. Because the models are being constructed procedurally, and I have to process that information anyway, this step adds almost no overhead to the job of loading models at runtime. I now have what I need to construct a tight bounding box around any model effectively for free.

Then I just had to pass that information to scene builders. The end result looks like this.

 

Every building now has a nice crisp bounding box trigger collider. While this is great to visualise the bounds, I’m not happy with adding so many GameObjects to scene. A large city like Daggerfall will add around 800+ new collider GameObjects. If a few large cities are in the world at once, then it’s very possible that 2000-3000 colliders would be added to scene, the majority of which will never be used. Not ideal from an optimisation point of view.

To work around this, I used the same solution I came up with for doors. I store the box information for every building on the block GameObject itself using component DaggerfallStaticBuildings. This is just a small amount of raw data stored on each block. When the player clicks on a block in scene level, a single box trigger is instantiated and tested for each of the buildings in that block, usually no more than 5-14 buildings. The world-space point of impact for hit ray is tested against known buildings in that block (and only those buildings). If a hit point intersects with a known building trigger in world space, then everything we need to know about that building from scene layout time is returned to PlayerActivate.

The end result is zero new collider objects in the scene and only a small amount of overhead for storing building data and testing hits, which happens only when the player clicks on a city block. The net result has practically no performance impact and still fits nicely hand in glove with Unity’s physics setup. With all of that in place, player can finally make info clicks on buildings in scene.

While I was working on this, I decided to add shop quality text. When the player enters a shop in Daggerfall, the overall quality level is presented to player as a popup. Each shop has a quality value between 1 and 20 with a total of 5 different quality popups. I’ve long assumed it was just qualityValue/4 to get the popup, but testing proved otherwise. Daggerfall weights the quality text a bit more in the mid-range that the extreme low or high ends. After checking shops in Daggerfall city and Gothway Garden, I think I have the weightings worked out. Anyway, It’s something that can be easily tweaked later if needed. Now when player enters a shop, the quality text will popup like in classic.

 

Because the popup actually prevents player from entering building until they click a second time, I added a quick INI option to present quality text to HUD instead, with a configurable delay. With this option configured in INI (ShopQualityPresentation=1), you can enter every building with a single click and watch the quality text scroll off HUD. You can also set ShopQualityPresentation=2 just to turn off quality text completely.

 

While I was on a roll with the whole info setup, I made a start on identifying static NPCs. These are the flat people standing around inside buildings and interior environments like Daggerfall Castle. This will be critical to dialogue as part of questing system eventually, so might as well break some ground for later. The first part of this was simple, just detecting when player clicks on an NPC.

 

Yep, that’s an NPC alright. Exactly how an NPC is detected had to evolve a little over the process of getting this initial text in place. I previously did this by detecting if the billboard had a faction and a gender – something I assumed only NPC billboards would have. This turned out not to be the case and there are plenty of factionless NPCs standing around. Also, the NPCs in building interiors had a different metadata setup to NPCs in dungeons. Just like Daggerfall to use two different data structures for effectively similar things. I ultimately determined NPC status by the texture archive flat belonged to. There are a small range of NPC-specific texture archives and this served better than faction to determine if player has clicked an NPC or not. In the process of doing all this, I actually gained some better understanding of a particular bitfield and found a new gender bit assigned to NPC records.

Before I can identify an NPC properly, I need to use their faction information. An NPC with faction type=4 is an individual NPC which means their name comes directly from faction data. Other NPCs just get a random name generated based on their gender. So before diving any farther down this rabbit hole, I have to implement factions for the player.

I had written faction file reader around a year ago, but this just reads the initial database from FACTION.TXT in game data. In Daggerfall, this initial faction data is assigned to player character at time of creation and persists with player all through their adventuring career. Every interaction can raise or lower their standing with a particular group. To start tracking faction data properly, and to make this information available to NPC info clicks, I added the PersistentFactionData class to player entity. This class represents the player’s current standing with all factions and provides basic lookup functionality. This has already been wired up to save/load system, so when you save a game in future builds, your faction data will be saved as well. This is also an important milestone for the questing system.

With faction data on the player, we can identify individual NPCs like King Gothryd and Queen Aubk-i.

 

But it means that group-based NPCs don’t resolve properly by faction alone.

 

These NPCs need to have a random name based on gender. Thankfully I’ve already written the random name generators, as these were required for building names and elsewhere. The only thing I’m missing is the correct seed value to generate the exact NPC name that Daggerfall uses. For anyone unfamiliar with random generators, the same seed value will always output the same result. Unfortunately, I wasn’t able to find the seed value Daggerfall was using to name NPCs. You’d think this would be obvious like it was for buildings, but sadly not. I decided that one random name is probably as good as any other for these non-essential NPCs and just used their record offset as a seed value. This means they will always have the same persistent name generated each time, it just won’t be the same name as in classic. If the correct seed value is ever located, I can just feed this into the generator instead and the correct name will pop out. Until then, it probably doesn’t really matter. Say hello to random NPC Alabyval Coppersmith.

 

At the end of this little coding adventure, all of the following has fallen into place:

  • Change activation mode between Steal, Grab, Info, Talk.
  • Identify buildings and static NPCs.
  • Shop quality text is now displayed when entering a shop.
  • Faction data now exists on player entity and persists with your save games.
  • The foundation for checking NPCs in scene are ready for “Person” quest resource.
  • The raw data needed for “Place” quest resource now in scene.

With all that done, I can go back to working on “Place” resource and “pc at” condition for quest system. You can see what a rabbit-hole this whole quest setup is. It touches on so many different parts of gameplay that sometimes I need to go in a different direction for a while before I can loop back and progress on what I’m trying to build. But it all adds up, and every tiny step brings us closer to real gameplay.

For more frequent updates on Daggerfall Unity, follow me on Twitter @gav_clayton.

Questing: Place Resource

I’ve decided to go in a slightly different direction regarding dev articles about quest system from now on. Instead of the traditional numbered sequence split into a few parts, I will post more about what I’m working on in the moment. There are two reasons for this. First, questing is a huge subject that resists being neatly split into a progressive narrative like items or streaming terrain. I often have to cross back and forth between related systems. Second, it gets a bit daunting trying to construct that narrative from such fragmented work. The end result is that I’m posting less and feeling more weight on my shoulders every time I try to construct a post. Just how do I describe to everyone I spent weeks working on research without a satisfying answer to a particular problem?

My solution is to tear the band-aid off and just post something. I’m slowly learning that many people enjoy the development process itself, including the potential for frustration and dead ends. Those outcomes aren’t particularly enjoyable for me when they happen, but maybe I can turn them into something positive and entertain my readers. This should result in more posts but they will often be shorter (which in itself might be a good thing). This post probably won’t be shorter, but it is my first in a while. 🙂

So here’s what I’ve been working through lately…

In a QBN section, Daggerfall quests defines resources that kind of glue the whole shebang together. They define places in the world, people to visit, timers, items, and enemies. Basically all the world-stuff player will contact to unroll that quest’s execution. A high-priority resource is Place, which defines locations the player must use in the quest, like a dungeon, shop, or residence. Here are some examples.

Place _mondung_ remote dungeon9
Place _house_ local house2
Place _inn_ local tavern
Place _palace_ remote palace
Place PiratesHold permanent PirateerHold1

To deconstruct the above: Place tells the compiler this is a place resource; _symbol_ is the name of that place for the compiler to reference; remote/local/permanent is where to select that place from; and the final bit is site which tells quest engine what type of place to select. The site code is actually a reference to a places data table which defines the parameters for these site types. I won’t go into these in much detail, just keep in mind they define what kind of building or dungeon to select.

Let’s use “local tavern” for now. This means find a random tavern within the same town as where player received quest. If this was “remote tavern”, we’d select a random tavern from another town in the same region. The site code “tavern” is then looked up in the places data table and the parameters tell us this is building type 15 (0x0F).

Now the quest engine knows it needs a tavern (building type 15) and it should select from the map player is currently in. Fortunately, Daggerfall keeps a handy list of buildings for every map definition in MAPS.BSA. This gives us information like the building name seed, faction, quality (“rusty relics” through “incense burning”), and best of all building type. Great! We already know we need a tavern, and it’s trivial to select taverns from this list of buildings and grab one at random. Now we have our quest location… well, almost.

A Daggerfall city is made up of geomorph-like blocks – up to 8×8 blocks for really big cities. They are like puzzle pieces laid out on a grid. Here’s the block layout for the City of Daggerfall, you might recognise this from Daggerfall Modelling.

 

Every block also carries a list of buildings it contains, sharing the same data structure as MAPS.BSA – with a few differences. One key difference is that a few of the values present at map level (e.g. name seed) are not present at block level. The reason for this is obvious when you consider how often blocks are reused across locations. If the name seed was stored in block data, our tavern would have the same name in every location that block is used. Thus the name seed is carried at map level and merged down to block level as needed. Same goes for the block texturing, which changes based on climate. Put together, this all makes blocks somewhat polymorphic in that they can take different forms depending on the location they belong to.

Back to our tavern which we found in building list at map level, how then do we map this to the actual physical building at block level? Besides other jobs like setting the correct names on automap, this is needed to determine correct physical location of quest buildings in the world. This is where some of my troubles started.

At time of writing, it is unknown exactly how Daggerfall links building data at map level down to building data at block level. To compound my problems, only a subset of buildings are represented at map level. A large city like Daggerfall will have many more physical buildings than listed for that location in MAPS.BSA. Even in small locations where the totals match, the individual building type counts don’t always match. For example, map data might define 6x House1 and 4x House2, while block data will contain 5x House1 and 5x House2. There doesn’t seem to be any consistent way to link these two sets of data together. If this were a relational database, I would expect a stable primary and foreign key matching on both sides. But not only does a key not seem to exist between them, the totals cannot be trusted to line up between map and block buildings.

Despite this, I have been able to make some good progress. I discovered that named buildings (taverns, stores, guilds, etc.) are always in the same order in the map building data as the block layout data. Couple this with the building name seed discussed a while back, it’s possible to merge down named buildings without much trouble. This is also needed for the automap like below. Credit goes to Nystul for the excellent automap implementation.

 

When it comes to generic premises like House1/House2, things become more difficult. I can’t depend on an exact match between building type distribution, and can’t find a way these could possibly be linked in a stable manner. Both Lypyl and myself have been through the binary data in great detail. Despite finding a few other interesting leads, we have not found a satisfying answer to the question of mapping non-named buildings from map level to block level.

After many frustrating weeks of searching, I’ve more or less come to the conclusion that it really doesn’t matter. The only buildings that need to be mapped 1:1 are named buildings, and I already have a working solution for this. When it comes to generic premises (which are selected randomly anyway) it should not matter which House1 or House2, etc. Daggerfall Unity selects for a quest. As long as the end behaviour closely matches that of Daggerfall by selecting a building of the correct type, I’m basically free to implement this in a manner suitable for Daggerfall Unity.

In hindsight, the apparent lack of stable linking between map and block data could account for some quirks in Daggerfall itself. For example, it’s not uncommon to find a tavern which Daggerfall thinks is a residence. And only about half the buildings in most towns can be entered anyway (“this house has nothing of value”). My feeling now is that when a location is loaded, Daggerfall simply distributes map building data amongst block buildings using some kind of algorithm where named buildings are populated first and generic buildings are distributed to best effort. As long as named buildings are handled (they are), and other buildings are selected randomly (they seem to be), then I can at least reproduce this behaviour in a way that feels exactly the same to the player. My solution might not be exactly what Daggerfall is doing, but it’s likely very close.

So that’s where I’m at right now – working through implementation of Place resource, selecting locations in the world, and ensuring this maps to physical environment correctly. During this process, I’ve added some fun bits along the way such as the flavour text when entering a dungeon area outdoors. This text is based on dungeon type and reads from strings in Daggerfall’s text database using the same variations.

The other side of a Place resource is the “pc at” condition which tests if player is at a Place or not. This is highly intertwined with Place resource handling so I’m likely to bounce back and forth between these two for a while until I’m happy.

That’s all for now. Rather than go through a long delay between posts again, I’ll try to post as regularly as possible with updates on what I’m working on at the time. Even if the post is short, I’ll try to put in some details of the development process for you to read.

If you enjoy this sort of post, please let me know! Feedback helps me work out what people enjoy reading and hopefully write better posts in the future. Thank you for reading, everyone. 🙂

It Lives!

With some back-end and core actions out of the way, it was incredibly satisfying to watch the quest system spring into life today. The two bootstrap quests are now launched with a new character. They don’t do much more than popup messages right now, but everything starts somewhere.

The work from here is “just” building out all the remaining actions and conditions for quest scripting. I say “just” because it’s still a huge amount of work. But it’s finally starting to feel like I’m getting somewhere!

If this doesn’t look like an awful lot of progress for a few months work, remember it’s a black triangle milestone. This is a pioneer of more interesting stuff to come.