Quantum / Q-script

Introduction to Q-script #

Q-script is an abbreviation for Quantum script, or code which runs in Quantum, the core framework products such as VNgen are built on. Quantum is a framework by XGASOFT designed to assign numeric IDs to blocks of code itself and provide a set of common practical functions to manipulate them, allowing for the creation of entirely custom programming languages within the GameMaker Language (or GML).

 

Structure

Q-script is structured in a hierarchy of events and actions, with some actions occasionally functioning as sub-events. Each event is self-contained, and will be executed in sequence. Individual actions within an event are executed simultaneously when the containing event is active. Once all of an event’s actions are complete, the current event will deactivate and the next event will be activated in its place. This process repeats itself until all events have been executed or the Q-script is terminated prematurely by the user.

Although Q-script itself does not require that events and actions be triggered by logical operators, for the sake of performance Quantum events are usually designed to be preceded by an ‘if’ statement, with actions following between brackets.

Example:

if (vngen_event()) {

   //Action 1

   //Action 2

   //Action 3

}

This sequence creates a single event, and should always be run in the Step Event of the running object. While it may appear that having many ‘if’ statements testing the same function will cause all of them to return the same result (by being either active or inactive simultaneously) Quantum enables each ‘if’ statement to return a unique result based on the corresponding event’s internal ID, which is generated automatically. Like quantum physics dealing with properties in indeterminate states, this unique and powerful functionality is what earned this framework the name ‘Quantum’.

 

Initialization

Q-script is initialized in three phases:

  1. The object Create Event
  2. The *_event_set_target operation
  3. The first frame of a new, active Quantum event

If the last two sound unfamiliar, don’t worry: these initialization phases are unique to Quantum and only require setting up once.

But first, the object Create Event. Before Q-script can run, the object it’s written in must be set up to run it. This is done with a simple *_init script, which can be customized to suit the needs of the individual product built on Quantum. In the case of VNgen, for example, this script is named ‘vngen_object_init’ and is customized with values that support both VNgen and Quantum itself out of the box.

Example:

vngen_object_init();

The other two initialization phases occur in the same object’s Step Event. Typically, all code placed in GameMaker Studio’s Step Event is executed every frame, but Q-script prevents this by only executing one Quantum event at a time. Again, this is due to its ability to assign numeric IDs to individual blocks of codea process which itself must be initialized before Q-script can be used. This is done with the *_event_set_target script, which must be run before any Q-script in the Step Event. Likewise, it’s just as imperative that the event target be reset once all Quantum event code is complete, which is handled by the *_event_reset_target script run after any Q-script in the code editor. Together, these two functions signal GameMaker Studio when Q-script begins and ends.

Example:

vngen_event_set_target();

if (vngen_event()) {

   //Action 1

   //Action 2

}

if (vngen_event()) {

   //Action 1

   //Action 2

}

vngen_event_reset_target();

The third and final initialization phase is performed within actions themselves, and can serve a variety of purposes depending on the action. Unlike the previous two phases, actions initialize automatically. However, it is important to be aware that any actions written in Q-script will not initialize until their containing event is active. When that occurs, there is a single frame in which all actions may perform any initialization necessary before proceeding onto any time-based activity, such as animations. There is no limit to how brief or long an individual action may be, but until all actions are complete or skipped by the user, the next event will not be activated.

 

Manipulating Events

As Quantum events are essentially nodes on a timeline, there will often come occasions when it is desirable to alter individual events’ behavior in a few key ways, such as:

  • Timing
  • Persistence
  • Execution order

These pertain to three optional arguments which can be supplied when creating Quantum events: pause, noskip, and label.

First, setting an event pause will delay execution of all further actions by the number of seconds supplied. Since events progress automatically, there may be times when stringing one event’s actions to the next feels too abrupt, or occurs too quickly for the user to keep up. In cases such as these, an event pause can work wonders for creating a smooth sense of flow, and in the case of sequenced animations, good timing is critical.

Tip: You can also add pauses between individual actions with an *_event_pause script

Second, an event’s persistence refers to whether or not its actions can be skipped by the user. If the ‘noskip’ argument is set to ‘true’, all actions will play out automatically for their full duration regardless of user input. However, be aware that some actions may override this behavior to prevent scenarios where events become impossible to complete due to user input being required.

The final property, the label, assigns a string to identify the event in addition to the automatically-generated numeric ID. Though not required, labels are inherently more memorable and become quite useful when used in combination with *_goto. As the name implies, running *_goto (e.g. vngen_goto(“my_event”);) will go to the Quantum event of your choice, effectively jumping anywhere in the timeline, forwards or backwards or even to other objects! This gives full control over the order events are executed.

These three arguments can be supplied in any order and any combination, but be aware that numeric values will always be interpreted as ‘pause’ first, then ‘noskip’.

Example:

vngen_event_set_target();

if (vngen_event("first_event")) {

   //Action

}

if (vngen_event(2)) {

   //Delayed action

}

if (vngen_event(0, true, "last_event")) {

   //Action

   vngen_event_pause(2);

   //Delayed action

}

vngen_event_reset_target();

 

Manipulating Actions

While Quantum events perform a fairly straightforward function, Quantum actions are much more difficult to define. There are very few limits on what actions can achieve, and some can even behave as sub-events themselves! However, actions are not plain code, nor should plain code be executed within a Quantum event. While events’ use of ‘if’ statements means this is possible to some extent, plain code will inherit almost none of the benefits offered by Q-script. It will have no third initialization phase, no ability to be skipped or prevented from skipping, and no protection from being executed repeatedly for as long as the event is active.

Therefore, Quantum actions, in the most basic sense, become Quantum actions when they are designed to follow a template which does inherit the benefits of Q-script: first they are initialized, then they are executed, then they perform any conditions for testing when the action is complete. Many actions also provide special conditions for how to behave when skipped.

With these basic behaviors in place, each Quantum-based product can use actions to achieve almost any effects desired. For more information, see related documentation for the action scripts you’re most interested in.

Tip: While you may not be able to run plain code in Quantum events, VNgen includes an action which ‘wraps’ other scripts to be executed as if they were Q-script, no modification required! See: vngen_script_execute() .

Last updated on November 8, 2017
Suggest Edit