Scripting

From Star Wars Combine :: Game Guide
Revision as of 10:25, 21 February 2017 by Kay Dallben (talk | contribs) (Custom NPC Environment)
Jump to: navigation, search

The scripting language used by SWC is currently available for speeches of Custom NPCs and for interactions with items (e.g. egg incubator).

The new language (SWC Lisp) is a big step ahead from the old system. Here we want to list the major differences with the old system to ease the conversion from the old system to the new one.

Wildcards (OLD SWC Script Syntax)

SWC Lisp Old Wildcard Description Example Default For Custom NPCs?
(get-name self) %npc.name% NPC's name Joe Bloggs N/A Yes
(get-race self) %npc.race% NPC's race Nautolan N/A Yes
(get-infofield self) %npc.infofield% NPC's infofield Master Carpenter N/A Yes
(get-gender self) %npc.gender% NPC's gender Male N/A Yes
(get-formal self) %npc.formal% NPC's formal greeting Sir/Ma'am N/A Yes
(is-ally? self) %npc.ally% is NPC IFF friendly? N/A N/A Yes
(is-enemy? self) %npc.enemy% is NPC IFF enemy? N/A N/A Yes
(is-neutral? self) %npc.neutral% is NPC IFF neutral? N/A N/A Yes
(is-unharmed? self) %npc.unharmed% is NPC unharmed? - requires (load "swclib") N/A N/A Yes
(is-slightly-wounded? self) %npc.slightlywounded% is NPC slightly wounded?- requires (load "swclib") N/A N/A Yes
(is-wounded? self) %npc.wounded% is NPC wounded?- requires (load "swclib") N/A N/A Yes
(is-badly-wounded? self) %npc.badlywounded% is NPC badly wounded?- requires (load "swclib") N/A N/A Yes
(get-name character) %character.name% Character's handle Selatos N/A Yes
(get-race character) %character.race% Character's race Human N/A Yes
(get-infofield character) %character.infofield% Character's 1st infofield Emperor Empty String Yes
(get-infofield2 character) %character.infofield2% Character's 2nd infofield 1st Recon Division Empty String Yes
(get-infofield3 character) %character.infofield3% Character's 3rd infofield 2nd Expansionary Fleet Empty String Yes
(get-gender character) %character.gender% Character's gender Male N/A Yes
(is-unharmed? character) %character.unharmed% is Character unharmed? - requires (load "swclib") N/A N/A Yes
(is-slightly-wounded? character) %character.slightlywounded% is Character slightly wounded? - requires (load "swclib") N/A N/A ]Yes
(is-wounded? character) %character.wounded% is Character wounded? - requires (load "swclib") N/A N/A Yes
(is-badly-wounded? character) %character.badlywounded% is Character badly wounded?- requires (load "swclib") N/A N/A Yes
(get-formal character) %character.formal% Character's formal greeting Sir/Ma'am N/A Yes
(get-entity-faction character) %character.faction% Character's current faction New Republic Freelance Yes
(is-owner? character) %character.isowner% Is character the owner of the NPC Produces no output Empty String Yes
(is-manager? character) %character.ismanager% Is character the manager of the NPC Produces no output Empty String Yes
(is-pilot? character) %character.issupervisor% Is character the owner of the NPC Produces no output Empty String Yes
(get-name (get-entity-faction character)) %faction.name% Character's faction's name New Republic Empty string (if freelance) Yes
(is-freelancer? character) n.a. is the character a freelancer? Yes
(faction-type (get-entity-faction character)) %faction.type% Character's faction's type Mining Empty string (if freelance) Yes
(faction-leader (get-entity-faction character)) %faction.leader% Character's faction's leaders name Ellias Empty String (if freelance) Yes
(faction-website (get-entity-faction character)) %faction.website% Character's faction's leaders name http://swcombine.com (Link) Empty string (if freelance) Yes
%owner.name% Name of the NPC's owner Darkness Empty string if special owner (Market, None) Yes
%owner.entityType% Type of the NPC's owner Faction or Character Empty string if special owner (Market, None) Yes
%owner.infofield% Owner's 1st infofield Emperor Empty String Yes
%owner.infofield2% Owner's 2nd infofield 1st Recon Division Empty String Yes
%owner.infofield3% Owner's 3rd infofield 2nd Expansionary Fleet Empty String Yes
(city-name character) %location.city% Current city name City 327 Unknown Yes*
(planet-name character) %location.planet% Current planet name Glee Anselm Unknown Yes*
(system-name character) %location.system% Current system name Danju Unknown Yes*
(sector-name character) %location.sector% Current sector name Tapani Unknown Yes*
(get-destination entity) %location.destination% Destination name "Corellia sector" (if deep space)
"Corellia system" (if heading to that system)

"Corellia planet" (if heading in sublight)
"Atmosphere (3,4) of Corellia" (if heading in atmo)
"Ground (3,4) of city Cityname on Corellia" (if heading to ground in city)
"Ground (3,4) at (4,7) on Corellia" (if heading to ground outside a city) ||Unknown ||Yes*

(get-eta entity) %location.eta% ETA for current travel 3 days, 24 hours and 5 minutes Unknown Yes*
(is-traveling? character) n.a. Checks if the character is traveling or not Yes
(get-name (get-container self)) %container.name% Current container name, e.g. the ship or vehicle standing in Tydirium Unknown Yes
(get-entity-type-name (get-container self)) %container.type% Current container type, e.g. the ship or vehicle standing in Lambda Shuttle Unknown Yes
(get-type entity-object) %container.entityType% Current container entity type, e.g. the ship, vehicle, city, planet, station Ship, Vehicle, City, Planet, Space Station N/A Yes
(in-room? entity-object) n.a. Checks if the entity is in any room at all, as opposed to outside on the surface Yes
cgt-year %cgt.year% Gets current CGT year 12 N/A Yes
cgt-day %cgt.day% Gets current CGT day 183 N/A Yes
cgt-hour n.a. Gets current CGT hour 23 N/A Yes
cgt-minute n.a. Gets current CGT minutes 59 N/A Yes
cgt-second n.a. Gets current CGT seconds 59 N/A Yes
timeofday %time.ofday% Gets current phase of day Morning, Afternoon, Evening N/A Yes

Entries with a "Yes" are available for custom NPCs. Entries with a "Yes*" may have some limitations on their use (e.g. they may not be available when the NPC cannot reliably determine the information without godmodding - for example location whilst in hyperspace).

Custom NPC Environment

This is the latest posting of functions and constants available to Custom NPCs. Some of these may not be synced to Main yet. Some are also listed above in Wildcards. Where possible, the syntax, required&optional parameters and example usage & evaluation are included.

SWC Lisp Required &Optional ("&") Parameters Description Example Evaluation Default eval Testing Status
self The object running the script (NPC, item...). Test Tickle n/a
character The character interacting with the object running the script. Kay Dallben n/a
evar 'name defaultValue This is a persistent variable in the context of self. See Persistent Variables for usage notes. special case defaultValue
ovar 'name defaultValue This is a persistent variable in the context of self & character. See Persistent Variables for usage notes. special case defaultValue
svar 'name defaultValue This is a persistent variable in the context of the current *session*. Session is the interaction between a PC and a scripted entity. See Persistent Variables for usage notes. special case defaultValue
#t This is "True" #t #t
+ a b &d &e … Basic addition function. Takes at least 2 numbers. a+b n/a
- a b &d &e … Basic subtraction function. Takes at least 2 numbers. Evaluates as a - b - c - d … or a - (sum b…n) a-b-c-d… n/a
> a b Preposition. Answers: Is a Greater than b? #t n/a
* a b Basic multiplication function. Takes at least 2 parameters. a*b n/a
/ a b Basic division function. Takes at least 2 parameters. a/b n/a
ge? a b Preposition. Answers: Is a Greater than OR equal to b? #t n/a
>= a b Preposition. Answers: Is a Greater than OR equal to b? #t n/a
le? a b Preposition. Answers: Is a less than OR equal to b? #t n/a
<= a b Preposition. Answers: Is a less than OR equal to b? #t n/a
gt? a b Preposition. Answers: Is a Greater than b? #t n/a
lt? a b Preposition. Answers: Is a less than b? #t n/a
< a b Preposition. Answers: Is a less than b? #t n/a
and a b &c… Logical Operand. #t if all its parameters are #t #t n/a
or a b &c… Logical Operand. #t if any of its parameters are #t. If it finds a #t, it will stop evaluating the rest of the parameters. #t n/a
not a Logical Operand. #t if a is #f #t n/a
concat stringA &stringB a concatenated string made up of the provided strings. abc… n/a
strlen string number of characters in the provided string a 4 n/a
trim string &character_mask removes:"\0" null "\t" tab "\n" new line "\x0B" vertical tabs "\r" carriage returns and " " spaces. &character_mask can be used to trim only some of those. sample string n/a
substr string start &length a string made of of the sequential characters within the provided string, beginning at the start character, and ending at &length, if provided. If &length is not provided, the rest of the string is provided. ample string n/a
stripos stringA searchFor &offset the start position of searchFor if contained in stringA, beginning the search at &offset. (stripos "sample string" "mp") -> 2 n/a
length listA number of elements in listA (length (list 'a 'b 'c 'd 4)) -> 5 n/a
reverse listA a list of the reversed elements of listA (reverse (list 'a 'b 'c)) -> (c b a) n/a
sublist listA offset &length &preserve_keys a list of the elements of listA beginning at offset and continuing to the end of listA OR to &length elements if provided. &preserve_keys should be #t or nil. NOTE: sublist will (perhaps unexpectedly) return strings from a list of symbols. Be aware when using it to get a sublist involving symbols. This is important because (eq? 'a "a") -> #f (sublist (list "a" 'b "c") 0 2) -> `("a" "b") n/a
sort listA a list of sorted elements of listA. Sort is alphanumeric. (sort `(b c a)) -> (a b c) n/a
nth-of listA n the element of listA at position n. 0 is the first element NOTE: nth-of will (perhaps unexpectedly) return strings from a list of symbols. Be aware when using it to get nth-of from a list involving symbols. This is important because (eq? 'a "a") -> #f (nth-of `(a b c) 1) -> "b" n/a
rand &min &max random number between &min &max. If not provided &min is 0 and &max is ?. See Randomization topic. (rand 0 5) -> 2 n/a
rand-from-list listA random element from listA NOTE: Be aware that rand-from-list will not return any Symbol if you give it a list of symbols. It will return a STRING if the random element it finds is a symbol. This is important because (eq? 'a "a") -> #f (rand-from-list `(a b c)) -> "b" or "a" or "c" n/a
get-entity-type-id name Type ID for the entity type name. {Ship, Vehicle, City, Planet, Space Station} (get-entity-type-id 'Planet) -> n/a
get-type-type typeID entityType returns a full TYPE (get-type-type 298 (enum "EntityType" "ITEM")) is equal to (get-item-type 298)
get-creature-type typeID returns the type of Creature (get-creature-type 175) returns the type for an Eye-Snatcher
get-droid-type typeID returns the type of Droid (get-droid-type 14) gets the droid type obj for Pit Droids
get-item-type typeID returns the type of Item (get-item-type 298) returns the type of a Focusing Crystal
get-npc-type typeID returns the type of NPC (get-npc-type NUM) returns the type for a NPC of typeid NUM needs testing
get-type-of entity returns the type object for the entity (get-type-of self) could return the type for a Quest NPC (if self is a quest npc)
get-npc-owner returns the "NPC Owner" object useful for an is-unclaimed? check.
get-hostile-owner returns the "Hostile Owner" object ie checks if it is a spawned Bandit/Creature
get-market-owner returns the "Market Owner" object
get-character name entity-object for character "name" (get-character "Kay Dallben") n/a
get-faction name faction-object for faction "name" (get-faction "Darkness") n/a
get-npc id npc-object for NPC with ID id (get-npc 155408) n/a
get-quest id quest-object for quest with ID id (get-quest 4408) n/a
get-item id item-object for item with ID id (get-item 481099) n/a
get-ship id ship-object for ship with ID id (get-ship 448088) n/a
get-vehicle id vehicle-object for vehicle with ID id (get-vehicle 46846816) n/a
get-room id room object for room ID. Rooms are commonly numbered among ALL of a given entity type. So all VSDs have the same room numbers, and no other entity has those room numbers. (get-room 4478) n/a
get-id entity ID for the entity (get-id (get-npc 100)) -> 100 n/a
get-name entity name of the object (get-name (get-vehicle 1150488)) n/a
get-formal entity Sir if gender is male, Maam if gender is female. (get-formal (get-character "Kay Dallben")) -> Sir n/a
get-infofield entity string of the first infofield of entity (get-infofield (get-npc 111548)) empty string
get-infofield2 pc-entity string of the 2nd infofield of entity (get-infofield2 (get-character "Kay Dallben"))
get-infofield3 pc-entity string of the 3rd infofield of entity (get-infofield3 (get-character "Kay Dallben"))
get-race entity string representing race of the entity (get-race self) n/a
get-gender entity string of the gender of entity (get-gender self) ->Male n/a
get-hp-status-text entity string of the hp-status-text {unharmed, slightly-wounded, etc.} (get-hp-status-text self) n/a
is-ally? test &source Preposition. Answers: is test an ally to &source (default: self) (is-ally? (get-npc 445158)) n/a
is-neutral? test &source Preposition. Answers: is test neutral to &source (default: self) (is-neutral? (get-npc 4408)) n/a
is-enemy? test &source Preposition. Answers is test an enemy to &source (default: self) (is-enemy? (get-npc 4408)) n/a
is-freelancer? test-character Preposition. Answers: is test-character a freelancer? (is-freelancer? (get-character "Kay Dallben")) -> #T n/a
faction-owned? entity Preposition. Answers: is the entity owned by a faction? (faction-owned? self) n/a
get-entity-faction entity faction-object for the faction entity belongs to? n/a needs testing
faction-type faction-entity type of faction String? needs testing
faction-leader faction-entity leader of faction String? needs testing
faction-website faction-entity website of faction String? needs testing
get-owner entity owner object of entity (get-owner self)-> Kay Dallben
get-type entity type of entity type ID or string? needs testing
get-entity-type-name entity name of type of entity string? needs testing
is-owner? Preposition. Answers: is character the owner of self (is-owner?) -> #t n/a
is-commander? Preposition. Answers: is character the commander of self (is-commander?)
is-manager? Preposition. Answers: is character the manager of self (is-manager?)
is-pilot? Preposition. Answers: is character the pilot of self (is-pilot?)
is-supervisor? Preposition. Answers: is character the supervisor of self (is-supervisor?)
in-room? entity Preposition. Answers: is entity in the same room as self? (in-room? (get-NPC 4808)) n/a
is-traveling? entity Preposition. Answers: is entity travelling? (is-traveling? (get-ship 3334)) n/a
get-container entity entity-object for container of entity. (get-container self) n/a
get-destination entity destination of entity needs testing
get-eta entity eta of arrival of entity to its destination needs testing
get-location entity String of location (currently including hyperlinks) if viewable without godmoding. needs testing
city-name entity Name of the city containing entity? needs testing
planet-name entity name of the planet containing entity? needs testing
system-name entity name of the system containing entity? needs testing
sector-name entity name of the sector containing entity? needs testing
send-message sender receiver message &subject Output: Sends a DM to receiver, from sender with message and subject &subject. Receiver and Sender must be any PC-object and self needs testing
flash type{'green 'red 'blue 'good 'bad 'info} message Puts a small coloured bar with the message on the screen of character. (flash 'green "You did it!") n/a
null null null
empty Use for the empty list `() null
nil aka #f null
cgt-year current year
cgt-day current day
cgt-hour current hour
cgt-minute current minute
timeofday string of timeofday Morning Afternoon Evening Night n/a
teleport-to-room entities container room ? needs testing
leave-room character direction ? needs testing
say message &close Output: NPC "says" message. &close is boolean. If true, this will start a new paragraph.
describe message &close Output: NPC "describes" message. &close is boolean. If true, this will start a new paragraph.
ooc message &close Output: NPC "oocs" message. &close is boolean. If true, this will start a new paragraph.
say-c message Output: NPC "says" message, continuing previous paragraph and using that formatting
describe-c message Output: NPC "describes" message, continuing previous paragraph and using that formatting
ooc-c message Output: NPC "oocs" message, continuing previous paragraph and using that formatting
add-response message callback Input: Adds a clickable option labelled 'message' that will a) display "You say " message; and b) run the callback function. NOTE: Currently the callback functions may not have any parameters.
add-action message callback Input: Adds a clickable option labelled 'message' that will a) display "You " message; and b) run the callback function. NOTE: Currently the callback functions may not have any parameters.
add-text message callback Input: Adds a clickable option labelled 'message' that will not display anything and simply run the callback function. NOTE: Currently the callback functions may not have any parameters.
add-input not implemented Input: creates a text box for the user to type something in. In progress.

Conditional Statements

The biggest differences are:

  • the "=" is no longer used to do comparisons;

Old system:

!if character.race=Gungan! Don't slip over!
!if character.race=Human! Humans are the best!
!ifnot character.race=Human! Alien scum!

New system:

(cond 
  [(eq? (get-race character) "Gungan") (say "Don't slip over!") (say "Alien scum!")]
  [(eq? (get-race character) "Human") (say "Humans are the best!")]
  [#t (say "Alien scum!")])

OR

(cond[(eq? (get-race character) "Gungan") (say "Don't slip over!") (say "Alien scum!")])
(cond [(is-owner?) (say "Oh, uh.  Welcome Boss!")]
  • with cond statement, the conditions are tested sequentially until one of them is true, and then it evaluates it and stops testing. This is much like an If...ElseIf...ElseIf. This means that if you have two statements, you must put them inside the same condition. If you have multiple alternate conditions (ElseIfs) to test, you must ensure that at least one of them evaluates true every time. Commonly this is done with a final [#t] condition.
  • You can use cond statements as a simple IF by only including one test.

Old system:

Responses:
!if character.race=Baragwin! !if character.gender=Female! Excuse me, how do you know I am a female? -> Baragwin female
!if character.race=Baragwin! !if character.gender=Male! Excuse me, how do you know I am a male? -> Baragwin male
!ifnot character.race=Baragwin! I'd like to have more information on the museum. -> info
!ifnot character.race=Baragwin! What can I do here? -> what to do
!ifnot character.race=Baragwin! Do I need to pay an entrance fee? -> fee

New system: NOTE: Technically, the last ElseIf can just be #t rather than (not (eq? (get-race character) "Baragwin")). This is because the first two checks cover all cases where the character could be a Baragwin (female or male).

  (cond 
    [(and (eq? (get-race character) "Baragwin") (eq? (get-gender character) "Female")) 
      (add-response "Excuse me, how do you know I am a female?" Baragwin-female)]
    [(and (eq? (get-race character) "Baragwin") (eq? (get-gender character) "Male")) 
      (add-response "Excuse me, how do you know I am a male?" Baragwin-male)]
    [(not (eq? (get-race character) "Baragwin"))
      (add-response "I'd like to have more information on the museum." info) 
      (add-response "What can I do here?" what-to-do)
      (add-response "Do I need to pay an entrance fee?" fee)][#t])

Note 2: Also, since the two add-responses in the first cases are so similar, you can combine them and toss the M/F determination, if important, into the Baragwin defun next conversation step.

(cond 
    [(eq? (get-race character) "Baragwin") (add-response (concat "Excuse me, how do you know I am a " (get-gender character) "?") Baragwin-female)]
    [#t
      (add-response "I'd like to have more information on the museum." info) 
      (add-response "What can I do here?" what-to-do)
      (add-response "Do I need to pay an entrance fee?" fee)])

Variable Examples

The following little script shows how to use session variables.

(defvar hp-session-var (svar 'hp 10))
(defvar str-session-var (svar 'str 5))
(defvar rand-val (svar 'rand (rand 1 5)))
(defvar setted-rand-val (svar 'setted-rand-val (rand 11 15)))
(defun (incr-hp val)
  (set-var! hp-session-var (+ hp-session-var val)))
(defun (incr-str val)
  (set-var! str-session-var (+ str-session-var val)))
(defun start
  (ooc (concat "Your HP is: " hp-session-var ". Your Str is: " str-session-var ". The rand-val is: " rand-val ". The 'setted-rand-val'  is: " setted-rand-val "." ) )
  (add-action "Set the setted-rand-val to store the rand between 6 and 10 for the whole session." set-rand-val)
  (add-action "Add 2 HP" add-2hp)
  (add-action "Sub 4 HP" sub-4hp)
  (add-action "Add Str to HP" add-str-to-hp)
  (add-action "Add Rand 1 - 9 to Str" add-rand-to-str))
(defun add-2hp (incr-hp 2) (start))
(defun sub-4hp (incr-hp -4) (start))
(defun add-str-to-hp (incr-hp str-session-var) (start))
(defun set-rand-val
  (set-var! setted-rand-val (rand 6 10)) (start))
(defun add-rand-to-str (incr-str (rand 1 9)) (start))

Public Script Modules

See the Rules Page on SWC for additional explanation.


swclib

(load "swclib")

is-unharmed? player-NPC-object - returns #t if player-NPC-object's HP-Status-Text is "unharmed" EG: (is-unharmed? character) -> #t

is-slightly-wounded? player-NPC-object - returns #t if player-NPC-object's HP-Status-Text is "slightly wounded"

is-wounded? player-NPC-object - returns #t if player-NPC-object's HP-Status-Text is "wounded"

is-badly-wounded? player-NPC-object - returns #t if player-NPC-object's HP-Status-Text is "badly wounded"

Contact: Selatos; Kay Dallben

funlib

(load "funlib")

join separatorCharacter list - Combine the elements of list with the separatorCharacter to form a string EG: (join ", " (list "Green" "Blue" "Yellow")) -> "Green, Blue, Yellow,"

map function list - Call function for each member of list and return the list of results. E.g. (map (lambda (x) (+ x 2)) (list 1 0 4) ) -> (3 2 7)

apply-foreach function list - Call function for each member of list but do not return results. e.g. (apply-foreach (lamda (x) (say x)) (list "I like" "cheesy poofs." "Do you?")) -> I like cheesy poofs. Do you?

append list element - adds element to the end of list e.g. (append (list 1 2) 3) -> (1 2 3)

reduce function init list - reduce a list to a single value, using the combiner function provided, which function takes two inputs init and (car list) e.g. (reduce (lamda (x y) (+ x (* 2 y))) 0 (list 1 2 3)) -> (((0 + 2*1) + (2*2)) + (2*3)) -> 12

repeat-fn function NumTimes object - repeat function Numtimes on object e.g. (repeat (lamda (x) (+ x 1)) 4 0) -> 4

eq-lists? listA listB - preposition: is listA equal to listB -> are all elements of A = all elements of B. - Does NOT currently take into account lists of lists, so just 1D lists atm. e.g. (eq-lists? `(a b c) `(d e f)) -> #f (eq-lists? `(a b c) `(a b c)) -> #t (eq-lists? `(a b c) `( `(a) b c)) -> Error.

neq? atomA atomB - preposition: is atomA NOT equal to atomB e.g. (neq? 1 2) -> #t

KayD-StringShortcuts

(load "KayD-StringShortcuts")

General Descrip: For inserting appropriate pronoun string based on gender.

heshe player-NPC-object EG: (say (concat "Yes, " (heshe (get-npc 54486)) " is pretty silly.")) -> "Yes, he is pretty silly." EG: (describe (concat (HerHis self) " gun points directly at you.")) -> Her gun points directly at you.

HeShe player-NPC-object

herhis player-NPC-object

HerHis player-NPC-object

herhim player-NPC-object

HerHim player-NPC-object

Contact: Kay Dallben

Basic Custom NPC Interaction

Conversation

Syntax Example of Use Actual Output
say string (say "Hello World!") "Hello World!"
describe string (describe "The droid beeps and burps.") The droid beeps and burps.
ooc string (ooc "Now go to the mentioned location and talk to the NPC there.")
add-response string next-function) (add-response "Wow, I didn't know that!" explainmore) say "Wow, I didn't know that!"
add-action string next-function (add-action " exit the room." room12) You exit the room.

LISP Language Functions

These are some general CLISP functions that are useable in SWC-LISP, and not necessarily included in the dbg-env tables above.

SWC Lisp Required &Optional ("&") Parameters Description Example Evaluation Default eval (if applicable)
car list The first element of the list. Aka 'First' (car `(1 2 3)) -> 1 n/a
cdr list A list of all the elements of the list, in order, except the first. AKA 'Rest' (cdr `(1 2 3)) -> (2 3) n/a
cons expr1 expr2 constructs a list from the two expressions provided. Typically used to prepend an element onto a list (push), using (cons atom1 list). Careful when consing atoms only. That creates a "dotted list" which can result in unexpected behaviour. If you want to make a list with just one element, either use (list atom) or `(atom), or (cons atom `()) aka (cons atom empty). (cons 1 `(2 3)) -> (1 2 3) n/a
list expr1 expr2 ... exprN Constructs a list out of atoms or lists, or I guess symbols. (list 1 2 `(3)) -> (1 2 (3)) n/a
empty? list checks if you have an empty list. Can have unexpected behaviour if attempting to store an empty list in a persistent variable. (empty? `()) -> #t (empty? `(1)) -> #f n/a
eq? atom1 atom2 Preposition: Are the two provided atoms equal? Unsure exactly which "eq" from LISP documentation this really is. Does not work for Lists. (eq? 1 1) -> #t (eq? 1 2) -> #f ... n/a
nth-of list index# aka "nth". Returns the nth element of list. Note: 0 is the first element. (nth-of `(1 2 3) 0) -> 1;

(nth-of `(1 2 (3 4)) 2 -> (3 4)

n/a
floor
ceil
round
log
modulo
stochastic_round

Admin-Only Functions

  • is-force-aware?
  • get-skill
  • get-force-skill

Admin scripts now have xvars and yvars which allow arbitrary context pairs (superseding q, o, t, e, etc. vars).

User scripts still have s-, o-, and e- vars

- *vars can now properly handle lists of values in addition to scalar values. Storing an instance of a class is not supported and (should) result in an exception being thrown.

How to Pass Parameters in Functions

Below you can see a simple example of creating a function accepting two parameters, and passing them.

(defun (myfun a b)
(ooc (concat "I do something with " a ", then I do something with " b)))
(defun start
(myfun "turkey" "salami"))

Another example with numbers. This calculate the absolute of a number.

(defun (abs x) 
  (cond
   [(lt? x 0) (* x -1)]
   [#t x]))
(defun start
  (say (concat "The absolute of 20 + -44 is " (abs (+ 20 -44)))))

Debugging Functions

  • dbg-break added to trigger an exception (ignoring the rest of the script) and print supplied values, for example (dbg-break self character (+ 1 2)) will display info about the current entity, current character, and the number 3
    • note that if you put (dbg-break) in the global scope (a line on its own), it'll block the whole script at startup. Instead, you must use it inside another function, in the point where you want the script to stop.
  • dbg-pp added to print values for debugging without triggering an exception (script continues), using the same semantics as dbg-break
  • dbg-env added, which dumps the entire symbol table (very large) and can be used to get basic information about the API to help with missing documentation

Understanding Errors

Most often, if you get an error it is a problem of parenthesis. When you save the script, the parser checks only for matching parenthesis; however, if the total of open parenthesis matches the total of closed parenthesis, the parser reports no errors on saving.

Symbol [name] is not defined!

If you get this error while the script runs, it could mean that there are misplaced parenthesis. In this case, go through your script placing your cursor on the end parenthesis to see if everything is ok.

If the error is not due to misplaced parenthesis, check that the name is not mispelt. If ok, check that the call to the function comes before the function called.

Symbol -> is not defined!

It is the easiest to fix. You've just written a "->" in an add-response function, between the end of text and the name of the function to go to. The old system used that symbol, but the new system need not that. Just remove that "->".

A second case is if you've added a parameter to the describe function different from close. Example, the old 'left alignment keyword, now invalid.

Symbol is undefined and cannot be evaluated

You've probably forgotten to specify where to go after an add-response text. Simply add the name of the function to continue with.

Mind the parenthesis if you have a concat function in add-response or other function with parameters. Example, this code is right:

(defun start
 (say "Hello, how may I help you?")
 (cond
   [(eq? (get-race character) "Kuati") 
   	(add-response "Excuse me, your dress is very elegant. May I know what caste are you?" caste01)]
   [(not (eq? (get-race character) "Kuati")) 
   	(add-response (concat "I see you are a " (get-infofield self) ". What do you do, exactly?") do01) 
   	(add-response "Are you a real expert on ships?" expert01)
   	(add-response "Very kind of you, but I am just browsing. No need for help." end01)]))

but if you write the add-response with the concat function as

(add-response (concat "I see you are a " (get-infofield self) ". What do you do, exactly?" do01))

you get this type of error, because the closing parenthesis of the concat function must go after the string end and before the next-function-name parameter.

Symbol set-var is undefined and cannot be evaluated

The correct syntax is set-var! (with the 'bang') and not set-var or setvar. Check your syntax.

Invalid speech option selected

This is a generic error, meaning that any thing wrong in the next-function-name called by the user click may cause this error. A syntax error, a logic error... Below you find some examples. Note that this error appears when you try to click on an answer, therefore you should look for the function called by that answer. You can use the (dbg-xx) functions in the functions called by the add-action/add-response/add-text to check your code for unexpected evaluation results.

  • If you're trying to concatenate a text with a describe, you'll get this error. Example:
(say (concat "Well, another protocol droid you can see here is the SP-4. It is defined as an analysis droid and it uses the same chassis and many parts assembled in the cheaper PK-series worker droid. You cannot say that it is made to resemble its owner..." (describe "winks")))

The solution is to put the describe in a single line, all alone, and remove the concat in the say function. `concat` only assembles several strings into one string. `describe` is a function that does not evaluate to a single string, and so concat cannot make proper use of it.

  • A conditional statement with a wrong use of keywords:
 (eq? (get-entity-faction character) "Galactic Empire")

is bugged;

 (eq? (get-name (get-entity-faction character)) "Galactic Empire")

is correct.

  • Adding a missing [#t] to a conditional statement.

`set-var!` can only be called on *vars

wip

Other Resources

You can also check out: http://racket-lang.org/ which is a version of LISP similar to SWC-Lisp and decent to practice with to get the basic idea of programming in LISP.

There is also LISP In Small Parts which is a good simple overview and basic introduction to LISP's methodology of programming. It primarily focuses on thinking about how to use the language, rather than memorizing the CLISP native functions (which won't help you in SWC-LISP).

Other Reading