Questing Part 2 – Compiling

In the first part of this series, I discussed how I’ll be using source files output by Tipton’s Template v1.11 for quests in Daggerfall Unity. If you’d like to check these out in full, the quest source files are already on GitHub. Follow this link to view them (ignore the .meta files).

Some interesting quest files to investigate are:

  • _BRISIEN.txt – This is the quest that launches when player starts in Privateer’s Hold. It sets the whole story arc in motion and starts timers for delivering letters that prompt player to visit Lady Brisienna. Failing to visit Lady B in time is ultimately a failure condition of main quest.
  • S0000999.txt – Starts when you leave Privateer’s Hold. Delivers letters from Prince Lhotun and Morgiah and sets key global variables.
  • S0000977.txt – Also starts when leaving Privateer’s Hold. Sets up regular ghost and wraith spawns in Daggerfall and plays the VENGEANCE! sound.
  • TUTOR.txt – Is the tutorial quest started when selecting Yes to the prompt at start of game.

As another interesting tidbit, longtime players may have noticed the initial journal entry that begins with…

"I am on a mission from the emperor to investigate
the shade of King Lysandus. His spirit has been
haunting the city of Daggerfall. The emperor
himself has charged me with the duty of laying
his ghost to rest."

…will stick around in your log forever. Even after you’ve completed the game, this first journal entry will remain. As part of researching the quest system a while back, I looked into why this was happening and found the above journal entry is added twice and removed only once. The below image sums it up visually. You may have already seen this when I posted it to Twitter back in September.

 

questlogmessagestuck

So the quest system in Daggerfall is quite powerful. It’s responsible for adding and removing journal text, starting timers, delivering letters, spawning enemies, playing sounds, setting global variables, moving NPCs, and a slew of other functions. At first blush it can appear a lot like a full programming language, but it’s only superficially so. The structure is actually more like a complex INI file, or even a kind of markup file. Everything is neatly categorized into its own section and execution flow generally only happens in a few different ways. Most commonly are at startup, when a timer ends, and due to a variable or condition changing state.

Thus despite the initial similarity to a programming language, the quest source is really just a collection of defined objects with some very basic scripting functions. Most of these functions revolve around spawning something, starting something, playing something, or changing something. Complex enough to get the job done, but don’t feel like you need to be a programming expert to create new quests in the future. Using Tipton’s Template v1.11, you could even start creating quests in classic Daggerfall now and later port them into Daggerfall Unity.

Likewise, the job of compiling the quest source back into Daggerfall Unity is not that difficult. It’s going to have some challenges, but nothing on the scale of building a real compiler, something I thought I’d be facing at the outset. The problem is largely just splitting source file up into correct parts and handing that source off to classes designed to support that part. For example, messages will go to a Message class, timers will go to a Timer class, etc. When serializing live quests as part of save games, the QuestMachine will save/load JSON state for each live quest along with the global variables for the current game.

To help Daggerfall Unity re-compile Template’s source output, I’m going to make some minor changes to the expected source files. I’m trying to keep these changes to an absolute minimum.

First change is for the quest header to be uncommented in source file. For example, _BRISIEN has the following header. The dash ‘-‘ prefix starts a comment.

-- StartsBy: letter
-- Questee: anyone
-- Repute: 0
-- QuestId: 0

This reason this can be commented out is that Template is designed to re-compile quests back into the original QBN/QRC format. When commented out, Template will just use the information already in the quest QBN data. However, Daggerfall Unity relies entirely on the quest source and will need the above uncommented to:

StartsBy: letter
Questee: anyone
Repute: 0
QuestId: 0

This way the information can be parsed back into the quest data at compile time.

The second change is that I would like an explicit startup task, rather than an implicit startup after the QBN object definitions (like Person, Clock, etc.). Currently the startup task looks like this:

-- Quest start-up:
log 1010 step 0 
pc at PiratesHold set _exitstarter_ 
say 1025 

I would like to change this to:

startup:
log 1010 step 0 
pc at PiratesHold set _exitstarter_ 
say 1025 

This makes the startup task an explicit task object to be executed when quest begins. This is already the current behaviour, but I think this change makes the task clearer to identify for both quest creators (even without a comment) and for my compiler. I could definitely get away without this change, but I prefer the explicitness to the current setup.

And of course, the above is subject to change as the quest system matures. If I learned anything from rolling out items, the feature will probably look different again by the time it’s mostly complete. Daggerfall Unity is not just a game remake, it’s an ongoing research project into the guts of Daggerfall. That adds a few twists outside of normal gamedev process, and I just need to roll with it.

One of the upcoming features not shown yet is the quest debugger currently in development. Hopefully, I will have something to show on this by part 3. The quest debugger will be used to manually start new quests, terminate and restart executing quests, and inspect state of global variables and quest objects. It’s a big UI that will continue to grow as development progresses. Should turn out to be quite useful though.

 

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

Questing Part 1 – Source

With items and loot more or less finished, it’s time to place my sights on the next big feature group. I had originally planned to work on spells and effects in the 0.4 cycle, but also had quests in mind as an equally important feature. So back in July, I used a Twitter poll to sample what the community wanted priority on. The answer came firmly in preference for quests over spells.

Fast forward a couple months: 0.3 stable is now tagged on Live Builds page and I’ve started work on the quest system in earnest. This post is the first in a series documenting the journey from raw bytes to a working feature.

When adding a big new feature, there’s always a technical planning stage before commencement. I need to understand which of Daggerfall’s binary files are involved in the feature, learn how much is already known about those files (sometimes a lot, sometimes almost nothing), map out the additional details I need to know before I can re-implement that feature, and finally start cutting some code.

Sometimes it takes a few iterations, as writing code to pull apart the binaries is itself a journey where new information is learned. I don’t know what I don’t know, and often that new information results in a new iteration with better understanding. There’s basically a research-implement-compare loop going at all times throughout development of Daggerfall Unity. It can be a bit draining.

Items for example needed considerable research to bridge the gap between “enough knowledge to make an item editor” and “enough knowledge to fully implement items in a new engine”. Believe me, there’s a huge amount of work needed between having a file spec with lots of unknowns and building a completely functional equivalent. Most of my time is spent somewhere in that gap.

So when starting quests, I set out to learn everything I could about the binary formats and the work others had done before me. I was pleasantly surprised to learn:

  • Quests are among the most well-understood formats, thanks to the work of several early Daggerfall hackers (notably Donald Tipton and Dave Humphrey).
  • Tools exist to edit live quests, but more importantly decompile the QRC and QBN files to a human-readable source file (thanks to Template v1.11 by Tipton).
  • Early Daggerfall modders already had a good understanding of creating quests for Daggerfall – there’s an established process.
  • Quest files are one of the few cleanly decoupled things in Daggerfall. Unlike items which have template data hard-coded in the executable, quests are nicely self-contained.

With the above in mind, it was no longer necessary for me write a quest decompiler from scratch, design a new file format, decouple quest data, or chase half a dozen other time sinks. I can almost go directly to implementation. Almost. But first I need quest data in a usable form.

For the first step, I’m using Template v1.11, which you can find on UESP. This tool can decompile all the QRC (quest text) and QBN (quest programming) files to a single easy-to-read text file. So the information goes from raw binary data to the following (snippet from starting quest _BRISIEN).

QBN:
Item _letter1_ letter used 1020
Item _letter2_ letter used 1021
Item stopMainQuest letter used 1022

Person ladyBrisienna face 1 named Lady_Brisienna anyInfo 1012 rumors 1013

Place PiratesHold permanent PirateerHold1
Place _dirtypit_ remote tavern

Clock _invitepc_ 7.00:00 14.00:00
Clock _remindpc_ 30.00:00 0 flag 1 range 0 1
Clock _pcfailed_ 14.00:00 0 flag 1 range 0 1
Clock _oneday_ 1.00:00 0 flag 1 range 0 1
Clock _nowwhat_ 29.09:00 0 flag 1 range 0 1

-- Quest start-up:
 log 1010 step 0 
 pc at PiratesHold set _exitstarter_ 
 say 1025

That can still look a bit daunting if you’re not comfortable with programming concepts, but the source format generated by Template v1.11 is generally very easy to read and understand – more like a complex INI file than a real programming language. It’s so good that I’ve decided to adopt Template’s output as the source data for quests in Daggerfall Unity. You won’t need to recompile quest source back to QBN/QRC, rather you will use the source directly in Daggerfall Unity where it will be compiled at runtime by the quest system.

This means the de facto standard for creating Daggerfall quests will remain essentially the same in Daggerfall Unity (with some minor differences I’ll discuss later). If you’ve ever created a quest for Daggerfall, or even seriously looked into it, then you already have the skills to create quests in Daggerfall Unity. If you’re new to Daggerfall quests then you can learn from existing quests and read Template’s excellent documentation. Just as I don’t need to start from scratch, neither do you.

I will need to change the format slightly for unique needs on my side, but I aim to keep my input format as close as possible to Template’s output format. There’s also the need to emulate support for every single condition and action in Daggerfall Unity to behave similarly to Daggerfall given the same quest source. That will probably be an ongoing process all the way through to 1.0. But we need to start somewhere, and this is a great starting point.

The next article in series will look at parsing quest source files and how quests will be executed inside Daggerfall Unity.

 

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

Tutorial – Cloning from GitHub

If you’re interested in developing mods or contributing to Daggerfall Unity, you’ll first need to clone the project from GitHub. This light tutorial goes through the basic process of cloning Daggerfall Unity using GitHub for Desktop and opening with a fresh Unity install. There are many other ways to clone from git, but this is probably the simplest if you’re new to Unity or open source repositories.

After cloning the project, I go for a quick run through Privateer’s Hold to check everything is working normally.

Standalone Builds Update

After launching Live Builds a week ago, I’ve been very happy with the ability to push out small incremental changes. Besides the streamlined build process and less of a wait time, it also means I’m not overwhelmed with bugs every release. I can now tackle large problems fast and keep track of smaller problems for when I have the time.

This ability to turnaround builds so quickly has lead me to rethink the standalone builds (for now) and continue with the leaner, more agile cloud build process. I will revisit the standalone builds later in Daggerfall Unity’s life cycle. Here’s a summary of how to get Daggerfall Unity moving forwards:

  • GitHub always has the most recent code for developers.
  • The Live Builds page always has the most recent builds, and links for getting Daggerfall.
  • I will start to tag specific live builds as “Stable”. This means that everything implemented so far is generally working as expected.
  • I will restore the Daggerfall Tools for Unity pages as soon as possible, including updated tutorials.

If you were waiting for the convenience of a standalone build, I apologise for changing my plans. Daggerfall Unity is very much a living thing, both in terms of development and community, and can take up a large amount of my personal time. Anything that saves me time I can put back into gameplay, or spend with my family, is extremely valuable to me.

The good news is that pointing Daggerfall Unity to your game files has never been easier. The setup helper introduced with version 0.2 makes it very easy to get up and running, and you only need to download the game files once.

The first 0.3 stable build will be tagged soon. Lootable monsters just went into the latest live build and is with testers now. I only have the Rest and Keybind UIs to go and I’ve hit all the feature milestones planned for this release.

Live Builds Now Available

live-builds-header

Get Up To Date

Live builds based on latest code are now available to testers, as described in this blog post.

Check the forum topic State of 0.3 for information on 0.3 at time of writing.

 

Get The Latest Test Build

You can download latest builds from the all new Live Builds page.

 

Provide Feedback

Use the Bug Reports forum to log bugs. Please read the Bug Report Guidelines topic first.

 

Stable Builds

The latest stable build is still version 0.2.9 from 09-Apr-16. This version will be updated to 0.3.x in a few weeks once the majority of bugs have been found and eliminated.