Denizen/0.6

From Citizens Wiki

< Denizen

Revision as of 16:04, 22 May 2012 by AgentKid (talk | contribs)

Note for Denizen Alpha: Some methods have been renamed in the new builds of C2. You must use build 194 of Citizens2.

Denizen.png

Denizen

Author aufdemrand
Version 0.5.3 ALPHA
Citizens build 2.0 dev build #194
Other dependencies Vault, a permissions system, and an economy system
Download Link
Download example scripts: Link
Description: Scriptable, interactive citizens!

Denizens are a great way to add MUD-style RPG Citizens (and some other features) to your server. Denizen NPCs use mini scripts with steps and events to interact with the player and world. They can be used in hundreds (thousands?) of different ways, from tutorials, to questing, to administrating and more!

Denizens are in ALPHA! Expect bugs! There is ZERO error handling for wrong scripts. If you would be so kind, please report them to the Github Issues page for Denizens. You can also get assistance with Denizens on the #citizens IRC channel on EsperNET from me (aufdemrand) when available. I'm working hard to add awesome features and to squash any bugs.


Changelog:

0.5.3 Alpha

  • Added SWITCH command. Denizens can now flip levers!
  • Added Denizen Project to Citizens Jenkins!

0.5.2 Alpha:

  • Fixed requirements WEARING and -TIME. Note: PermissionsBukkit users are still having problems with GROUP.
  • Added FOLLOW, TAKE, NARRATE, and CAST commands.

Smaller update than I planned, stay tuned for more!

0.5.1 Alpha:

  • Fixed requirements... they should all work now, except haven't tested requirements which can have an enchantment.
  • Added the ability to give Denizens 'Location Bookmarks'. Use /denizen bookmark location [name].
  • Added WALKTO, PERMISS, FINISH, RESPAWN, WEATHER and EXECUTE commands.
  • Started to flesh out /denizen help
  • Added activity scheduler.

Note: I've been having problems getting the NPCs to WALKTO a bookmarked location that is far away. Working on it.

Up next: Activity scripts.


Timeline:

  • Alpha -- You are here.
  • Beta 1 -- All functionality used in the example config files.
  • Beta 2 -- Additional functionality additional content pre-documented in this wiki.
  • 1.0 -- Bug fixes from Beta plus your ideas and contributions.
  • 1.5 -- Online script writer/manager.
  • 2.0 -- Profit???

Items in strikethrough have been planned, but not yet been implemented. These features will be coming soon and are just being documented in the meantime.

What will Denizens have to offer?

There are lots of cool things that the Denizens plugin has to offer, such as:

  • YAML scripted NPCs (Denizens) with a multitude of flexibility.
  • Triggered scripts on click, chat, location, and more!
  • Listener scripts run scripts when the player does a specific task.
  • Activity scripts run around the clock, and keep your Denizens lively.
  • MUD-like chat interface. You say to the Denizen, 'Very RPG!'
  • Completely customizable user experience let's you keep Denizens within your theme.

All these features are documented here, and it is recommended you read the entire document when using Denizens. First, let's get into the basics of scripted NPCs with Trigger Scripts.

A basic trigger script

First, we need a script. Scripts can be simple or very powerful, thanks to a wide array of commands and functions at your disposal. Each script has at least 2 parts, Requirements and Steps. For now, let's take this very simple script as an example. We'll get more detailed later on.

Scripts are defined in plugins/Denizen/scripts.yml

'Daytime in the City':   
  Type: Trigger
  Requirements:
    Mode: All
    List:
    - TIME Day
  Steps:
    1:
      Click Trigger:
        Script:
        - CHAT Welcome to the city! Isn't it beautiful in the daytime?

So what just happened there? A quick literal translation: This script is named 'Daytime in the City'. This name is used when assigning Denizen NPCs their scripts to use. When the script is called by a trigger, in this case a 'Click Trigger', for it to activate the Requirements set must be met, more specifically ALL of the requirements set. In this example, the only requirement is that the time in the world is daytime. If the Requirements are met, the script defined in the 'Click Trigger' is sent to be run. It will have the Denizen NPC chat to the player 'Welcome to the city! Isn't it beautiful in the daytime?'.

But before the script can be triggered, it needs to be assigned.

A basic assignment

In order for a Denizen to be associated with a script, he needs to be assigned to it. The following shows a simple assignment format.

Assignments are defined in the Denizens node found in plugins/Denizen/config.yml

Denizens:                         
  'Steve':                        
    Interact Scripts:                      
    - 10 Daytime in the City  
    Texts:
      No Scripts To Trigger: 'I have nothing to say to you at this time.'

Another literal translation. This assignement will work for Denizens named 'Steve'. Triggers that involve this NPC, such as a 'Click Trigger' will call the script named 'Daytime in the City'. The 10 before the name is the script priority, useful when assigning multiple scripts, but we'll get into that next. If no scripts meet requirements (in this case -- if it's NOT daytime when clicking on Steve), 'No Scripts To Trigger' will run instead. So to reiterate, if the player clicks on Steve during the daytime, the player will get a chat containing 'Welcome to the city! Isn't it beautiful in the daytime?' If the player clicks during the nighttime, since the script requirements are not met, the player will see a chat containing 'I have nothing to say to you at this time.'

Multiple Scripts

The key to Denizens being dynamic is their ability to handle multiple situations. This is done by multiple script assignments. Let's take this example configs below to see how script priority is handled.

---- Config.yml ----

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

---- Scripts.yml ----

'Regular Joe':
  Type: Trigger   
  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:
        - CHAT Hello <PLAYER> the Builder! Take this shovel!
        - GIVE WOOD_SPADE 1
        - FINISH

Denizen Steve has been assigned two scripts. Upon player interaction, each script is checked for met requirements. If only one script has their requirements met, it's clear what script will be returned. But what if both meet requirements? That's where the number before each script assigned comes in. Higher priority always wins. To break down this specific situation, if a player with the 'modifyworld.*' permission clicks on Steve, both scripts meet the requirements, but since the script 'Joe the Builder' has a priority of 10, and 'Regular Joe' only has a priority of 0, 'Joe the Builder' sends its script. 'Regular Joe' is simply ignored. Denizens can be issued as many scripts as you want. If two scripts have the same priority, the first in the list will be the one to trigger, if both scripts meet their requirements.

Some other basic 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'.

Scripts are defined in plugins/Denizens/scripts.yml

In the YAML files, nodes are case sensitive! 'Scripts:' will work. 'scripts:' will not! All nodes are first letter capital, rest of the word lowercase.

YAML Ain't Markup Lanugage

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.

From the official 1.0 YAML Specs, this is section 4.2.1 on Indentation:

YAML streams use lines and spaces to convey structure. This requires special processing rules for white space (space and tab).

In a YAML character stream, structure is often determined from indentation, where indentation is defined as a line break character followed by zero or more space characters. With one notable exception, a node must be more indented than its parent node. All sibling nodes must use the exact same indentation level, however the content of each such node could be further indented. Indentation is used exclusively to delineate structure and is otherwise ignored; in particular, indentation characters must never be considered part of the document's content.

Tab characters are not allowed in indentation since different systems treat tabs differently. To maintain portability, YAML's tab policy is conservative; they shall not be used. Note that most modern editors may be configured so that pressing the tab key results in the insertion of an appropriate number of spaces.

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.

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.


Denizens Node in detail

In addition to handling the script assignments, there are also a few other things that are declared in the Denizens node. Let's take this example to show the different options. Note: Some of the functionality in this has not yet been discussed, you may need to read further.

Denizens:

 'Steve':                        
   Interact Scripts:                      
     - 10 Joe the Builder  
   Options:
     Languages: HU EN
     Chat Name: Steve the Master Builder 
     Finish Cooldown: 600
   Texts:
     Finish Cooldown:
     No Scripts To Trigger: I have nothing for you at this time!
     Interact Cooldown: That's all I have for now! Come back later!


Denizen Options

  • Languages:
    Adds a spoken/understood language to the Denizen. Languages are defined in the Languages: node. See: #Languages
  • Finish Cooldown:
    Sets a delay for the speed in which you can trigger scripts between FINISHes. If the selected script only has a simple reward, this is a way to control how fast the player can re-trigger the NPC. In the above example, clicking on Steve will trigger the script 'Joe the Builder' in which he hands over a Shovel. With an interact cooldown specified, it keeps the player from getting a shovel every click. Instead, the player must wait 600 seconds. This will also delay any other script from triggering, if the script is required! Useful scenario: Script 1 gives a wood shovel, Script 2 gives a wood sword, but requires Script 1 to be complete first. To keep the player from redeeming Script 2 right away, use a Finish Cooldown.

  • Chat Name:
    Allows you to expand on a Denizens name, or completely change it. If this is set, all chat heard from the Denizen will use this 'Chat Name' instead of the actual NPCs name, which can only be one word. Note: On Human NPCs, this will NOT change the name above them in-game. For now, that is coded into the Minecraft client, which this plugin can not modify.


Denizen Texts

  • No Scripts To Trigger:
    If no scripts meet requirements, this message is CHATted instead.

  • Cooldown Not Yet Met:
    If an Interact Cooldown: is set and not yet satisfied, this message is CHATted instead.

Scripts Node in detail

The general structure of a script should always include the 'Name', 'Requirements', and 'Steps' nodes. These are required. You can optionally include 'Options', which include other conditions, such as if the script should have a cool-down or is not repeatable.

Scripts are defined in the plugins/Denizen/config.yml under the Scripts: node.


General layout of a Script

'Name of script':   # Name Node
  Type: ...         # Type Node
  Requirements:     # Requirements Node
    ...:
    ...:
      - ...
      - ...
  Steps:            # Steps Node
    ...:
      - ...
    ...:
  Options:          # Options Node
    ...:

Name Node

This node is pretty self-explanatory, but here are some things to keep in mind.

  • Names, just like nodes are case-sensitive! 'This script name' is different than 'THIS SCRIPT NAME'.
  • Names that contain spaces must have single or double quotes around it. ie: "This script": or 'This script': is acceptable.
  • If the name includes a single quote in it, you must use double quotes around it, or 'escape' the quote with another quote. ie: "John's Script": or 'John''s Script':


Requirements Node

This node sets the rules for the player to qualify for the script. There are a couple different options that you should know when using requirements. For example:

  Requirements:
    Mode: All
    List:
    - TIME Night
    - MONEY 1000000
    - STORMY

This would be a difficult script to obtain, for sure. To trigger, the time would have to be after 16000, but before 0, the player would need one million dollars on hand (or whatever economy you use), and the weather must be storming! But it shows the flexibility of requirements. First is the 'Mode'. Currently there are three different types. Second is the requirement type, with arguments if applicable.


Mode Types

[] indicates required field

  • ALL
    Requires all requirements listed to be met.
  • ANY [#]
    Requires the specified number of requirements to be met, out of the total of requirements listed.
  • NONE
    Requires NO requirements to be met.


Requirements Types

[] indicates required field, () indicates an optional field, OR indicates alternative usage.

  • NAME [Player Name] (or this Player Name) (or this Player Name..) (Etc..)
    Requires a specific player.
  • ITEM [ITEM_NAME] (# of that item, or more)
    Requires the player to have an item in their inventory. You can also specify an amount and enchantment.
  • WEARING [ITEM_NAME]
    Requires the player to be wearing a specific piece of armor.
  • HOLDING [ITEM_NAME] (# of that item, or more)
    Requires the player to have an item in their hand. You can also specify an amount and enchantment.
  • TIME [Day|Night] OR TIME [0-23999] [1-24000]
    Requires day or night. Alternatively you can specify a time window.
  • HUNGER [Full|Hungry|Starving]
    Requires a specific hunger state.
  • PRECIPITATING
    Requires a rain or snow.
  • SUNNY
    Requires clear skies. Note: This can still trigger at night as it does not check time.
  • WORLD [World Name] (or this World Name) (or this World Name..) (Etc..)
    Requires the player to be in a specific world, or worlds. You can check as many as you'd like with one line.
  • PERMISSION [this.permission.node]
    Requires one of the listed permission nodes. Only one is required. If you require multiple permission nodes, use multiple entries.
  • LEVEL [This Level # or higher] OR LEVEL [At least this Level #] [But no more than this Level #]
    Requires a specific Minecraft level, or a range of levels.
  • FINISHED [Script Name]
    Requires a specific script to be FINISHed, x amount of times or more. If no number is provided, 1 time is assumed.
  • GROUP [Name of Group]
    Requires the player be a member of a group. Requires a Permissions system that allows groups, such as PermissionsEX.
  • MONEY [Amount of Money, or more]
    Requires the player to have at least a certain amount of money on hand. Requires an economy system, such as iConomy.
  • POTIONEFFECT [POTION_EFFECT]
    Requires the player to be under the influence of a specific potion. You can use 'ANY' to specify the player just be under the influence of a potion, without being specific as to which type.

Negative Requirements Types

Requirements can also be 'negative' requirements. In the Requirements List, just place a '-' in front of the requirement to inverse its logic. For example, 'HOLDING IRON_SWORD' would require the player to be holding an Iron Sword. '-HOLDING IRON_SWORD' would require the player to NOT be holding an Iron Sword. All requirements have a negative alternative, even ones whose function overlaps, such as '-WEATHER Precipitating' and 'WEATHER Sunny' technically being the same thing. If anything, it can add to script readability.

  Requirements:
    Mode: All
    List:
    - -TIME Night
    - -MONEY 1000000
    - -STORMY

Negative requirements completely change our original example around. For this script to trigger, time needs to be Day, the weather in the current world must NOT be storming, and the player must not have more than 1000000 units of currency on them.

Steps Node

Steps are the meat of the script. They control what to listen for and what actions to take. Each script can have multiple steps, each with multiple triggers. Let's use an example.

'Welcome to Harbortown':
  Requirements:
    Mode: NONE
  Steps:
    '1':
      Click Trigger:
        Script:
        - CHAT What's your name, stranger?
        - HINT
      Chat Trigger:
        '1':
          Trigger: My name is /<PLAYER>/.
          Script:
          - CHAT Ah ha, your name sounds familiar! 
          - CHAT Are you from around this area?
          - ZAP
    '2':
      Click Trigger:
        Script:
        - HINT
      Chat Trigger:
        '1':
          Trigger: /Yes/, I grew up in Harbortown!
          Script:
          - CHAT I thought so, welcome back! 
            Have you heard about Tom the Taylor? 
            Isn't that just horrible?
          - ZAP 3 
        '2':
          Trigger: /No/, you must be mistaken. 
          Script:
          - CHAT Oh, sorry about that. 
          - CHAT Hey, if you're looking for some work, 
            Bill the Baker is understaffed! 
            This is the bakery's busy season.
          - ZAP 4
    '3':
      Click Trigger:
        Script:
        - CHAT I wonder if Tom the Taylor is doing any better.
        - NARRATE Perhaps you should check on Tom the Taylor.
    '4':
      Click Trigger:
        Script:
        - CHAT Oh, nice to see you again <PLAYER>!
        - CHAT Have you stopped by the bakery?

The sub-sections below reference this example.


Trigger Types

Steps handle the flow of commands and messages with triggers.

Denizen Triggers trigger from interaction with Denizens. They are defined in the Steps: node.

  • Click Triggers activate when the Denizen is clicked on.
Click Trigger:
  Script:
  - CHAT Scripts are nested as a list.
  - CHAT You can use any command that
    you'd wish.


  • Chat Triggers activate when players chat with Denizens. Players' chat within the configurable range will be directed to the Denizen instead of global chat. Chat also follows the configuration setting
Chat Trigger:
  '1':
    Trigger: The word needed to /Trigger/ is inside slashes. 
    Script:
    - CHAT Scripts are nested as a list.
    - CHAT You can use any command that
      you'd wish.

Script Commands

Note: There are plenty more to come, some I've even used in examples here but aren't in the alpha. Be patient, more are coming!

[] indicates required field, () indicates an optional field, OR indicates alternative usage.

  • ZAP (Step #)
    Progresses the player through the steps. ZAP used alone will progress to the next step. ZAP with a number following will progress the player to a specific step.
  • FINISH
    Marks the script as completed to check against with the requirement type 'FINISHED'.
  • LOOK [Close|Away]
    Toggle 'lookclose' on the Denizen.
  • GIVE [ITEM_NAME] (Quantity)
    Denizen will drop specified items.
  • TAKE [ITEM_NAME|MONEY] (Quantity)
    Takes specific item or money from the player.
  • CHAT [The text to chat.]
    Makes the Denizen talk to the player. Long messages will be formatted for multiple lines automatically.
  • NARRATE [The text to narrate.]
    Sends text to the player without branding the Denizen. Long messages will be formatted for multiple lines automatically.
  • FOLLOW [PLAYER|NOBODY]
    Makes the Denizen follow the player, or stop following the player.
  • WALKTO [Location Bookmark]
    Makes the Denizen walk to a specified location.
  • WALK [Z] [X] [Y] Note: Z(-NORTH(2)/+SOUTH(0)) X(-WEST(1)/+EAST(3)) Y (+UP/-DOWN)
    Makes the Denizen walk. This is not for making the Denizen to specific coordinates. The values for X Y and Z will get added or subtracted from the Denizen's current location.
  • RETURN
    Can be used after initiating a WALK command. This will make the denizen return to its previous location.
  • EXECUTE [ASPLAYER|ASNPC|ASSERVER] [command to execute] Ex: EXECUTE ASSERVER toggledownfall
    Executes a command, issues from either the Player, NPC, or Server. No need for a /.
  • STRIKE
    Strikes the player with lightning.
  • WEATHER [Sunny|Stormy|Precipitating]
    Sets the weather for the world.
  • RESPAWN [Location Bookmark]
    Despawns the Denizen and respawns it to a bookmarked location.
  • PERMISS [permission.node.to.add]
    Gives the player interacting the specified permission node.
  • SWITCH [block location] [ON|OFF]
    If a lever is found at the block location, it will be switched ON or OFF.


Denizen in-game bukkit commands

/denizen reload|save

  • Reloads|saves the config.yml and scripts.yml. Useful for testing scripts without rebooting your server.

/denizen bookmark location [name]

  • Stores a location to the selected Denizen for use with script commands such as RESPAWN and WALKTO. Note: Names can only be one word, and are unique to the Denizen.

/denizen bookmark block [name]

  • Stores the Player crosshair's block location to the selected Denizen for use with script commands such as SWITCH. Note: Names can only be one word, and are unique to the Denizen.