reznok/gmcabilitysystem/gmas-rules

Claude Code and agent skill by reznok/gmcabilitysystem

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Use when changing gameplay that involves a GMC_AbilitySystemComponent (GMAS) - deciding where state lives (bound, replicated, derived), attribute binding, ability lifetime under replay, effect queue types, server operations, impulses and tags.

Install

npx vskill@latest install reznok/gmcabilitysystem/gmas-rules

SKILL.md

Behavior below was verified against GMC 2.3.x and GMAS 1.4. Confirm signatures in this project's own headers (paths are relative to each plugin's root, e.g. Source/GMCCore/Public/Components/GMCReplicationComponent.h); GMC's source is not part of this plugin.

GMAS (GMC Ability System) is an ability system built on GMC's predicted move cycle instead of on RPCs. UGMC_AbilitySystemComponent (Source/GMCAbilitySystem/Public/Components/GMCAbilityComponent.h, "the ASC") binds its attributes, tags and operation queue into the pawn's move, so abilities and effects are predicted, validated and replayed by the same machinery as movement. Read gmas:gmc-prediction first if moves, replays and bound values are new to you; this skill holds the rules every other gmas:* skill links to. GMAS paths below are relative to Source/GMCAbilitySystem/.

How GMAS rides GMC

The ASC is not a GMC component and does nothing on its own: the pawn's movement component (UGMC_MovementUtilityCmp or a subclass) forwards five of its hooks to it.

GMC hook on the movement componentASC callWhat the ASC does there
BindReplicationData_Implementation() (Source/GMCCore/Public/Components/GMCReplicationComponent.h)BindReplicationData()resolves a null GMCMovementComponent from the owner and refuses with an Error when there is none (1.4.1+), instantiates attributes from AttributeDataAssets, binds every bound attribute's Value and RawValue, the granted-ability and active tag containers, the task-data slot, the operation-queue slot and the active-effect id list (1.4+)
PreLocalMoveExecution_Implementation(const FGMC_Move&) (same header)PreLocalMoveExecution()moves the next queued task payload and the next queued operation into their bound slots so they travel with this move
GenPredictionTick_Implementation(float DeltaTime) (Source/GMCCore/Public/Components/GMCMovementUtilityComponent.h)GenPredictionTick(DeltaTime)sets ActionTimer from the move timestamp, processes the operation in the bound slot (activations, effects, impulses, events), ticks abilities and effects, recalculates bound attributes; replayed
GenAncillaryTick_Implementation(float DeltaTime, bool bLocalMove, bool bCombinedClientMove) (same header)GenAncillaryTick(DeltaTime, bCombinedClientMove)the non-replayed half: activations and task payloads of abilities with bActivateOnMovementTick = false, every active ability's AncillaryTick, cooldown expiry, change delegates (OnAttributeChanged, OnActiveTagsChanged), the server-operation grace countdown, and on the server StartingEffects once the pawn has a controller (1.4.1+; polled from the prediction tick on 1.4.0)
GenSimulationTick_Implementation(float DeltaTime) (same header)GenSimulationTick(DeltaTime)change delegates on simulated proxies, teleport smoothing
cpp
void UMyMovementCmp::BindReplicationData_Implementation()
{
Super::BindReplicationData_Implementation();
BindSinglePrecisionFloat(DashCooldown, /* modes */); // the game's own values first
AbilitySystem->BindReplicationData(); // GMAS binds LAST
}
void UMyMovementCmp::GenPredictionTick_Implementation(float DeltaTime)
{
Super::GenPredictionTick_Implementation(DeltaTime);
AbilitySystem->MatchTagToBool(StunnedTag, StunTimer > 0.f); // bound tag follows bound state
AbilitySystem->GenPredictionTick(DeltaTime); // then abilities, effects, attributes
}
void UMyMovementCmp::GenAncillaryTick_Implementation(float DeltaTime, bool bLocalMove, bool bCombinedClientMove)
{
Super::GenAncillaryTick_Implementation(DeltaTime, bLocalMove, bCombinedClientMove);
AbilitySystem->GenAncillaryTick(DeltaTime, bCombinedClientMove);
}

GenSimulationTick and PreLocalMoveExecution forward the same way. The ASC binds last by convention: it reads the movement component and binds a tag-sorted, variable-length block (one pair of floats per bound attribute, plus containers) after the game's fixed ones. The order of the ASC call relative to the game's own logic inside each hook is a design choice; keep it identical on every machine.

Where does this state live?

Decide this before writing a UPROPERTY. "Predicted logic" is anything that runs inside GenPredictionTick on either side: movement, ability ticks, effect ticks, activation checks.

The value is…Keep it asHow
read by predicted logic in any move (stamina a dash spends, the cooldown the tick checks, a stun that stops movement, a speed cap)GMC-boundan attribute with bGMCBound = true; a state tag kept with MatchTagToBool; or a value the movement component binds itself (gmas:gmc-prediction)
decided by the server and only displayed elsewhere (health under server-side damage, score, kills, respawn timer)replicatedan unbound attribute (bGMCBound = false, sent through UnBoundAttributes), or UPROPERTY(Replicated) on the pawn or player state; changed on the server only, through ServerAuth / ServerInstantAttribute effects or plain server code
derivable on every machine from identity and configuration (max speed from a loadout, weapon parameters from an archetype)derivedcomputed from the replicated identity plus data assets on each machine; nothing is sent. GetExternalModifierValue (1.4+) is the hook for feeding such values into modifiers
a one-shot the server imposes on a pawn (knock-back, forced effect, teleport)server operationthrough the target's ASC (AddImpulse, a ServerAuth effect, FireCustomEvent); it lands inside the target's move
purely visual (muzzle flash, trail, hit flash, HUD cache)localspawned on live moves, in GenSimulationTick, from change delegates, or through the MC_* cosmetic helpers

Two rules follow:

  • Never `DOREPLIFETIME` (or make an unbound attribute of) something predicted logic reads. A replicated property arrives between moves, is never restored by a replay, and gives client and server two different values for the same move: every read is a correction waiting to happen.
  • Never bind something only the HUD or a cosmetic reads. A bound value costs bandwidth in every move and state, splits combined moves whenever it changes (CombineIfUnchanged), and corrects the client every time the two sides disagree about a number nobody acts on. Replicate it, or derive it from bound values on the display side.

Worked example, UMyAbility_Dash on AMyPawn:

StateHomeBecause
Attribute.Stamina the dash spends, clamped by Attribute.MaxStaminabound attributesthe prediction tick checks and spends it
the dash cooldown the tick compares againstbound float on UMyMovementCmppredicted logic reads it; GMAS cooldowns are not rewound
State.Stunned blocking the dashbound tag via MatchTagToBoolan activation gate evaluated in the move
dash distance and costderived from the loadout data assetidentical on every machine, never changes mid-life
dashes performed, shown on the scoreboardreplicated on the player statethe server counts, nobody predicts it
dash trail and soundlocal, on the live move + cosmetic multicastnobody decides anything from it

Attributes

Attributes are declared in UGMCAttributesData assets (Public/Attributes/GMCAttributesData.h, FAttributeData) listed in the ASC's AttributeDataAssets; the runtime struct is FAttribute (Public/Attributes/GMCAttributes.h).

FAttributeData fieldDefaultRule
AttributeTag–Attribute.*
bGMCBoundtruetrue only for attributes predicted logic reads. A bound attribute binds Value and RawValue as ServerAuth_Output_ClientValidated, Periodic_Output: both sides compute them in the move, a mismatch corrects the client, simulated proxies receive them through smoothing. An unbound attribute replicates through UnBoundAttributes (OnRep_UnBoundAttributes) and cannot take part in prediction
DefaultValue, bStartFull (1.4+)0, falsebStartFull starts the attribute at its resolved upper clamp (needs Clamp.Max or MaxAttributeTag)
Clamp (FAttributeClamp, Public/Attributes/GMCAttributeClamp.h)bClampMin / bClampMax true (1.4+), Min / Max 0, tags emptyThe default clamp holds the attribute at 0. Set Max or MaxAttributeTag (Attribute.MaxStamina), or untick bClampMax; same for the floor. On trees older than 1.4 a clamp whose bounds are all zero is ignored instead
ValueCombineMode (1.4+)CombineIfUnchangedleave it. AlwaysCombineOverwrite only for an attribute that changes every tick (continuous regen) and does not feed the movement integration
  • Data before binding. BindReplicationData() reads AttributeDataAssets and binds the attributes sorted by tag. Fill AttributeDataAssets (and StartingEffects, StartingAbilities, StartingTags) in the constructor, in class defaults, or in PostInitializeComponents before the call that runs the GMC bind, identically on every machine: a different attribute list on client and server corrupts every state they exchange. Initial values can be overridden per attribute in SetAttributeInitialValue / OnInitializeAttributeInitialValue.
  • Change bound attributes inside the move, on both sides. Through effects (gmas:gmas-effect) or ApplyAbilityAttributeModifier(const FGMCAttributeModifier&) (Op Add, Set, SetReplace (1.4+), …) called from predicted logic on the owning client and the server alike; the result is validated like any bound value. Unbound attributes change on the server only.
  • `SetAttributeValueByTag(Tag, NewValue, bResetModifiers)` is deprecated and inert (removed in 1.5). It changes nothing; 1.4.0 returned true, 1.4.1+ returns false and logs once. Do not use it; initial values come from the data asset or SetAttributeInitialValue, changes from a Set modifier.
  • Read with GetAttributeValueByTag (with temporal modifiers) or GetAttributeRawValue (permanent part only). OnAttributeChanged(Tag, Old, New) fires from the ancillary and simulation ticks once per real change, on every machine: the hook for HUD and cosmetics, never for gameplay decisions.

Abilities under replay

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
0

Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/reznok/gmcabilitysystem/gmas-rules/badge)](https://verified-skill.com/skills/reznok/gmcabilitysystem/gmas-rules)

Something wrong with this skill or its page? Tell us.