Ted's RPG Rant

A place to rant about RPG games, particularly the Temple of Elemental Evil. Co8 members get a free cookie for stopping by. Thats ONE cookie each, no seconds.

Thursday, August 25, 2005

Writing Dialogue for ToEE Part 4

Ok this is the last major part of the Tutorial, after this you should be able to do most of the necessary dialogue writing for a module. In fact you can do a lot now, even if you don't realise it! But there will be many more tutorial chapters to come, dealing with all sorts of things... if necessary, review the previous chapters, then on with the show!

Quick review:

We know what the various bracketed elements in each line do, and why there will always b the same number in each line no matter what is happening.

We know how to go from one line to the next, and hence can already create great long dialogues if we like full of lots of options.

We know how to add conditions so that the dialogue can reflect the situation, and so that certain lines only occur in certain circumstances (depending on the speaker, or the state of the storyline, or whatever).

We know how to execute certain functions from the dialogue (not many yet ;-)).

What next? Well, lets do quests.

Quests can be activated from inside the dialogue files: indeed, this is pretty much the primary way of doing so. They can be set as mentioned, accepted, botched, completed or unknown. First, we need to assign the quest a number, then we can deal with it.

Numbers are assigned in gamequest.mes and gamequestlog.mes. The one accesses the other, and the relevance of the stuff in them is at the top (the 1st is the number and CR rating, the 2nd has the brief and full descriptions, numbered 200 apart). Its pretty self-explanatory. Open them up and look! Find a spare number (check the Co8 modding forum here, to see if anyone has claimed any new quests for an upcoming mod) and add:

1) The name of the quest (that will appear in the game in the quest log).

2) A description of the quest (ditto).

3) The CR number of the quest.

Note: these files are ornery! Take careful note where previous modders have left gaps between numbers and emulate these: if you get a CTD ingame when opening the logbook, you haven't been careful enough!

But enough cheerful thoughts, lets start adding quests to the .dlg files. The command for quests is game.quests[#].state (so if you are using quest nmber 180, that'll be game.quests[180].state). So, to change the state of a quest it would be:

game.quests[#].state = qs_mentioned
game.quests[#].state = qs_accepted
game.quests[#].state = qs_completed
game.quests[#].state = qs_botched

Of course, quests start off as qs_unknown. You could probably turn it back if bugtesting (or cheating, tsk tsk tsk) otherwise I can't think of any reason to do it.

Now, these commands would go in the 'execute command' section in the last brackets in a line. Comparative commands to see if a quest is accepted or completed or whatever will look like this:

game.quests[#].state == qs_mentioned
game.quests[#].state == qs_accepted
game.quests[#].state == qs_completed
game.quests[#].state == qs_botched
game.quests[#].state == qs_unknown

Note that other than the extra equals sign these are identical to the executable commands. You may find yourself using 'copy & paste' a lot for some of them: it is easier, and 'safer' than typing out lines that might then contain typos. If a line doesn't work, chances are you forgot to add the extra equals sign: I have done it many times!

There's one other:

game.quests[#].state <= qs_mentioned

I've seen this, I assume it means 'mentioned or unknown'. Interesting :-)

Comparatives can also be 'not', eg:

game.quests[#].state != qs_botched
game.quests[#].state != qs_unknown

Damn handy these! So, lets see them in action:

{10}{Do my new quest?}{Do my new quest?}{}{}{}{}

{11}{I know it}{}{1}{game.quests[120].state == qs_mentioned}{20}{}
{12}{I'm doing it}{}{1}{game.quests[120].state == qs_accepted}{20}{}
{13}{I done it}{}{1}{game.quests[120].state == qs_completed}{20}{}
{14}{I stuffed it}{}{1}{game.quests[120].state == qs_botched}{20}{}
{15}{What was that?}{}{1}{game.quests[120].state == qs_unknown}{20}{}

{20}{Just do it}{Just do it}{}{}{}{game.quests[120].state = qs_accepted}

{21}{Bite me}{}{1}{}{0}{}

Simple. Lets look now at flags and variables.

I have listed which ones I am using in the guide in my mod, and Liv has said which ones she is using. Again, check the modding forum at Co8 to see which ones people are using. Some of them are set aside for internal stuff like the random encounters. Others are simply used as counters for the various characters, flagging when you have done something they will react to or whatever. Any time a character dies for instance, it gets flagged. Just go beyond the ones Liv set aside and you should be fine.

The global flags are straight 'on / off' (0/1) thing. For instance, when Meleney dies, it gets flagged by her san_dying script. Go see Filliken, and his san_dialog script has a thing in it that if that flag is there, the conversation starts with him weeping (and finishes soon after with him attacking you). If she gets resurrected it should reset the flag to off (0).

The global variables are counters, so you can use them the same as flags, only with more than one return. For instance, with my mod, rather than wasting a whole bunch of different flags for all the various items you bring Lila, I just used a variable counter. When you brought something to Lila, the counter went up by one. When it hit 8, it meant you had finished. Of course, to stop people bringing 8 pieces of hemlock, I had to flag that one :-)

To use them, just use the following scripts: (these are examples of course)

game.global_vars[#] = game.global_vars[#] + 1 (increases variable by 1)
game.global_vars[#] = 5 (sets it to 5)
game.global_vars[#] == 0 (sees if it is 0, the default value)
game.global_vars[#] >= 2 (sees if it is greater than or equal to 2)
game.global_flags[#] = 1 (sets flag)

Again, note the difference between the comparative and executable commands.

I should mention, the game seems to save 'quest complete' etc for the .dlg files: in the .py files (the scripts) it prefers to use flags. So it might use a flag to indicate a finished quest. But you can certainly handle the flags and variables in the .dlg files as well as the .py files.

What next? Well, we should have a good look at the other default options for dialogues. We have seen {G:} the default greeting for NPCs, and {E:} the default goodbye line for PCs. Here are the others as Phalzyr lists them:

{A:} = Appreciation Response (Thank You)
{B:} = Barter Response
{F:} = Forget it response
{K:} = More Questions Response
{N:} = "No" Response
{Q:} = Crash To Desktop When Displayed.
{R:} = Any Rumors? Auto asks for money.
{S:} = Sorry Response
{Y:} = Yes Response

Straightforward? Before I go into possible complications, lets see them in action. This is from Liv's addition of the gnoll attack. (Hard woman, that Liv - the only good gnoll is a dead gnoll and if you show mercy, Liv doesn't!)

{5000}{It must have been those gnolls that we encountered back in the moathouse. Maybe paying them off wasn't such a good idea.}{It must have been those gnolls that we encountered back in the moathouse. Maybe paying them off wasn't such a good idea.}{}{}{}{}

On the screen, this will show up as something like this:

Spugnoir: It must have been those gnolls that we encountered back in the moathouse. Maybe paying them off wasn't such a good idea.
1. I am sorry.
2. I must go.
3. Yes, of course.

Now, the details: the main one to consider is {B:}, because you need to use it to initiate bartering: but you don't have to use the default comment, you can add one.

{11}{B:Ok Lodriss, show me your goodies!}{}{1}{}{0}{}

Note the use of 0 in the line section, you are terminating dialogue and entering barter phase.

The {K:} response is used in the template, you can use it to take you to a 'default' dialogue bit where the player has a few options to talk about different things. Eg, in Jaroo's .dlg, {K:} takes you to line 80:

{80}{How can I help you, my son?}{How can I help you, my daughter?}{}{80}{}{}

{81}{Can you look at something I found?}{}{8}{pc.item_find( 3000 ) != OBJ_HANDLE_NULL or pc.item_find(5800) != OBJ_HANDLE_NULL}{160}{}
{82}{Me find stuff. You look at it?}{}{-7}{pc.item_find( 3000 ) != OBJ_HANDLE_NULL or pc.item_find(5800) != OBJ_HANDLE_NULL}{160}{}

{83}{I am in need of healing.}{}{8}{}{370}{}
{84}{Me have ouchies.}{}{-7}{}{370}{}

{85}{I would like to donate some gold.}{}{8}{}{40}{}
{86}{Me want to give gold.}{}{-7}{}{40}{}

{87}{I am trying to help Mytch the Miller.}{}{8}{game.global_flags[12] == 1 and game.quests[8].state == qs_accepted and game.global_flags[13] == 0}{240}{}
{88}{Me helping miller!}{}{-7}{game.global_flags[12] == 1 and game.quests[8].state == qs_accepted and game.global_flags[13] == 0}{240}{}

{89}{I've finally done it, Jaroo. I've gotten Terjon to agree to convert Marek, the carpenter's brother, to the Old Faith!}{}{8}{game.global_flags[17] == 1 and game.quests[5].state != qs_completed}{336}{}
{90}{Terjon say it OK for carpet man brother to join you.}{}{-7}{game.global_flags[17] == 1 and game.quests[5].state != qs_completed}{336}{}

{91}{I have some questions about the Old Faith.}{}{8}{}{200}{}
{92}{Me learn about Old Faith.}{}{-7}{}{200}{}

{93}{Why haven't you sent in your monthly report to Hrudek in the Gnarley Forest?}{}{8}{game.party_alignment == TRUE_NEUTRAL and game.global_flags[18] == 0}{318}{game.global_flags[18] = 1; game.global_flags[67] = 1}
{94}{Hrudey wants report.}{}{-7}{game.party_alignment == TRUE_NEUTRAL and game.global_flags[18] == 0}{318}{game.global_flags[18] = 1; game.global_flags[67] = 1}

{95}{Why don't you help Tarim with the Deklo Spiders?}{}{8}{game.quests[2].state == qs_mentioned}{920}{}
{96}{Jaroo, do you mind if we kill the spiders that have infested the Deklo Grove?}{}{8}{game.quests[2].state == qs_accepted}{920}{}
{97}{Jawoo care about Decklow spiders?}{}{-7}{game.quests[2].state == qs_mentioned or game.quests[2].state == qs_accepted}{920}{}


Simple enough. :-) If you have a 'default' dialogue tree, makes things easier and then you can flesh out each branch as appropriate.

Phalzyr also mentions {C:} = Story state response. Having scanned the .dlg files, I don't believe this is ever used. But there are still default lines for it, which as Phalzyr mentions can be found in the mes folder in gd_cls_pc2m.mes and gd_cls_pc2f.mes. We'll go into scripting for story state later.

For the moment, thats it! You can now create .dlg files, have them show dialogue appropriate to the situation as decreed by a wide number of parameters, keep track of things with flags and variables, initiate and complete quests and even initiate bartering or have the NPC attack! There's plenty more, but this is the main stuff.

Enjoy, and check back regularly for more stuff. In a couple days we will look at some more complicated scripts for the .py file.

The next chapter is now here.


At 10:09 pm, Anonymous just a bum said...

uh sorri homie dis stuffs 2 complacated 4 me... liek maths at skool i neva get dem rite -_-

geek stuffs...

At 6:48 pm, Blogger ShiningTed said...

Yup, thats me!


Post a Comment

<< Home