API Reference of GS2-StateMachine SDK for Game Engine

Model

EzStatus

Status of state machine

TypeRequireDefaultLimitationDescription
statusIdstring~ 1024 charsStatus of State Machine GRN
namestringUUID~ 36 charsStatus name
enableSpeculativeExecutionenum {
    “enable”,
    “disable”
}
“disable”~ 128 charsWhether to enable speculative execution
stateMachineDefinitionstring{enableSpeculativeExecution} == “enable”~ 16777216 charsState machine definition
randomStatusEzRandomStatus{enableSpeculativeExecution} == “enable”Random status
stacksList<EzStackEntry>~ 1024 itemsStack
variablesList<EzVariable>~ 1000 itemsState variables for each state machine
statusenum {
    “Running”,
    “Wait”,
    “Pass”,
    “Error”
}
“Running”~ 128 charsStatus
lastErrorstring~ 1024 charsLast error
transitionCountint0~ 2147483645Number of transitions

Enumeration type definition to specify as enableSpeculativeExecution

Enumerator String DefinitionDescription
enableEnable
disableDisable

Enumeration type definition to specify as status

Enumerator String DefinitionDescription
RunningRunning
WaitWait
PassPass
ErrorError

EzStackEntry

Stack

TypeRequireDefaultLimitationDescription
stateMachineNamestring~ 128 charsName of the state machine
taskNamestring~ 128 charsTask name

EzVariable

State variables per state machine

TypeRequireDefaultLimitationDescription
stateMachineNamestring~ 128 charsName of the state machine
valuestring~ 1048576 charsValue

EzChangeStateEvent

Change state event

TypeRequireDefaultLimitationDescription
taskNamestring~ 128 charsTask name
hashstring~ 64 charsHash
timestamplongTimestamp (Unix time unit:milliseconds)

EzEmitEvent

Send a message event

TypeRequireDefaultLimitationDescription
eventstring~ 128 charsEvent name
parametersstring~ 1024 charsParameters
timestamplongTimestamp (Unix time unit:milliseconds)

EzEvent

Event

TypeRequireDefaultLimitationDescription
eventTypeenum {
    “change_state”,
    “emit”
}
~ 128 charsEvent type
changeStateEventEzChangeStateEvent{eventType} == “change_state”Change state
emitEventEzEmitEvent{eventType} == “emit”Send a message

Enumeration type definition to specify as eventType

Enumerator String DefinitionDescription
change_stateChange state
emitSend a message

EzRandomStatus

Random number status

TypeRequireDefaultLimitationDescription
seedlong~ 4294967294Random seed
usedList<EzRandomUsed>~ 1000 itemsList of used random number

EzRandomUsed

Used random number

TypeRequireDefaultLimitationDescription
categorylong~ 4294967294Category
usedlong~ 4294967294Used random number

Methods

emit

Send an event to the state machine

Request

TypeRequireDefaultLimitationDescription
namespaceNamestring~ 128 charsNamespace name
accessTokenstring~ 128 charsUser Id
statusNamestring~ 36 charsStatus name
eventNamestring~ 36 charsEvent name
argsstring“{}”~ 4096 charsArguments to be passed to the state machine

Result

TypeDescription
itemEzStatusStatus of State Machine

Implementation Example

    var domain = gs2.StateMachine.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        statusName: "$status1.name"
    );
    var result = await domain.EmitAsync(
        eventName: "event-0001",
        args: "{\"value1\": \"value1\", \"value2\": 2.0, \"value3\": 3}"
    );
    var item = await result.ModelAsync();
    var domain = gs2.StateMachine.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        statusName: "$status1.name"
    );
    var future = domain.EmitFuture(
        eventName: "event-0001",
        args: "{\"value1\": \"value1\", \"value2\": 2.0, \"value3\": 3}"
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.Model();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;
    const auto Domain = Gs2->StateMachine->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Status(
        "$status1.name" // statusName
    );
    const auto Future = Domain->Emit(
        "event-0001", // eventName
        "{\"value1\": \"value1\", \"value2\": 2.0, \"value3\": 3}" // args
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // obtain changed values / result values
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

exit

Delete the state machine that has finished

Request

TypeRequireDefaultLimitationDescription
namespaceNamestring~ 128 charsNamespace name
accessTokenstring~ 128 charsUser Id
statusNamestring~ 36 charsStatus name

Result

TypeDescription
itemEzStatusExited state machine

Implementation Example

    var domain = gs2.StateMachine.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        statusName: "$status1.name"
    );
    var result = await domain.ExitAsync(
    );
    var domain = gs2.StateMachine.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        statusName: "$status1.name"
    );
    var future = domain.ExitFuture(
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    const auto Domain = Gs2->StateMachine->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Status(
        "$status1.name" // statusName
    );
    const auto Future = Domain->Exit(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
    const auto Result = Future->GetTask().Result();

getStatus

Get the current status of the state machine

Request

TypeRequireDefaultLimitationDescription
namespaceNamestring~ 128 charsNamespace name
accessTokenstring~ 128 charsUser Id
statusNamestring~ 36 charsStatus name

Result

TypeDescription
itemEzStatusStatus of State Machine

Implementation Example

    var domain = gs2.StateMachine.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        statusName: "$status1.name"
    );
    var item = await domain.ModelAsync();
    var domain = gs2.StateMachine.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        statusName: "$status1.name"
    );
    var future = domain.Model();
    yield return future;
    var item = future.Result;
    const auto Domain = Gs2->StateMachine->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Status(
        "$status1.name" // statusName
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
Value change event handling
    var domain = gs2.StateMachine.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        statusName: "$status1.name"
    );
    
    // Start event handling
    var callbackId = domain.Subscribe(
        value => {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    domain.Unsubscribe(callbackId);
    var domain = gs2.StateMachine.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        statusName: "$status1.name"
    );
    var future = domain.Model();
    yield return future;
    var item = future.Result;
    const auto Domain = Gs2->StateMachine->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Status(
        "$status1.name" // statusName
    );
    
    // Start event handling
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::StateMachine::Model::FStatus> value) {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    Domain->Unsubscribe(CallbackId);

listStatuses

Get the current status of the state machine

Request

TypeRequireDefaultLimitationDescription
namespaceNamestring~ 128 charsNamespace name
accessTokenstring~ 128 charsUser Id
statusenum {
    “Running”,
    “Wait”,
    “Pass”,
    “Error”
}
~ 128 charsStatus
pageTokenstring~ 1024 charsToken specifying the position from which to start acquiring data
limitint301 ~ 1000Number of data acquired

Enumeration type definition to specify as status

Enumerator String DefinitionDescription
RunningRunning
WaitWait
PassPass
ErrorError

Result

TypeDescription
itemsList<EzStatus>List of Status of State Machine
nextPageTokenstringPage token to retrieve the rest of the listing

Implementation Example

    var domain = gs2.StateMachine.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var items = await domain.StatusesAsync(
        status: "Running"
    ).ToListAsync();
    var domain = gs2.StateMachine.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var it = domain.Statuses(
        status: "Running"
    );
    List<EzStatus> items = new List<EzStatus>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }
    const auto Domain = Gs2->StateMachine->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    const auto It = Domain->Statuses(
        "Running" // status
    );
    TArray<Gs2::UE5::StateMachine::Model::FEzStatusPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }
Value change event handling
    var domain = gs2.StateMachine.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    
    // Start event handling
    var callbackId = domain.SubscribeStatuses(
        () => {
            // Called when an element of the list changes.
        }
    );

    // Stop event handling
    domain.UnsubscribeStatuses(callbackId);
    var domain = gs2.StateMachine.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var it = domain.Statuses(
        status: "Running"
    );
    List<EzStatus> items = new List<EzStatus>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }
    const auto Domain = Gs2->StateMachine->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    
    // Start event handling
    const auto CallbackId = Domain->SubscribeStatuses(
        []() {
            // Called when an element of the list changes.
        }
    );

    // Stop event handling
    Domain->UnsubscribeStatuses(CallbackId);

report

Send the speculative execution result of the state machine

Request

TypeRequireDefaultLimitationDescription
namespaceNamestring~ 128 charsNamespace name
accessTokenstring~ 128 charsUser Id
statusNamestring~ 36 charsStatus name
eventsList<EzEvent>~ 1000 itemsList of events

Result

TypeDescription
itemEzStatusStatus of State Machine

Error

Special exceptions are defined in this API. GS2-SDK for GameEngine provides specialized exceptions derived from general exceptions to facilitate handling of errors that may need to be handled in games. Please refer to the documentation here for more information on common error types and handling methods.

TypeBase TypeDescription
StateMismatchExceptionBadRequestExceptionState of the verification result of the report is inconsistent.

Implementation Example

try {
    var domain = gs2.StateMachine.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        statusName: "$status1.name"
    );
    var result = await domain.ReportAsync(
        events: new List<Gs2.Unity.Gs2StateMachine.Model.EzEvent> {
            new Gs2.Unity.Gs2StateMachine.Model.EzEvent() {
                EventType = "emit",
                EmitEvent = 
                new Gs2.Unity.Gs2StateMachine.Model.EzEvent() {
                    Event = "message",
                    Parameters = "{\"payload\": \"Hello World\"}",
                    Timestamp = 1000,
                },
            },
        }
    );
    var item = await result.ModelAsync();
} catch(Gs2.Gs2StateMachine.Exception.StateMismatch e) {
    // State of the verification result of the report is inconsistent.
}
    var domain = gs2.StateMachine.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        statusName: "$status1.name"
    );
    var future = domain.ReportFuture(
        events: new List<Gs2.Unity.Gs2StateMachine.Model.EzEvent> {
            new Gs2.Unity.Gs2StateMachine.Model.EzEvent() {
                EventType = "emit",
                EmitEvent = 
                new Gs2.Unity.Gs2StateMachine.Model.EzEvent() {
                    Event = "message",
                    Parameters = "{\"payload\": \"Hello World\"}",
                    Timestamp = 1000,
                },
            },
        }
    );
    yield return future;
    if (future.Error != null)
    {
        if (future.Error is Gs2.Gs2StateMachine.Exception.StateMismatchException)
        {
            // State of the verification result of the report is inconsistent.
        }
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.Model();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;
    const auto Domain = Gs2->StateMachine->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Status(
        "$status1.name" // statusName
    );
    const auto Future = Domain->Report(
        []
        {
            auto v = MakeShared<TArray<TSharedPtr<Gs2::UE5::StateMachine::Model::FEzEvent>>>();
            v->Add(
                MakeShared<Gs2::UE5::StateMachine::Model::FEzEvent>()
                ->WithEventType(TOptional<FString>("emit"))
                ->WithEmitEvent(MakeShared<Gs2::UE5::StateMachine::Model::FEzEmitEvent>() 
                    ->WithEvent(TOptional<FString>("message"))
                    ->WithParameters(TOptional<FString>("{\"payload\": \"Hello World\"}"))
                    ->WithTimestamp(TOptional<int32>(1000))
                );
            );
            return v;
        }() // events
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        auto e = Future->GetTask().Error();
        if (e->IsChildOf(Gs2::StateMachine::Error::FStateMismatchError::Class))
        {
            // State of the verification result of the report is inconsistent.
        }
        return false;
    }

    // obtain changed values / result values
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();