# Platformer Physics

> Platformer Physics

- Skill: `vchelaru/platformer-physics` (Agent Skill)
- Install (CLI): `npx skillmds@latest add vchelaru/platformer-physics`
- Raw SKILL.md: https://api.skillmd.com/api/skills/vchelaru/platformer-physics/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: vchelaru (https://skillmd.com/u/vchelaru)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/vchelaru/platformer-physics

---


# Platformer Physics

Platformer entities are generated code, not engine classes: **FRBDK/Glue/PlatformerPlugin** (the Glue plugin) reads `Models/PlatformerValues.cs` field values from the Glue project and emits the actual movement logic into the user's project via `CodeGenerators/EntityCodeGenerator.cs`. To change runtime platformer behavior, edit the templates in `EntityCodeGenerator.cs`; to change what values a user can configure, edit `Models/PlatformerValues.cs` + the plugin's ViewModels/Views.

## Movement value sets and state machine

A platformer entity holds up to three `PlatformerValues` sets — `GroundMovement`, `AirMovement`, `AfterDoubleJump` — plus an enum `MovementType {Ground, Air, AfterDoubleJump}`. `CurrentMovementType` setter calls `UpdateCurrentMovement()` (`EntityCodeGenerator.cs:337`) which resolves `CurrentMovement` to the matching set (falls back to `AirMovement` if `AfterDoubleJump` is unset) and applies `Gravity`→`YAcceleration`. `DetermineMovementValues()` (`EntityCodeGenerator.cs:666`) drives the Ground/Air/AfterDoubleJump transitions each frame off `mIsOnGround` and `mHasDoubleJumped`.

`mIsOnGround` is set only inside `CollideAgainst(...)` during solid-collision resolution (`EntityCodeGenerator.cs:882`), not by any standalone "am I touching the floor" check — it's a side effect of that frame's collision pass.

## Terrain-specific values (ice, water, sticky) aren't automatic

Swapping `GroundMovement`/`AirMovement` per terrain type is user code, not plugin-generated: check `GroundCollidedAgainst`/`ItemsCollidedAgainst` (populated after all of that frame's collision resolves) against named `TileShapeCollection` relationships in `CustomActivity`, then reassign e.g. `this.GroundMovement = PlatformerValuesStatic[...IceGround]`. Full pattern: `FlatRedBallDocs/tutorials/platformer-plugin/groundcollidedagainst-for-movement-values.md`.

## Value meanings

Full explanations (with tuning guidance and video examples) live in `FlatRedBallDocs/tutorials/platformer-plugin/platformer-basics/04-control-values.md`. Field reference: `Models/PlatformerValues.cs`. Key gotcha: `AccelerationTimeX`/`DecelerationTimeX` of 0 means **Immediate** movement (no easing); `JumpApplyByButtonHold` implements variable jump height by turning gravity off while held, not by delaying the jump.

## Related docs

`FlatRedBallDocs/tutorials/platformer-plugin/` has the full tutorial tree (basics, animations, ladders, moving platforms, multiplayer, etc.) — check there before re-deriving behavior from code.

