escript

Simple macro-based event scripting engine.


Keywords
engine, escript, event, game, script, scripting
License
MIT
Install
haxelib install escript 0.4.1

Documentation


Simple system which utilizes macros to allow for linear time-dependant scripting in Haxe.

Allows to define scripts that incorporate waiting, as well as delayed execution or waiting for input, without having to resort to callbacks and overall spaghetti code.

openChatBubble("hello there");

sleep(2);

closeChatBubble();

As you can see in the above example, an event is defined in which a chat bubble opens for 2 seconds and then closes. And this is executed without freezing the thread, the code is simply rearranged in such a way that expressions are automatically split up and executed at the correct time.

Some of the main benefits of this system:

  • A linear scripting engine without the need to manage states and timers.
  • Do the scripting directly in Haxe, with access to the rest of the codebase.
  • Scripts are executed coherently, even though the time of execution of each line is dynamic, the scope is still respected, so it is possible to declare variables.

Installation

haxelib install escript

Usage

Define event scripts by extending the Event class.

import escript.Event;

class MyEvent extends Event
{
    // The start function contains the script that is run when the event is started.
    override function start()
    {
        // Do things.
        doThing();

        // Wait for 2 seconds.
        sleep(2);

        // Do more things.
        doMoreThings();
    }
}

Then an instance of EventEngine should be used to manage events.

import escript.EventEngine;
var engine: EventEngine = new EventEngine();

// Start new events.
engine.dispatch(new MyEvent());
engine.dispatch(new MyOtherEvent());

// Then update the engine in the game's update loop.
while (true)
{
    engine.update(deltaTime);
}

Scripting

The following methods to control execution are available within the script's environment.

  • sleep(t): Causes a delay in the script execution for a given time t in seconds.
  • pause(): Pauses a script, suspending execution until resume() is called on the event object.
  • x = input(?p): Pauses a script, suspending execution until write(d) is called on the event object, which will assign the input data d to x. Can optionally specify a custom input prompt p in order to differentiate input requests from the same event.

Note: The functions sleep() and pause() can only be called from the top-level of a method inside an Event class.

  • jump(s, t): Jumps to the script function s after a delay of t in seconds.
  • stop(): Aborts the execution of the current event.

Event engine callbacks

The following callback functions may be registered on the EventEngine instance, to be notified of changes to an event's state.

  • onEventDone(e): Invoked when event e has just finished.
  • onEventPaused(e): Invoked when event e has been paused.
  • onEventWaitInput(e, p): Invoked when event e has been suspended to wait for input, with input prompt p.

Limitations

  1. Functions like sleep() and pause() can only be called from the top-level of an event method.
override function start()
{
    // This is ok
    sleep(1);
}
override function start()
{
    if (x < 5)
    {
        // This is NOT OK
        sleep(1);
    }
}
  1. Calling other functions is possible, but using sleep() or pause() in a function called from a script will cause the original script to terminate at that point, with execution moving fully to the function that was called.
override function start()
{
    x = 1;

    foo();

    trace(x); // This will NOT run.
}

function foo()
{
    x++; // This will run.

    sleep(2);

    x++; // This will run.
}

So doing this to move from one script method to another is possible, but it should only be used at the end of a script.