MarbleMagnificence

Dev log

The stagger that walked marbles into the sea

Hazards commit a75f293

Long falls now cost something and six things now hunt the marble. Not one of them rolls a die, and an early dizzy marble drowned with nobody steering it.

Until this commit the world was indifferent. You could fall off anything and the only cost was the walk back. Now a long drop leaves the marble dizzy, a cliff breaks it, and the levels have residents. The comment at the top of FallDamage sets the terms: “Neither costs the run; both are punchlines.”

The residents

Two appear on every release level. The other four belong to one level each, because they only make sense there.

  • Acid, every level, reach 1.1. A marble flying over the acid gets away with it.
  • Muncher, every level, reach 5. A fed muncher naps before it hunts again.
  • Steelie, The Mountain, reach 9. A steelie that falls off its court comes back.
  • Icicle, The Long Thaw, reach 0.65. A standing icicle is solid.
  • Laser, Prism Hall, reach 6. Beyond the beam’s end is safe.
  • Vortex, Escher, reach 4.5. A held stick escapes the vortex from its rim.

The italics are test names, and the reach is each kind’s default.

The steelie never kills anything on its own. It chases you round its court and shoves, and the edges do the rest.

Two gameplay screenshots side by side. Left: a green pipe with a red shape spilling from behind it, on a grey tiled court. Right: a red marble beside a black marble with one googly eye peering round a stone column.
A marble left sitting by the muncher, which is a mistake, and the steelie coming round a column. Simulator captures from this commit, parked in place with its -hazard debug flag.

Where a fall starts

A drop is measured along gravity’s up, from the last real ground contact to the next one. Not from the apex: a boing pad that throws you six units up and lands you where you started is a toy, not a fall.

Height alone still over-counts. A marble sliding down a flank too steep to count as ground was technically airborne the whole way, and it should not score like a plummet onto flat stone. So the drop is capped by what the landing actually hit like:

let struck = marble.impactSpeed * marble.impactSpeed
    / (2 * abs(profile.gravity))
let drop = min(from - height, struck)

A straight fall’s impact gives back its own height, so for those the cap changes nothing.

The thresholds are not round numbers somebody liked. Each sits just above a promise the levels had already made:

A horizontal scale of drop height from 0 to 20 units with three bands: free below 6, dizzy from 6 to 15, and shatter from 15 up. Dashed markers show a 5-unit chute flight inside the free band and a 12.9-unit rail fall inside the dizzy band.
FallRules. The mountain’s chutes throw you 5 units by design, and the intended route must never make you dizzy. The Prism quick rail drops 12.9, and the level promises you walk away from it — dizzy, but whole.

Water breaks a fall completely. The kill plane sits under the surface, so that case is a seabed you were never meant to reach, but it is still not a cliff.

Two sines and a beach

Dizzy steering bends your push by an amount that wobbles with the clock:

let angle = rules.swerve * strength
    * (0.65 * sin(2.3 * t) + 0.35 * sin(5.1 * t + 1.0))

The two sines are incommensurate on purpose. One sine is a pattern you learn in a second and steer against. Two are a marble that has had a few.

On top of that goes a slow stagger, and this is where it went wrong. A stagger that drives the marble by itself will drive it while nobody is touching anything, and it walked hands-off marbles off the beach into the sea: a respawn the player did nothing to earn.

So the wander is multiplied by the length of your push. Let go and a dizzy marble sits there with stars round its head. The test is named for the whole rule: “Drunk steering bends a push, and leaves a released stick alone.”

No dice

None of this uses a random number. Every hazard is clock-driven, and that is worth a lot more than it sounds:

  • Runs replay exactly. “Hazards replay exactly” drives two simulations through a muncher and a steelie and compares the results.
  • Tests can stand next to one and know what it will do. There are 26 hazard tests and 10 for falls, and a failure in one is a bug, not bad luck.
  • Players can learn them, which is the point of a hazard you can see coming.
Two gameplay screenshots side by side. Left: pale icicles hanging in the air over a stone court on the icy Long Thaw level, near a penguin and a lamp post. Right: a red marble near a dark post on a blue and green floor, with a red beam and a cyan beam extending from it.
Icicles over the Long Thaw, and the Prism Hall laser on its post. They hang out of sight, throw a shadow, and drop; it just keeps turning.

Determinism has a price, and the geometry critics paid it. Their autopilots drive a fixed line, and a fixed line cannot dodge a muncher or wait out a gravity well. The Escher and Prism finale runs now switch hazards off, certifying the geometry alone, and the hazards keep their own tests.

Being put back

Respawning has its own trap. The game banks safe points as you roll, and being put back after the muncher ate you, in front of the muncher, is an infinite loop with a sound effect. So nothing banks inside a hazard’s reach, and three tests hold the level data to it: no checkpoint in reach, no hazard inside a minigame, and every hazard standing on the floor it was placed on.

One more switch: fall rules are off in multiplayer. A phone predicts its own marble and reconciles against the TV, and a state only one side believes in is a rubber band.

Unmeasured

The tests say what each hazard does. They have no opinion on whether being chewed by a green pipe is any fun, and no player has told us yet. These shots came from a simulator with the marble teleported into place, which is a fine way to take a picture and no way at all to judge a game.