--- name: platformer-physics description: How FRB's platformer entity movement/physics works — MovementType state machine, ground/air value sets, collision-driven terrain switching. Triggers: PlatformerValues, MovementType, GroundMovement, AirMovement, AfterDoubleJump, CurrentMovement, GroundCollidedAgainst, IsOnGround, PlatformerPlugin. --- # 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.