jengine-platformer
Platformers: hero feel (coyote time, jump buffering, wall jumps, dash) and level parts on the engine’s character controller.
| Kind | Project package: linked into the builds of the projects that list it |
| Source | packages/jengine-platformer |
| Version | 0.1.0 |
| Entry point | jengine_platformer::PlatformerPackage |
| Script namespace | Platformer |
| Listed by | projects/arcade-classics |
Using it
Section titled “Using it”List it in the top-level "packages" array of project.jengine:
{ "packages": [ { "name": "jengine-platformer", "source": { "type": "path", "path": "../../packages/jengine-platformer" } } ]}Then rebuild the editor viewport for the project (jengine viewport-build projects/<name>, or the
editor’s Rebuild viewport banner). Native and web builds link it on their own.
A scene that uses its components must be a v2 scene ("version": 2): a v1 scene has no field
for a package component and keeps it as inert custom data.
A script can check that the package is linked with if Platformer == nil then return end.
Components
Section titled “Components”| Scene key | Rust type | |
|---|---|---|
platformer_hero | PlatformerHero | package only: needs a v2 scene |
platformer_walker | Walker | package only: needs a v2 scene |
platformer_mover | Mover | package only: needs a v2 scene |
platformer_crumble | Crumble | package only: needs a v2 scene |
platformer_spring | Spring | package only: needs a v2 scene |
platformer_pickup | Pickup | package only: needs a v2 scene |
platformer_hazard | Hazard | package only: needs a v2 scene |
platformer_checkpoint | Checkpoint | package only: needs a v2 scene |
platformer_goal | Goal | package only: needs a v2 scene |
Script commands
Section titled “Script commands”Commands run in every runtime and return nothing; a package publishes what scripts read onto components (see the notes below). The flat name also works.
| Call | Flat name |
|---|---|
Platformer.input(e, x, jump, jump_held, down, dash) | plat_input |
Platformer.respawn(e) | plat_respawn |
Platformer.freeze(e, frozen) | plat_freeze |
Scenes that use it
Section titled “Scenes that use it”projects/arcade-classics/assets/scenes/hollow.sceneprojects/arcade-classics/assets/scenes/peak1.sceneprojects/arcade-classics/assets/scenes/peak2.sceneprojects/arcade-classics/assets/scenes/peak3.sceneprojects/arcade-classics/assets/scenes/rain1.sceneprojects/arcade-classics/assets/scenes/rain2.sceneprojects/arcade-classics/assets/scenes/rain3.scene
From packages/jengine-platformer/README.md.
A platformer hero that feels right to run and jump with, and the things a
level is made of. The collision is the engine’s: everything that moves here
is a kinematic body with a character_controller, and the level is a
tilemap with a tilemap_collider.
Used by projects/arcade-classics (Pebble Peak). Engine Test Lab scene 81
covers the engine half.
| Module | What it is |
|---|---|
hero | The feel: acceleration, coyote time, jump buffering, variable jump height, wall slides and wall jumps, an air jump, a dash, and running along slopes. A pure function of the input and the controller’s report. |
lib | The level’s parts and what happens when the hero meets them, the script commands, and what it publishes. |
The feel
Section titled “The feel”Hero::step takes the player’s intent and what the controller reported
after the last physics step, and answers with the velocity to ask for next.
Every rule in it is one a platformer needs to feel fair:
- Acceleration, not instant speed, and a stronger push when turning around.
- Coyote time (0.1 s): a jump just after running off a ledge still jumps.
- Jump buffering (0.12 s): a jump pressed just before landing happens on landing.
- Variable height: letting go early cuts the rise to 45%.
- A heavier fall than the rise, and a capped fall speed.
- Wall slides while pushing into a wall, and wall jumps off it, with a moment where the stick cannot pull you back into it.
- One air jump and one dash, both back when you land.
- Slopes: on the ground the hero runs along the surface, so uphill is as quick as the flat.
- Down + jump drops through a one-way platform.
The defaults suit 32-unit tiles: a jump clears about 4 tiles of height and
6 of distance. They are all fields of Feel on the component.
The level’s parts
Section titled “The level’s parts”| Component | Is |
|---|---|
platformer_hero | The player. Feel, hearts, damage, knockback, death and respawn. |
platformer_walker | An enemy that patrols, turning at walls and at ledges. Stomp it from above; walk into it and you are hurt. |
platformer_mover | A kinematic platform that travels a path of points, back and forth or round a loop. The engine carries whoever stands on it. |
platformer_crumble | A platform that shakes when stood on, falls away, and comes back. |
platformer_spring | Launches the hero upward. |
platformer_pickup | A coin, a gem or a heart, collected on touch. |
platformer_hazard | Spikes and the like: hurts, or kills outright. |
platformer_checkpoint | Where the hero comes back after dying. |
platformer_goal | The end of the level. |
Pickups, hazards, walkers, springs, checkpoints and goals are sensors:
the hero’s controller reports them in touching without being stopped by
them. Put enemies on their own collision layer and leave that layer out of
the hero’s collider filter, so they never block each other (Pebble Peak
uses layer 4 for them).
Death is not the end of a run: the hero loses its hearts, dies, and is
put back at its last checkpoint with them all back. Falling below kill_y
does the same. A game that wants lives counts the died events.
Script commands
Section titled “Script commands”| Call | Does |
|---|---|
Platformer.input(e, x, jump, jump_held, down, dash) | This frame’s input: x is -1 to 1, the rest are flags. Send it every frame. |
Platformer.respawn(e) | Back to the last checkpoint, healed. |
Platformer.freeze(e, frozen) | Stops the hero: a menu, a cutscene, the end of a level. |
What scripts read
Section titled “What scripts read”PlatformerState on the hero, every frame: pose (idle, run,
jump, fall, wall, dash, hurt, dead, goal), facing,
grounded, vx, vy, hearts, max_hearts, coins, gems,
invulnerable, frozen, goal, dead, checkpoint and air_jumps.
PlatformerEvents.events on the hero: jump, air_jump, wall_jump,
land (with its impact), dash, drop, collect (with item,
value and where), stomp, spring, hurt, died, respawn,
checkpoint, goal, and shake / crumble / restore for the
crumbling platforms.
PlatformerWalker on each walker: dir and dead, for the sprite.
src/hero.rs, with no physics at all: acceleration and turning, coyote time and the jump buffer, the cut-short jump, wall slides and wall jumps, one air jump and one air dash, running up a slope, and dropping through.tests/level.rs, on the engine’s real physics, one frame at a time in the order the runtimes run: running and jumping, collecting a coin and hitting a spring, stomping a walker and being hurt by one, walkers turning at ledges, a crumbling platform falling and coming back, riding a moving platform, dying on spikes and in a pit and coming back at the checkpoint, and the goal.