GS2 States Language Format

Introduction

GS2 States Language (GSL) is a state machine definition language with a unique structure. A state machine is generally composed of Tasks, which represent multiple states, and Transitions, which represent transitions between tasks. When a message is sent from the outside, the “running Task” transitions based on the rules defined by the Transition to manage the state.

In addition to “running Tasks,” a state machine also has “state variables. There are several different types of Tasks, but in general, the process can be described by executing a GS2-Script. GS2-Script can refer to “state variables” and can rewrite “state variables” as a result of script execution.

(C) Game Server Services Inc. and affiliates.

Implementation of GSL specifications and derivative specifications are permitted free of charge. However, the above copyright notice must be included in any derivative works. You may not sublicense or sell derivative works of this specification.

This specification is provided “as is” without warranty of any kind, either express or implied, including, but not limited to, the implied warranties that this specification does not infringe the copyrights of others. Game Server Services, Inc. shall not be liable for any claims, damages, or other liability arising out of this use.

The sample code contained in this specification is licensed under the Apache License, Version 2.0 unless otherwise indicated.

GSL Examples

StateMachine MainStateMachine {
  Variables {
    int counter;
  }

  EntryPoint Task1;

  Task Task1(int initCounter) {
    Event StartLoop();
    Event Error(string Reason);

    Payload {
      args.variables.counter = args.params.initCounter
      result = {
          event="StartLoop",
          params={},
          updatedVariables=args.variables
      }
    }
  }

  SubStateMachineTask Task2 {
    using SubStateMachine;
    in (initCounter <- counter);
    out (loopCounter -> counter);
  }

  WaitTask WaitForExternalEvent {
    Event ExternalEvent(int newCounter);
  }

  Task Task3(int newCounter) {
    Event Pass();

    Payload {
      print(args.variables.counter)
      print(args.params.newCounter)
      result = {
          event="Pass",
          params={},
          updatedVariables=args.variables
      }
    }
  }

  PassTask Pass;

  ErrorTask Error(string reason);

  Transition Task1 handling StartLoop -> Task2;
  Transition Task2 handling Pass -> WaitForExternalEvent;
  Transition Task2 handling Error -> Error;
  Transition WaitForExternalEvent handling ExternalEvent -> Task3;
  Transition Task3 handling Pass -> Pass;
}

StateMachine SubStateMachine {
  Variables {
    int currentCounter;
    int loopCounter;
  }

  EntryPoint SubTask1;

  Task SubTask1(int initCounter) {
    Event Pass();
    Event Error(string reason);

    Script grn:gs2:{region}:{ownerId}:script:state-machine-0001:script:SubTask1
  }

  Task SubTask2(int currentCounter) {
    Event IncrementCounter();
    Event Pass();
    Event Error(string reason);

    Script grn:gs2:{region}:{ownerId}:script:state-machine-0001:script:SubTask2
  }

  PassTask Pass;
  ErrorTask Error(string reason);

  Transition SubTask1 handling Pass -> SubTask2;
  Transition SubTask1 handling Error -> Error;
  Transition SubTask2 handling IncrementCounter -> SubTask2;
  Transition SubTask2 handling Pass -> Pass;
  Transition SubTask2 handling Error -> Error;
}

GS2-Script examples corresponding to the samples

SubTask1

args.variables.currentCounter = args.params.initCounter
args.variables.loopCounter = 0
result = {
	event="Pass",
	params={},
	updatedVariables=args.variables
}

SubTask2

args.variables.loopCounter = args.variables.loopCounter + 1
if args.variables.currentCounter < 5 then
	args.variables.currentCounter = args.variables.currentCounter + 1
	result = {
		event="IncrementCounter",
		params={},
		updatedVariables=args.variables
	}
else
	result = {
		event="Pass",
		params={},
		updatedVariables=args.variables
	}
end

Language specification

StateMachine

StateMachine ${name} {

}

The StateMachine block is used to define a state machine, and there can be more than one in a file. A StateMachine can be named and must be unique within the file.

Variables

Variables {
  string ${variableName};
  int ${variableName};
  float ${variableName};
  bool ${variableName};
}

The Variables block allows you to specify the state variables that the state machine has. A state variable consists of a data type and a variable name.

The data type can be one of the following types

name | data type – | string string | String int | 64bit signed integer value float | 64bit floating point number bool | boolean value

EntryPoint

EntryPoint ${taskName};

EntryPoint is the first task to transition to when the state machine is invoked.

Task

Task defines a node that represents a state. There are several types of nodes for different purposes.

Task

Task ${taskName}(sting ${argumentName}, int ${argumentName}) {
  Event ${eventName}();
  Event Error(string Reason);

  Script ${scriptId}
}

The Task block is the most common node and executes a GS2-Script script. Tasks can be named, but must be unique within the StateMachine. The name defined here is used to specify the Transition between tasks.

Task ${taskName}(sting ${argumentName}, int ${argumentName})

Tasks can take arguments. Arguments may be none, singular, or multiple. Use “data type variable name” to declare arguments, and separate multiple arguments with commas.

Event ${eventName}();

Event defines the type of event received during the execution of a task. An event can have a name, and you can specify additional parameters to be attached to the event.

Event Error(string Reason);

Note that the event Error(string Reason) must be declared. It can send a message when an error occurs in a script, but it can also be sent by internal processes, such as when a script fails to execute.

Script ${scriptId}

Script specifies the script GRN of the GS2-Script to execute when transitioning to a task.

Payload {
  result = {
      event="Event",
      params={},
      updatedVariables=args.variables
  }
}

Payload directly specifies the GS2-Script to be executed when transitioning to the task.

A Task must implement either Script or Payload. If both are described at the same time, Script is adopted.

SubStateMachineTask

SubStateMachineTask ${taskName} {
  using ${nextStateMachine};
  in (${inputArgumentName} <- ${variableName});
  out (${outputVariableName} -> ${variableName});
}

SubStateMachineTask defines the process of moving the process to another state machine. The nextStateMachine is the name of the state machine to transition to.

in (${inputArgumentName} <- ${variableName});

in specifies the argument to pass to the entry point of the destination state machine. inputArgumentName is the name of the argument to be received by the task at the entry point, and variableName is the value to be passed as the name of a state variable in the source state machine.

out (${outputVariableName} -> ${variableName});

out is the parameter that the destination state machine receives when it transitions to PassTask. outputVariableName is the name of the state variable of the destination state machine, and variableName is the name of the state variable of the current state machine that will receive the returned result.

WaitTask

WaitTask ${taskName} {
  Event ${eventName}(sting ${argumentName}, int ${argumentName});
}

WaitTask is a task that does nothing in particular. It just waits for external messages to be sent. Typically used to wait for the result of a game in progress on the client.

Event ${eventName}(sting ${argumentName}, int ${argumentName});

Event defines the type of event to receive while executing a task. Events can have names that are accepted to be sent out, and parameters can be added to the event.

PassTask

PassTask Pass;

PassTask is a task that indicates the completion of a state machine on a required node. The name of the PassTask must be Pass.

ErrorTask
ErrorTask Error(string reason);

ErrorTask is a task that indicates an abnormal termination of the state machine at a required node. The name of the ErrorTask must be Error.

Transition

Transition ${taskName} handling ${eventName} -> ${nextTaskName};

Transition represents a transition between nodes. taskName is the name of the task to transition from, eventName is the type of event received, and nextTaskName is the name of the task to transition to.