Applied Module 12 · The Lora Playbook

The Movement and Camera Feel Lab

What you'll learn

~55 min
  • Generate a real-time parameter tuning sandbox for Phaser 3 movement physics
  • Adjust run speed, jump height, gravity, dash, and air control with sliders while playing
  • Tune camera smoothing, zoom, and follow behavior for side-scrolling feel
  • Dial in the fast, acrobatic movement style that defines BloodRayne

What you’re building

You have combat. Now you need movement that feels right. BloodRayne was defined by how Rayne moved — fast, fluid, acrobatic. She could sprint across a room, leap over enemies, and change direction mid-air. That feel did not happen by accident. It happened because someone sat in a room and tuned numbers until the movement stopped feeling like a character and started feeling like an extension of the player’s hands.

That is what you are doing in this lesson. You are building a tuning sandbox — a Phaser 3 scene with a side-scrolling level and an HTML control panel that lets you adjust every movement parameter in real time. Change the run speed slider, the character moves faster immediately. Change the jump height, the character jumps higher on the next press. No code editing, no page reloads. Just play and tweak until it feels like BloodRayne.

Software pattern: Real-time parameter tuning with hot reload

This is the same pattern used in professional game development — expose tunable values to a UI so designers can iterate without touching code. Unity has its Inspector panel, Unreal has Blueprints, and now you have an HTML slider panel that talks directly to your Phaser game. This pattern applies anywhere you need to find the right values by feel rather than calculation: animation timing, UI transitions, physics simulations.


The showcase

Here is what the finished sandbox gives you:

  • Side-scrolling level with multiple platforms at different heights, a long floor, and walls to test movement against
  • Player character (Rayne) with full movement: run, jump, dash, wall slide
  • Tuning panel (HTML sidebar) with real-time sliders for:
    • Run speed (50-500 px/s, default 200)
    • Acceleration (100-2000 px/s^2, default 800) — how fast you reach top speed
    • Deceleration (100-3000 px/s^2, default 1200) — how fast you stop
    • Jump velocity (-100 to -600, default -350) — how high you jump
    • Gravity (200-1200, default 600) — how fast you fall
    • Air control (0-100%, default 60%) — how much horizontal control mid-air
    • Dash distance (50-300 px, default 150)
    • Dash cooldown (200-2000 ms, default 800)
    • Camera lerp (0.01-1.0, default 0.1) — how smoothly the camera follows
    • Camera zoom (0.5-2.0, default 1.0) — zoom in for detail, out for overview
  • Real-time value display — each slider shows its current numeric value
  • Preset buttons — “BloodRayne Fast”, “Floaty Platformer”, “Tight and Precise”, “Reset Defaults”
  • Export button — copies all current values as a JSON object to your clipboard

The character responds instantly to every slider change. You can literally hold the jump button and drag the gravity slider to feel the difference in real time.


The prompt

Open your terminal, navigate to your project folder, start your AI CLI tool, and paste this prompt:

Build a Phaser 3 movement tuning sandbox for a BloodRayne-inspired side-scrolling
action game. The sandbox lets you adjust all movement parameters with real-time
sliders while playing. Create a single folder:
PROJECT STRUCTURE:
movement-feel-lab/
index.html (Phaser 3 game + HTML tuning panel, all inline)
SPECIFICATIONS:
1. PAGE LAYOUT
- Split layout: game canvas on the left (700px wide), tuning panel on the right (280px wide)
- Tuning panel is a styled HTML sidebar with dark background (#1a1a2e), light text
- Sliders are HTML range inputs, each with a label and a live numeric value display
- Panel scrolls if content exceeds viewport height
- Panel has section headers: "Movement", "Jump & Gravity", "Dash", "Camera"
2. GAME SCENE (700x450 canvas)
- Background: dark gradient (deep purple #1a0a2e to black)
- Ground platform: full width at bottom, gray
- Elevated platforms: 5-6 platforms at varying heights and widths to test
jumping between them, including:
* A tall wall on the right to test wall collision
* A series of small stepping-stone platforms to test precise jumping
* A long high platform to test running at speed
* A gap that requires a dash to cross (exactly dash distance at default settings)
- Level wraps: if player goes off the right edge, appear on left (and vice versa)
- Subtle grid lines on background for visual speed reference
3. PLAYER CHARACTER
- 32x48 dark red rectangle (#8B0000) -- same as the combat prototype
- Arrow keys for movement, up arrow to jump, X to dash
- All movement values read from a shared config object that the sliders modify:
* runSpeed (default 200) -- max horizontal velocity
* acceleration (default 800) -- horizontal acceleration rate
* deceleration (default 1200) -- horizontal deceleration when no input
* jumpVelocity (default -350) -- initial vertical velocity on jump
* gravity (default 600) -- downward acceleration
* airControl (default 0.6) -- multiplier for horizontal acceleration while airborne
* dashDistance (default 150) -- total pixels traveled during dash
* dashDuration (default 200) -- milliseconds for the dash
* dashCooldown (default 800) -- milliseconds before dash is available again
- Jump: only when grounded. Apply jumpVelocity as an impulse.
- Air control: while airborne, horizontal acceleration is multiplied by airControl.
At 0%, player has no air control (committed to jump arc). At 100%, full control.
- Dash: press X to dash in facing direction. During dash, override horizontal
velocity to (dashDistance / dashDuration * 1000) for dashDuration ms.
Player is semi-transparent during dash. Cannot dash again until cooldown expires.
- Acceleration model: don't set velocity directly. Apply acceleration toward
target speed so movement has ramp-up and ramp-down feel. This is what makes
the difference between "ice skating" and "responsive."
4. TUNING PANEL SLIDERS
Each slider updates the config object in real time (on input event, not on change):
Movement section:
- Run Speed: range 50-500, step 10, default 200
- Acceleration: range 100-2000, step 50, default 800
- Deceleration: range 100-3000, step 50, default 1200
Jump & Gravity section:
- Jump Velocity: range -600 to -100, step 10, default -350
(label shows absolute value for clarity)
- Gravity: range 200-1200, step 50, default 600
- Air Control: range 0-100, step 5, default 60 (shown as percentage)
Dash section:
- Dash Distance: range 50-300, step 10, default 150
- Dash Cooldown: range 200-2000, step 50, default 800
Camera section:
- Camera Lerp: range 0.01-1.0, step 0.01, default 0.1
- Camera Zoom: range 0.5-2.0, step 0.05, default 1.0
5. CAMERA
- Camera follows the player using Phaser's camera follow with lerp
- Camera lerp value reads from config.cameraLerp -- low values = smooth
follow with lag, high values = snappy follow
- Camera zoom reads from config.cameraZoom
- Camera bounded to the level edges (don't show void beyond the level)
- Update camera follow properties every frame from the config object
6. PRESETS
Four buttons at the top of the tuning panel:
"BloodRayne Fast": runSpeed 350, acceleration 1500, deceleration 1800,
jumpVelocity -420, gravity 800, airControl 80, dashDistance 200,
dashCooldown 500, cameraLerp 0.08, cameraZoom 0.9
"Floaty Platformer": runSpeed 150, acceleration 400, deceleration 400,
jumpVelocity -300, gravity 300, airControl 90, dashDistance 100,
dashCooldown 1200, cameraLerp 0.05, cameraZoom 1.0
"Tight and Precise": runSpeed 180, acceleration 2000, deceleration 2500,
jumpVelocity -380, gravity 900, airControl 40, dashDistance 120,
dashCooldown 600, cameraLerp 0.15, cameraZoom 1.1
"Reset Defaults": all values back to the defaults listed above
When a preset is clicked, update all slider positions and their displayed
values, and update the config object. The character should immediately
respond to the new values.
7. EXPORT BUTTON
A button at the bottom of the panel labeled "Copy Values to Clipboard"
that copies the current config object as formatted JSON. This is how
you save your tuned values to paste into the combat prototype later.
8. VISUAL FEEDBACK
- Show current velocity as a small debug readout below the health bar area:
"vel: 187 / -342" (horizontal / vertical)
- Show "GROUNDED" or "AIRBORNE" state indicator
- Show "DASH READY" or "DASH COOLDOWN: 0.4s" indicator
- Trail effect: when running above 250px/s, show faint afterimage dots
behind the player (3-4 semi-transparent copies spaced behind, fading)
TECHNICAL: Use Phaser.Physics.Arcade. All sprites are colored rectangles.
Load Phaser 3 from CDN. Game must run by opening index.html -- no server needed.
The HTML sliders communicate with the Phaser game through a shared JavaScript
object (window.gameConfig or similar).
💡Copy-paste ready

That entire block is the prompt. The preset values are where the real design work lives — “BloodRayne Fast” is a starting point for how your remake should feel. You will spend most of your time in this sandbox bouncing between presets, tweaking individual values, and jumping between platforms until the movement makes you smile. That is the job.


What you get

After the AI finishes, you have one file:

movement-feel-lab/
index.html

Play it

Terminal window
cd movement-feel-lab
open index.html

Start by clicking “BloodRayne Fast” and running around the level. Jump between the platforms. Dash across the gap. Then start tweaking. Pull the gravity slider up — notice how the jump becomes snappy and short. Pull it down — now you are floating. Find the sweet spot where the jump feels powerful but committed.

If something is off

ProblemFollow-up prompt
Sliders don’t affect the gameThe HTML sliders are not connected to the Phaser game. Create a window.gameConfig object that both the sliders and the Phaser update loop reference. Each slider's oninput handler should set the corresponding gameConfig property. In the Phaser update function, read all movement values from window.gameConfig instead of hardcoded numbers.
Character slides on the ground like iceThe deceleration is not being applied. When no horizontal input is pressed and the player is grounded, apply deceleration by reducing velocity toward 0 using the deceleration value from config. Use Phaser.Math.Linear or manually reduce velocity by deceleration * delta each frame.
Camera jumps instead of smoothingThe camera lerp is not being applied correctly. Use this.cameras.main.startFollow(player, true, config.cameraLerp, config.cameraLerp) and update the follow offset and lerp values each frame. Don't call startFollow every frame -- call it once in create() and then update the camera's lerp properties directly in update().
Dash goes the wrong distanceThe dash travels too far or too short. Calculate dash velocity as (dashDistance / dashDuration) * 1000 to convert from ms to per-second. Set player horizontal velocity to this value for exactly dashDuration ms using a timer, then restore normal movement control.

Deep dive

This sandbox is not just a toy. It is how professional game designers work. Here is why each parameter matters and how to think about tuning them.

Acceleration is the secret ingredient

Most people think run speed is what makes a game feel fast or slow. It is actually acceleration and deceleration. High acceleration means the character reaches top speed instantly — it feels responsive and snappy. Low acceleration means the character ramps up slowly — it feels heavy and deliberate. BloodRayne needs high acceleration (Rayne reacts instantly to player input) and high deceleration (she stops on a dime, no sliding). Compare this to a Mario game where Mario has low deceleration — he slides, and that sliding IS the game. For a combat game, sliding gets you killed.

Air control defines jump commitment

Air control at 0% means once you jump, your horizontal trajectory is locked — you are committed to the arc. Air control at 100% means you have full steering mid-air. BloodRayne should be somewhere around 60-80% — enough to adjust your landing, not so much that jumping feels like floating. This is a design decision about how punishing missed jumps should be.

Camera lerp creates feel without touching the character

A camera lerp of 0.1 means the camera moves 10% of the distance to its target each frame. The result: the camera lags slightly behind, creating a sense of momentum and speed. The player character actually runs “ahead” of the camera center, which subconsciously makes the player feel fast. Drop the lerp to 0.03 and suddenly the game feels cinematic and weighty. Push it to 0.5 and it feels like a security camera — locked on, clinical. The right value for BloodRayne is low (0.05-0.1), because Rayne should feel like she is outrunning the camera.

🔍The 'copy values' workflow

When you find movement values that feel right, click “Copy Values to Clipboard.” This gives you a JSON object you can paste directly into the combat prototype from Lesson 10. This is intentional — the tuning sandbox and the combat prototype are separate so you can iterate on movement without worrying about enemy behavior, and vice versa. In Lesson 19 (Playable Demo Assembly), the AI CLI will stitch these systems together using your tuned values.


Customize it

Add wall jumping

Add wall sliding and wall jumping. When the player is airborne and
pressing into a wall (left arrow against left wall or right arrow against
right wall), they slide down at 40% of normal gravity. Pressing jump
while wall sliding launches the player away from the wall at a 45-degree
angle with 80% of normal jump velocity. Add a "Wall Jump" section to the
tuning panel with sliders for wall slide gravity multiplier (0.1-1.0,
default 0.4) and wall jump force multiplier (0.5-1.5, default 0.8).

Add double jump

Add a double jump ability. The player can press jump once in the air for
a second jump at 70% of normal jump velocity. Add a slider for double
jump velocity multiplier (0.3-1.0, default 0.7) and a visual indicator
showing whether double jump is available (small dot below the player
that disappears after use and reappears on landing).

Add a speed trail particle system

When the player is running above the threshold speed (configurable via
slider, default 250px/s), emit a particle trail behind them. Particles
are small red squares that fade from 80% opacity to 0 over 300ms. Emit
rate increases with speed. Add a slider for trail threshold speed and
trail particle lifetime.

Try it yourself

  1. Paste the prompt and open index.html in your browser.
  2. Click each preset button and spend one minute with each. Which one feels closest to how you remember BloodRayne?
  3. Starting from the “BloodRayne Fast” preset, adjust three values to make it feel better to you. Write down what you changed and why.
  4. Find the minimum air control percentage where you can still reliably land on the small stepping-stone platforms. That is your lower bound.
  5. Set gravity to maximum and jump velocity to maximum. This is the “heavy and powerful” extreme. Now set both to minimum. This is the “floaty and light” extreme. BloodRayne lives somewhere between these — find it.
  6. Click “Copy Values to Clipboard” when you have values you like. Save them in a text file. You will use them in Lesson 19.

The numbers do not lie, but they also do not matter until they feel right under your fingers. Trust your hands. Rayne would.


💡You own the feel

Movement feel is the thing players notice first and describe last. They will say “this game feels great” without being able to explain why. You now know why — it is acceleration curves, air control percentages, and camera lerp values. You have the sandbox to find the exact numbers that make YOUR BloodRayne remake feel right. Next lesson: enemy behaviors that are worth dodging.