Scripting Overview

From Cloud Party Wiki
Jump to: navigation, search

Back to Scripting main page

Contents

What is Scripting?

Scripting allows an entity to respond when clicked, move around, create other entities, and other behaviors.

The scripts are written in a limited version of JavaScript/ECMAScript 5. If a script fails for some reason the error should be broadcast on the "scriptdebug" channel, which you can listen to as a user by running the command "/listen scriptdebug".

Defining Scripts

To create a new Script asset go to the Library pane and choose 'Script' from the 'Create' pulldown button.

To edit an existing Script asset, locate it in your library or palette and double-click it or select 'Edit' from the right-click context menu.

To attach a script to an object go to the Object pane, expand the 'Scripts' expander, and click the '+' button, then click the text area to choose a Script from your library. Objects can have more than one Script attached at a time - they will all run in parallel.

API Functions

The scripting language generally looks and feels like JavaScript, with a set of API functions you can call to create certain behavior or perform certain operations. For example, the following example is a script which will cause the entity to say "Hello, Cloud Party!" when it spawns.

say('Hello, Cloud Party!');

Script Functions

Functions you write, called Script functions, look like JavaScript functions. Each function you declare in your script represents a script function of the same name. The following example is an entity with three scripts functions, "up", "down" and "stop":

function up() {
  setVelLinear({vel: [0, 0, 1]});
}

function down() {
  setVelLinear({vel: [0, 0, -1]});
}

function stop() {
  setVelLinear({vel: [0, 0, 0]});
}

So this entity now has three script functions it could run. In this example nothing is actually calling them, they just exist. In order for the script functions to actually be run, something needs to call them.

At the top level of your object's code (outside any script functions you declared) you can directly call your script functions, just like API functions. These script functions and API functions will be run when the entity is first created in the world.

Direct calls to script functions

You can make direct calls to your script functions at the top level. The following example is an entity that will say "Hello, Cloud Party!" when it is created:

function alive() {
  say('Hello, Cloud Party!');
}

alive();

In this example we declare the 'alive' script function, which when run will call the say API function to say "Hello, Cloud Party!". We then call the script function. Because the call is at the top level it runs when the entity is created.

Global Variables and Script Function Arguments

You can also declare global variables and pass arguments to your script functions, similar to standard JavaScript. The follow example modifies the previous example to store parts of the phrase in global variables, and pass them to the script function.

var greeting = 'Hello';

function alive(prefix, suffix) {
  say(prefix + ', ' + suffix + '!');
}

alive(greeting, 'Cloud Party');

In this example we declare the 'alive' script function, which when run will call the say API function to say the prefix and suffix it is provided, with a comma and exclamation point added in. We then call the script function, passing it a global variable and a literal string. Because the call is at the top level it runs when the entity is created.

Indirect calls to script functions

There are also three API functions you can call to get your script functions up and running.

timerCreate()

Timers are objects that call a script function after a certain amount of time. Each timer has a name, and may have a script function name, a period, a jitter, a delay, and user-defined data.

  • "script" is an optional string that defines the script function name the timer will call. If no script is specified, the timer will call the script function with the same name as the timer.
  • "period" is an optional number that defines how much time passes between firings of the timer. If no period is specified the timer will fire just once and then remove itself.
  • "jitter" is an optional number that defines how much jitter there is on the period. For example, a period of 10 and a jitter of 0.5 means each period is anywhere from 9.5 to 10.5 seconds. If no jitter is specified the period time is always as specified.
  • "delay" is an optional number that defines how much time passes before the first firing of the timer. If no delay is specified the timer will fire immediately.
  • "data" is optional used-defined data that can contain whatever you want. The script function that is called by the timer can read the data by calling getTimerData().

The following example is an entity that hops into the air once every two to three seconds, and says "BORED!" after it's been around for 20 seconds.

Note: The entity must have its physics type set to 'Simulated' for the hopping to work.

function hop() {
  setVelLinear({vel: [0, 0, 5], world: true});
}

timerCreate({
  name: 'hop',
  period: 2.5,
  jitter: 0.5
});

function talk() {
  say(getTimerData());
}

timerCreate({
  name: 'bored',
  script: 'talk',
  delay: 20,
  data: 'BORED!'
});

In this example we have two script functions and two timers.

The 'hop' script function will cause the entity to hop into the air when it is called. The subsequent call to timerCreate() creates a timer named 'hop', which (implicitly) calls the 'hop' script function every 2.5 +/- 0.5 seconds.

The 'talk' script function will cause the entity to say the value returned by getTimerData() when it is called. The last call to timerCreate() creates a timer named 'bored', which (explicitly) calls the 'talk' script function after 20 seconds, setting its data to the string 'BORED!'.

handlerCreate()

Handlers are objects that call a script function when the entity receives a certain message. For example, a handler may respond to click events, collision events, or even the nearby conversation of other entities. Each handler has a name, and may have a script function name, channel, message filter, entity filter and user-defined data.

  • "script" is an optional string that defines the script function name the handler will call. If no script is specified, the handler will call the script function with the same name as the handler.
  • "channel" is a string that defines the channel the handlers listens on. There are a few pre-defined channels such as "chat" and "physics", but you can also listen to channels you and the other users make up on your own, such as "weather", "gameplay" or "robot_butlers".
  • "message" is an optional a string that matches against the messages on the channel. If you specify a message, only the messages on the channel that match exactly will trigger the handler.
  • "ents" is an optional array that lists the entities you are listening to. For example you can use this to filter out messages that come from anyone but the entity that created you.
  • "users" is an optional array that lists the users you are listening to. For example you can use this to filter out messages that come from anyone but the entity's owner.
  • "data" is optional used-defined data that can contain whatever you want. The script that is called by the handler can read the data at getHandlerData().

The following example is an entity that will say 'BOO!' and jump into the air whenever it is clicked.

Note: The entity must have its physics type set to 'Simulated' for the hopping to work.

function boo() {
  say('BOO!');
}

handlerCreate({
  name: 'boo',
  channel: 'direct',
  message: 'clickStart'
});

function move() {
  setVelLinear({vel: getHandlerData(), world: true});
}

handlerCreate({
  name: 'fright',
  script: 'move',
  channel: 'chat',
  message: 'say',
  ents: [ getSelfEnt()],
  data: [0, 0, 5]
});

In this example we have two script functions and two handlers.

The 'boo' script function will cause the entity to say 'BOO!' when it is called. The subsequent call to handlerCreate() creates a handler named 'boo', which (implicitly) calls the 'boo' script function whenever anyone clicks on the entity.<p>The 'move' script function will cause the entity to set its velocity to the value from getHandlerData() when it is called. The last call to handlerCreate() creates a handler named 'fright', which (explicitly) calls the 'move' script function whenever the entity hears something in local chat, but only if the entity it heard was itself. It sets its data to [0, 0, 50] so the 'move' script function will make it jump into the air.


Pre-defined Channels and Messages:

physics: collisionStart, collisionStop

direct: clickStart

chat: say

player: no predefined messages (listened to by all players, useful for finding nearby players)

controller: no predefined messages (used by default for controller communication)

scriptdebug: no predefined messages (used for error broadcasting)

call()

The call API function should not need to be used, but is included for completeness. It will run the script function with the matching name. The following example is functionally identical to the direct call example:

function alive() {
  say('Hello, Cloud Party!');
}

call({script: 'alive'});

In this example we declare the 'alive' script function, which when run will call the say API function to say 'Hello, Cloud Party!'. We then call the call API function, passing it an object which specifies which script function we want to call, in this case the 'alive' script function. Because call() is at the top level it runs when the entity is created, resulting in a call to the 'alive' script function.

Beginner Examples


Related Pages