A billion years ago, I made a little game for the game jam Ludum Dare (Ludum Dare #23). A lot of my games are procedural, and just an exploration of a game mechanic but this was one of the few that had a story that had to be hand written. This was something I enjoyed, and planned to go back to someday. Flash-forward to today, and I’m remaking it for Android.

Most of the story elements were hard code in the original, but this project called for something new. I had the choice between picking a scripting language like Lua or Javascript, but opted to make my own. Here’s what it looks like

General Syntax

FUNCTION_NAME(arg1,arg2,arg2)

Functions are split up by semicolons or newlines and each arg can also be a function. Functions without brakes are taken literally – no quotes (commas and brackets should be escaped with backslashes, but I haven’t implemented it yet). There are a number of types of function

Condition Functions

These are functions that return a boolean. They start of quite simple

  • true() – returns true
  • false() – returns false
  • eq(a,b) – true if a equals b
  • gt(a,b) – true if a and b are numbers, and a > b
  • lt(a,b) – inverse of above (so really less than or equals)
  • isNull(a) – true if a evaluates to null
  • collides(w,h) – used on items, which have an origin. true if player x/y is inside of a box w wide and h high
  • inBounds(x,y,w,h) – true if player x/y is inside the defined box

Value functions

Like condition functions, but they return more than just boolean values, and can be null

  • get(a) – gets a variable named a (a is always interpreted as a literal)
  • add(a,b,c….z) – adds all values. Values that are null or not a number are interpreted as zero
  • rand(min,max) – picks a random floating point value, between min (inclusive) and max (exclusive)

Void functions

These don’t return anything, but they’re still important

  • set(a,b) – sets variable named a (literal) to the value of b
  • clear(a) – sets variable named a (literal) to null
  • if(condition,a,b) – If the condition evaluates to true, function list a is executed, else (if present) function list b is executed
  • teleport(name,x,y) – changes the level to the literal name. if present, moves player to specified x and y
  • sayChoice(text,choiceA,functionsA,choiceB,functionsB) – displays text text, and choices choiceA, choiceB etc. Choices and functions are listed in pairs, and the associated function list is executed once the user selects the named choice. Choices are optional, and can have any number listed
  • setChoices(choiceA,functionsA,choiceB,functionsB) – same as above, without setting text
  • onChange(cond,var,onTrue,onFalse) – evaluates condition cond. If the value differs from the value of variable var (literal name) then function list onTrue is executed if now true, and onFalse executed if now false. onFalse is optional

Variables

As functions belong to an item, there are local and global variables. Global variables start with a $, and include

  • $x – player’s x position
  • $y – player’s y position
  • $text – text displayed

Local variables don;t need a “this” prefix, but if referencing a variable of another item, you need to specify its name like itemName.varName. All items have the variables:

  • x – the item’s origin x
  • y – the item’s origin y

So what does this look like?

It’s not particularly pretty. There’s only one type of bracket, no objects, no arrays, no user-defined functions (yet) and IntelliJ obviously doesn’t have any idea of how to auto-format it.

onChange(
 collides(5,5),
 atDoor,
 setChoices(Outside,teleport(village1)),
 setChoices()
);
if(eq(get(talk),false),
  onChange(
   inBounds(38,41,5,4),
   talking,
   setChoices(
    Talk,
    set(talk,true);
   ),
   setChoices()
  )
 );
onChange(
 eq(get(talk),true),
 talkTmp,
 sayChoice(
   Go talk to your neighbour,
   OK,
   set($talk,null());
   setChoices()
 )
)

 

Leave a comment

Your email address will not be published. Required fields are marked *