Script tricks

From Open Surge Wiki
Revision as of 01:54, 6 March 2020 by Alexandre (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

The legacy scripting system has been replaced by SurgeScript.

This section is deprecated due to newer versions. We ask that you don't use the information provided in this section, but read up on the most recent information available on this wiki or in the forum.

Overview

Do you know a scripting trick that you want to share with others? Please share it here. Your contribution is appreciated.

How to Use [If...Then...Else] Statements in an Object: The Blackbox Method

Trick by lunarrush

How to create:

  • Create an object which creates three other objects, one for each character which is only visible in editor mode. Ensure that the three objects which are created are not selectable in editor mode.
  • On the script for each of the three objects created by the master object add the tag observe_player "player_name", ensuring that each of the three objects is named differently and observes a different player ("Surge", "Neon" and "Charge").
  • Add the attach_to_player line to each of the sub-object's script.
  • Add the hide attribute to each of the sub-objects.

How to use:

Let's say that you have an object which requires that you change the player's animation. This would normally cause a problem because there was no way to sense which player was observed under the old system (nowadays there is: use on_observed_player). Using these three distinct objects, however, you now have a way to determine which is the observed player. Rather than using an on_player_collision decorator, use three on_collision tags, one for each object inside of your object. Then, although you need to describe more states you will be able to change the player animation depending on which of the objects collides with your object.

If you would like an example of how this has been used, please download the water object from the page I will list below and examine the script. You will see that I use the selector object to determine which player animation will be used upon drowning. Please remember that this may be one solution to the problem but it is not necessarily the only way to do it. The link: [1]

Reset Objects From Anywhere

Trick by SilverstepP

How to create:

  • Upon activation of an object, spawn a detector object using 'create child "'insert detector name here' 0 0"' (you may want to use a . at the beginning of the new object name so it won't needlessly clutter up your object list in the editor). This creates the 'detector' object on top of the activated object.
  • When the object is deactivated by some outside influence (For example: the Pipe Off Object) change the closest object of the detector to destroy itself and reset the object.
  • The object that's spawned should have a code that looks a bit like this:
object ".my_detector"
{
    requires 0.1.4
    always_active // This allows it to be reset from absolutely anywhere

    state "main"
    {
    }

    state "reset"
    {
        change_closest_object_state "original object here" "main (or whatever state the 'deactivation' occurs)"
        destroy      
    }
}

Important Note:

  • Make the detector destroy itself after its activated or else this strategy won't work.

How to use and when to use it:

This is basically one of the secrets behind the pipe entrance system.

It allows you to make a chain of objects that interact with a player... and still reset itself regardless of other objects of the same kind around it interfering (For example, you can put pipe entrances anywhere and they'd still reset the one you went out of, not others around it, even if they're closer to the Pipe Off Object).

If you simply use 'change_closest_object_state' to reset, it could affect the wrong objects (thus limiting creativity due to having to take this into account). This workaround solves that problem, and allows you to essentially reset any 'chain' of objects (similar to the pipe system) you may have made. For an example, refer to the Basic Pipe System object here: [2].

This is also present in the t-bar object here: [3]

How to detect if an object has been destroyed

Trick by Alexandre

The engine offers no way to detect directly if a given object has been destroyed (by using the destroy command, the level editor or by any other means). This trick consists in spawning an auxiliary object to detect when this event happens.

  • Suppose we want to tell if an object named Target has been destroyed. Let's spawn an object called Observer. The last one will tell us whether the target exists or not.
  • Observer will constantly attempt to send a message to Target: HELLO. If Target exists, it will reply with ACK.
  • In this example, if Observer doesn't receive an ACK message after 10 attempts of contacting Target, it will consider that Target does not exist anymore. The number of attempts is stored in $t.
  • Both objects must have the always_active flag to make this technique work.

The implementation below is a possibility. Alternatively, you could make Target spawn Observer and use change_child_state / change_parent_state to do the message passing.

object "Target"
{
    requires 0.2.0
    always_active

    state "main"
    {
        // do all the Target's business here
    }

    state "HELLO"
    {
        change_closest_object_state "Observer" "ACK"
        return_to_previous_state
    }
}

object "Observer"
{
    requires 0.2.0
    always_active

    state "main"
    {
        if "($t += 1) >= 10" "timeout"
        change_closest_object_state "Target" "HELLO"
    }

    state "ACK"
    {
        let "$t = 0"
        change_state "main"
    }

    state "timeout"
    {
        // 'Target' is not responding anymore
        textout "default" 0 0 "'Target' has been destroyed."
    }
}