TWU Script - Case Studies

TWU Script can be quite versatile, but sometimes it helps to have examples to study what can be done with TWU script.

We'll be going over the following use cases:

* An NPC that opens the a merchant dialog when the player selects one option, and tells the player a little tale when they select the other
* A quest chain that has multiple steps, together with pointers on what to do on each step when they return to the NPC that gave the quest
* An NPC that gives a player a random riddle that will send them to the location of a treasure chest, together with an item to open the chest

Which should display some of the flexibility and give you ideas on what to do yourself.

### Preamble: Quests and Quest Keys

Before we take a look at some things, let us first examine how to use quest keys.

In order to better structure your quest, TWU comes with a **Quest Key** feature. Quest Keys are, in the end, just sudo char vars that store an arbitrary number, but there are special means to access and work with these quest key

Quest keys can be used to structure quests into various stages. Take a simple quest, for example, that has the player do these things:

1. Let the player talk to a Town Guard. That Town Guard informs the player that there has been a theft, and that the merchant from whom goods were stolen is looking for someone to get the stolen goods back from the bandits
2. Let the player talk to the merchant, where the merchant tells the player where those bandits are
3. Let the player go towards the bandit camp and defeat the bandits to gain the merchants goods back
4. Speak to the merchant again to give back the goods, where the merchant tells the player to go back to the guard for the reward
5. Let the player go back to the guard to receive their reward, which completes the quest

Now if we take that rough "script", we can turn it into quest stages. Quest stages always have a number. Let's give our quest the key Q\_STOLEN\_GOODS. We would have those stages for Q\_STOLEN\_GOODS:

Q\_STOLEN\_GOODS - Stages
 20
 30
 40

Now we know which stages our quest has!

If we structure our quest like this, we are now able to create a script - in a very simple manner. Each NPC that is involved in the quest can now get an if-endif block that checks for each quest stage to then display a dialogue. The resulting script is, in the end, very linear and quite easy to understand. It is recommended to put your quest stages into a comment block at the beginning of the script, so that everyone may be able to understand it easier.

### Jump To Merchant

Let us take a look at a very easy example: We have a merchant, and that merchant will offer the player to show them their wares - or to tell them a tale.

Let's go over what we need for this:

* We need a script, obviously
* A TWU Utility NPC to hold the script
* A TWU merchant to hold the merchant definition when we exit to merchant mode

Let's start with the script, both as image and as text import:

```
{"ScriptId":851130752.0,"Name":"Nias Test Quest","Parts":[{"PartId":696829120.0,"StepType":15.0,"A":"Hoi there, Exiles!

Are you here to see my wares? I can tell you, getting these was quite the journey, they are well worth their price!","B":"Please show me your wares!;Actually, I would not mind hearing your tales.","C":"Nevermind","V":0.0,"N":"Initial Greeting - Give players options on what they would like to have from this interaction","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":726279488.0,"StepType":10.0,"A":"","B":"5||>0","C":"Please show me your wares!","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":550096128.0,"StepType":21.0,"A":"If the first option is selected, we put the merchant into merchant mod.","B":"","C":"","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":488784448.0,"StepType":27.0,"A":"","B":"","C":"","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":109164704.0,"StepType":11.0,"A":"","B":"","C":"","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":956114432.0,"StepType":0.0,"A":"I will gladly tell you about that!

It all started [...]","B":"And then?!","C":"I heard enough, thank you!","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":588427392.0,"StepType":0.0,"A":"And then [...]","B":"","C":"That was qutite the tale, thank you!","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":470534400.0,"StepType":12.0,"A":"","B":"","C":"","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}}]}

```

If you have problems understanding what each band does, head over to TWU Script. But here are the basics:

1. Present the player with options: Wares, Story or Leave
2. If the options is wares -> use the exit to merchant mode band to display the merchant interface
3. If the option is story -> use two display text bands to display a small story to the player, with the option to skip if it turns out to be boring.

Now. Next, we will need to make a merchant defintion. Let's have our merchant sell some items from Siptah. It could look like this:

Now we just need to combine both and voila, we got ourselves an NPC that can exit to merchant mode or tell the player a story.

### Webhooks - Tracking boss spawns

TWU can handle Webhooks. In this example, we'll be doing a simple script that will increment a character variable and a global variable (that track spawns of a specific boss) and then push them through a discord webhook into a discord channel.

Before you can do that, please set up a webhook for your channel. Follow the instructions here, and note down the URL of the webhook somewhere.

#### Setting up the Webhook in TWU

In the sudo admin panel, open the Thrall Wars menu and go to webhooks. Create a new, generic webhook. Then fill it like this:

#### The Script

With the webhook done, let's first go over the theory of what we have to do:

* We have to track the number of times a player has spawned a boss
* We have to track the number of times a boss has been spawned globally
* We have to push the data to a webhook after each spawn of the boss

Let's go through the problems one by one, before going over the script.

To track the numbers of executions, we can use global variables and character variables. Both are variables stored in sudo exiles, and TWU allows you to access and mutate them.

**Character variables** are bound to a player character, and are not shared across those. So one character can have variable "C\_MINO\_SPAWNS" with the value "5" and another character can have the variable "C\_MINO\_SPAWNS" with the value 3. Whenever you access a character variable, you access the variable for **that specific chracter.**

**Global variables** on the other hand are global to the entire server. All character share access to that variable, so when the variable "G\_MINO\_SPAWNS" is 10, then from wherever you read that variable, it has the value 10.

Implementing this, our boss script will look like this:

Next, we will notify the webhook after each successful trigger. To do so, we utilize the **TWU params.** Params can be treated as registers. They will, temporarily, hold a value until the script either finishes or the variable is replaced. There are 3 params available: param1, param2 and param3. You can access them in the text processor through {{param1}}, {{param2}} and {{param3}}.

Since our webhooks use the same text processor, these params will be available. So we change our script like this, to push the two tracking variable "C\_MINO\_SPAWNS" and "G\_MINO\_SPAWNS" into param2 and param3. It will look like this:

Now, if we execute this script, we get a message like this in discord:

`Nia has spawned boss "" (Player spawned 2.0 times, globally spawned 2.0 times)`

**But what about the boss name?**

This is the last bit of what we need. The boss name. Now, we could just make one webhook for each boss and be done with it, but we can also re-use the existing webhook. That's what the {{param1}} substitution was meant for.

We can't directly push a static value into a param. But we can push a static value into a char variable, and then push that char variable into param1! It will look like this:

Now we have the string "Minotaur" available in TEMP1 char variable, and then we can just push TEMP1 into param1. Done!

If we execute the webhook now, it will be completed:

`Nia has spawned boss "Minotaur" (Player spawned 3.0 times, globally spawned 3.0 times)`

And that's it! Here is the full script, with comments:

```
{"Version":"1.1","ScriptId":"456190688","Name":"Mino Spawn Test","Parts":[{"PartId":"814020224","StepType":0.0,"A":"Spawn Mino?","B":"Yes","C":"No","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"59846796","StepType":21.0,"A":"We use two variables to track the spawns:
C\_MINO\_SPAWN is the char var that tracks spawns for each character
G\_MINO\_SPAWN is the glob var that tracks spawns globally, across all characters","B":"","C":"","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"521378208","StepType":20.0,"A":"C\_MINO\_SPAWN","B":"","C":"","V":1.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"316995776","StepType":25.0,"A":"G\_MINO\_SPAWN","B":"","C":"","V":1.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"567491712","StepType":8.0,"A":"SPAWN\_MINO","B":"","C":"","V":1.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"739829696","StepType":21.0,"A":"To have the values available in the text processor of the webhook engine, we need to push the char variable and then glob variable into param2 and param3 to have them available as {{param2}} and {{param3}}","B":"","C":"","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"258339200","StepType":23.0,"A":"C\_MINO\_SPAWN","B":"0","C":"","V":2.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"24842066","StepType":26.0,"A":"G\_MINO\_SPAWN","B":"0","C":"","V":3.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"688070272","StepType":21.0,"A":"To reuse our webhook for each boss, we use a temporary char variable to then push it's value into {{param1}}.","B":"","C":"","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"57802060","StepType":13.0,"A":"TEMP1","B":"1","C":"Minotaur","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"903836160","StepType":23.0,"A":"TEMP1","B":"1","C":"","V":1.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"208044672","StepType":21.0,"A":"Lastly, we just trigger the webhook!","B":"","C":"","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"662038016","StepType":28.0,"A":"","B":"","C":"","V":167241424.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}}]}

```

### Server Guardian - Manual Validation

Something most servers will want is a server guardian. An NPC that will not let a player pass unless they have been verified in some way, usually by having opened up a ticket on discord. Such a server guardian can easily be implemented with TWU. The server guardian we are building here will be using manual validation!

Before you start, you will have to have the following already done:

* Created a Spawnpoint Override in TWU to an area that a player can not leave. Ideally, this is just a walled off building. Let's call it "Starter Area"
* Created a role in Sudo that you want to give to players that are verified. In this example, we will use the role "Exile".
* Created a warp somewhere outside the starter area, let's called it "Verified Start".

#### The Theory

So. We have our new player spawn in at the Spawnpoint override, and all they see is a utility NPC, let's call them "Guardio". Guardio is valiantly standing there, letting only players that are verified pass. Players that are not verified yet will be told to join a Discord server and submit a ticket for verification.

That means we have two cases we need to represent:

* Already verified players need to be teleported "Verified Start"
* Non-verified players need to be provided with a link and instructions

So. Let's start off with that! We hit Shift+U, go to Thrall Wars Utiltities and create a new script "Server Guardian"!

#### Two Branches

First let's create the two branches. We create an if-then-else-endif construct. As always, the simpler branch goes into the if, the complex branch goes into the else.

We can safely assume that verification will be the larger branch, so our condition would "is in role Exile". Somewhat like this:

#### Sending Verified Players Away

Great! Let's start with the if-branch. We determined that the player is already verified, so we simply use the warp-Band to warp a player to the Verified Start warp! Add a return band for good measure and we are done with this part. Of course, you can throw in some dialogue. Maybe tell the player that they should set a spawnpoint to not be affected by this!

#### Requesting player verification

Now the second part! We will start off with a display text to throw some text at the new player, with some general details about the server. To make sure the player really got the message, we will also post to local chat so that player can then copy the discord link off of it.

Alright! Script is done! Time to spawn yourself a new "Utility NPC". Add the script and your new server guardian is ready to use.

#### Potential Improvements

Obviously, you could improve this a bit further. You could:

* Add a server password that players can find on your discord and automatically grant the "Exile" role when the player enters the right password
* Use the discord webhook feature to notify your admins that a new player needs approval

#### Final Script

```
{"Version":"1.1","ScriptId":"637714752","Name":"Server Guardian","Category":"","Microscript":false,"Parts":[{"PartId":"162877296","StepType":10.0,"A":"","B":"11||>0","C":"Exile","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"116367080","StepType":21.0,"A":"Player is already verified. Send player to start!","B":"","C":"","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"476729632","StepType":5.0,"A":"","B":"","C":"","V":870265856.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"983520000","StepType":52.0,"A":"","B":"","C":"","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"771172224","StepType":11.0,"A":"","B":"","C":"","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"356120512","StepType":21.0,"A":"Player needs verification! Tell player to verify!","B":"","C":"","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"735221376","StepType":0.0,"A":"Hello and welcome!

[...]

discord.gg/my-cool-server","B":"Understood!","C":"","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"942045312","StepType":29.0,"A":"Hello and welcome! Please head over to discord.gg/my-cool-server to get yourself verified! Open a ticket there, an admin will get back to you!","B":"","C":"","V":1.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"833124800","StepType":52.0,"A":"","B":"","C":"","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}},{"PartId":"479964576","StepType":12.0,"A":"","B":"","C":"","V":0.0,"N":"","Condition":{"Key":"None","Operator":1.0,"Value":0.0}}]}
```