Finite State Machine (FSM)

The Finite State Machine (FSM) system provides centralized management of game object states in Gem RTS. It processes incoming state change requests from various control subsystems — such as AI, user commands, physics, and others — and ensures valid and consistent state transitions.

The primary purpose of the FSM is to resolve conflicts between multiple requests and select the most appropriate state for the object. This maintains logical consistency, smooth animation transitions, and correct operation of gameplay mechanics.

The FSM does not execute animations or behavior logic directly. It only determines and updates the object’s current state. Other systems handle animations, behavior, and scripts based on the active state provided by the FSM.

FSM Functions

  • Receive state change requests from external control systems.

  • Resolves conflicts between incoming requests.

  • .Selects valid state transitions based on current state and conditions

  • Update and broadcast the current state to dependent systems, including animation, behavior, and scripting subsystems.

The finite state machine logic is defined in the unit’s .def file using the fsm block


FSM Components

State

A state represents the current position or action of a unit (e.g., stand, walk, fire, blown_away). At any given moment, a unit can be in only one state. States function as nodes in the FSM transition graph.

Each state:

  • has a unique name;

  • has at least one tag;

  • is connected to other states through defined transitions, forming possible state switches.

Tags

A tag is a textual label assigned to a state. Tags serve two purposes:

  • They allow external systems to identify the logical condition of the unit.

  • They define which request should trigger a transition to that state. Example: A state tagged with fire will be selected in response to a fire request.

Requests

A request is an external command issued by control subsystems (AI, user input, physics, etc.) that initiates the process of transitioning a controlled object to a new state within the FSM.

Unlike a signal, which is an instantaneous event, a request can remain active for a period of time — until it is either processed or canceled.

Each request is associated with at least one FSM state via a tag that matches its name. The presence of this tag enables the FSM to identify which state can handle the given request, provided the transition conditions are met.

Tags in states are used not only to handle FSM requests but also by other game subsystems.

The result of request processing depends on:

  • the current state of the unit;

  • the priority of the request;

  • the transition rules defined in the FSM graph.

FSM supports multiple types of requests.

Request types are defined in the code and cannot be overridden through FSM configuration files.

The table of request types is provided for reference to give a complete understanding of how the Finite State Machine (FSM) works in Gem RTS.

Request Types

Type
Description
Example

Switch

A one-time request triggered in the code. It enters a queue and waits for an opportunity to execute. Once executed, it is removed.

Command: “Go prone”

Job

This request type is called every tick by the code after the unit transitions into the target FSM state. It holds the unit in that state as long as the request remains active. The request is reset if it is not called for longer than the duration parameter or if a higher-priority request is received. When reset, it triggers a Switch request from the exit block in the FSM description, if the unit is still in the target state.

Command: “Repair”

Action

This request is triggered every tick before the unit is allowed to enter the target state. If conditions are met, it transitions the unit into the state to perform the action, and then it is removed. If not triggered for at least one tick, it is discarded without execution.

Command: “Throw grenade”

State

A one-time request that causes an immediate transition into the target state. The state is maintained until it is canceled or a higher-priority request arrives.

Hide the weapon if it gets stuck in a wall

The request and tag system is used in the engine to coordinate the behavior of various gameplay subsystems. Some requests and tags are hardcoded, while others can be defined in configuration files (e.g., interface elements, inventory items, weapons), allowing developers to modify and extend object behavior without altering the source code.

State Subsets

An FSM Subset is a component of the finite state machine that defines restrictions on state transitions by excluding states that are incompatible with the unit’s current state.

Example: If a unit is holding a fuel canister, the FSM subset excludes the states prone, squat, and repair, as performing these actions would be incompatible with the unit's current condition.


Request Processing in FSM

Stages of the request processing workflow

  1. FSM Subset Selection Based on the unit’s current state, the state handler selects an FSM subset that limits the pool of states available for transition.

  2. Priority Analysis If multiple requests are received simultaneously, the FSM analyzes their priorities. The request with the highest priority takes precedence when selecting the next state. Requests with equal priority are resolved in the order they were received.

  3. Transition Availability Check:

    • Whether the FSM graph defines a transition to the target state from the current state.

    • Whether the conditions are met (e.g., presence of specific tags or additional request parameters).

  4. Request Processing Result The FSM selects the nearest available state in the graph that matches the request tag, regardless of whether it is directly connected to the current state — state transitions may pass through intermediate states.

Typical FSM Scenario Initial position: the unit is in an idle state. Combat begins: the unit detects an enemy, receives an attack command from the AI, and simultaneously a “dig in” command from the player. A nearby explosion occurs, with a blast strong enough to knock the unit back and cause damage. State change requests are sent to the FSM. Since the unit cannot be in multiple states at once (digging in, attacking, reacting to the explosion, healing, or dying), the FSM resolves this conflict by selecting the most prioritized and valid state.

When the new state is activated, the state handler passes the state to the game systems and triggers the scripts and animations associated with that state.

Upon exiting the state, the handler notifies the game systems of the state’s completion, stops the corresponding animations and effects, terminates all processes and scripts linked to the state, and then clears the used resources.


FSM Configuration Components

The logic of the finite state machine is defined in the unit’s .def file using the fsm block:

FSM block syntax

{fsm "name"
  ...
}

where "name" is the name of the FSM.

The FSM description can be placed in a separate file or directory. For example, in the resources of the Men of War game series:

  • \properties\animal.ext — FSM for the horse entity

  • \properties\human_fsm\ — FSM for the human entity

Request List

A complete description of requests is available in the source code. Only parameters available for configuration are exposed in the configuration file.

The request parameter blocks are used to declare the requests handled by the state processor within the FSM description. Each block contains values for configurable parameters.

Request block syntax

{Request "name"
    {priority N} 
    {interrupt}
    {duration N}
    {exit "state_name"} 
}
Parameter
Description

Request

Request name. The FSM selects a state whose tag matches this name.

priority

Defines the request’s priority. When processing competing requests, the one with the higher value is selected.

interrupt

Allows immediate transition to a new state, forcibly terminating the current one regardless of active animations.Optional

duration

Sets the maximum number of ticks between consecutive calls to the request from code. If the request is not called within the specified time, it is automatically canceled.Optional; applicable only to Job-type requests

exit

Specifies the name of the state to transition to automatically when the request is canceled due to a timeout as defined by the duration parameter.Optional; applicable only to Job-type requests

Example: Request definition
{Request "move"
    {priority 30}
    {interrupt}
    {duration 2}
    {exit "stop-move"}
}

Initial State

The Start parameter block is used to specify the name of the initial state for unit initialization.

Initial FSM State Definition Format

Start block syntax

{Start "state_name"}

State List

The state parameter blocks are used to define the nodes of the FSM graph. Nested blocks are used to describe available transitions between states, state tags, and other parameters.

State Block Syntax

{State "state_name"
    {from "source_state"}
    {fromTagged "source_tag"}
    {transit "transit_state"}
    {to "target_state"}
    {tag "name"}
    {condition "name"}
    {split "part1" "part2"}
}
Parameter
Description

State "state_name"

Unique identifier of the defined state.

from "source_state"

Defines the source state from which a transition to this state is allowed.

fromTagged "source_tag"

Allows transition into this state from any state that has the specified tag.

transit "transit_state"

(Optional) Defines an automatic transition to the next state without an external request, as soon as conditions allow.

to "target_state"

Declares a valid transition from this state to the specified target state. Multiple to parameters can be used for alternative transitions.

tag "name"

Tag assigned to the state. Multiple tag entries may be specified for a single state. (Optional)

condition "name"

Condition required for entering this state. The value should match the name of a request.

split "part1" "part2"

Divides the object into semi-independent parts (e.g., "walk_all" "linked"). Used for complex transitions or actions when unit animation can be split into parts — for example, upper and lower body.

Example: State definition
{State "stand_bazooka_pick"
    {from "stand"}
    {fromTagged "up"}
    {transit "stand"}
    {to "stand"}
    {tag "up"}
    {tag "bazooka-pick"}
    {condition "knock-down"}
    {split "walk_all" "linked"}
}

State Subset

The subset parameter block is used to define FSM subsets that restrict the list of valid states available for selection based on the unit’s current FSM state.

Subset block syntax

{subset "name" from "source_subset"
  {disable "state_A"}
  {enable "state_B"}
}
Parameter
Description

subset

Name of the FSM subset. Defines a set of allowed and disallowed states for this subset.

from

Name of the parent subset from which allowed states are inherited.(Optional)

disable

Disables access to states tagged with the specified value within this subset. Can be used multiple times for different tags.

enable

Enables access to states tagged with the specified value within this subset. Can be used multiple times for different tags.

Example: Subset definition
{subset "with_item" from "default"
    {disable "down"}
    {disable "squat"}
    {disable "looking"}
    {disable "repair"}
    {disable "step-aside"}
    {enable "open-with_item"}
}

The subset named with_item inherits the states from the default subset but excludes the following states from the selection: prone (down), crouching in cover (squat), looking around (looking), repairing (repair), and strafing (step-aside). These states are incompatible with the condition in which the unit is carrying a heavy object, such as a canister or a crate.

Last updated