v0.1 ⌊ALPHA⌉
Claim set · data/claims/celeste-player.yaml

Celeste (NoelFB/Celeste, Source/Player/Player.cs)

Game: Celeste.

A normal jump sets Madeline's vertical speed to JumpSpeed, −105 px/s. celeste-player/jump-speed

About: Celeste Jump

Value: -105 px/s

T3 code-verifiedCeleste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L49private const float JumpSpeed = -105f;Checked by claude, 2026-10-20 — read the constant at the pinned commit

−1.75 px/frame at 60 Hz (exact for a 1/60 s step). Negative is up.

Cited by: Celeste, Variable jump height

Jump() sets vertical speed to JumpSpeed plus any platform lift boost, saves it as varJumpSpeed, starts varJumpTimer at VarJumpTime, and zeroes the grace timer. celeste-player/jump-function

About: Celeste Variable jump height

T3 code-verifiedCeleste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L1660-L1673jumpGraceTimer = 0; varJumpTimer = VarJumpTime; … Speed.Y = JumpSpeed; Speed += LiftBoost; varJumpSpeed = Speed.Y;Checked by claude, 2026-10-20 — read Jump() at the pinned commit

Cited by: Celeste, Variable jump height

Celeste's gravity is 900 px/s²; each airborne update moves vertical speed toward the fall limit by Gravity * mult * Engine.DeltaTime. celeste-player/gravity

About: Celeste Gravity

Value: 900 px/s²

T3 code-verifiedCeleste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L24private const float Gravity = 900f;Celeste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L2957Speed.Y = Calc.Approach(Speed.Y, max, Gravity * mult * Engine.DeltaTime);Checked by claude, 2026-10-20 — read the constant and NormalUpdate's gravity block at the pinned commit

15 px/s per update, i.e. 0.25 px/frame² at 60 Hz (exact for a 1/60 s step).

Cited by: Celeste, Variable jump height

HalfGravThreshold is 40 px/s, the vertical speed below which (in either direction) holding jump halves gravity. celeste-player/half-grav-threshold

About: Celeste Variable jump height

Value: 40 px/s

T3 code-verifiedCeleste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L25private const float HalfGravThreshold = 40f;Checked by claude, 2026-10-20 — read the constant at the pinned commit

2/3 px/frame at 60 Hz.

Cited by: Variable jump height

Gravity halves while |Speed.Y| is under HalfGravThreshold and jump is held (or auto-jump is on), so a held jump hangs at the top. celeste-player/half-grav-rule

About: Celeste Variable jump height

Value: 0.5 × gravity

T3 code-verifiedCeleste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L2952float mult = (Math.Abs(Speed.Y) < HalfGravThreshold && (Input.Jump.Check || AutoJump)) ? .5f : 1f;Checked by claude, 2026-10-20 — read NormalUpdate's gravity block at the pinned commit

Cited by: Celeste, Variable jump height

VarJumpTime, how long holding jump can keep the take-off speed, is 0.2 s. celeste-player/var-jump-time

About: Celeste Variable jump height

Value: 0.2 s

T3 code-verifiedCeleste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L51private const float VarJumpTime = .2f;Checked by claude, 2026-10-20 — read the constant at the pinned commit

12 updates of exactly 1/60 s, but the float comparison can end it a frame early (see float-timer-frames).

Cited by: Celeste, Variable jump height

While varJumpTimer runs, holding jump keeps Madeline rising no slower than varJumpSpeed, canceling gravity; releasing zeroes the timer and cuts no speed. celeste-player/var-jump-rule

About: Celeste Variable jump height

T3 code-verifiedCeleste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L2960-L2966//Variable Jumping if (varJumpTimer > 0) { if (AutoJump || Input.Jump.Check) Speed.Y = Math.Min(Speed.Y, varJumpSpeed); else varJumpTimer = 0;Checked by claude, 2026-10-20 — read NormalUpdate's variable-jumping block at the pinned commit

Cited by: Celeste, Variable jump height

MaxFall, the normal limit on falling speed, is 160 px/s; NormalBegin starts maxFall there and gravity approaches it. celeste-player/max-fall

About: Celeste Gravity

Value: 160 px/s

T3 code-verifiedCeleste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L23public const float MaxFall = 160f;Celeste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L2760-L2763maxFall = MaxFall;Checked by claude, 2026-10-20 — read the constant

2.667 px/frame at 60 Hz (8/3, not a finite decimal).

Cited by: Celeste, Variable jump height

Holding down while falling at MaxFall or faster raises the limit toward FastMaxFall (240 px/s) at FastMaxAccel (300 px/s²); otherwise it eases back. celeste-player/fast-max-fall

About: Celeste Gravity

Value: 240 px/s

T3 code-verifiedCeleste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L27-L28private const float FastMaxFall = 240f; private const float FastMaxAccel = 300f;Celeste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L2911-L2924if (Input.MoveY == 1 && Speed.Y >= mf) … maxFall = Calc.Approach(maxFall, mf, FastMaxAccel * Engine.DeltaTime);Checked by claude, 2026-10-20 — read the constants and the max-fall block at the pinned commit

4 px/frame at 60 Hz.

JumpGraceTime, Celeste's coyote time, is 0.1 s. celeste-player/jump-grace-time

About: Celeste Coyote time

Value: 0.1 s

T3 code-verifiedCeleste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L48private const float JumpGraceTime = 0.1f;Checked by claude, 2026-10-20 — read the constant at the pinned commit

6 updates of exactly 1/60 s, but in practice 5 airborne frames (see float-timer-frames).

Cited by: Celeste, Coyote time

Grounded updates refill jumpGraceTimer; airborne ones subtract Engine.DeltaTime before NormalUpdate, which jumps on a press while it is above zero. celeste-player/jump-grace-rule

About: Celeste Coyote time

T3 code-verifiedCeleste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L713-L720//Jump Grace if (onGround) … jumpGraceTimer = JumpGraceTime; … else if (jumpGraceTimer > 0) jumpGraceTimer -= Engine.DeltaTime;Celeste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L2970-L2975if (Input.Jump.Pressed) … if (jumpGraceTimer > 0) { Jump();Checked by claude, 2026-10-20 — read Update's timer block and NormalUpdate's jump block at the pinned commit

Cited by: Celeste, Coyote time, Variable jump height

In each update, Player.Update ticks both jump timers, the state machine runs NormalUpdate (gravity, hold, and new jump), and then MoveV applies Speed.Y * Engine.DeltaTime. celeste-player/update-order

About: Celeste Variable jump height

T3 code-verifiedCeleste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L742-L744//Var Jump if (varJumpTimer > 0) varJumpTimer -= Engine.DeltaTime;Celeste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L908base.Update();Celeste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L934-L935MoveV(Speed.Y * Engine.DeltaTime, onCollideV);Celeste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L322-L323StateMachine.SetCallbacks(StNormal, NormalUpdate, null, NormalBegin, NormalEnd);Monocle Engine (public source, GitHub mirror JamesMcMahon/monocle-engine) · Monocle/Entity.cs#L95-L98 — public Monocle; an entity's update runs its components (the state machine is one, Player.cs L346)Components.Update();Checked by claude, 2026-10-20 — read Update

So on the press frame the jump speed already moves her, and the first gravity is applied one update later.

Cited by: Celeste, Variable jump height

In the public Monocle source, Calc.Approach(val, target, maxMove) moves val toward target by at most maxMove without overshooting. celeste-player/approach

About: Celeste Gravity

T3 code-verifiedMonocle Engine (public source, GitHub mirror JamesMcMahon/monocle-engine) · Monocle/Util/Calc.cs#L852-L855return val > target ? Math.Max(val - maxMove, target) : Math.Min(val + maxMove, target);Checked by claude, 2026-10-20 — read Calc.Approach at the pinned mirror commit

Celeste's own build of Monocle isn't public; this assumes Approach is unchanged.

Cited by: Variable jump height

Celeste's actors sit on whole pixels; MoveV adds the float distance to a remainder, moves by its rounded value, and keeps the fraction. celeste-player/move-remainder

About: Celeste Gravity

T2 primary statementCeleste and TowerFall Physics · Actor BasicsxRemainder += amount; int move = Round(xRemainder); if (move != 0) { xRemainder -= move;Celeste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L935 — the call site; Actor itself is not in the released filesMoveV(Speed.Y * Engine.DeltaTime, onCollideV);Checked by claude, 2026-10-20 — read the article (Wayback copy) and the MoveV call at the pinned commit

The article shows MoveX; MoveY/MoveV is the same with Y. It writes Round() without a tie rule; the widget uses C#'s Math.Round (ties to even), which never matters here because the float remainders are never exactly .5.

Cited by: Celeste, Subpixel, Variable jump height

Celeste's developers describe the game as locked to 60 updates per second, so the bundled PICO-8 port skips every second frame. celeste-player/fixed-60fps

About: Celeste Variable jump height

Value: 60 Hz

T2 primary statementCeleste: released class files (NoelFB/Celeste) · Source/PICO-8/Emulator.cs#L268-L270// this is a pretty dumb hack but because Celeste is locked to 60fps // and PICO-8 runs at 30 ... we just skip every 2nd frameChecked by claude, 2026-10-20 — read the comment in Emulator.Update at the pinned commit

Cited by: Coyote time, Variable jump height

At normal speed, Celeste's Engine.DeltaTime is most likely (float)0.0166667 s, the XNA and FNA default 166,667-tick step, not an exact 1/60 s. celeste-player/delta-time

About: Celeste Coyote time

Value: 0.0166667 s

T1 secondarydisputedFNA (XNA 4.0 reimplementation) · src/Game.cs#L247 — FNA's default; Celeste's own setting is not publicTargetElapsedTime = TimeSpan.FromTicks(166667); // 60fpsCeleste: released class files (NoelFB/Celeste) · Source/Player/Readme.md#L28If you're playing on macOS or Linux you're on FNA, and on consoles you're on MonoGame.Monocle Engine (public source, GitHub mirror JamesMcMahon/monocle-engine) · Monocle/Engine.cs#L198-L199RawDeltaTime = (float)gameTime.ElapsedGameTime.TotalSeconds; DeltaTime = RawDeltaTime * TimeRate;Coyote Time (DGMI wiki) · Examples — 5 frames matches this step; an exact 1/60 s step would give 6 (float-timer-frames)Celeste (2018) – The player character can jump up to 5 frames after leaving a ledge.

Disputed: Not shown in released code. Player.cs only reads Engine.DeltaTime, and the public Monocle source sets IsFixedTimeStep = false (Monocle/Engine.cs L121), unlike the shipped game, which the developers call "locked to 60fps". If the step were exactly 1/60 s, the grace and variable-jump timers would each last one frame longer.

The widget lets the reader switch between the two steps.

Cited by: Coyote time, Variable jump height

The 0.1 s grace and 0.2 s variable-jump timers end on float rounding; a (float)0.0166667 step gives 5 and 11 updates, and (float)(1/60) gives 6 and 12. celeste-player/float-timer-frames

About: Celeste Coyote time

Value
{
 "step0_0166667": {
  "grace": 5,
  "varJump": 11
 },
 "step1_60": {
  "grace": 6,
  "varJump": 12
 }
}
T4 reproducedCeleste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L713-L720 — grace timerCeleste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L742-L744 — variable-jump timerCoyote Time (DGMI wiki) · ExamplesThe player character can jump up to 5 frames after leaving a ledge.Checked by claude, 2026-10-20 — ran the probe (float32 arithmetic via Float32Array) and the model testsProbe: probes/jump-physics/jump-heights.mjs

After six subtractions 0.1f - 6 * (float)0.0166667 is about −1.9e−7 (no jump), while 0.1f - 6 * (float)(1/60) is about +3.7e−9 (jump). Assumes float32 arithmetic per C# statement.

Cited by: Coyote time, Variable jump height

Simulating the jump code (flat ground, no lift boost, (float)0.0166667 step) gives apexes of 7 px tapped and 27 px held, airtimes 15 and 39 updates; an exact 1/60 s step gives 29 px held in 40. celeste-player/apex-by-hold

About: Celeste Variable jump height

Value
{
 "step0_0166667": {
  "tap": {
   "apex": 7,
   "airtime": 15
  },
  "full": {
   "apex": 27,
   "airtime": 39
  }
 },
 "step1_60": {
  "tap": {
   "apex": 7,
   "airtime": 15
  },
  "full": {
   "apex": 29,
   "airtime": 40
  }
 }
}
T4 reproducedCeleste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L2952-L2966 — gravity and variable jumpCeleste: released class files (NoelFB/Celeste) · Source/Player/Player.cs#L1660-L1673 — Jump()Checked by claude, 2026-10-20 — ran the probe and the widget model tests; both agreeProbe: probes/jump-physics/jump-heights.mjs

Heights are whole pixels at Madeline's feet (her Position is the bottom of her hitbox, Player.cs L263).

Cited by: Variable jump height

The developers chose one large file of long methods for the player's behavior, so its tightly ordered logic reads in sequence. celeste-player/one-file

T2 primary statementCeleste: released class files (NoelFB/Celeste) · Source/Player/Readme.md#L16In a platformer like Celeste, the player behavior code needs to be very tightly ordered and tuned, and this style of code was a conscious choice to fit the project and team.Checked by claude, 2026-10-20 — read the Player readme at the pinned commit

Cited by: Celeste