Divinity Development Diary 1: Building the story
By Dante (Story Editor), 20001-02-26
Okay, Rat is leaving. I don’t like it (I still have to go drink that pint of beer with that guy) but I guess this means it is more than time to tell about development stuff that has been done in the mean time.
So I have been asked to take care about the story, together with Patrick.
Well, the first 3 weeks (in January) we started not really from a story. We had a bunch of nice ideas and demos, but they were inconsistent and we had not really a captivating story. So, Patrick, Lar and I spent a long time in making things work, building up the story and setting the right tempo. This was all done on paper, resulting in two main documents: the storyboard and the quest log.
The quest log lists all quests, involved characters and places, such that the world editors, the programmers and the graphic artists could derive a complete task list of things they still needed to do. In the storyboard we describe the major story flow: how the events link to each other, what are the cut scenes to keep pace in the story and add drama. In addition, we created documents about background information known by the NPCs as a feeding ground for their dialogs, and background information about the world history for books and the like.
Using our dialog editor, we can define dialogs for every NPC. Every dialog starts with a start node holding the greeting message of the NPC. This start node can contain multiple greeting messages, the correct one being chosen depending on the current situation. For instance, where the NPC will greet you with "Hello stranger" the first time, it should greet you with "Hi my friend" the second time. As well, when the player carries objects of importance to that NPC, he could have some special greeting as well. Then, this start node is connected to all questions the player can possibly ask. Again, these nodes all have their individual conditions. Only if these conditions are satisfied, the dialog will show the node text as a possible question the player can ask to the NPC. Etc… Some nodes are special in that they end the dialog, or that they can prevent other nodes from appearing. For instance, if you can answer yes or no to a quest invitation, you have something like: "Could you do this for me?", with two sub nodes: "yes" and "no". If one of the two is chosen, the other node is disabled (after you choose "yes" you cannot say "no" anymore and vice versa).
I give here an example to show you how this works.

In this screenshot, I created a dialog called "Lar". Repeatedly, I add nodes containing the different phrases Lar and the player will say. After I wrote down all these lines, I connect the nodes to show which sentences of Lar are the answers to the specific questions the player can ask. This results in a graph like this.

"Add node" connects all possible questions the player can put, "Set answer node" connects to Lar’s answer.

Where two nodes are each others opposite, I need to "remove" the latter node when the former is chosen. In the example below, the player can accept to fetch a bone for Lar. So, if the player chooses "yes", the possible option "Sorry, no time" should disappear.
Let’s have a look at the start of the dialog.

"Goodbye!" is a special node, since it closes the dialog when the player chooses this as his line. And to get my dialog perfect, I need to use some "memory" such that in the greeting node (the so called start group node) the right greeting message is chosen for Lar.

This memory is established by defining dialog events. They serve both as Boolean conditions (they can be TRUE of FALSE) and as events to communicate to the story engine, since the change of their value is reported to LStory. In the screenshot, I define that in order to make the line "Hi again my friend!" to be active, the condition "Lar_knows_player" needs to be TRUE.
You can see as well that I defined another dialog event, called "player_carries_a_bone". This event will be set TRUE in LStory when the player picks up a bone, such that the next time when the player and Lar meet and start talking, Lar will react on that by saying "Wow! A bone!". The player’s reply node looks like this:

So, this specific reply is only showed in the list of possible lines for the player if he has a bone. And if the player chooses this line, it will reset "player_carries_a_bone". LStory will be notified and remove the bone from the inventory. I can define this by just dragging the events listed in the centre box to one of the four boxes cornering it:
- The two on top define the condition that needs to be satisfied for this node to be shown
- The bottom two define which events to set or clear when this node is chosen by the player.
This is the LStory code to move the bone from the player to Lar:
IF
DialogEventCleared(_,DIALOG_EVENT_player_carries_a_bone,_,_)
THEN
NPC_RemoveFromInventory(NPC_Hero,OBJECT_CLASS_Bone,1);
NPC_IncreaseExperience(NPC_Hero,100);
We do not need all parameters in DialogEventCleared, hence we are using "don’t care" variables ‘_’. In LStory, all events get prefix "DIALOG_EVENT_" and the player is called NPC_Hero (just as in a lot of RPGs - this does not mean that he has to behave like one). So, the rule removes 1 bone from the player’s inventory and gives a small bonus in experience points as reward. If more than one bone can be found in the game (and with all these skeletons walking around, you never know!) this rule should be protected such that it cannot be used over and over again to get 100 exp points.
Since I have the privilege to work together with a writer (Patrick) we split up the tasks as follows. We first agreed upon the quests, the knowledge and background of all characters in the game, and about the storyboard. Then Patrick creates the dialogs. A dialog tester tool makes it possible to test the dialogs without needing to start the game or having the quests and objects implemented.
Whenever Patrick delivers me a new file with dialogs, I import it into the game story file. I then check all dialog events. The ones that are being set in dialogs usually trigger some quest, or item creation. E.g., if the player accepts to deliver a note (or a bone!) to somebody, I will need to program code that puts a scroll with the message in his inventory. Or when on the other hand some quest is completed, I not only need to give the necessary rewards to the player, but need to assert as well a dialog event that informs the dialog system that all NPCs concerned switch to a sort of "thank you" message.
In addition, I can use the story engine to:
- write scripts (cut scenes)
- to implement general rules of behaviour. E.g. I should implement rules that make an NPC angry when things are being stolen from him, …
Writing scripts is nothing more than letting NPCs do their act (where it is important to the story) and making sure that the player sees this act. This involves positioning NPCs, creating the right one liners or dialogs they say to each other, but as well moving the camera, controlling weather, etc… Most difficult here is to get the timing right and the behaviour of NPCs and camera natural. Here, really a lot of time is consumed! A complex cut scene takes me over a day to get it right. In the beginning, even a simple one took me that long.
Implementing general rules of behaviour is really using the story engine’s full power and is like logic programming. I can write general rules like these:
IF
NpcTookProperty(_Thief,_Owner) AND
_Owner.Sees(_Thief) AND
...
THEN
_Owner.KnowsThief(_Thief);
...
So if any NPC, whose name is assigned to rule variable "_Thief" takes property of another NPC, called "_Owner", then the _Owner will remember that _Thief is a thief and will react on it in future. He will change his opening dialog, his attitude, and perhaps will not be eager to cooperate any more. All this in just a few lines of story code.
While the tools are currently already pretty good, we still need to work on getting them to suit group work better (Patrick doing dialogs and me implementing the story), and to debug the stories.
While I will be busy this month and a good part of next month to implement all quests, sub quests and cut scenes, next thing to do is game balancing regarding equipment found, experience earned, skills learned, treasure acquired, etc… Lar is programming tools for this, but probably, end of March and certainly April will be important months regarding this subject.
See you around!
|