GS2 States Language Definition Extension
extension syntax for defining GS2 States Language in CDK
GSL is a state machine definition language with excellent readability and descriptiveness, but it is not superior in terms of IDE input support and learning cost. CDK is available as a way to define GSLs using various programming languages.
Start defining a state machine
Use the following syntax to start a state machine definition
class TestStateMachine extends io.gs2.cdk.stateMachine.integration.StateMachineDefinition {
public TestStateMachine() {
// write state definition here
}
}
class TestStateMachine extends \Gs2Cdk\StateMachine\Integration\StateMachineDefinition {
public function __construct() {
parent::__construct();
// write state definition here
}
}
class TestStateMachine(gs2_cdk.state_machine.StateMachineDefinition):
def __init__(self):
# Write state definition here.
class TestStateMachine extends StateMachineDefinition {
constructor() {
super();
// Write the state definition here
}
}
public class TestStateMachine : Gs2Cdk.Gs2StateMachine.Integration.StateMachineDefinition
{
public TestStateMachine()
{
// Write state definition here.
}
}
State machine definition.
stateMachine(
"MainStateMachine", // name of the state machine
new IVariable[]{
new IntType("turn")
} // Parameters that the state machine receives
)
.entryPoint(task1.getName()) // first state name of the state machine
.task(
task1,
task2,
error // type of state
);
$this->stateMachine(
"MainStateMachine", // name of the state machine.
[
new IntType("turn"),
] // parameters received by the state machine
)
->entryPoint($task1->getName()) // first state name of the state machine
->task(
$task1,
$task2,
$error // type of state
);
self.state_machine(
name="MainStateMachine", # name of the state machine
variables=[
self.int_type("turn"),
], # Parameters that the state machine receives
).entry_point(
task_name=task1.name, # first state name of the state machine
).task(
task1,
task2,
error, # type of state
)
this.stateMachine(
"MainStateMachine", // name of the state machine.
[
this.intType("turn"),
] // parameters that the state machine receives
)
.entryPoint(task1.name) // first state name of the state machine
.task(
task1,
task2,
error // type of state
)
StateMachine(
"MainStateMachine", // name of the state machine
new IVariable[] {
IntType("turn")
} // Parameters that the state machine receives
)
.EntryPoint(task1.Name) // first state name of the state machine
.Task(
task1,
task2,
error // type of state
);
State definition.
Task
var task1 = scriptTask(
"Task1", // state name
new IVariable[0], // list of parameters to be received by the state
"""
result = 'Pass'
""" // Lua script to execute when transitioning to state
)
.result(
"Pass", // result issued by the script (Pass)
new HashMap<>(), // parameters to pass to the next state
task2.getName() // name of the state to transition to when a Pass is issued
)
.result(
"Error", // result issued by the script (Error)
Map.of(
new StringType("reason"), // name and type of the parameter to pass to the next state
"reason" // name of the Lua variable to pass to the parameter
),
error.getName() // name of the state to transition to if Error is issued
);
$task1 = $this->scriptTask(
"Task1", // state name
[], // list of parameters to be received by the state
"result = 'Pass'" // Lua script to execute when transitioning to state
)
->result(
"Pass", // result issued by the script (Pass)
[], // parameters to pass to the next state
$task2->getName() // the name of the state to transition to if Pass is issued
)
->result(
"Error", // result issued by the script (Error)
[
[
new StringType('reason'), // name and type of the parameter to pass to the next state
'reason' // name of the Lua variable to pass to the parameter
],
],
$error->getName() // name of the state to transition to if Error is issued
);
task1 = self.script_task(
name="Task1", # state name
arguments=[], # list of parameters that the state receives
script=""
result = 'Pass'
""", # Lua script to run when transitioning to state
).result(
result_name="Pass", # The result the script issues (Pass)
emit_event_argument_variable_names={}, # Parameters to pass to the next state
next_task_name=task2.name, # Name of the state to transition to if Pass is issued
).result(
result_name="Error", # Result issued by the script (Error)
emit_event_argument_variable_names={
self.string_type("reason"): # Name and type of parameter to pass to next state
"reason", # name of the Lua variable to pass to the parameter
},
next_task_name=error.name, # name of state to transition to if Error is issued
)
let task1 = this.scriptTask(
"Task1", // state name
[], // list of parameters received by the state.
`
result = 'Pass'
` // Lua script to execute when transitioning to state
)
.result(
"Pass", // result issued by the script (Pass)
new Map(), // parameters to pass to the next state
task2.getName() // the name of the state to transition to if Pass is issued
)
.result(
"Error", // result issued by the script (Error)
new Map([
[
new StringType("reason"), // name and type of the parameter to pass to the next state
"reason" // name of the Lua variable to pass to the parameter
]
]),
error.getName() // name of the state to transition to if Error is issued
);
var task1 = ScriptTask(
"Task1", // state name
new IVariable[0], // list of parameters that the state receives
@"
result = 'Pass'
" // Lua script to execute when transitioning to state
)
.Result(
"Pass", // result issued by the script (Pass)
new Dictionary<IVariable, string>(), // parameters to pass to the next state
task2.Name // the name of the state to transition to if Pass is issued
)
.Result(
"Error", // the result issued by the script (Error)
new Dictionary<IVariable, string> {
{
new StringType("reason"), // name and type of the parameter to pass to the next state
"reason" // name of the Lua variable to pass to the parameter
}
},
error.Name // name of the state to transition to if Error is issued
);
SubStateMachineTask
var task3 = subStateMachineTask(
"ChoiceSkill", // state name
"ChoiceSkill", // subStateMachineName to transition to
new InParam[] {
this.inParam(
this.intType("turn"), // state variable name of the currently executing state machine
this.intType("turn") // name of the argument to pass as a parameter to the first state of the sub-state machine
)
},
new OutParam[] {
this.outParam(
this.intType("choiceSkill"), // name of the state variable to receive as a result from the sub-state machine
this.intType("choiceSkill") // name of the argument to pass as a parameter to the state after returning from the substate machine
)
},
"InGame" // name of the state to transition to after returning from the sub-state machine
)
$task3 = $this->subStateMachineTask(
"ChoiceSkill", // state name
"ChoiceSkill", // name of the sub-state machine to transition to
[
$this->inParam(
$this->intType("turn"), // state variable name of the currently executing state machine
$this->intType("turn") // name of the argument to pass as a parameter to the first state of the sub-state machine
)
],
[
$this->outParam(
$this->intType("choiceSkill"), // name of the state variable to receive as a result from the sub-state machine
$this->intType("choiceSkill") // name of the argument to pass as a parameter to the state after returning from the substate machine
)
],
"InGame" // name of the state to transition to after returning from the sub-state machine
)
task3 = self.sub_state_machine_task(
name='ChoiceSkill', # state name
sub_state_machine_name="ChoiceSkill", # name of the sub state machine to transition to
in_params=[
self.in_param(
self.int_type("turn"), # name of the state variable of the currently running state machine
self.int_type("turn") # name of the argument to pass as a parameter to the first state of the sub-state machine
),
],
out_params=[
self.out_param(
self.int_type("choiceSkill"), # name of the state variable to receive as a result from the sub-state machine
self.int_type("choiceSkill") # name of the argument to pass as a parameter to the state after returning from the substate machine
),
],
next_task_name="InGame", # the name of the state to transition to after returning from the sub-state machine
)
let task3 = this.subStateMachineTask(
"ChoiceSkill", // state name
"ChoiceSkill", // subStateMachineName to transition to.
[
this.inParam(
this.intType("turn"), // state variable name of the currently executing state machine
this.intType("turn") // name of the argument to pass as a parameter to the first state of the sub-state machine
),
],
[
this.outParam(
this.intType("choiceSkill"), // name of the state variable to receive as a result from the sub-state machine
this.intType("choiceSkill") // name of the argument to pass as a parameter to the state after returning from the substate machine
),
],
"InGame" // name of the state to transition to after returning from the sub-state machine
)
var task3 = SubStateMachineTask(
"ChoiceSkill", // state name
"ChoiceSkill", // name of the sub-state machine to transition to
new InParam[] {
InParam(
IntType("turn"), // state variable name of the currently executing state machine
IntType("turn") // name of the argument to pass as a parameter to the first state of the sub-state machine
)
},
new OutParam[] {
OutParam(
IntType("choiceSkill"), // name of the state variable to receive as a result from the sub-state machine
IntType("choiceSkill") // name of the argument to pass as a parameter to the state after returning from the substate machine
)
},
"InGame" // name of the state to transition to after returning from the sub-state machine
)
WaitTask
var task4 = this.waitTask(
"WaitChoiceSkill" // state name
).result(
"ChoiceSkill", // name of the event to wait for
new HashMap<>() {{ // parameters of the event to wait for
put(
stringType("skill"), // type and name of the parameter to pass to the destination state
"skill" // name of the parameter to receive in the event
);
}},
"ChoiceSkill" // name of the state to transition to when this event is received
).result(
"ReLotterySkill", // name of the event to wait for
new HashMap<>(), // Parameters of the event to wait for
"ReLotterySkill" // name of the state to transition to when this event is received
)
$task4 = $this->waitTask(
"WaitChoiceSkill" // state name
)->result(
"ChoiceSkill", // name of the event to wait for
[ // parameters of the event to wait for.
[
$this->stringType("skill"), // type and name of the parameter to pass to the state to transition to
"skill" // name of the parameter to receive in the event
]
],
"ChoiceSkill" // name of the state to transition to when this event is received
)->result(
"ReLotterySkill", // name of the event to wait for
[], // Parameters of the event to wait for
"ReLotterySkill" // state name to transition to when this event is received
)
task4 = self.wait_task(
name="WaitChoiceSkill", # state name
).result(
result_name="ChoiceSkill", # name of the event to wait for
emit_event_argument_variable_names={ # Parameters of the event to wait for
self.int_type("skill"): # Type and name of the parameter to pass to the destination state
"skill", # Name of the parameter to receive in the event.
},
next_task_name="ChoiceSkill", # name of the state to transition to when this event is received
).result(
result_name="ReLotterySkill", # Name of the event to wait for
emit_event_argument_variable_names={ # Parameters of the event to wait for
},
next_task_name="ReLotterySkill", # Name of the state to transition to when this event is received
)
let task4 = this.waitTask(
"WaitChoiceSkill" // state name
).result(
"ChoiceSkill", // name of the event to wait for
new Map<IVariable, string>() // parameters of the event to wait for
.set(
this.stringType("skill"), // type and name of the parameter to pass to the destination state
"skill" // name of the parameter to receive in the event
),
"ChoiceSkill" // name of the state to transition to when this event is received
).result(
"ReLotterySkill", // name of the event to wait for
new Map<IVariable, string>(), // Parameters of the event to wait for
"ReLotterySkill" // name of the state to transition to when this event is received
)
var task4 = this.WaitTask(
"WaitChoiceSkill" // state name
).Result(
"ChoiceSkill", // name of the event to wait for
new Dictionary<IVariable, string>{{ // parameters of the event to wait for
StringType("skill"), // type and name of the parameter to pass to the destination state
"skill" // name of the parameter to receive in the event
}},
"ChoiceSkill" // name of the state to transition to when this event is received
).Result(
"ReLotterySkill", // name of the event to wait for
new Dictionary<IVariable, string>(), // Parameters of the event to wait for
"ReLotterySkill" // state name to transition to when this event is received
)
PassTask
var task2 = passTask(
"Task2" // state name
);
$task2 = $this->passTask(
"Task2" // state name
);
task2 = self.pass_task(
name="Task2" # state name
)
let task2 = this.passTask(
"Task2" // state name
);
var task2 = PassTask(
"Task2" // state name
);
ErrorTask
var error = errorTask(
"Error" // state name
);
$error = $this->errorTask(
"Error" // state name
);
error = self.error_task(
name="Error" # state name
)
let error = this.errorTask(
"Error" // state name
);
var error = ErrorTask(
"Error" // state name
);
Register to the stack.
new io.gs2.cdk.stateMachine.model.Namespace(
this, // Stack object
"state-machine-0001" // namespace name of GS2-StateMachine
).stateMachine(
new io.gs2.cdk.script.model.Namespace(
this, // Stack object
"script-0001" // namespace name of GS2-Script
),
new TesStateMachine() // StateMachineDefinition object
);
(new \Gs2Cdk\StateMachine\Model\Namespace_(
$this, // Stack object
"state-machine-0001" // namespace name of GS2-StateMachine
))->stateMachine(
new \Gs2Cdk\Script\Model\Namespace_(
$this, // Stack object
"script-0001" // namespace name of GS2-Script
),
new TestStateMachine() // StateMachineDefinition object
);
gs2_cdk.state_machine.Namespace(
self, # Stack object
name='state-machine-0001', # Namespace name of GS2-StateMachine
).state_machine(
script_namespace=gs2_cdk.script.Namespace(
self, # Stack object
name='script-0001', # Namespace name of GS2-Script
),
definition=TestStateMachine(), # StateMachineDefinition object
)
new StateMachineNamespace(
this, // Stack object
"state-machine-0001" // namespace name of GS2-StateMachine
).stateMachine(
new ScriptNamespace(
this, // Stack object
"script-0001" // namespace name of GS2-Script
),
new TestStateMachine() // StateMachineDefinition object
);
new Gs2Cdk.Gs2StateMachine.Model.Namespace(
this, // Stack object
"state-machine-0001" // namespace name of GS2-StateMachine
).StateMachine(
Gs2Cdk.Gs2Script.Model.Namespace(
this, // Stack object
"script-0001" // namespace name of GS2-Script
),
new TestStateMachine() // StateMachineDefinition object
);
Full sample
class TestStateMachine extends StateMachineDefinition {
public TestStateMachine() {
ErrorTask error = errorTask("Error");
PassTask task2 = passTask("Task2");
Task task1 = scriptTask(
"Task1",
new IVariable[0],
"""
result = 'Pass'
"""
)
.result("Pass", new HashMap<>(), task2.getName())
.result("Error", Map.of(new StringType("reason"), "reason"), error.getName());
stateMachine(
"MainStateMachine",
new IVariable[]{new IntType("turn")}
)
.entryPoint(task1.getName())
.task(task1, task2, error);
}
}
class TestStateMachineStack extends Stack {
public TestStateMachineStack() {
super();
new io.gs2.cdk.stateMachine.model.Namespace(this, "state-machine-0001")
.stateMachine(
new io.gs2.cdk.script.model.Namespace(this, "script-0001"),
new TesStateMachine()
);
}
}
class TestStateMachine extends StateMachineDefinition {
public function __construct() {
parent::__construct();
$error = $this->errorTask("Error");
$task2 = $this->passTask("Task2");
$task1 = $this->scriptTask(
"Task1",
[],
"result = 'Pass'"
)
->result("Pass", [], $task2->getName())
->result("Error", [[new StringType('reason'), 'reason']], $error->getName());
$this->stateMachine(
"MainStateMachine",
[new IntType("turn")]
)
->entryPoint($task1->getName())
->task($task1, $task2, $error);
}
}
class TestStateMachineStack extends Stack {
public function __construct() {
parent::__construct();
(new \Gs2Cdk\StateMachine\Model\Namespace_($this, "state-machine-0001"))
->stateMachine(
new \Gs2Cdk\Script\Model\Namespace_($this, "script-0001"),
new TestStateMachine()
);
}
}
class TestStateMachine(gs2_cdk.state_machine.StateMachineDefinition):
def __init__(self):
task2 = self.pass_task("Task2")
error = self.error_task("Error")
task1 = self.script_task(
name="Task1",
arguments=[],
script="""
result = 'Pass'
""",
).result(
result_name="Pass",
emit_event_argument_variable_names={},
next_task_name=task2.name,
).result(
result_name="Error",
emit_event_argument_variable_names={
self.string_type("reason"): "reason",
},
next_task_name=error.name,
)
self.state_machine(
name="MainStateMachine",
variables=[
self.int_type("turn"),
],
).entry_point(
task_name=task1.name,
).task(
task1,
task2,
error,
)
class TestStateMachineStack(gs2_cdk.Stack):
def __init__(self):
super().__init__()
gs2_cdk.state_machine.Namespace(
self,
name='state-machine-0001',
).state_machine(
script_namespace=gs2_cdk.script.Namespace(
self,
name='script-0001',
),
definition=TestStateMachine(),
)
class TestStateMachine extends StateMachineDefinition {
constructor() {
super();
let error = this.errorTask("Error");
let task2 = this.passTask("Task2");
let task1 = this.scriptTask(
"Task1",
[],
`
result = 'Pass'
`
)
.result("Pass", new Map(), task2.getName())
.result("Error", new Map([[new StringType("reason"), "reason"]]), error.getName());
this.stateMachine(
"MainStateMachine",
[new IntType("turn")]
)
.entryPoint(task1.getName())
.task(task1, task2, error);
}
}
class TestStateMachineStack extends Stack {
constructor() {
super();
new StateMachineNamespace(
this,
"state-machine-0001"
).stateMachine(
new ScriptNamespace(
this,
"script-0001"
),
TestStateMachine()
);
}
}
public class TestStateMachine : StateMachineDefinition
{
public TestStateMachine()
{
var error = ErrorTask("Error");
var task2 = PassTask("Task2");
Task task1 = ScriptTask(
"Task1",
new IVariable[0],
@"
result = 'Pass'
"
)
.Result("Pass", new Dictionary<IVariable, string>(), task2.Name)
.Result("Error", new Dictionary<IVariable, string> { { new StringType("reason"), "reason" } }, error.Name);
StateMachine(
"MainStateMachine",
new IVariable[] { IntType("turn") }
)
.EntryPoint(task1.Name)
.Task(task1, task2, error);
}
}
public class TestStateMachineStack : Stack
{
public TestStateMachineStack()
{
new Gs2Cdk.Gs2StateMachine.Model.Namespace(
this,
"state-machine-0001"
)
.StateMachine(
new Gs2Cdk.Gs2Script.Model.Namespace(
this,
"script-0001"
),
new TestStateMachine()
);
}
}