Denizen/0.7/Assignments

From Citizens Wiki

Assignments

Interact Script Assignment

Before a Denizen can run a script, it needs to be assigned first.

Assignments are defined in plugins\Denizen\assignments.yml

This yaml file contains a single node called 'Denizens' and each Denizen gets its own entry under this node.

Assignments must be made by hand. We recommend a good text editor like [Notepad++]

Here is a very basic example, assigning a single interact script to a Denizen named Steve.

Denizens:                         
  'Steve':                        
    Interact Scripts:                      
    - 10 Daytime in the City  

Let's break this down.

First, if you are unfamiliar with yaml, 'Interact Scripts:' contains a yaml list. Each item in the list is prefixed with '-'. indentation and spacing is important.

This assignment will work for Denizens named 'Steve'. Denizen NPC names are case-sensitive! Triggers that involve this NPC, such as a 'Click Trigger' will now attempt to call the script named 'Daytime in the City'.

The 10 before the name is the script priority, useful when assigning multiple scripts.

If you wanted to assign this same script to another NPC, you would make another entry like this:

Denizens:                         
  'Steve':                        
    Interact Scripts:                      
    - 10 Daytime in the City  
  'Bob':                        
    Interact Scripts:                      
    - 10 Daytime in the City  

Now Bob and Steve both have this one script assigned to them.


Multiple Script Assignments

The key to Denizens being dynamic is their ability to handle multiple scripts in different situations. Denizens can be assigned multiple interact scripts with varying requirements, changing their behavior based on player, npc, and world conditions.

The important thing to remember is that:

For each interaction with a Denizen: ONE, and only ONE script is picked to run.

Which script gets picked is based on several factors:

Ignoring that last item for now, the process goes like this:

Starting from highest priority and working towards the lowest, the Denizen engine checks each script's Requirements. The first script found that meets requirements is picked.

Let's look at an example.


assignments.yml ----

Denizens:

 'Steve':                        
   Interact Scripts:                      
   - 0 Regular Joe
   - 10 Joe the Builder  

script.yml ----

'Regular Joe':

 Type: Interact   
 Requirements:
   Mode: None
 Steps:
   1:
     Click Trigger:
       Script:
       - CHAT "Hello <PLAYER>! I supply builders only!"

'Joe the Builder':

 Type: Interact  
 Requirements:
   Mode: All
   List:
   - PERMISSION modifyworld.*
 Steps:
   1:
     Click Trigger:
       Script:
       - ENGAGE
       - CHAT "Hello <PLAYER> the Builder! Take this shovel!"
       - GIVE WOOD_SPADE QTY:1
       - FINISH
       - DISENGAGE

Denizen Steve has now been assigned two scripts. Upon player interaction, both scripts are checked for met requirements in order of descending priority. Since the "Regular Joe" script has NO requirements at all, it will ALWAYS get picked before scripts of lower priority. This is why you can see in this example we gave it a priority of 0.

What if both scripts had a priority of 0? In that case the first script to appear in the list would get picked. It's always best to give each assigned script a different priority to avoid any confusion.

An Overlay Interact Script Assignment

Advanced usage! Overlay Script Assignments are new in 0.7 and open a wide array of new possibilities with multiple script interaction. This is completely optional, and probably should be ignored if you are a first time user and instead be revisited when you start to master Denizen Scripting.

Normally, requirement-matching scripts are selected to run regardless of whether or not an actual matching trigger exists.

If no matching trigger exists on the active step in the the script for the player, either nothing happens or some default text is shown, depending on the type of trigger.

With an Overlay Assignment, the defined triggers become a part of the requirements for selection.

A script assigned with this option will never be selected for a trigger type it cannot process.

This makes it easy to tack-on script assignments that only handle one trigger type, without having to mash it in to an existing script.

To assign a script as an 'Overlay', place a ^ directly in front of the script name.

Example time:

---- assignments.yml ----

Denizens:                         
  'Steve':                        
    Interact Scripts:                      
    - 0 Proximity Joe
    - 10 ^Regular Joe
    - 20 ^Joe the Builder  

---- script.yml ----
'Proximity Joe':
  Type: Interact
  Requirements:
    Mode: None
  Steps:
    1:
      Proximity Trigger:
        Script:
        - CHAT "Nice to see you, <PLAYER>!"

'Regular Joe':
  Type: Interact  
  Requirements:
    Mode: None
  Steps:
    1:
      Click Trigger:
        Script:
        - CHAT "Hello <PLAYER>! I supply builders only!"

'Joe the Builder':
  Type: Trigger   
  Requirements:
    Mode: All
    List:
    - PERMISSION modifyworld.*
  Steps:
    1:
      Click Trigger:
        Script:
        - ENGAGE
        - CHAT "Hello <PLAYER> the Builder! Take this shovel!"
        - GIVE WOOD_SPADE QTY:1
        - FINISH
        - DISENGAGE

Here the 2 scripts from the last example will now only be selected for Click interaction, while the new 0 priority script will be selected for any interaction.

Let's see what happens in a few different scenarios.

First Scenario Let's say a Player clicks, doesn't have the permissions 'modifyworld.*', so therefore only two scripts meet requirements: 'Regular Joe' and 'Proximity Joe'. It should be pretty obvious what happens. 'Regular Joe' has higher priority, so a Click Trigger will use that script. The Player will see "Hello Player! I supply builders only!". That's the only trigger, right? Wrong. This leads us into the next scenario.

Second Scenario The first thing to trigger the Denizen NPC would actually be the Proximity Trigger. In a regular assignment situation, with the same permissions situation as the first scenario, 'Regular Joe' would beat out 'Proximity Joe' and since there is no Proximity Trigger in 'Regular Joe', no script would trigger. But this is an Overlay Assignment. Since there is no Proximity Trigger in the script 'Regular Joe', the next script available, 'Proximity Joe', would attempt to trigger instead. And what do we have here? A Proximity Trigger! The Player would see "Nice to see you, Player!".

Third Scenario Player triggers a Proximity Trigger. Player has permission 'modifyworld.*', so the highest matching script is 'Joe the Builder' since it has a priority of 30. But there is no Proximity Trigger for this script, so the next script in line is checked. 'Regular Joe', of course, has no Proximity Trigger either! And since both 'Joe the Builder' and 'Regular Joe' are Overlay Assignments, we're back to 'Proximity Joe' triggering, alerting the player "Nice to see you, Player!".

Do you see now the possibilities of the Denizen Script Engine? I love it

Simple, right? To get your teeth wet, take a look at this additional example situation which uses FLAGS and magic :) Advanced Scripts


Texts

In addition to handling the script assignments, there are also a few other things that can be declared in the Denizens node of assignments.yml. Under the text node you can define single chat lines that will be displayed for each of 3 core trigger types if there is not matching script found. Click, Damage and Chat. Additionally a message can be defined for when the Denizen is Engaged or its interaction cooldown isn't finished.

Settings here override the default setting found in Denizen/config.yml for this Denizen.

Denizens: 
  Castle Guard: 
    Interact Scripts: 
      - 10 Guard_Script
    Texts: 
      No Click Trigger: Don't poke, me, <PLAYER>!
      No Damage Trigger: Ouch! you lookin' to get smacked?
      No Chat Trigger: Eh, what's that?
      Denizen Unavailable: I'm busy right now.

Other Things to Note

Denizens with the same name use the same script assignments. The plus to this is the ability to quickly make 'generic NPCs' such as a 'Townsman' or 'Miner'. You can also assign to NPC IDs instead of name. This is covered in Advanced Usage.

All the scripts and configuration nodes are in YAML. Remember! Spacing is CRITICAL when dealing with YAML files. Each parent node and sibling node should follow the spacing and formatting guidelines set forth by the YAML 1.0 standard. Generally, your indents should remain consistant. In all the examples used in this guide, 2 spaces are used for indenting. Generally, whatever you choose should be maintained through your YAML document. Remember: NO TABS are allowed in YAML files. If you are using notepad++ to edit your scripts, be sure to change the tab->space setting in Preferences>LanguageMenu/Tab Settings.

In all the denizen YAML files, nodes are case sensitive! For example, in a script.yml, 'Scripts:' will work. 'scripts:' will not! All nodes are first letter capital, rest of the word lowercase. Scripts names follow this rule too! Also: Commands/Requirements are generally ALL UPPERCASE, but we'll get to that.

YAML tutorials can be intimidating, but this small tutorial on the Essentials wiki is pretty useful for basic YAML, which is the extent of which Denizens uses.