API Reference of GS2-StateMachine SDK for Game Engine
Model
EzStatus
Status of state machine
| Type | Condition | Required | Default | Value Limits | Description | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| statusId | string | ✓ | ~ 1024 chars | Status of State Machine GRN | ||||||||||||
| name | string | ✓ | UUID | ~ 36 chars | Status name Maintains a unique name for each status of state machine. The name is automatically generated in UUID (Universally Unique Identifier) format and used to identify each status of state machine. | |||||||||||
| enableSpeculativeExecution | String Enum enum { “enable”, “disable” } | ✓ | “disable” | ~ 128 chars | Whether to enable speculative execution
| |||||||||||
| stateMachineDefinition | string | {enableSpeculativeExecution} == “enable” | ~ 16777216 chars | State machine definition * enabled if enableSpeculativeExecution is “enable” | ||||||||||||
| randomStatus | EzRandomStatus | {enableSpeculativeExecution} == “enable” | Random status * enabled if enableSpeculativeExecution is “enable” | |||||||||||||
| stacks | List<EzStackEntry> | [] | 0 ~ 1024 items | Stack | ||||||||||||
| variables | List<EzVariable> | [] | 0 ~ 1000 items | State variables for each state machine | ||||||||||||
| status | String Enum enum { “Running”, “Wait”, “Pass”, “Error” } | ✓ | “Running” | ~ 128 chars | Status
| |||||||||||
| lastError | string | ~ 1024 chars | Last error | |||||||||||||
| transitionCount | int | ✓ | 0 | 0 ~ 2147483645 | Number of transitions |
EzStackEntry
Stack
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| stateMachineName | string | ✓ | ~ 128 chars | Name of the state machine | ||
| taskName | string | ✓ | ~ 128 chars | Task name |
EzVariable
State variables per state machine
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| stateMachineName | string | ✓ | ~ 128 chars | Name of the state machine | ||
| value | string | ✓ | ~ 1048576 chars | Value |
EzChangeStateEvent
Change state event
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| taskName | string | ✓ | ~ 128 chars | Task name | ||
| hash | string | ✓ | ~ 64 chars | Hash | ||
| timestamp | long | ✓ | Timestamp |
EzEmitEvent
Send a message event
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| event | string | ✓ | ~ 128 chars | Event name | ||
| parameters | string | ✓ | ~ 1024 chars | Parameters | ||
| timestamp | long | ✓ | Timestamp |
EzEvent
Event
| Type | Condition | Required | Default | Value Limits | Description | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| eventType | String Enum enum { “change_state”, “emit” } | ✓ | ~ 128 chars | Event type
| ||||||||
| changeStateEvent | EzChangeStateEvent | {eventType} == “change_state” | ✓* | Change state * required if eventType is “change_state” | ||||||||
| emitEvent | EzEmitEvent | {eventType} == “emit” | ✓* | Send a message * required if eventType is “emit” |
EzRandomStatus
Random number status
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| seed | long | ✓ | 0 ~ 4294967294 | Random seed | ||
| used | List<EzRandomUsed> | 0 ~ 1000 items | List of used random number |
EzRandomUsed
Used random number
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| category | long | ✓ | 0 ~ 4294967294 | Category | ||
| used | long | ✓ | 0 ~ 4294967294 | Used random number |
EzVerifyActionResult
Verify action execution result
EzConsumeActionResult
Consume action execution result
EzAcquireActionResult
Acquire action execution result
EzTransactionResult
Transaction execution results
Transaction execution results executed using server-side transaction auto-execution functionality
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| transactionId | string | ✓ | 36 ~ 36 chars | Transaction ID | ||
| verifyResults | List<EzVerifyActionResult> | 0 ~ 10 items | List of verify action execution results | |||
| consumeResults | List<EzConsumeActionResult> | [] | 0 ~ 10 items | List of consume action execution results | ||
| acquireResults | List<EzAcquireActionResult> | [] | 0 ~ 100 items | List of acquire action execution results |
Methods
emit
Send an event to the state machine
Request
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name | ||
| accessToken | string | ✓ | ~ 128 chars | Access token | ||
| statusName | string | ✓ | ~ 36 chars | Status name | ||
| eventName | string | ✓ | ~ 36 chars | Event name | ||
| args | string | ✓ | “{}” | ~ 4096 chars | Arguments to be passed to the state machine |
Result
| Type | Description | |
|---|---|---|
| item | EzStatus | Status of State Machine |
Implementation Example
var domain = gs2.StateMachine.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
statusName: "status-0001"
);
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: "status-0001"
);
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.ModelFuture();
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(
"status-0001" // 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
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name | ||
| accessToken | string | ✓ | ~ 128 chars | Access token | ||
| statusName | string | ✓ | ~ 36 chars | Status name |
Result
| Type | Description | |
|---|---|---|
| item | EzStatus | Exited state machine |
Implementation Example
var domain = gs2.StateMachine.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
statusName: "status-0001"
);
var result = await domain.ExitAsync(
); var domain = gs2.StateMachine.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
statusName: "status-0001"
);
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(
"status-0001" // 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
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name | ||
| accessToken | string | ✓ | ~ 128 chars | Access token | ||
| statusName | string | ✓ | ~ 36 chars | Status name |
Result
| Type | Description | |
|---|---|---|
| item | EzStatus | Status of State Machine |
Implementation Example
var domain = gs2.StateMachine.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
statusName: "status-0001"
);
var item = await domain.ModelAsync(); var domain = gs2.StateMachine.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Status(
statusName: "status-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->StateMachine->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Status(
"status-0001" // 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: "status-0001"
);
// 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: "status-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->StateMachine->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Status(
"status-0001" // 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);Warning
This event is called when the value in the local cache that the SDK has is changed.
The local cache will only be changed by executing the SDK’s API, or by executing a stamp sheet via GS2-Distributor with GS2-Gateway notification enabled, or by executing a GS2-JobQueue with GS2-Gateway notification enabled. GS2-Gateway notification enabled.
Therefore, callbacks will not be invoked if the value is changed in any other way.
listStatuses
Get the current status of the state machine
Request
| Type | Condition | Required | Default | Value Limits | Description | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name | ||||||||||||
| accessToken | string | ✓ | ~ 128 chars | Access token | ||||||||||||
| status | String Enum enum { “Running”, “Wait”, “Pass”, “Error” } | ~ 128 chars | Status
| |||||||||||||
| pageToken | string | ~ 1024 chars | Token specifying the position from which to start acquiring data | |||||||||||||
| limit | int | ✓ | 30 | 1 ~ 1000 | Number of data acquired |
Result
| Type | Description | |
|---|---|---|
| items | List<EzStatus> | List of Status of State Machine |
| nextPageToken | string | Page 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);Warning
This event is called when the value in the local cache that the SDK has is changed.
The local cache will only be changed by executing the SDK’s API, or by executing a stamp sheet via GS2-Distributor with GS2-Gateway notification enabled, or by executing a GS2-JobQueue with GS2-Gateway notification enabled. GS2-Gateway notification enabled.
Therefore, callbacks will not be invoked if the value is changed in any other way.
report
Send the speculative execution result of the state machine
Request
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name | ||
| accessToken | string | ✓ | ~ 128 chars | Access token | ||
| statusName | string | ✓ | ~ 36 chars | Status name | ||
| events | List<EzEvent> | 0 ~ 1000 items | List of events |
Result
| Type | Description | |
|---|---|---|
| item | EzStatus | Status 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.
| Type | Base Type | Description |
|---|---|---|
| StateMismatchException | BadRequestException | State 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: "status-0001"
);
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: "status-0001"
);
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.ModelFuture();
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(
"status-0001" // 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();