Callback Messages

Revision as of 10:18, 12 July 2009 by Dʹlanor (Talk | contribs) (New page: With Callback Messages you can make an event, for example an animation or a sound, wait on another event to finish. There are several types of callback messages: oneshot callbacks for ava...)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

With Callback Messages you can make an event, for example an animation or a sound, wait on another event to finish.

There are several types of callback messages: oneshot callbacks for avatar animations, timer callbacks and event callbacks. Oneshot callbacks are discussed elsewhere but we must take them into account as well when we are going to set up the "wait to command" (waittocmd) table.


Note 1: This tutorial is far from complete. It just contains what has been figured out so far. If you have any additional information feel free to add it.

Note 2: This is an advanced tutorial which assumes that you are already familiar with setting up responders. In short, a responder consists of one or more command messages to be executed. Without callbacks all of these commands are executed at the same time.


General Principles

  • waittocmd keys are stored into a waittocmd table within the responder.
  • A waittocmd key is assigned to the command which should be waited on.
  • The waiton value of the next command (the command that should wait) is set to the value of the waittocmd key. A waiton value of -1 always means "do not wait".
  • waittocmd keys must be numbered in order of appearance starting with 0.
  • The number of callbacks can be defined for each responder (this may be optional).


Timer Callback Message

This is a simple type of callback. It makes the next command message wait for any given time. Here is an example AlcScript:

    logic:
        actions:
          - type: responder
            name: <responder name>
            responder:
                states:
                  - cmds:
                      - type: timercallbackmsg
                        params:
                            receivers:
                              - respondermod:<responder name>
                            id: 0
                            time: 3.14
                        waiton: -1
                      - type: <next message>
                        params:
                            <any params>
                        waiton: 0
                    nextstate: 0
                    ncallbacks: 1
                    waittocmd:
                      - key: 0
                        msg: 0
  • waittocmd key / msg: Ok, so we have a waittocmd key 0 but how do we set that key in the timer callback message? This has been a source of confusion for some time. At first glance you may think the key is set by the id property. However, this is not the case. You do not need to set the key in the message itself because it is already defined in the waittocmd table's msg property. "msg: 0" tells Plasma to look for key 0 in the first command it finds within the responder which happens to be our timer message (remember to count like a programmer starting from 0).
  • id: Should we set the id in the timer script to match our key? For simplicity's sake I would say yes, although this should not be necessary as long as the id is unique for this responder.
  • time: Setting the actual timer is straightforward. This is done by the time property (3.14 seconds in the example).
  • waiton: As you can see I have placed a generic "next message" into the script. All that matters here is its waiton value which should match our key: 0.
  • ncallbacks: And finally, since we have a single callback, we will set the number of callbacks to 1.


Event Callback Message

Event Callback Messages can make any command message wait on a previous animation- or sound command message. Let's add an animation with callback to our timer example:

    logic:
        actions:
          - type: responder
            name: <responder name>
            responder:
                states:
                  - cmds:
# msg 0, callback key 0
                      - type: timercallbackmsg
                        params:
                            receivers:
                              - respondermod:<responder name>
                            id: 0
                            time: 0.1
                        waiton: -1
# msg 1, callback key 1
                      - type: animcmdmsg
                        params:
                            receivers:
                              - 006D:<animated object>
                            animname: <animation name>
                            callbacks:
                              - type: eventcallbackmsg
                                params:
                                    receivers:
                                      - respondermod:<responder name>
                                    user: 1
                                    event: 1
                            cmds:
                              - addcallbacks
                              - continue
                        waiton: 0 #waits on msg 0, key 0
# msg 2
                      - type: <next message>
                        params:
                            <any params>
                        waiton: 1 #waits on msg 1, key 1
                    nextstate: 0
                    ncallbacks: 2
                    waittocmd:
                      - key: 0
                        msg: 0
                      - key: 1
                        msg: 1
  • waittocmd key / msg: The key / msg for our timer remains the same, but now we add a second key / msg combo to the waittocmd table. Keys must be numbered in order of appearance so this becomes key 1. "msg: 1" tells Plasma to look for key 1 in the second command in this responder, our animation command message.
  • user / event: We will set these to 1 to match the key. Again this is done for simplicity. Any other values unique for this responder should be ok.
  • waiton: The animation command waits on the timer with key 0 and therefore its waiton value must be 0. The generic "next command" waits on the animation with key 1 and therefore its value must be 1.
  • ncallbacks We now have 2 callbacks so we will set this to 2.


At this point you may wonder: Why did I put a useless timer message at the beginning of the responder? Was this only done as an example? Unfortunately, no. Somehow you cannot have an event callback as your first callback. It will fail. The first callback must be either a oneshot or a timer message. This is most likely a PyPRP bug. So for now if you are not starting the responder with a oneshot callback you have to start with a very short timer callback.

Advanced Example

In the previous examples the waittocmd key and msg values were the same. However, within complex responders this may be different. In such cases you will have to number your command messages carefully (counting up from 0) and then combine them with the proper key within the waittocmd table.

In the following RL example I had a very long elevator ride with 3 different sounds. A start sound, a running sound loop and a stop sound. Obviously these sounds should not all start at once. And I also needed to stop the sound loop at the end of the ride. So here we have a perfect example for callbacks. This is the AlcScript I used:

<animated object>:
    animations:
      - name: <animation name>
        autostart: 0
        loop: 0
    logic:
        actions:
          - type: responder
            name: <responder name>
            responder:
                states:
                  - cmds:
# msg 0
                      - type: soundmsg
                        params:
                            receivers:
                              - 0011:<start sound>
                            cmds:
                              - play
                              - setvolume
                            volume: 1
                        waiton: -1
# msg 1, callback key 0
                      - type: timercallbackmsg
                        params:
                            receivers:
                              - respondermod:<responder name>
                            id: 0
                            time: 0.5
                        waiton: -1
# msg 2
                      - type: soundmsg
                        params:
                            receivers:
                              - 0011:<running sound loop>
                            cmds:
                              - play
                              - setvolume
                            volume: 0.2
                        waiton: 0 #waits on msg 1, key 0
# msg 3, callback key 1
                      - type: animcmdmsg
                        params:
                            receivers:
                              - 006D:<animated object>
                            animname: <animation name>
                            callbacks:
                              - type: eventcallbackmsg
                                params:
                                    receivers:
                                      - respondermod:<responder name>
                                    user: 1
                                    event: 1
                            cmds:
                              - addcallbacks
                              - continue
                        waiton: -1
# msg 4
                      - type: soundmsg
                        params:
                            receivers:
                              - 0011:<stop sound>
                            cmds:
                              - play
                              - setvolume
                            volume: 1
                        waiton: 1 #waits on msg 3, key 1
# msg 5, callback key 2
                      - type: timercallbackmsg
                        params:
                            receivers:
                              - respondermod:<responder name>
                            id: 2
                            time: 1.0
                        waiton: -1
# msg 6
                      - type: soundmsg
                        params:
                            receivers:
                              - 0011:<running sound loop>
                            cmds:
                              - stop
                        waiton: 2 #waits on msg 5, key 2
                    nextstate: 0
                    ncallbacks: 3
                    waittocmd:
                      - key: 0
                        msg: 1
                      - key: 1
                        msg: 3
                      - key: 2
                        msg: 5
                curstate: 0
                flags:
                  - detecttrigger

First take a look at the waittocmd table. Hmm, that looks weird... The key and msg values do not match up at all here. Then take a good look at my comments in the script where I counted the command messages and their keys. At this point there should be a lightbulb appearing over your head. ;) If it does not then I am sorry. I'm afraid I cannot make it any clearer than this.

A few notes about the timers: The first timer had to be added because of the bug I mentioned earlier which prevents having an animation (or sound) as the first callback. And since I had that timer anyway I made it fire up the running sound loop somewhere halfway through the start sound. The running sound loop starts and stops rather abruptly and now the start sound can mask that. The second timer was added to make the sounds at the end more smooth. The stop sound has a fade in and a fade out so the timer makes the running sound loop right in the middle.