Difference between revisions of "A beginner's guide, lesson 6 - Quest Dialogue"
A beginner's guide, lesson 6 - Quest Dialogue (edit)
Revision as of 14:28, 21 December 2023
, 14:28, 21 December 2023no edit summary
imported>Pyrocow2 (→Three Problems: editing English) |
Tag: Manual revert |
||
(25 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
{{Featured}} | {{Featured}} | ||
{{ABGContents}} | |||
==Preamble== | |||
This is the Sixth in a proposed series of Tutorial Lessons aimed at teaching how to mod TES IV: Oblivion aimed at beginners. It will build up into a complete modding course. Don't worry, there are no exams (though, there is some homework). This version was written for use on the forum. The RTF version contains additional material that was left out due to formatting limitations. | |||
===Files=== | |||
I have uploaded some files in a .zip which will be used to accompany the next few tutorials. | |||
It contains: | |||
''' | '''A. BGModTutBase.esp:''' This contains a building, a farmhouse, and a dungeon that we will use as sets in lessons 6, 7 and 8. This file is referred to in the text as the BASE file. | ||
'''B. BGModTutPlayTest.esp:''' This is the interim quest mod illustrating the stage you should have reached prior to polishing the mod. This is referred to in the text as the PLAYTEST file. | |||
''' | '''C. BGModAnvilCheat.esp:''' This is a small optional cheat mod to give users 5000 Septims to allow them to follow this tutorial if they have not yet completed the quest. (See [[A_beginner's_guide,_lesson_4_-_Anatomy_of_a_quest,_part_1#Introduction|Introduction to Lesson 4]]) | ||
''' | '''D.''' An RTF document containing the text for the first 7 lessons (as requested). | ||
[http://www.tesnexus.com/downloads/file.php?id=4865 Download the mod files] | |||
===Using this Tutorial=== | |||
I suggest that you modify the CS configuration file to allow you to open multiple copies at the same time. (See [[A_beginner's_guide,_lesson_3_-_The_external_world#Introduction|Introduction to Lesson 3]]) | |||
Open one CS window for the '''PLAYTEST''' version. You can use this to look at the expected results of the mod. We will not edit this mod. | |||
Open a second window for the '''BASE''' version (unless you want to make your own buildings - then just make a new file). This window is for your working file. | |||
==Introduction== | ==Introduction== | ||
Line 43: | Line 36: | ||
The next three lessons will work to develop a quality version of a quest. While we will do this exercise, I have designed the quest to allow us to focus on key skills as we go on. This lesson deals with the creation of dialogue. In lesson seven we will really turn our focus to scripting, although you will begin scripting in this lesson. The eighth lesson will complete the quest by focusing on AI and Audio. | The next three lessons will work to develop a quality version of a quest. While we will do this exercise, I have designed the quest to allow us to focus on key skills as we go on. This lesson deals with the creation of dialogue. In lesson seven we will really turn our focus to scripting, although you will begin scripting in this lesson. The eighth lesson will complete the quest by focusing on AI and Audio. | ||
I assume that you have completed lessons one to three, and that that you have at least read through the [[A_beginner's_guide_-_Appendix_1|appendix section on the Quest Interface]]. | |||
==Our Plot== | ==Our Plot== | ||
Line 580: | Line 573: | ||
It expects to find for each dialogue response files, which we have not created. One is an MP3 which contains the sound files, and the others are lip synch files used to animate the actor's face as we carry out the dialogue. The text is supposed to appear on screen for the duration of these files. | It expects to find for each dialogue response files, which we have not created. One is an MP3 which contains the sound files, and the others are lip synch files used to animate the actor's face as we carry out the dialogue. The text is supposed to appear on screen for the duration of these files. | ||
Since we don't have them yet, the text runs very quickly. In later tutorials we will look at polishing this mod to include these files. For now, these are cosmetic problems. It's irritating not to see the text for any length of time, but it can't be helped until we add those MP3's. | Since we don't have them yet, the text runs very quickly. In later tutorials we will look at polishing this mod to include these files. For now, these are cosmetic problems. It's irritating not to see the text for any length of time, but it can't be helped until we add those MP3's. | ||
It doesn't stop the quest running. You can repeatedly play the on-screen text by selecting the topic message for you until you get the message | It doesn't stop the quest running. You can repeatedly play the on-screen text by selecting the topic message for you until you get the message. (Alternatively, you could install a mod like [http://www.tesnexus.com/downloads/file.php?id=16622 Universal Silent Voice].) | ||
The second problem deals with the script as it currently stands and may not be so obvious to a non-scripter. A quest script runs every 5 seconds. That means that every 5 seconds this script tries to add the topic BGMMessage4u to the players topic list. I don't honestly know what the effect of repeatedly adding a topic to the player's list is, but I suspect that extra requests to add the topic are simply ignored. | The second problem deals with the script as it currently stands and may not be so obvious to a non-scripter. A quest script runs every 5 seconds. That means that every 5 seconds this script tries to add the topic BGMMessage4u to the players topic list. I don't honestly know what the effect of repeatedly adding a topic to the player's list is, but I suspect that extra requests to add the topic are simply ignored. | ||
Line 642: | Line 635: | ||
Change the Begin block to look like this. | Change the Begin block to look like this. | ||
Begin GameMode | |||
If (DoOnce1 == 0) | |||
AddTopic BGMMessage4U | |||
Set DoOnce1 to 1 | |||
EndIf | |||
End | |||
This is perfectly fine but it can get a little hard to read, when these if statements get long and complex. So again we use an optional convention. We indent using the tab key all lines after an IF statement, to make clear what is going on. | |||
<pre> | |||
Begin GameMode | |||
If (DoOnce1 == 0) | If (DoOnce1 == 0) | ||
AddTopic BGMMessage4U | |||
Set DoOnce1 to 1 | |||
EndIf | EndIf | ||
End | |||
</pre> | |||
So this script uses another new command called SET-TO. | |||
this script uses another new command called SET-TO. | |||
Whenever you declare variables they are automatically assigned a value of Zero. | Whenever you declare variables they are automatically assigned a value of Zero. | ||
Line 669: | Line 672: | ||
IF statements and Set statements both use standard mathematical comparisons | IF statements and Set statements both use standard mathematical comparisons | ||
Comparison Operators | ===Comparison Operators=== | ||
An IF statement may contain one or more comparison operators. | An IF statement may contain one or more comparison operators. | ||
Below is a table of valid comparison operators: | Below is a table of valid comparison operators: | ||
Line 681: | Line 684: | ||
<= Less than or equal to | <= Less than or equal to | ||
Combining Comparisons | ===Combining Comparisons=== | ||
Comparisons can be linked together using the following logical operators: | Comparisons can be linked together using the following logical operators: | ||
Line 708: | Line 711: | ||
We have added the topic once and once only. | We have added the topic once and once only. | ||
==A third problem== | |||
The third major problem is that this topic has been added to every NPC in the game. It is just about conceivable that if you complete every quest in the game and then some that you might meet every NPC there is, but I don't see how it's logical to suggest that they all might know Vilanus Villa and know he has a message for you. We need to limit who speaks to you on this topic. We must set some response conditions. | The third major problem is that this topic has been added to every NPC in the game. It is just about conceivable that if you complete every quest in the game and then some that you might meet every NPC there is, but I don't see how it's logical to suggest that they all might know Vilanus Villa and know he has a message for you. We need to limit who speaks to you on this topic. We must set some response conditions. | ||
==Conditions== | ==Conditions== | ||
The conditions box in the Topics Tab is used to limit who gets to say a particular response. | The conditions box in the Topics Tab is used to limit who gets to say a particular response. We can limit this in many ways. | ||
For example, Restrict by group ([[GetInFaction]]), race ([[GetRace]]) or limit to only one NPC ([[GetIsID]]), Restrict by Worldspace, City, Cell or distance from a particular chair, Restrict by Game Time, Season, Weather or progress of quest. | |||
Open up the topics tab, select the BGMMessage4u topic and highlight the response we added earlier. | |||
Open up the topics tab, select the BGMMessage4u topic and highlight the response we | |||
At the bottom of the window is the condition box. | At the bottom of the window is the condition box. | ||
Again we can use Right | Again we can use Right-click + New to add conditions, or we can click on the New button at the bottom of the tab page. | ||
These conditions are just like the ones we used in Quest Data before. | |||
By default, all NPCs will have our new topic available. We need to use conditions to choose which NPCs can or can't display our topic. | |||
This particular topic is a general one and we want to set some general conditions just to reduce the number of NPCs that can use it. | |||
This particular topic is a general one and we want to set some general conditions just to reduce the number of NPCs that can | |||
First let's get rid of a number of races. Why? | First let's get rid of a number of races. Why? | ||
Well in the middle part of the window is the response box. | Well, in the middle part of the window is the response box. | ||
Double click on the response to the BGMMessage4u topic to re-open the pop-up response dialog box. | Double click on the response to the BGMMessage4u topic to re-open the pop-up response dialog box. | ||
Have a look at the lower section and you can see a long list. | Have a look at the lower section and you can see a long list. | ||
This is the list of expected MP3 files which we would need to create. It is very long | This is the list of expected MP3 files which we would need to create. It is very long; it expects both a male and female response for every single race. | ||
We can remove some of these to make our life easier later on | We can remove some of these to make our life easier later on, when it's time to record. | ||
Select | Select New in the condition box with the response "I hear a lawyer named..." highlighted. | ||
In the | In the ''Condition Function'' drop down menu, scroll down to the function [[GetIsRace]]. | ||
Click on the ''Function Parameter'' box and a list of races will be displayed. These are the valid parameters for this function. | |||
Click on | Select "Argonian" from the list. | ||
Select Argonian from the list. | The comparison reads == by default, so you can leave that unchanged. | ||
The comparison reads == | The value current reads 1.0000. This is value the function [[GetIsRace]] would give if the character's race was in fact "Argonian". | ||
The value current reads 1. | We want to change this to the negative response: 0.0000. | ||
We want to change this to the | |||
In English this means: | In English this means: | ||
Look at the Actor who might | Look at the Actor who might use this response. Check what race they are. If they are not an Argonian, then carry on. | ||
Otherwise, they are an Argonian and should not be able to use this line. | |||
(Note the condition Argonian == 0 is | (Note that the condition Argonian == 0 is logically equivalent to Argonian != 1) | ||
Now, let's add a few more Race conditions. | Now, let's add a few more Race-based conditions. | ||
Right click | Right-click on the condition we just created and copy it using the Copy option from the menu. | ||
Now right-click again and paste. | |||
Now right click and paste. | |||
We now have an exact copy of our condition. | We now have an exact copy of our condition. | ||
Click on the parameter box and now choose "Elf". | |||
We now have two races excluded. | We now have two races excluded. | ||
Repeat this process to exclude the other races, until we are left with Bretons, Redguards, Imperialsm and Nords (i.e. the Human races). | |||
Is this some sort of cultural imperialism on my part? No, it's just that I reckon I could add an MP3 file which might sound passable for those races. Orcs, Argonians, and Khajiits have unique voice types that are harder to replicate. It is a matter of style and choice. If you want to extend the range, do so. | |||
We | We call these conditions "exclusive conditions" because they exclude a group or individual from using that response. | ||
We also want to limit the in-game locations where these lines are valid. | |||
All major locations, including the cities, have special "dummy cells" created to allow us to use a single condition on many individual locations. The game searches for cells with a given text string at the beginning of its name. So if we select a cell called "IC", it actually triggers every cell that begins with "IC". Everything from ''ICPalaceLibrary'' to ''ICTalosPlazeTheTiberSeptimHotelUpstairs''. | |||
If you called a cell Icnatta or something else that also begins with "IC", even though this cell might have nothing to do with the Imperial City, the catch all nature of the "IC" description means that that cell will also be triggered. This would conflict with the Imperial City's naming prefix. This means we do need to be careful when naming cells. | |||
It also means that we can use this trick ourselves. If we create huge mods that add towns or cities, we can use prefixes in the same way. By carefully naming all my external and interior cells VeronaHouseSomethingorOther, we could then create a "dummy" (i.e., completely empty and unused) cell called VeronaHouse, which would allow us to use VeronaHouse in condition statements and identify if something was anywhere in the Verona House area. | |||
I choose the Imperial City (again, I could have chosen any number of locations) because it is the Capital, and most players will at one point or another visit the City. It is as ever about style rather than technique and you are free to choose your own path. | |||
It | |||
In the condition box select | In the condition box select New. | ||
Now select condition function GetInCell. | Now select condition function [[GetInCell]]. | ||
The parameter for this is | The parameter for this is initially invalid until we click on it select a cell from the menu. You can only select cells that are named and unique. Notice that all those exterior cells called "Wilderness" don't show up. If you wish to use an exterior cell, you must give it a unique name. | ||
Set the condition to test. | Set the condition to test. (This is an inclusive condition, since it includes a group in that response.) | ||
(This is an inclusive condition, since it includes a group in that response.) | |||
Another way to select groups is by using [[faction]]s (see lesson 7 for more details on creating a Faction) | Another way to select groups is by using [[faction]]s (see lesson 7 for more details on creating a Faction) | ||
One such faction is the ICFaction. It groups all the NPCs who are considered citizens of this city. It is a useful way to distinguish between the merchants | One such faction is the ICFaction. It groups all the NPCs who are considered citizens of this city. It is a useful way to distinguish between the merchants, soldiers, and workers of the capital and a tourist from Chorrol who is passing through. | ||
Set up a | Set up a new condition. | ||
Choose the [[GetInFaction]] function, and then choose the ICFaction from the list to get a new condition | Choose the [[GetInFaction]] function, and then choose the ''ICFaction'' from the list to get a new condition. | ||
Finally we want to exclude our NPC Vilanus Villa from | Finally, we want to exclude our NPC Vilanus Villa from using these lines. It would be awfully silly if Vilanus himself told us, "I hear a lawyer named Vilanus Villa is looking for you." | ||
To do this we use the condition function [[GetIsID]]. | To do this we use the condition function [[GetIsID]]. | ||
Then from the parameter list select BGVilanusVilla. | Then from the parameter list we select BGVilanusVilla. | ||
Remember to set the value to 0 so that your condition | Remember to set the value to == 0 (or != 1) so that your condition EXCLUDES him. | ||
Finally, we want to set a condition that removes this topic from all potential speakers once we have met Villa. | Finally, we want to set a condition that removes this topic from all potential speakers once we have met Villa. | ||
Line 840: | Line 833: | ||
Let's summarise what we have for this first topic | Let's summarise what we have for this first topic | ||
{| class="wikitable" border="1" cellpadding="5" | {| class="wikitable" border="1" cellpadding="5" | ||
!colspan=2|'''BGMMessage4u''' | |||
|- | |- | ||
! TOPIC | ! TOPIC | ||
| | | Message for you | ||
|- | |- | ||
! RESPONSE | ! RESPONSE | ||
| I hear a | | I hear a lawyer named Vilanus Villa is looking for you. | ||
|- | |- | ||
! CONDITIONS | ! CONDITIONS | ||
| | | | ||
GetInCell | * GetIsRace 'Argonian' == 0, etc.<br> | ||
GetInFaction | * GetInCell 'IC' == 1<br> | ||
GetIsID BGVilanusVilla == 0<br> | * GetInFaction 'ICFaction' == 1<br> | ||
GetStage BGM001 < 10<br> | * GetIsID 'BGVilanusVilla' == 0<br> | ||
* GetStage 'BGM001' < 10<br> | |||
|- | |- | ||
! ADD TOPICS | ! ADD TOPICS | ||
| | | | ||
* BGVilanusVilla | |||
|- | |- | ||
! RESULT SCRIPT | ! RESULT SCRIPT | ||
| SetStage BGM001 10 | | | ||
SetStage BGM001 10 | |||
|} | |} | ||
I'll use these summaries throughout these tutorials | I'll use these summaries throughout these tutorials. I have used this table as a template when planning my own quests, and I find it really useful. Remember, if you get stuck refer to the PLAY TEST (BGModTutPlayTest) version to see how it should look. | ||
==Stage Update== | ==Stage Update== | ||
Line 870: | Line 867: | ||
Let's do this. It's the same old routine. Right Click and new in the Log Entry box. Add a suitable bit of text like: | Let's do this. It's the same old routine. Right Click and new in the Log Entry box. Add a suitable bit of text like: | ||
''I have been told a lawyer called Vilanus Villa is looking for me. I should find out where he is staying. He may have important news for me.'' | ''I have been told a lawyer called Vilanus Villa is looking for me. I should find out where he is staying. He may have important news for me.'' | ||
Ok, we have now added a topic called ''' | Ok, we have now added a topic called ''BGMMessage4u''. | ||
For now, save and go test. | For now, save and go test. | ||
Line 878: | Line 875: | ||
You should now find that this topic only appears for human characters in the Imperial City. Try in other locales like Anvil, etc. to make sure. When you're done, come back and we can move on. | You should now find that this topic only appears for human characters in the Imperial City. Try in other locales like Anvil, etc. to make sure. When you're done, come back and we can move on. | ||
When you click on the | When you click on the ''BGMMessage4u'' topic in the game the topic Vilanus Villa will now automatically be added. | ||
I don't intend to continue to give you a click-by-click method for every topic and response. Remember the basic idea of right click and select. | I don't intend to continue to give you a click-by-click method for every topic and response. Remember the basic idea of right click and select. | ||
Line 884: | Line 881: | ||
Let's move on. | Let's move on. | ||
Select the BGVilanusVilla topic we added earlier and add a response (See table below). This response should direct the player to the Talos District of the Imperial City. | Select the ''BGVilanusVilla'' topic we added earlier and add a response (See table below). This response should direct the player to the Talos District of the Imperial City. | ||
We need some conditions. | We need some conditions. | ||
Since this is a direct follow- | Since this is a direct follow-up from'BGMMessage4u'', we can use the same conditions to do the job. | ||
In the | In the ''BGMMessage4u'' condition box, right click and select copy all conditions and then paste these into the ''BGVilanusVilla'' response. | ||
This response is fine, unless | This response is fine, unless we're talking to someone who's already in Talos Plaza. | ||
We need to add one more condition to account for this by using the [[GetInCell]] function. | We need to add one more condition to account for this by using the [[GetInCell]] function. We also need to update the stage values that [[GetStage]] checks for. | ||
{| class="wikitable" border="1" cellpadding="5" | {| class="wikitable" border="1" cellpadding="5" | ||
!colspan=2| '''BGMVilanusVilla''' | |||
|- | |- | ||
! TOPIC | ! TOPIC TEXT | ||
| | | "Vilanus Villa" | ||
|- | |- | ||
! RESPONSE | ! RESPONSE | ||
| I believe he | | "I believe he's staying in Talos Plaza." | ||
|- | |- | ||
! CONDITIONS | ! CONDITIONS | ||
| | | | ||
GetInCell | *GetIsRace 'Argonian' == 0, etc. | ||
GetInFaction | *GetInCell 'IC' == 1 | ||
GetIsId BGVilanusVilla == 0 | *GetInFaction 'ICFaction' == 1 | ||
GetStage BGM001 < 20 | *GetIsId 'BGVilanusVilla' == 0 | ||
'''GetInCell | *'''GetStage 'BGM001' < 20''' | ||
*'''GetInCell 'ICTalosPlaza' == 0''' | |||
|- | |- | ||
! ADD TOPICS | ! ADD TOPICS | ||
Line 916: | Line 916: | ||
| ''No script'' | | ''No script'' | ||
|} | |} | ||
We should also add responses that only work inside Talos Plaza. This next one should direct the player to the Imperial Hotel where we placed Vilanus Villa. Again, we can copy the conditions by using the copy and paste method, and then change the last condition (GetInCell 'ICTalosPlaza') to 1. (You could also duplicate the entire response by right-clicking and selecting copy, and then edit the duplicate from there.) | |||
This one should direct the player to the Imperial Hotel where we placed Vilanus Villa. Again we can copy the conditions | |||
{| class="wikitable" border="1" cellpadding="5" | {| class="wikitable" border="1" cellpadding="5" | ||
!colspan=2| '''BGMVilanusVilla''' | |||
|- | |- | ||
! TOPIC | ! TOPIC TEXT | ||
| | | "Vilanus Villa" | ||
|- | |- | ||
! RESPONSE | ! RESPONSE | ||
| I believe he is staying in the | | "I believe he is staying in the Tiber Septim Hotel." | ||
|- | |- | ||
! CONDITIONS | ! CONDITIONS | ||
| | | | ||
GetInCell | *GetIsRace 'Argonian' == 0, etc. | ||
GetInFaction | *GetInCell 'IC' == 1 | ||
GetIsID BGVilanusVilla == 0 | *GetInFaction 'ICFaction' == 1 | ||
GetStage BGM001 < 20 | *GetIsID 'BGVilanusVilla' == 0 | ||
'''GetInCell | *'''GetStage 'BGM001' < 20''' | ||
*'''GetInCell 'ICTalosPlaza' == 1''' | |||
|- | |- | ||
! ADD TOPICS | ! ADD TOPICS | ||
Line 942: | Line 944: | ||
|} | |} | ||
If you wanted to get really flashy | If you wanted to get really flashy you could add another response for the occasions when we ask NPCs about Vilanus Villa inside the hotel itself. However, I have not done this to save a bit of time. Feel free to try this yourself. A response like "Yeah I've seen him around here." would do. Don't forget to copy the conditions and alter the GetInCell parameter. Also remember that [[GetInCell]] matches the beginning of the cell strings, so you should add another [[GetInCell]] condition to the second response which excludes the Hotel cell (so that the response "I believe he is staying in the Imperial Hotel." shows up everywhere in Talos Plaza EXCEPT for the hotel itself). | ||
However, I have not done this to save a bit of time. Feel free to try this yourself. A response like | |||
Don't forget to copy the conditions and alter the GetInCell parameter. | |||
==Using the GREETING topic== | ==Using the GREETING topic== | ||
Another way to pass on information via dialogues is to use the GREETING topic. If you remember the discussion in | Another way to pass on information via dialogues is to use the GREETING topic. If you remember the discussion in Lesson 4 about how conversations work, all dialogues begin with a GREETING, which is selected by the game from the GREETING topic. | ||
If we add our own greeting and set the right conditions we can force a start to a dialogue. | If we add our own greeting and set the right conditions we can force a start to a dialogue. | ||
In the topics tab | In the topics tab add GREETING. This topic already exists, so you will not need to create a new topic when the list appears. | ||
We can now add Vilanus Villa's little speech. | We can now add Vilanus Villa's little speech. | ||
This is quite a long response so we should split it up | This is quite a long response so we should split it up to reduce the amount of text that appears on the screen at any given time. | ||
Add this response first to the GREETING topic. Note this is blank because there are no GREETING responses added by this quest yet. | Add this response first to the GREETING topic. Note this is blank because there are no GREETING responses added by this quest yet. | ||
''Hello, my name is Vilanus Villa and I've been looking for you. I'm afraid I have some bad news.'' | |||
Now click OK to add the response. | Now click OK to add the response. | ||
Then in the | Then in the ''Response Details'' box (not the upper info box), add a new line of response text. You'll get a new interface to write in. | ||
''Your uncle passed away peacefully in his sleep.'' | |||
Then add another | Then add another: | ||
''I have been asked to look after his last will and testament.'' | |||
We can go adding new lines to this response info if we wish. In the top box we can see the number of responses increments to 3. The text appears in the top box as: | We can go on adding new lines to this response info if we wish. In the top box we can see the number of responses increments to 3. The text appears in the top box as: | ||
'' | ''Hello, my name is Vilanus Villa and I've been looking for you. I'm afraid I have some bad news. || Your uncle passed away peacefully in his sleep. || I have been asked to look after his last will and testament.'' | ||
Hello, my name is Vilanus Villa and I've been looking for you. I'm afraid I have some bad news || Your uncle | |||
With the || indicating separate lines of this single response. | |||
We need to add some conditions, to control who says these lines. This is very important when using the GREETINGS topic as this is so wide spread within the game. While it is silly that every character could respond to ''BGMMessage4u'', it is dangerous to have an unconditional greeting, as this might override every other greeting in the game and prevent other quests from working properly. | |||
We need to add some conditions, to control who says these lines. This is very important when using the GREETINGS topic as this is so wide spread within the game. While it is silly that every character could respond to BGMMessage4u, it is dangerous to have an unconditional greeting as this might override every other | |||
Limiting a response to just one character is easier than using groups. | Limiting a response to just one character is easier than using groups. | ||
We can use the GetIsID function. | We can use the [[GetIsID]] function for this. | ||
We need to have an NPC reference which is why we built BGVilanusVilla first. We will also restrict this response to the opening stage of our quest. | We need to have an NPC reference, which is why we built ''BGVilanusVilla'' first. We will also restrict this response to the opening stage of our quest. | ||
* '''GetStage BGM001 | * '''GetStage 'BGM001' <= 10''' | ||
* '''GetIsID BGVilanusVilla==1''' | * '''GetIsID 'BGVilanusVilla' == 1''' | ||
Now we want to add a new topic called BGWill. However, there is an issue (and many thanks to Hecks for pointing this out) when adding topics to the GREETING or indeed any existing Bethesda topic. For technical reasons, the topic might not get added if more than one plug-in is attempting to use GREETING to add a topic. | Now we want to add a new topic called ''BGWill''. However, there is an issue (and many thanks to Hecks for pointing this out) when adding topics to the GREETING or indeed any existing Bethesda topic. For technical reasons, the topic might not get added if more than one plug-in is attempting to use GREETING to add a topic. | ||
I'll be honest and say I don't know why this happens. It's not difficult to work around once you know the issue exists. When I found out it took me thirty seconds in the CS to fix. | I'll be honest and say I don't know why this happens. It's not difficult to work around once you know the issue exists. When I found out it took me thirty seconds in the CS to fix. | ||
First create a new topic | First create a new topic called ''BGWill''. | ||
Now add this | Now add this to the result script for the GREETING response. | ||
AddTopic BGWill | AddTopic BGWill | ||
Line 1,001: | Line 998: | ||
The speech that Villa gives contains a lot of exposition, and we don't want to force the player to repeat this every time. | The speech that Villa gives contains a lot of exposition, and we don't want to force the player to repeat this every time. | ||
We can stop this by setting up | We can stop this by setting up a pair of conditional responses. | ||
==Conditional Pairs== | ==Conditional Pairs== | ||
Line 1,008: | Line 1,005: | ||
These might take the form | These might take the form | ||
<pre> | |||
Response 1: Long Explanation | Response 1: Long Explanation | ||
Response 2: Short Explanation | Response 2: Short Explanation | ||
Line 1,017: | Line 1,014: | ||
Response 1: ‘Ah you've found the widget my friend' | Response 1: ‘Ah you've found the widget my friend' | ||
Response 2: ‘You must find the widget my friend' | Response 2: ‘You must find the widget my friend' | ||
</pre> | |||
Let's try this | |||
Add a new variable called MetVilla to the top of the Quest Script (under the quest data tab). We should declare any variables used by the quest in the Quest-type script. | |||
<pre> | |||
SCN BGM001QuestScript | |||
Short DoOnce1 | |||
Short MetVilla | |||
Begin GameMode | |||
If (DoOnce1 == 0) | |||
AddTopic BGMMessage4U | |||
Set DoOnce1 to 1 | |||
EndIf | |||
End | |||
</pre> | |||
This | This variable will be automatically set to zero. We can use the response result box to bump this up to one after the speech with a bit of script. Add this in after "AddTopic BGWill". | ||
Set BGM001.MetVilla to 1 | Set BGM001.MetVilla to 1 | ||
Don't forget to click the compile button | Don't forget to click the compile button! | ||
Summarising the first response | Summarising the first response: | ||
{| class="wikitable" border="1" cellpadding="5" | {| class="wikitable" border="1" cellpadding="5" | ||
!colspan=2| '''GREETING''' | |||
|- | |- | ||
! TOPIC | ! TOPIC TEXT | ||
| GREETING | | GREETING | ||
|- | |- | ||
! RESPONSE | ! RESPONSE | ||
| | | | ||
* Hello, my name is Vilanus Villa and I've been looking for you. I'm afraid I have some bad news. | * "Hello, my name is Vilanus Villa and I've been looking for you. I'm afraid I have some bad news." | ||
* Your uncle has passed away peacefully in his sleep. | * "Your uncle has passed away peacefully in his sleep." | ||
* I have been asked to look after his last will and testament. | * "I have been asked to look after his last will and testament." | ||
|- | |- | ||
! CONDITIONS | ! CONDITIONS | ||
| | | | ||
GetIsID BGVilanusVilla==1 | *GetStage 'BGM001' <= 10 | ||
'''GetQuestVariable BGM001.MetVilla == 0''' | *GetIsID 'BGVilanusVilla' == 1 | ||
*'''GetQuestVariable 'BGM001.MetVilla' == 0''' | |||
|- | |- | ||
! ADD TOPICS | ! ADD TOPICS | ||
| | | ''No add topic'' | ||
|- | |- | ||
! RESULT SCRIPT | ! RESULT SCRIPT | ||
| Set BGM001.MetVilla to 1 | | | ||
AddTopic BGWill | |||
Set BGM001.MetVilla to 1 | |||
|} | |} | ||
We can then add this alternative response info to the GREETING topic | |||
We can then add this alternative response info to the GREETING topic: | |||
{| class="wikitable" border="1" cellpadding="5" | {| class="wikitable" border="1" cellpadding="5" | ||
!colspan=2| '''GREETING''' | |||
|- | |- | ||
! TOPIC | ! TOPIC TEXT | ||
| GREETING | | GREETING | ||
|- | |- | ||
! RESPONSE | ! RESPONSE | ||
| Whenever you want to talk about your uncle's will, let me know | | "Whenever you want to talk about your uncle's will, let me know." | ||
|- | |- | ||
! CONDITIONS | ! CONDITIONS | ||
| | | | ||
GetIsID BGVilanusVilla==1 | *GetStage 'BGM001' <= 10 | ||
'''GetQuestVariable BGM001.MetVilla == 1''' | *GetIsID 'BGVilanusVilla' == 1 | ||
*'''GetQuestVariable 'BGM001.MetVilla' == 1''' | |||
|- | |- | ||
! ADD TOPICS | ! ADD TOPICS | ||
| ''No | | ''No add topic'' | ||
|- | |- | ||
! RESULT SCRIPT | ! RESULT SCRIPT | ||
| ''No | | ''No script'' | ||
|} | |} | ||
The first time we greet him he gives the longer speech, the second time a shorter one. | The first time we greet him he gives the longer speech, the second time a shorter one. | ||
We can now add | We can now add response info to the ''BGWill'' topic. | ||
Try this one yourself using this summary to guide you. | Try this one yourself using this summary to guide you. | ||
Don't forget the quest bump script. | Don't forget the quest bump script. | ||
You will need to add a new topic called BGHubart. | You will need to add a new topic called ''BGHubart''. | ||
{| class="wikitable" border="1" cellpadding="5" | {| class="wikitable" border="1" cellpadding="5" | ||
!colspan=2| '''BGWill''' | |||
|- | |- | ||
! TOPIC | ! TOPIC TEXT | ||
| | | "My uncle's will" | ||
|- | |- | ||
! RESPONSE | ! RESPONSE | ||
| | | | ||
* Apparently your uncle | * "Apparently your uncle had some property here in Cyrodiil. I'm not sure where, though." | ||
* I was expecting a courier to deliver the details but | * "I was expecting a courier to deliver the details, but she hasn't shown up." | ||
* Captain Hubart of the Chorrol Guard | * "Captain Hubart of the Chorrol Guard notified me that the courier never made it to her stop in Chorrol." | ||
* You will have to | * "You will have to visit him in Chorrol to find out more about what's going on. Here's the letter he sent me." | ||
|- | |- | ||
! CONDITIONS | ! CONDITIONS | ||
| | | | ||
GetIsID BGVilanusVilla==1 | *GetStage 'BGM001' <= 10 | ||
*GetIsID 'BGVilanusVilla' == 1 | |||
|- | |- | ||
! ADD TOPICS | ! ADD TOPICS | ||
| | | | ||
*BGHubart | |||
*BGMVilanusVilla (In case the player talked to Vilanus before using the "Message for you" topic) | |||
|- | |- | ||
! RESULT SCRIPT | ! RESULT SCRIPT | ||
| SetStage BGM001 20 | | | ||
SetStage BGM001 20 | |||
|} | |} | ||
Again we have a stage bump, this time to stage 20. | |||
In the Quest Stages tab, add a journal entry for stage 20. | |||
''I've been told that I may have inherited some property from my late uncle, but the courier carrying the details has gone missing. I will need to go to Chorrol and speak to a Captain Hubart of the Chorrol Guard to get more information.'' | |||
We will also add a Quest Stage Result Script. | We will also add a Quest Stage Result Script. | ||
Line 1,109: | Line 1,138: | ||
But first we need to create a prop letter, so we can refer to it in the script. | But first we need to create a prop letter, so we can refer to it in the script. | ||
Again we can create a | Again we can create a new item from scratch, but it means trying to add artwork to the game. Unless we want the letter or scroll to look completely unique, and have some talent in that direction, it is a chore we don't need to do. | ||
Instead select any letter from the | Instead, select any letter from the Items->Book list in the object window, change its ID to something meaningful like ''BGHubartLetter''. | ||
The text on the right hand side indicates the content of the letter. We can edit this. I will look at the precise details and syntax needed to produce text in another lesson. | The text on the right hand side indicates the content of the letter. We can edit this. I will look at the precise details and syntax needed to produce text in another lesson. It uses standard HTML tags. | ||
It uses standard HTML | For now, the key command is <nowiki><br></nowiki>, which produces a 'line break' or 'new line'. The font face can be left alone. | ||
For now the key command is <nowiki><br></nowiki> which produces a line break | |||
'''BGHubartLetter''' | '''BGHubartLetter''' | ||
Line 1,123: | Line 1,151: | ||
<br> | <br> | ||
<br> | <br> | ||
I regret to inform you that the White Horse courier Janus Jakobs, who you asked me to meet, has not arrived for her expected rendezvous. I know you | I regret to inform you that the White Horse courier Janus Jakobs, who you asked me to meet, has not arrived for her expected rendezvous. I know you were expecting some important documents to arrive.<br> | ||
<br> | <br> | ||
I don't have enough man power to launch a search | I don't have enough man power to launch a search; perhaps you could find someone willing to assist me in finding Jakobs? | ||
<br> | <br> | ||
<br> | <br> | ||
I look forward to hearing from you old friend. | I look forward to hearing from you, old friend. | ||
<br> | <br> | ||
<br> | <br> | ||
Line 1,135: | Line 1,163: | ||
Captain Hubart | Captain Hubart | ||
</nowiki></pre> | </nowiki></pre> | ||
Save the letter | Save the letter, AND MAKE SURE YOU CLICK 'YES' TO CREATE A NEW FORM. | ||
Now, type this in the results script box for stage 20: | |||
Player.AddItem "BGHubartLetter" 1 | |||
Then click the "Compile Result" button. | |||
We can also add a new response info to the topic called BGHubart, to direct the player to Chorrol | We can also add a new response info to the topic called ''BGHubart'', to direct the player to Chorrol: | ||
{| class="wikitable" border="1" cellpadding="5" | {| class="wikitable" border="1" cellpadding="5" | ||
!colspan=2| '''BGHubart''' | |||
|- | |- | ||
! TOPIC | ! TOPIC TEXT | ||
| | | Captain Hubart | ||
|- | |- | ||
! RESPONSE | ! RESPONSE | ||
| You’ll find him in Chorrol | | "You’ll find him in Chorrol." | ||
|- | |- | ||
! CONDITIONS | ! CONDITIONS | ||
| | | | ||
GetIsID BGVilanusVilla==1 | *GetStage 'BGM001' == 20 | ||
*GetIsID 'BGVilanusVilla' == 1 | |||
|- | |- | ||
! ADD TOPICS | ! ADD TOPICS | ||
Line 1,164: | Line 1,195: | ||
Try this for yourself. You can always refer to the PLAYTEST version if you get stuck. | Try this for yourself. You can always refer to the PLAYTEST version if you get stuck. | ||
We have completed phase one, | We have completed phase one. You should stop to test everything out before moving on. Just test a few conditions to make sure that everything is working, and that you haven't made any small mistakes. | ||
==Chorrol Phase== | ==Chorrol Phase== | ||
In this phase of the quest we want to use a new NPC called Captain Hubart to direct the player to solve a mystery. He will direct the player to a cottage, where they will discover a mysterious medallion and the dead body of the courier. Hubart will then be able to help us move on to Aleswell and the next phase. | |||
For this phase, we will need to create: | |||
*NPC Captain Hubart | *NPC Captain Hubart | ||
*NPC Dead Courier | *NPC Dead Courier | ||
Line 1,179: | Line 1,209: | ||
*A cottage to house courier. | *A cottage to house courier. | ||
Again we need to add the NPC first so we can reference him in conditions. | Again, we need to add the NPC first so we can reference him in conditions. | ||
As always, we could use a new NPC object, but it really saves a lot of time and effort if we simply change the name and ID of an existing one. This time we can just copy a Chorrol Guard NPC, such as ''ChorrolGuardPatrolNight01''. Change the ID to ''BGCptHubart'', and save it as a new form. | |||
Strip out the AI, but leave his inventory as is, since the Chorrol guard's inventory already contains all we need. We can also leave the factions alone. I placed Hubart outside the Fire and Steel shop in Chorrol (worldspace ''ChorrolWorld'').<br /> | |||
This is only his starting position. We can add AI | ''Hint: a fast way to get to an exterior cell is to select the interior cell, and then click on the teleport marker by the door.''<br /> | ||
This is only his starting position. We can add AI packages later to move the character about. | |||
We have to set up a new | We have to set up a new response to the ''BGHubart'' topic. | ||
We could add a new topic but it is always a good idea to try to limit how many new topics we add | We could add a new topic but it is always a good idea to try to limit how many new topics we add. This reduces the ‘footprint' of the mod, and helps avoid possible conflicts with other mods. | ||
We want to set up a response that when any Chorrol based NPCs are questioned they will direct the PC toward the likely location of the | We want to set up a response so that when any Chorrol based NPCs are questioned they will direct the PC toward the likely location of the captain. Add conditions to limit the race to human again (saving all that MP3 work), and the location to the ''Chorrol'' dummy cell (thereby including all cells within Chorrol). We can also limit the ‘timescale' to the current quest stage (20). Try this yourself. You can always refer to the PLAYTEST version if you get stuck. | ||
{| class="wikitable" border="1" cellpadding="5" | {| class="wikitable" border="1" cellpadding="5" | ||
!colspan=2| '''BGHubart''' | |||
|- | |- | ||
! TOPIC | ! TOPIC TEXT | ||
| | | "Captain Hubart" | ||
|- | |- | ||
! RESPONSE | ! RESPONSE | ||
| | | "He's usually on duty near the Fire and Steel." | ||
|- | |- | ||
! CONDITIONS | ! CONDITIONS | ||
| | | | ||
GetInCell | *GetIsRace 'Argonian' == 0, etc. | ||
GetInFaction | *GetInCell 'Chorrol' == 1 | ||
GetIsID BGCptHubart == 0 | *GetInFaction 'ChorrolFaction' == 1 | ||
GetStage BGM001>= 20 | *GetIsID 'BGCptHubart' == 0 | ||
*GetStage 'BGM001' >= 20 | |||
|- | |- | ||
! ADD TOPICS | ! ADD TOPICS | ||
Line 1,217: | Line 1,250: | ||
The first can be attached to Vilanus Villa topic, to reduce the ‘footprint'. | The first can be attached to Vilanus Villa topic, to reduce the ‘footprint'. | ||
First, add a TOPIC called ''BGCourier''. | |||
{| class="wikitable" border="1" cellpadding="5" | {| class="wikitable" border="1" cellpadding="5" | ||
!colspan=2| '''BGMVilanusVilla''' | |||
|- | |- | ||
! TOPIC | ! TOPIC TEXT | ||
| | | "Missing courier" | ||
|- | |- | ||
! RESPONSE | ! RESPONSE | ||
| Vilanus has sent you to investigate the | | "Vilanus has sent you to investigate the courier's disappearance?" | ||
|- | |- | ||
! CONDITIONS | ! CONDITIONS | ||
| | | | ||
GetStage BGM001== 20 | *GetIsID 'BGCptHubart' == 1 | ||
*GetStage 'BGM001' == 20 | |||
|- | |- | ||
! ADD TOPICS | ! ADD TOPICS | ||
| BGCourier | | | ||
*BGCourier | |||
|- | |- | ||
! RESULT SCRIPT | ! RESULT SCRIPT | ||
Line 1,238: | Line 1,274: | ||
|} | |} | ||
Stop to test this out, and then refer to the PLAYTEST version if you are stuck. | |||
Before we go any | Before we go any farther, we need to set the scene at the cottage. | ||
==Locating the Cottage== | ==Locating the Cottage== | ||
Line 1,252: | Line 1,288: | ||
We want to set the internal scene in readiness for the PC's arrival. I have used a copy of the White Stallion Lodge as a base. We want to customise this. Again we can work on this in more detail when we polish the quest prior to release. | We want to set the internal scene in readiness for the PC's arrival. I have used a copy of the White Stallion Lodge as a base. We want to customise this. Again we can work on this in more detail when we polish the quest prior to release. | ||
We want to remove some of the clutter. We also want to give the impression a fight has taken place. Tips some chairs and tables over (Y=90). Remember this set will be locked at the start and you will only use it for a short time, so don't go overboard. We also want to place some props. We need an amulet to trigger the next phase. Why an amulet | We want to remove some of the clutter. We also want to give the impression a fight has taken place. Tips some chairs and tables over (Y=90). Remember this set will be locked at the start and you will only use it for a short time, so don't go overboard. We also want to place some props. We need an amulet to trigger the next phase. Why an amulet? It's small enough that you have to look for it, but not so small that it becomes hard to find. Copy an existing item of jewelry from Items->Clothing->Amulet as a base and edit it. Change the ID to ''BGEmbossedAmulet''. Check off the ''Quest Item'' box. The player can not drop or sell quest items. | ||
We also want to create a custom letter | We also want to create a custom letter called ''BGPartialLetter''. Set the letter as a quest item. We will refer to it in some scripts. | ||
<pre><nowiki> | <pre><nowiki> | ||
<br> | <br> | ||
Line 1,261: | Line 1,297: | ||
<br> | <br> | ||
<br> | <br> | ||
The client wishes his only living heir in Cyrodiil | The client wishes his only living heir in Cyrodiil to inherit his house. I have enclosed the deed and key. The location of the house is registered at the Imperial City Land Offices...<br> | ||
the deed and key. the | |||
<br> | <br> | ||
<br> | <br> | ||
Line 1,270: | Line 1,305: | ||
<br> | <br> | ||
</nowiki></pre> | </nowiki></pre> | ||
Of course | Of course it would look really cool if we could create a custom texture for a torn scroll, but that is beyond the scope of this tutorial. | ||
Finally we need to place the body of the unfortunate courier. | |||
Bodies are NPCs who just happen to be dead. You will need to create another NPC. Use ''Courier1'' as the base. | |||
Place this character in the render window, set its ID to ''BGDeadCourierRef'', and position the corpse in a suitable place. I put her in a side room so you don't see her right away. I also left a nice blood trail to lead you to her. Initially, the NPC will be standing up. | |||
Next click ''Edit Base'' to open the NPC window. Change the NPC's ID to ''BGDeadCourier''. Edit the NPC's health to read zero (0). (To access this stat, uncheck the ''PC Level Offset'' and ''Auto calc stats'' boxes.) | |||
Down she goes. | Now, the awkward thing is the fact that she is just standing there. She will stay standing in the game unless we make her fall first. To get her to fall, click on the WORLD menu and select ''Run Havok Sim'' (with the bouncing red ball). Down she goes. | ||
We can now drag her about to get the position right. | We can now drag her about to get the position right. | ||
I also placed a sword which pointed directly at the amulet. | |||
Next, we have to add the letter to the dead courier's inventory. Open the NPC window for ''BGDeadCourier'' and click on the ''Inventory'' tab. Then drag ''BGPartialLetter'' from the objects window over into the inventory list. You will be warned that the letter is a quest item. Just click OK. | |||
Another useful technique is to create an NPC called something like BGDummyPlayer | Another useful technique is to create an NPC called something like ''BGDummyPlayer''. We will not place this NPC in the world, so don't bother to edit anything other than the object ID. | ||
We can now set the ownership of the door and cell ( | We can now set the ownership of the door and cell ([[A_beginner's_guide,_lesson_3_-_The_external_world#Matching_Interiors|Lesson 3]]) to ''BGDummyPlayer''. This means that all items in the cottage will display the red hand, with the exception of the embossed amulet. This is a handy way to set ownership without having to create detailed NPCs. We can use ''BGDummyPlayer'' to set the ownership of all the doors and sets we want to prohibit our player from entering. | ||
Now create a key called ''BGCourierKey''. Select an existing key and change the editor ID. Also check the ''Quest Item'' box. Edit the cottage door to set its lock status to "Needs a key", and use our new object as the key. | |||
We need to add two other items to the cottage. | We need to add two other items to the cottage. | ||
We need to add an [[XMarker]] to the interior and | We need to add an [[XMarker]] to the interior, and a [[map marker]] to the exterior. | ||
We will find these under the Static Objects. | We will find these under the Static Objects. | ||
Drop an | Drop an XMarker or an [[XMarkerHeading]] object inside the cottage and give it a reference name like ''BGCourierLodgeXMarker''. | ||
Now select a MapMarker and drop it just outside the cottage door, in the exterior cell. | Now select a MapMarker and drop it just outside the cottage door, in the exterior cell. It looks a bit like a door teleport marker, but it's pink rather than yellow. | ||
It looks a bit like a door teleport marker but | |||
Edit its details to give it a reference name like | Edit its details to give it a reference name like ''BGCourierLodgeMapMarker''. | ||
Open up the MapMarker Data tab, check the marker data tick box and select settlement. | Open up the MapMarker Data tab, check the marker data tick box and select settlement. | ||
Theses flags control what type of icon appears on the players map. | Theses flags control what type of icon appears on the players map. | ||
Finally in the name box call it Courier Cottage. | Finally in the name box call it Courier Cottage. This is the name that will appear on the map. | ||
We need to add a bit of script to enable it. First we need to add a bit more conversation. | We need to add a bit of script to enable it. First we need to add a bit more conversation. | ||
Add | Add stage 30 in the stage tab, and create a topic named ''BGCluesFound'' (which we won't be editing just yet). | ||
Then create the following topic. | |||
{| class="wikitable" border="1" cellpadding="5" | |||
!colspan=2| '''BGCourier''' | |||
|- | |||
! TOPIC TEXT | |||
| Courier | |||
|- | |||
! RESPONSE | |||
| | |||
* "She's usually very reliable, but she failed to turn up for our usual meeting." | |||
* "She sometimes stays in a small cottage just west of here. I'll mark it on your map." | |||
* "Here's a key to get you in. Let me know what you find out." | |||
|- | |||
! CONDITIONS | |||
| | |||
*GetIsId 'BGCptHubart' == 1 | |||
*'''GetStage 'BGM001' == 20''' | |||
|- | |||
! ADD TOPICS | |||
| | |||
*BGCluesFound | |||
|- | |||
! RESULT SCRIPT | |||
| | |||
SetStage BGM001 30 | |||
|} | |||
Add one more response to this topic in case the player tries to talk to Hubart again after they've been given the key to the cottage, but before they've found it. | |||
{| class="wikitable" border="1" cellpadding="5" | {| class="wikitable" border="1" cellpadding="5" | ||
!colspan=2| '''BGCourier''' | |||
|- | |- | ||
! TOPIC | ! TOPIC TEXT | ||
| | | Courier | ||
|- | |- | ||
! RESPONSE | ! RESPONSE | ||
| | | | ||
"Did you check out the cottage?" | |||
|- | |- | ||
! CONDITIONS | ! CONDITIONS | ||
| | | | ||
GetStage BGM001 | *GetIsId 'BGCptHubart' == 1 | ||
*'''GetStage 'BGM001' == 30''' | |||
|- | |- | ||
! ADD TOPICS | ! ADD TOPICS | ||
| | | ''No add topic'' | ||
|- | |- | ||
! RESULT SCRIPT | ! RESULT SCRIPT | ||
| | | ''No script'' | ||
|} | |} | ||
Now in the stage tab for stage 30, add this to the journal: | |||
''Hubart told me that the courier sometimes stays in a small cottage just west of Chorrol. He marked its location on my map and gave me a key to the door. I should go check it out.'' | |||
And add this to the stage result script: | |||
And add this to the stage result script | |||
Player.AddItem "BGCourierKey" 1 | |||
ShowMap BGCourierLodgeMapMarker | |||
This | This gives the player the key to the cottage and activates the map marker. | ||
The | The syntax for the [[ShowMap]] Function is | ||
ShowMap MapMarkerID, enableFastTravel (optional) | ShowMap MapMarkerID, enableFastTravel (optional) | ||
The MapMarker ID is the reference id for the map marker. | The MapMarker ID is the reference id for the map marker. | ||
The enableFastTravel is an optional parameter which takes the value 1 if you want to be able to fast travel immediately. | The enableFastTravel is an optional parameter which takes the value 1 if you want to be able to fast travel immediately to that location. | ||
If | If enableFastTravel is not given (or set to 0) then you can not fast travel to that location until you've found it once. | ||
We still need to add all the quest targets, and we'll use the XMarkerHeading for that. | |||
Up | Up 'til now we have been using dialogue to control progression, but now we need to begin using scripts more continue. | ||
In [[A beginner's guide, lesson 7 - Using Scripts in Quests|Lesson 7]] we will complete the quest and focus on SCRIPTING. | In [[A beginner's guide, lesson 7 - Using Scripts in Quests|Lesson 7]] we will complete the quest and focus on SCRIPTING. | ||
[[Category:A beginner's guide]] | [[Category:A beginner's guide]] |