Patterns

Patterns associated with the GS_Play featuresets.

Outline

The strength of the GS_Play framework is in it’s straightforward, and intuitive patterns.

By creating simple ways to look at certain featuresets, you can reliably expand your gameplay knowing you’re always going to properly connect with the underlying system.

Using our extensive list of templates, you can even more rapidly develop the features that make your project unique.

Use this quick list to jump to the features you want to look at.

You can expect a diagram outlining the relationships between feature elements, and then explanations on how the pattern plays out.

Have fun!

 

Legend

Colour Legend for pattern diagrams

 

Contents


Managers & Startup - GS_Core

Game Manager Startup Pattern Graph

Breakdown

When the project starts, the Game Manager runs three stages before the game is considered ready:

StageBroadcast EventWhat It Means
1 — Initialize(internal)Each manager is spawned. They activate, then report ready.
2 — SetupOnSetupManagersSetup stage. Now safe to query other managers.
3 — CompleteOnStartupCompleteLast stage. Everything is ready.
Do any last minute things. Now safe to begin gameplay.

For most scripts, you only need OnStartupComplete. Wait for this event before doing anything that depends on managers to be completely setup.

Back to top…


Save - GS_Core

Save System Pattern Graph

Breakdown

When a save or load is triggered, the Save Manager broadcasts to every Saver in the scene. Each Saver independently handles its own entity’s state. The Record Keeper persists flat progression data alongside the save file.

PartBroadcast EventWhat It Means
Save ManagerOnSaveAllBroadcasts to all Savers on save. Each serializes its entity state.
Save ManagerOnLoadAllBroadcasts to all Savers on load. Each restores its entity state.
Record KeeperRecordChangedFires when any progression flag is created, updated, or deleted.

Savers are per-entity components — add them to anything that needs to persist across sessions. The Record Keeper is a global singleton for flags and counters.

Back to top…


Stage Change - GS_Core

Stage Change Pattern Graph

Breakdown

When a stage change is requested, the system follows a five-step sequence before gameplay resumes in the new level:

StepBroadcast EventWhat It Means
1 — StandbyOnEnterStandbyGame Manager enters standby, halting all gameplay systems.
2 — Unload(internal)The current stage’s entities are torn down.
3 — Spawn(internal)The target stage prefab is instantiated.
4 — Set UpOnBeginSetUpStageStage Data runs its layered startup: SetUpStage → ActivateByPriority → Complete.
5 — CompleteLoadStageCompleteStage Manager broadcasts completion. Standby exits. Gameplay resumes.

The Stage Data startup is layered — OnBeginSetUpStage, ActivateByPriority, then OnLoadStageComplete — so heavy levels can initialize incrementally without causing frame-time spikes.

Back to top…


Dialogue Authoring - GS_Cinematics

Dialogue Authoring Pattern Graph

Breakdown

A dialogue sequence is authored in the node editor, stored in a .dialoguedb asset, and driven at runtime by the Dialogue Manager and Sequencer:

LayerWhat It Means
DialogueDatabaseStores named actors and sequences. Loaded at runtime by the Dialogue Manager.
DialogueSequenceA directed node graph. The Sequencer walks from startNodeId through Text, Selection, Effects, and Performance nodes.
ConditionsPolymorphic evaluators on branches. Failed conditions skip that branch automatically.
EffectsPolymorphic actions at EffectsNodeData nodes — set records, toggle entities.
PerformersNamed actor anchors in the level. Resolved from database actor names via DialoguePerformerMarkerComponent.

Conditions, effects, and performances are discovered automatically at startup — custom types from any gem appear in the editor without modifying GS_Cinematics.

Back to top…


Pulse - GS_Interaction

Pulse Pattern Graph

Breakdown

When an entity enters a Pulsor’s trigger volume, the Pulsor emits its configured pulse type to all Reactors on the entering entity:

StepWhat It Means
1 — Collider overlapPhysics detects an entity entering the Pulsor’s trigger volume.
2 — Pulse emitPulsorComponent reads its configured PulseType and prepares the event.
3 — Reactor queryEach PulseReactorComponent on the entering entity is checked with IsReactor().
4 — ReactionReactors returning true have ReceivePulses() called and execute their response.

Pulse types are polymorphic — new types are discovered automatically at startup. Any gem can define custom interaction semantics without modifying GS_Interaction.

Back to top…


World Triggers - GS_Interaction

World Trigger Pattern Graph

Breakdown

World Triggers split conditions from responses. Any number of World Triggers can stack on a single entity — each fires its own response independently when the condition is met.

PartWhat It Means
Trigger SensorMonitors for a condition. When satisfied, calls Trigger() on all WorldTriggerComponent instances on the same entity.
World TriggerExecutes a response when Trigger() is called. Can be reset with Reset() to re-arm for the next activation.

No scripting is required for standard patterns. Compose Trigger Sensors and World Triggers in the editor to cover the majority of interactive world objects without writing any code.

Back to top…


Camera Blend - GS_PhantomCam

Camera Blend Pattern Graph

Breakdown

When the dominant Phantom Camera changes, the Cam Manager queries the Blend Profile to determine transition timing and easing:

StepWhat It Means
1 — Priority changeA Phantom Camera gains highest priority or is activated.
2 — Profile queryCam Manager calls GetBestBlend(fromCam, toCam) on the assigned GS_PhantomCamBlendProfile asset.
3 — Entry matchEntries are checked by specificity: exact match → any-to-specific → specific-to-any → default fallback.
4 — InterpolationCam Core blends position, rotation, and FOV over the matched entry’s BlendTime using the configured EasingType.

Because Blend Profiles are shared assets, editing one profile updates every camera that references it.

Back to top…


Unit Possession - GS_Unit

Unit Possession Pattern Graph

Breakdown

Every unit has exactly one controller at a time, or no controller at all. Possession is established by calling Possess on the unit and released by calling DePossess. The unit fires UnitPossessed on UnitNotificationBus whenever ownership changes so other systems can react.

ConceptDescription
PossessionA controller attaches to a unit. The unit accepts input and movement commands from that controller only.
DePossessionThe controller releases the unit. The unit halts input processing and enters a neutral state.
UnitPossessed eventFires on UnitNotificationBus (addressed by entity ID) whenever a unit’s controller changes.
GetControllerReturns the entity ID of the current controller, or an invalid ID if none.
GetUniqueNameReturns the string name assigned by the Unit Manager when this unit was spawned.

Back to top…


Unit Input Handling - GS_Unit

Unit Input Handling Pattern Graph

Breakdown

The input pipeline has three stages. Each stage is a separate component on the unit entity, and they run in order every frame:

StageComponentWhat It Does
1 — ReadGS_PlayerControllerInputReaderComponentReads raw input events from the active input profile and writes them into GS_InputDataComponent.
2 — StoreGS_InputDataComponentHolds the current frame’s input state — button presses, axis values — as structured data.
3 — ReactReactor componentsRead from GS_InputDataComponent and produce intent: movement vectors, action triggers, etc.

All reactor components downstream of the store stage read from the same GS_InputDataComponent, so there is no duplicated hardware polling and no risk of two reactors seeing different input states for the same frame.

Back to top…


Movers & Grounders - GS_Unit

Movers & Grounders Pattern Graph

Breakdown

Movers and Grounders are multiple components on a Unit that are constantly changing activation based on the units state. When a mover is active, it freely processes the unit’s movement based on it’s functionality. At any moment, through internal or external forces, the Movement, Rotation, or Grounding state can change, which disables the old movers, and activates the new one to continue controlling the Unit.

Input
    ↓  InputDataNotificationBus::InputStateChanged
Input Reactor Components
    ↓  MoverContextRequestBus::SetMoveInputAxis
GS_MoverContextComponent
    ↓  ModifyInputAxis() → camera-relative
    ↓  GroundInputAxis() → ground-projected
    ↓  MoverContextNotificationBus::MovementModeChanged("Free")
GS_3DFreeMoverComponent  [active when mode == "Free"]
    ↓  AccelerationSpringDamper → rigidBody->SetLinearVelocity
GS_PhysicsRayGrounderComponent  [active when grounding mode == "Free"]
    ↓  MoverContextRequestBus::SetGroundNormal / SetContextState("grounding", ...)
    ↓  MoverContextRequestBus::ChangeMovementMode("Slide")  ← when slope too steep
GS_3DSlideMoverComponent  [active when mode == "Slide"]

The Slide mover activates when the Unit is walking on too steep an angle. It takes control over the unit, slides down the hill, then restores the previous movement behaviour.

Back to top…