> For the complete documentation index, see [llms.txt](/llms.txt)

# 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 can be used to define GSL using various programming languages.

[CDK details]()

## Start defining a state machine

Use the following syntax to start a state machine definition



**Java**
```java

    class TestStateMachine extends io.gs2.cdk.stateMachine.integration.StateMachineDefinition {
        public TestStateMachine() {
            // write state definition here
        }
    }
```
**PHP**
```php

    class TestStateMachine extends \Gs2Cdk\StateMachine\Integration\StateMachineDefinition {
        public function __construct() {
            parent::__construct();

            // write state definition here
        }
    }
```
**Python**
```python

    class TestStateMachine(gs2_cdk.state_machine.StateMachineDefinition):
        def __init__(self):
            # Write state definition here.
```
**TypeScript**
```ts

    class TestStateMachine extends StateMachineDefinition {
        constructor() {
            super();

            // Write the state definition here
        }
    }
```
**C#**
```csharp

    public class TestStateMachine : Gs2Cdk.Gs2StateMachine.Integration.StateMachineDefinition
    {
        public TestStateMachine()
        {
            // Write state definition here.
        }
    }
```


## State machine definition



**Java**
```java

    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
        );
```
**PHP**
```php

    $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
        );
```
**Python**
```python

    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
    )
```
**TypeScript**
```ts

    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
        )
```
**C#**
```csharp

    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



**Java**
```java

    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
            );
```
**PHP**
```php

    $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
        );
```
**Python**
```python

    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
    )
```
**TypeScript**
```ts

    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
        );
```
**C#**
```csharp

    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



**Java**
```java

    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
    )
```
**PHP**
```php

    $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
    )
```
**Python**
```python

    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
    )
```
**TypeScript**
```ts

    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
    )
```
**C#**
```csharp

    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



**Java**
```java

    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
    )
```
**PHP**
```php

    $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
    )
```
**Python**
```python

    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.string_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
    )
```
**TypeScript**
```ts

    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
    )
```
**C#**
```csharp

    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



**Java**
```java

    var task2 = passTask(
        "Task2" // state name
    );
```
**PHP**
```php

    $task2 = $this->passTask(
        "Task2" // state name
    );
```
**Python**
```python

    task2 = self.pass_task(
        name="Task2" # state name
    )
```
**TypeScript**
```ts

    let task2 = this.passTask(
        "Task2" // state name
    );
```
**C#**
```csharp

    var task2 = PassTask(
        "Task2" // state name
    );
```


### ErrorTask



**Java**
```java

    var error = errorTask(
        "Error" // state name
    );
```
**PHP**
```php

    $error = $this->errorTask(
        "Error" // state name
    );
```
**Python**
```python

    error = self.error_task(
        name="Error" # state name
    )
```
**TypeScript**
```ts

    let error = this.errorTask(
        "Error" // state name
    );
```
**C#**
```csharp

    var error = ErrorTask(
        "Error" // state name
    );
```


## Register to the stack



**Java**
```java

    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 TestStateMachine() // StateMachineDefinition object
    );
```
**PHP**
```php

    (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
    );
```
**Python**
```python

    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
    )
```
**TypeScript**
```ts

    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
    );
```
**C#**
```csharp


    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



**Java**
```java

    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 TestStateMachine()
                );
        }
    }
```
**PHP**
```php

    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()
                );
        }
    }

```
**Python**
```python

    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(),
            )
```
**TypeScript**
```ts

    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"
                ),
                new TestStateMachine()
            );
        }
    }

```
**C#**
```csharp

    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()
                );
        }
    }
```







