Skip to main content

News

Topic: How to make a non-blocking event queue in the map engine? (Read 106 times) previous topic - next topic

  • DaVince
  • [*][*][*][*][*]
  • Administrator
  • Used Sphere for, like, half my life
How to make a non-blocking event queue in the map engine?
Imagine I have an event queue that triggers at some point, for example:

- Make player walk north a few tiles
- Then make NPC walk south a few tiles
- Then show a text box
- Then wait a little
- Then show another text box
- Then make both player and NPC walk north at the same time (as if he was following the NPC)
- End event when both reach their destination

To be honest, I'm not sure I've ever really known how to do this properly in a non-blocking way. You know, something that leverages the renderscript and updatescript in classic Sphere while not blocking anything else going on on the map. Now that miniSphere comes with its whole new and improved API, I'd like to know even more how to do this the proper way, but I'm not really even sure where to begin with this...

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • miniSphere Developer
Re: How to make a non-blocking event queue in the map engine?
Reply #1
This is exactly what Scenario was designed for, and of course it's an official part of the Sphere now thanks to me. ;)

The last standalone version of Scenario (3.8.1) actually included scenelets for moving persons around the map, but I removed them from the miniSphere version since the map engine is eventually going to be phased out.  There's nothing stopping you from implementing them yourself, though.  Anyway, how your example would look in Scenario is:

Code: (JavaScript) [Select]
import { Scene } from 'sphere-runtime';

new Scene()
    .move('scott', 'north', 3 * 16)
    .move('lauren', 'south', 3 * 16)
    .talk("maggie", "I'M HUNGRY!!! *munch*")
    .pause(5.0);
    .talk("Lauren", "You know Scott, pigz r dum!")
    .fork()  // fork the timeline
        .move('scott', 'north', 10 * 16)
    .end()
    .move('lauren', 'north', 10 * 16)
    .resync()  // ensure forks have finished
    .run(false);  // false = non-blocking, return immediately

And a .move scenelet might look like this:
Code: (JavaScript) [Select]
Scene.defineAction('move',
{
    start(scene, person, direction, steps) {
        this.name = person;
        // TODO: figure out commandID to send based on direction parameter
        for (let i = 0; i < steps; ++i) {
            QueuePersonCommand(person, commandID, false);
        }
    },
    update(scene) {
        // return true to continue, false to finish
        return !IsCommandQueueEmpty(this.name);
    }
});

Note that the resync in the above example scene is actually redundant, since there's an implicit sync point at the end of a timeline (= the timeline won't end until all its forks have).  I only put it there to illustrate its purpose. :)
  • Last Edit: August 04, 2017, 10:12:50 am by Fat Cerberus
miniSphere 5.0b2 (stable: 4.8.8) - Cell compiler - SSj debugger - thread | on GitHub
For the sake of our continued health I very much hope that Fat Cerberus does not become skilled enough at whatever arcane art it would require to cause computers to spawn enormous man-eating pigs ~Rhuan

  • DaVince
  • [*][*][*][*][*]
  • Administrator
  • Used Sphere for, like, half my life
Re: How to make a non-blocking event queue in the map engine?
Reply #2
Damn! I knew there was something but forgot what it was! It sounds like I need to start using Scenario as a standard addition to my games from now on.

Really happy that it even handles the forking! :D

  • DaVince
  • [*][*][*][*][*]
  • Administrator
  • Used Sphere for, like, half my life
Re: How to make a non-blocking event queue in the map engine?
Reply #3
Another question: can several of these run at the same time? For examples, for a few NPCs' moving paths in the background while the main event is happening in the foreground? And would that be as simple as constructing several Scenes and all running them non-blocking?

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • miniSphere Developer
Re: How to make a non-blocking event queue in the map engine?
Reply #4
Another question: can several of these run at the same time? For examples, for a few NPCs' moving paths in the background while the main event is happening in the foreground? And would that be as simple as constructing several Scenes and all running them non-blocking?

Yep, it hooks into Thread, which in turn hooks into the Dispatch API so things get updated on every map update. ;D

I actually use Scenario a lot for tweening menu animations and such.  That wasn't what it was originally designed for, but fork and resync work great for coordinating fades, slide-ins, etc.
miniSphere 5.0b2 (stable: 4.8.8) - Cell compiler - SSj debugger - thread | on GitHub
For the sake of our continued health I very much hope that Fat Cerberus does not become skilled enough at whatever arcane art it would require to cause computers to spawn enormous man-eating pigs ~Rhuan