Recent Changes - Search:

Britannia Wiki





edit SideBar

USECODE Lessson 1

USECODE: Lessson 1

Tools: Siege Tools (ST)
Reference Info: The Usecode System

Conversation System Documentation

Location of usecode libraries in ST (SVN): britannia_logic/world/global/usecode/library/u6p_logic_world/global/usecode/Library/

Navigation & GUI

  • ST has a nice Outline at the top left which makes it easier to find things in the file instead of scrolling through


  • While you are in a convo, banter or usecode file...
    • There is a hover over feature
    • An autocomplete feature (make sure that's turned on)
      • If you start to end a usecode statement, it will give you what functions and parameters are available for any given Library
    • To access these features, as an example, in u6p_npc, under added to library folder, pick a town and npc, bring up the convo
      • You can take your cursor and hover over a usecode statement already in there over the Library, Function or Parameter. It will give you basic info
      • When you are typing a new usecode:
        • Once you get to adding the Library name, it will bring up a box for autocomplete and you can choose what you want there
        • It will assist for function and parameters as well

Libraries - some of these are for specific things

  • PB Libraries
    • Banter Library -for use in banters
    • Component, Debug, Event Console, GameHelpers, librarymain, Skills, stdinclude, Tester, TesterCustom, UI, Utils, and WorldPosition - for tech use
  • U6P Libraries
    • u6pquest - keeps track of u6p quests that require multiples of things, such as the pirate map, and the multiple shrines needing to be free for getting ships
  • In ST, go to pb_logic - britannia_logic/world/global/usecode/library/
    • What you will see under that folder is our library - the skrit names are called a Library
      • some not commonly used - some used for tech
      • most are used in convos, banters, convo banters and usecode files
        • Convos - you have an NPC that the player talks to, it has keywords, etc. to interact
        • Banters - are fires, they are usually placed in the world with flags/usecode; if conditions are met, it will fire and the player will see it
        • Convo Banters - a hybrid. It fires like a banter and placed in the world, but also is like a convo in that it has keywords/options, etc (eg: Cove Temple)
        • Usecode - for use with lorebooks, items, etc.

Working & Using the Libraries

  • Within the Library listing, the blue text above each example lists every possible usecode option for that function, includes possible parameters & whether they are optional, required, etc.
    • These form the "words" of this programming language
    • If you know that your condition is about interacting with an NPC, it's likely what you want to use can be found in the NPC Library
  • Syntax is very important
    • a missing something, an extra something can make the convo bomb
      • eg: where the blonde female Av is talking to Gypsy and saying nothing, if you see that screen - something is very amiss with the usecode

Basic Structure

  • A simple usecode line is: <flag *When$("library.function?parameter_1:value_1")=true/false>(there is a space between "flag" and "*")
    • "library" = the library name (one of those skrits found in logic)
      • within each library there are functions and parameters that are assigned for possible use
      • For examples, open up NPC.skrit.
      • In the first one listed (and examples in blue):<flag *When$("NPC.IsHealer")=true>Option 1
        • Library = NPC
        • Function = IsHealer
        • Parameter & Value are not used in this one
        • Result can only be "true" or "false"
          • if this is set to true - the NPC is a healer and is in a work schedule
          • if false, then they do not heal
      • For example of parameter use:<flag *When$("NPC.InSchedule?schedule:mario_0800")=true>
        • Parameter = schedule:
        • Value = mario_0800
        • Can have multiple parameters, separated by a comma<flag *When$("NPC.InSchedule?schedule:mario_0800,mario_1300,mario_2200")=true>
          • for this keyword/trigger, if mario is in one of those 3 schedules, then it will proceed to give the text, options and actions within that trigger
          • if not, then it will continue to look for another trigger that has conditions that are applicable
      • There are some that have possible multiple parameters such as for NPC.IsActorNear<flag *When$("NPC.IsActorNear?template:sherry_npc")=true>Option 1


  • Nearly all flags are created by the person writing the usecode
  • Flags are used to progress to move the convos along
    • <flag flag_name=value>
      • "flag_name" is defined by the person doing the coding
      • Use unique names for "flag_name" unless you are tying something together
        • Eg: if you have two quests, and both are about the shipwrecks, you will not want to use the same flag for info regarding 2 ships if they aren't supposed to be tied together. Use something like empire_shipwreck, virtuous_shipwreck, etc.
        • Flag names are case sensitive
          • IMPORTANT: Always use lower case flags
      • If you are progressing along a certain path/story/line use the same flag name and progress through the values
      • If it's 2 different paths/stories/lines make the flag name unique
  • One common flag is used a lot:nameknown_npcnamewhere "npcname" is the name of the npc (eg: nameknown_Jaana)
    • It will always be in that format because it's somewhat hardwired in the system
    • Any previous ppl known from past Ultimas... will always be:nameknown_npcname=1
      • so Jaana will be nameknown
    • Any options will need to have the nameknown flag with it in Default Options and in the convo triggers after their name is known
  • Flag Values
    • All flags start in game as 0 (one exception is nameknown which always =1)
    • 0 = false
    • 1 = true
  • There is a file that then sets some flags before player gets to the gypsy realm.
    • Eg: because the player would have met them in previous Ultimas
      • Companions are set to nameknown=1
      • LB is nameknown=1
    • There are also other things set in pregame
      • such as what time it is in Britannia when you enter
      • also things like the traveling npcs, where they are at start is also entered in the background


  • Triggers are case sensitive
  • With triggers, we do use variations of lower and upper case


  • Does the engine care if you create a conversation that is not tied to anything else?
    • Convos are tied to the npc templates (using NPC Generator)
    • if the convo isn't tied to anything, you'll never see it and get errors if you try to interact with the npc
  • Conversation actions listing can be found at: Conversation Actions
  • Example - Look at Cabirus in Serpent's Hold (in "u6p_npc\ added to library" folder). His convo is just a place holder right now.
    • When you create a new convo, you get placeholder stuff (it's just the basics)


  • "000 Cabirus"
    • "000" is the NPC ID - Ignore this for now
      • It's not currently used for anything
      • Eventually those will be assigned
      • For now those are manually assigned (we have a wiki page that tracks numbers as we assign them)
    • Make sure the first letter of the name is capitalized, unless it's a special name that has no caps (eg: for an NPC with the name of e.e.cummings, the first letter of the name would not be capitalized, it would be all lower case)
      • The NPC name must be consistent with the template name for the NPC
      • This allows all references to the NPC to be tied together
      • If you have Cabirus and cabirus, the system thinks they are two different NPCs
        • Eg: There could be NPCs named thehawk, Thehawk, and theHawk, and the system would see them as three different people
  • "Look first:"
    • This is the statement that the player first sees when they click/interact with an NPC
    • It is the only line in which it's 'process' is on the next line:for a placeholder you see "You see and NPC"
  • "Alternate:"
    • Typically the statement you see on the 2<sup>nd</sup> & subsequent times you initiate a convo with the NPC
  • "Default Options:"
    • The default key words that connect to "triggers" that are available in the convo
      • Typically: "Name", "Job", "Bye"
    • "Conversation branches"
      • See next example
  • "trigger:"
    • The convo triggers, keyed by keywords
    • "response" - the output to the trigger
  • "Action: end conversation"
  • Example - Dr. Cat in Paws is a fully populated convo file.
    • You will see at the top "Look first:"
      • That is the -default- "Look first"
      • You need to always have a default text in the top Look first (doesn't matter what, just something)
    • "startup_trigger"
      • "startup_trigger" is always run first when the system accesses the convo
      • startup is technically run before the convo is started
        • If it is false, then it will hand off to the next logical step
        • If it is true, it will execute
      • It is important for NPCs that ask a question and needing a response from the player before the name, job and bye are given, such as for Ariana
      • "startup_trigger" is located always after the "Conversation branches:" line
    • The coding always goes in an order:
      • "npc_id" "name"
        • Integer, then npc name
      • "Look first:"
        • On line below: a description, then the response
      • "Alternate:"
        • Can be multiple alternates
        • Defined by flag & function statements
      • "Default Options:"
        • Open, job, bye
        • Additional defaults can be added using flags
      • "Conversation branches:"
      • Then all the "trigger" lines that make up the convos
    • For Dr. Cat, before we have the player get the options of name, job, bye, we wanted to check to see if Taynith was around (Taynith is an NPC and we need to know if she's in the area)
      • So we use the function IsActorNear (see lines 15-20 in figure below)
      • Then we have to give the parameter of her template - she's either there or not
      • So that means for startup_trigger you need 2 options in the first trigger for startup_trigger
        • One for true, one for false
        • Always use the true usecode first, then have the false after that one
        • So the first trigger (line 15) has text for when Taynith is around, so you fill out the "response:" with the applicable text (line 16)


  • Since she's around and he won't talk, we end the conversation (line 17) using the action"Action: end conversation"
  • When the player talks to him and Taynith isn't around, system will bypass the "true" option because it's not applicable, then read the next, which is the false
    • Note the response: <ignore>
      • This is used a lot
      • Since there is no specific text to alter, it will use the default text, which is the default text found after the Look first: statement (lines 4 & 5)
  • If the startup_trigger is false and not applicable, the system then looks at the 3 Look first:s that follow (the "Alternate:" statements in lines 7 thru 9)
    • Those are looking to see if Sherry is a party member and if Dr. Cat's shop is open
    • The system always checks to see if this is the first time you've talked to this npc
      • System starts at 0 for everything
      • startup_trigger and Look first: are like 0 (a clean slate)
      • startup_trigger also progresses, but it will always be the first thing checked
      • That is important for shopkeepers that sell via convos (See Example Arbeth)
    • In line 8 you will see:<flag *WhenAll$("!Party.IsPartyMemberNear?template:sherry_npc|Nameknown")=true><Look first:>
      • Notice the ! at the start of the WhenAll statement ("!Party. …)
      • ! means a negative or false
      • In a WhenAll that would mean... Sherry is not a party member = true
      • In line 7 the "!" is not present, so that line means … Sherry is a party member = true
      • The ! allows you to toggle a false or true condition
      • There are three types of "When" statements used to check conditions:
        • WhenAll are used when you have more than one condition and they all have to be either true or false
          • WhenAll statements use the "|" character to separate the different conditions
        • WhenAny is used when you have more than one condition, but only one needs to be true or false
          • WhenAny uses "|" and sometimes a "," to separate the different conditions
        • When is for a single condition that can be either true or false
      • For WhenAll statements, it is really, really important to make sure you cover every possibility, otherwise the convo will lock up
        • For this example, the possibilities are:
          • A) Sherry is a party member AND B) shop is open
          • A) Sherry is not a party member AND B) shop is open
          • A) Shop is closed (in which case it doesn't matter if Sherry is a party member or not)
      • Be careful as to how many WhenAll conditions you have, because you can end up with a lot of triggers for each usecode statement
        • It's not a good idea to check for 10 flags, if shop is open, and checking for party members in one because you have to write usecode for all of those possibilities
  • Shopkeepers that sell via convos
    • Look at Arbeth


  • The first thing done each time you access Arbeth's convo is to recalc pricing, and that calls up all the things needed to populate needed shop pricing and info first behind the scenes.
    • None of this is seen by the player
    • It ensures flags are set so the rest of the convo can use this information dynamically
    • Selling via convos will always be in the startup_trigger
  • Most of the time startup_trigger is behind the scenes, but it always involves options that are available before name, job and bye are needed:
    • Such as the NPC on Look first:
    • Alternate: have a question that the Av must answer first before they will talk in convo like Ariana (she wants you name before she will talk with you)
  • Once startup_trigger is done, then Look first: comes next
    • With Look first:, the system will show the Default Options and make the rest of the normal convo available to the player
  • Then the next possibility in general for a convo the system checks for is Alternate:
    • This is only done when the NPC's convo has previously been accessed
    • "Alternate:" must exist in the convo, or you get a black text when you talk with the NPC again
      • Even if it says the same thing as the "Look first:"
  • Once the system checks are done (startup_trigger, Look first, Alternate), it will then show you the "Default Options"
    • The basic ones are: "Name", "Job", "Bye"
      • These must always be present, or will cause major problems
      • Never use these keyword names in the "Trigger" "Add options:", or will totally hose the convo
    • The triggers following are for the Default Options of name, job, bye (see line 23 in Dr. Cat convo screenshot)
    • If additional options are needed, those are added using "Add options:"
    • Both of these can use Usecode, if you have conditions that must be met before they can be shown or accessed
      • In Dr. Cat's convo, under name (lines 32-35), you will see Add options: +<flag play_nim=1>Play Nim
      • That is for player convenience, so they don't have to wade through keywords each time to play nim


  • Also in the Default Options, you will see the same flag (just written different) with Dr. Cat's nameknown flag


  • what that does is:
    • if you have met Dr. cat before and he is nameknown, and you have talked to him about Nim before, then when you talk with him again, that keyword will be available with name, job, bye
  • For nameknown conditions you will need at least 2 options
    • One for default, so the player doesn't have to wade through triggers all over again each time
    • And another logic place in the regular options
    • Often it's easiest to be with the name trigger
  • If you look at the nameknown flags and others, there is a different format for them
    • A single flag will be <flag my_flag=value>
    • When you have to include in usecode to be considered with other conditions/flags, it will become:<flag *WhenAll$("Flag.EQ1?flag:play_nim|Flag.EQ1?")=true>
      • don't forget the flag: parameter
      • EQ will either be:
        • EQ0 EQ1 or just EQ
        • First 2 are easy to understand
          • if =0 use EQ0
            • for all flags that are -not- 0 or 1
          • use Flag.EQ?flag:my_flag&value:X
            • X will equal any value above 1
            • Look at Lazeena in Britain for an example of flags going up to 13
  • Now I know this might sound complicated, but it really isn't: all you need to do is:
    • take a trigger and decide if there are certain conditions that should be met
    • so, if for job you need to check if shop is open or closed use Nameknown true and false
      • You will have 2 job triggers
      • one for usecode true and other for usecode false
    • if you want to check for shop open and a party member is in party or not
      • then you will use a WhenAll and over all possible conditions
      • so if you have 3 unique situations of Sherry in party and whether shop is open
        • first will cover Sherry in party, shop open
        • second Sherry not in party, shop open
        • 3rd would be Sherry in party, shop closed
        • (or possible 4th) Sherry not in party, shop closed
        • For Dr. Cat we only have 3 since if shop is closed, we didn't care if sherry was in party.
        • If there was a reason to have a 4th unique text, we would have done the last 2 options
  • Summary
    • The system always looks at things in this order:
      • startup_trigger
      • Look first:
      • Alternate:
      • Default Options
      • Then at all subsequent triggers in the order you have them opened up with Add options:
    • Make sure all true usecode statements come first, then follow with false
Edit - History - Print - Recent Changes - Search
Page last modified on October 06, 2008, at 08:51 AM