Feel comparison (on-foot movement and the follow camera)¶
Verified against: SLUS_212.15 (NTSC-U, SHA1 e9cb2cc49aa046b9e494313dce2f5038ed17b2f4) and Coney at commit
ae87e1b. Runtime claims were made in PCSX2 2.9.94 (2026-10-05), reading memory over PINE once per character update
while a scripted pad played, from copies of the test save states with the pad input patched in
(Driving PCSX2); each claim names its save. The saves' "street"
is in level99's world: the player's spots, the ground height (0.223) and the objects there (a 1.505 m trash can,
a material 30 fence 19.04 m ahead of the fence save) are exactly where level99's collision mesh puts them.
Purpose¶
What it takes for Coney's player to feel like the original's: the same scripted analog inputs were played in the original and in Coney, from the same spot, and the per-update traces of position, speed, heading, clip and camera were compared. This page lists every difference beyond noise with the original's value and its evidence, and which Coney value or rule to change. The mechanics themselves are on Characters and Camera, which were corrected in place where the runs contradicted them.
Method¶
- Inputs. Each run is a Coney input script (
FRAME stick left X Y,press l2,tap triangle, Input scripts) with the frame read as the update number. On the original side a PINE client wrote the same raw stick bytes Coney makes from a script value (160 + round(0.95 × v)forv > 0,95 − round(0.95 × |v|)below, 128 at rest) and the same button bits, through the patched pad read, at the update the script names (±1 update of latency, aligned by the clip change). The original's stick table at0x0050b8d0is the same map as Coney'spad::stickValue(dead band 95-160,(raw − 160) / 95; read from the save's RAM), so both sides saw identical stick values. Deflections used: 35, 50 (diagonal), 60, 70 (diagonal), 80, 96 and 100 %, plus turns of 15°, 45°, 90° and 180°, stick sweeps of 1.5°, 3° and 6° per update, the right stick at 30, 60 and 100 %, L2 and triangle. - Original trace. Every update (game time
*(0x0050b734) + 0x48advancing by 1/30 s): the transform table (0x00714b00, position and heading), human+0x1acspeed,+0x1a8gait,+0x3a0vertical speed, record+0x20clip,+0x08flags,+0x14astamina, and the follow camera (*(0x005d9158)):+0x10position,+0x180look-at,+0x250wanted position,+0x3b4target pitch,+0x388lag,+0x32c/+0x330leash band. No update was missed in any run. - Coney trace. A throwaway tool (outside the repository) stepped Coney's
HumanandFollowCameraheadless onlevel99's collision mesh, from the save's position and heading, with the camera placed behind at the save's view heading, and printed the same quantities per update. Coney's own--traceoption now writes them (Running Coney). - Saves. Slot 1 (a clear street, facing −x) for walks, runs, turns, sprint, jumps and the right stick; slot 7 (the fence) for the running fence climb; slot 8 (the trash can and roof) for the short-wall and wall climbs.
Comparison¶
"Coney" is Coney at ae87e1b driven by the same script. Rates are per character update (1/30 s) unless marked.
| Quantity | Original | Coney | Difference | Coney value to change |
|---|---|---|---|---|
| Turn limit per update, player: walk / jog / run / sprint | 20° / 18° / 18° / 16° | 12° / 6° / 4° / 2.5° | 1.7× to 6.4× faster | LocomotionTuning::walkTurnDegrees, jogTurnDegrees, runTurnDegrees, sprintTurnDegrees |
| Heading error at which the turn eases to full | 2.0 rad | 1.5 rad | ease is gentler | kTurnEaseError |
| Stick turned 90° at a run | 16.1°, then 18° per update; facing reached in 6 updates (0.2 s) | 4° per update, 23 updates | (above) | |
| Stick turned 45° at a run | 6.3°, 9.8°, 10.8°, 10.0°, 8.4°, 4.5° | 2.2°, 3.7°, then 4° | (above) | |
| Stick turned 90° in a sprint | 14.3°, then 16° per update | 2.5° per update | (above) | |
| Stick released at a run (7.80 m/s) | run stop 417 for 24 updates, the body slides 1.63 m | stops dead, idle at once | missing | play the run stop after a run's skid as after a sprint's |
| Stick reversed (180°) at a run | turns 18°, then skid: 417 for 24 updates sliding 1.63 m the old way, then the walk/run start toward the stick, turning 20° per update | speed 0 at once, then turns 12° per update while gaining 0.8 m/s per update, no clip | missing | (above, and the turn limits) |
| First update with the stick pushed (from idle) | the start clip begins, speed 0 | the start clip begins and the body moves at 0.8 m/s | Coney moves one update early | no locomotion speed on the update the start clip begins |
| Walk start (413) / run start (414) length | 13 updates each | 14 updates each | +1 update | the start clip's length or its hand-over test |
| Root-motion speed of a clip that moves the body | walk start 0.762 m/s, landing 436 4.230 m/s | 0.786, 4.361 | Coney 3.1 % fast: the original scales root motion by the body scale (0.97) | multiply root motion by Human::scale() |
| Walk / run / sprint speed | 1.629 / 7.801 / 10.245 m/s | the same | none | |
| Gain per update | 0.8 m/s | 0.8 m/s | none | |
| Walking body: distance kept from a wall face | 0.480 m (two walls and the fence) | 0.34 m | 0.14 m closer in Coney | the player's sphere is 0.35 × 1.4286 (body +0x60) × 0.97 × 0.97 (the scale counts twice) = 0.4705 m: BodyTuning::radius 0.5 for a player |
| Running into a wall 60-70° off its line | speed drops to the slide's share (4.0, 1.5, 0.86, 0.65, 0.56, …, 0.40 m/s) and the player ends in the idle pressing the stick | keeps 7.80 m/s and slides along the wall at about 6.9 m/s | Coney slides, the original stops | keep the swept (slid) velocity as the next update's current speed (the speed is its length) |
| Jump during the run start | allowed once faster than 3.3 m/s (tap at 3.35 m/s jumped) | refused until the start clip ends | Coney late | drop the start-clip test from the jump |
| Run jump: arc | 5.5 m/s up, apex 1.06 m, the same per-update heights | the same | none | |
| Run jump: time in the air / take-off to landing | 24 updates, 6.24 m | 23 updates, 5.94 m | Coney lands 1 update early | let the last airborne move end below the ground (0.19 m at runtime) and land on the next update |
| Speed on the landing update | 7.80 m/s (full), then 436 at 4.23 | 0.82 m/s, then 3.27, 4.36 | Coney brakes early | keep the horizontal speed on the landing update |
| Landing 436 | 11 updates, then a gait blend from 4.23 m/s gaining 0.8 per update | 11 updates | none (but speed above) | |
| Air turn | 4° per update | 4° per update | none | |
| Sprint: speed, stamina drain and refill | 10.245 m/s; 20 per second; 40 per second | the same, update for update | none | |
| Running fence climb (slot 7, tap at the same update) | 440 for 11 updates, snap 1.11 + 1.17 m, ends 0.48 m from the face; 441 15; 442 13; run again 39 updates after the tap | 440 for 13 updates, snap 0.98 + 0.98 m, ends 0.68 m from the face; 441 15; 442 13; 41 updates | 440 2 updates long | the start point (the body stops at its 0.485 m sphere) |
| Short wall (trash can, 1.28 m up) | the feet rise in 2 updates (1.12 m, then 0.17 m) | 1 update | ||
| Wall onto a roof (2.64 m up) | rise of 2.30 m, then +0.097 m per update for 4 updates | 1 update | ||
| Camera leash band (wanted distance) | 4.8-5.3 m (the configured default distance and + 0.5) | 3.0-3.5 m | Coney 1.8 m closer | FollowSettings::leashNear / leashFar from the default distance, not 3.0 |
| Camera distance walking / running | 5.49 m / 5.65 m | 3.68 m / 3.85 m | (band) | (above) |
| Camera pitch walking / running | 12.6° / 11.1° | 12.3° / 10.3° | follows from the band | |
| Auto-follow (camera swings toward the facing) | runs whenever the player walks, runs, sprints or is in the air: the auto-centre rule, within about 5°/s for angles of 30-90° | none | missing | add the auto-centre rule (0x00129f88), Camera |
| Stick held 90° to the side | the player runs in a circle: camera and facing turn together at about 191°/s running and 143°/s walking (35-80 % stick); the auto-centre rule gives 122 and 127°/s of it, the leash's drag the rest | a wide arc, turned only by the leash (about 35°/s) | (auto-follow) | (above) |
| Sprint camera | from the first update at the sprint gait the band moves 4.8-5.3 → 3.0-3.5 and the target pitch 13° → 7°, both over 14 updates; back over 14 updates once the run stop slows the body | none | missing | add the sprint zoom (values below) |
| Camera in a sprint | 4.70 m, pitch 5.2° | 3.85 m, 9.7° | (sprint camera) | |
| Right-stick yaw at 30 / 60 / 100 % | 74.8 / 106.7 / 150.0 °/s | the same | none | |
| Right-stick pitch upper limit | 40° | 30° | 10° | FollowSettings::upperPitchDegrees 40 at the default zoom |
| Look-at height after a climb's rise | eases 20 % of the way per update while more than 0.8 m is left, then in 2 updates (the look-at point's distance limit, 0x00127d88); pitch stays at 3.6° or more |
snaps with the feet; pitch falls to −22° (roof) and −8° (trash can) | Coney looks up from below | ease the look-at height |
| Camera during a fence climb | 4.9-5.3 m throughout, the fence (material 30) between camera and player | collapses to 0.5 m while the body passes through | Coney's ray hits the fence | the camera's ray skips material 30 (and, inferred, the other see-through fences) |
| Camera passing a face just behind the player (slot 7, 0.19 m behind) | unaffected: the face is a 2.65 m panel the game has disabled, and the camera's ray ignores a disabled triangle within 0.5 m of the look-at point | pulled in to 0.5 m for about 1 s | Coney pulls in | keep the triangles' enabled bits as the game sets them, and the ray's disabled-triangle rule (Camera) |
Evidence: confirmed (runtime) for every "Original" value, PCSX2 2.9.94, the saves named in Method, each run read per update; the turn values are also confirmed (code), below.
Details behind the table¶
- Turn rates are set by the scripts.
config_preload2.luacallsCfgSetTurnRates(11, 16, 18, 18, 20, 24)andCfgTurnRate(true, false, 2.0, 0.8)(CfgSetTurnRates): the six player entries of the table at0x005101b0(the even words; the odd words, the non-players' 1.5°, 2.5°, 4°, 6°, 12°, 24°, keep their.datavalues) become 11°, 16°, 18°, 18°, 20°, 24°, and the ease reaches its full rate at 2.0 rad.Human_MaxTurn(0x002213d8) and its gait lookup (0x002212d0, the even word for a pad-controlled human, per-player record+0x1b) give the player: 16° sprinting (gait 5,0x00223a98), 18° running (0x00223a60) and jogging (0x00223a50), 20° otherwise; 4° and 6° in the states0x00227f68/0x00227f40; 11° in the states0x00223980/0x00223ad0, and 11° × 0.25 under0x00227d98; 24° in a combat stance (0x00228340); 16° × 0.25 = 4° with record flags0x1000080. Confirmed (code) at the cited addresses and confirmed (runtime): the values read in the save's RAM are those, and every measured step fitslimit × (1 − cos(π · error / 2.0)) / 2 + 0.8 × previous step, clamped to the limit (90° at a run: 18 × 0.891 = 16.0, then the clamp; 45°: 6.1, then 9.9 with the carry). In the air the turn stayed at 4° per update, the non-player run value (inferred:Human_AirControlreads the other column). - Auto-follow. The auto-centre rule's rate,
(a − 45°) × 2.444 + 45°per second from 22.5° to 90° (negative just above 22.5°: at 22.6° the camera turned 4°/s the other way), 200°/s from 90° to 100° and falling to 60°/s at 157.5°, fits the measured rotation of the wanted position witha= the angle between the player's new facing and the view from the camera's position at the start of the update to its look-at point (mean error 5.4°/s over 656 updates; the other definitions tried were 8-30°/s worse). It turned nothing while standing, during the walk and run start clips and during the landing clip 436, and turned at walk, run, sprint and in the air: the rule runs only at the gaits 2, 4 and 5 (walk, run, sprint), confirmed (code) at0x00129c78, and those clips move the body at gait 0, 1 or 3 (Camera). The save has the per-pad option bytes0x0050b240and0x0050b248at 1 (the auto-centre rule). Confirmed (runtime) in slot 1. Both are 1 by default: their bytes in the executable's.dataare 1 for both pads;0x0050b248(and+1) is set to 1 again by every camera reset (0x00122b80);0x0050b240is changed only by the options menu (its first choice writes 1, its second 0,0x001d7ff0→0x00418aa8, which also stores it in the profile at+0x448+ pad × 4) and by loading a profile (0x00421ad0). The camera reads both at0x00129e00/0x00129e2cand takes the default rule when either is 0. Confirmed (code). So a fresh boot uses the auto-centre rule; what a new profile saves at+0x448is not traced. - Sprint camera. Band and target pitch per update after the first update at gait 5 (the band's near edge; the
far edge is 0.5 more): 4.569, 4.379, 4.221, 4.085, 3.968, 3.863, 3.770, 3.686, 3.607, 3.533, 3.462, 3.391, 3.315,
3.216, then 3.000; the target pitch falls 0.4286° per update (6° in 14 updates, 12.9°/s). On the way back the same
14 values in reverse, starting 8 updates after the run stop began (when the body had slowed to about 2.5 m/s).
The view's pitch follows its target at the usual rate. Confirmed (runtime), slot 1, stick 100 % and L2. The code
(
0x00128cf0and the band's ease0x0012aae0, Camera): a 0.5 s timer; the band's near edge moves byd × |d| / T × dttoward the minimum distance (dleft,Tthe timer), the target pitch in a straight line to 7°; it starts on the first update at gait 5 and goes back 250 ms after the gait leaves 5 (8 updates). Confirmed (code) and, for the fields, confirmed (runtime). - Run stop. From a run or a sprint, 417 plays for 24-25 updates with record
+0x08=0x80000; the speed is the clip's (0, 2.24, 5.00, 5.10, 5.23, 5.38, 4.19, 3.19, 2.49, 2.16, 2.12, 2.06, 1.93, 1.74, 1.43, 1.14, 0.89, 0.75, 0.65, 0.55, 0.47, 0.39, 0.30, 0.20 m/s), 1.63 m in all, the facing held. A walk released stops at once with the idle (35, 60 and 80 % sticks), as Coney does. - Walls. The player's physics body has
+0x60=+0x64= 1.4286 (= 0.5 / 0.35) in the save, and its shape's radius+0x40is 0.3395 (0.35 × 0.97); times the scale again (0.97) makes the walking sphere 0.4705 m (Characters), and the measured stops were 0.480 m from the face (a straight wall, an angled wall and the fence). After a blocked move the velocity is the slid velocity, so the next update's speed starts from its length: running at 20° off a wall's normal settled at0.8 k / (1 − k)withk= sin 20° (0.42 m/s measured, 0.416 predicted) until the speed fell under a quarter of the sneak-walk speed (0.396 m/s) and the idle played. Confirmed (runtime), slot 1; the body fields read from the save. - Jump during a start clip. The tap that jumped came 7 updates into the run start (414), at 3.35 m/s; record
+0x08held0x10000000then, so that record bit does not block the jump. Confirmed (runtime), slot 7.
Coney's implementation¶
The fixes below are in Coney (Characters,
Camera); the values are from Coney's own trace (--trace,
Running Coney) on the sandbox's parkour lane with the same kind of scripted stick:
| Quantity | Original | Coney now |
|---|---|---|
| Turn limits walk / jog / run / sprint / combat stance; ease | 20° / 18° / 18° / 16° / 24°; 2.0 rad | the same (defaults, and from the preload's calls for a level) |
| Stick turned 90° at a run | 16.1°, then 18° per update | 16.0°, then 18° |
| Released or reversed at a run | run stop 417, 24 updates; a reversal turns 18° first | 417 for 24-25 updates; a reversal turns 18°, then the start toward the stick at 20° per update |
| First update with the stick pushed | the start clip begins, speed 0 | the same |
| Walk / run start length | 13 updates | 13 |
| Walk start speed (35 % and 60 %) | 0.762 m/s on all 12 moving updates | the same |
| Run start speeds | 2.773, 2.486, 2.558, 2.629, 2.844, 3.346, 3.895, 4.540, 5.112, 5.399, 5.614, 5.686 | the same but the 6th and 10th (3.251, 5.543): see below |
| Run stop speeds | 2.244, 4.996, 5.101, 5.229, 5.382, 4.193, 3.190, … | 2.244, 4.996, 5.101, 5.229, 5.382, 3.894, 3.190, …: the same but the 6th and 10th |
| Walking body | 0.4705 m sphere, steep walls brake | the same |
| Step under 0.25 m; stop at a taller face | walked onto in one update, speed and clip unchanged; stops 0.396 / 0.400 / 0.424 m from 0.255 / 0.26 / 0.30 m faces | the same |
| Jump during the run start | from 3.3 m/s | the same |
| Run jump: air time, last airborne height, landing update | 24 updates, −0.19 m, 7.80 m/s | 24, −0.19 m, 7.80 m/s, then 436 at 4.23 m/s for 10 more |
| Landing | the first update that starts 0.17 m or more below the floor | the same |
| Running fence climb clips | 440 for 11 updates from the tap's, unfaded, 5.79 m/s on the first update after the snap; 441 15 and 442 13, each still on its first update | the same (11, 15, 13 on the sandbox's 2 m fence; 5.79 m/s after the snap); the snap moves 0.68 m twice, as Coney's start point differs |
| Camera band; distance running | 4.8-5.3 m; 5.65 m | the same |
| Sprint camera | the timer rule: band 4.569 … 3.216, 3.0 and pitch to 7° over 14 updates; back 250 ms after the sprint | the same rule and fields; 4.70 m, 5.2° in a sprint |
| Upper pitch limit | 40°, 30° in a sprint | the same |
| Auto-follow | the auto-centre rule at gaits 2, 4 and 5, latched off by a blocked view until the player stops | the same; the latch clears on the second update standing |
| Stick held 90° to the side | about 191°/s running, 143°/s walking | about 197°/s and 144°/s (Rembrandt in the sandbox) |
| Fence climb camera | 4.9-5.3 m throughout | every ray passes through materials 30, 122 and 107 |
| Look-at point after a climb's rise | 20 % per update, then 2 updates | the distance limit: 20 % beyond 0.8 m, then 1 − 2 (d − 0.4), then all |
| Disabled panel 0.19 m behind the player | ignored by the camera's ray | the ray's rule is in place, but Coney does not know which triangles the game disables, so the panel is enabled and still pulls the camera in |
The start clips' and the run stop's first updates now match because Coney's sampler takes a clip's keys as the
original's cursor does (Animation): the key in force is the one at the
nearest whole frame, and the value is carried from it toward the next key by (frame − key), which is negative at
frame 0.75 (a start clip's first update at its rate of 0.75). With the old lerp from frame 0, whose root speed is 0
in every clip, the first moving update was 0.75 of the original's. The run stop's 0.1333 s fade never touched its
speed (the gait blend it fades from has no root velocity). On a frame that is exactly half-way between two keys
(frames 4.5 and 7.5 of the run start and the run stop) the original took the lower key and Coney takes the upper:
the floats of its game time land a hair above the half.
Still different: those half-frame updates, the circling rate by about 6°/s at a run, and the disabled panel.
Notes for implementers¶
The fixes in order of how much they change the feel:
- Turn rates: player limits 20° (walk, standing), 18° (jog, run), 16° (sprint) per update, 24° in a combat stance; ease full at 2.0 rad; carry 0.8 as now. The air turn stays at 4°.
- Camera auto-follow: the auto-centre rule of Camera, with
ameasured from the camera's position at the start of the update; only at the walk, run and sprint gaits (2, 4, 5), which leaves out standing, the start clips and the landing clip without testing the clip; not from an update on which the camera's main ray was blocked until the player stops (the+0x45dlatch, Camera); held off 0.334 s after right-stick input. Holding the stick sideways must make the player circle at about 190°/s running and 143°/s walking, which Coney's rule plus the leash's drag already gives. - Camera distance: leash band = default distance and default + 0.5 (4.8-5.3 m with
CfgFollowCamera's 4.8), hard band as now; the sprint zoom (3.0-3.5 m and 7° over 14 updates, back over 14, by the timer rule of Camera, starting at gait 5 and going back 250 ms after it); upper pitch limit 40°. - Run stop after a run: the skid at gait 4 plays 417 with its root motion, as after a sprint; a reversal skids too.
- Walls: the player's walking sphere 0.4705 m (0.5 × scale²); keep the slid velocity, so running into a wall at a steep angle brakes to a near stop and the idle.
- Camera collision: the rays skip materials 30 (
LOW_FENCE), 122 (RAILING) and 107 (CHAINLINK_NOCLIMB) and keep the main ray's rule for disabled triangles; the look-at point's move per update is limited by its length (20 % above 0.8 m, a share falling from 100 % at 0.4 m to 20 % at 0.8 m in between), except in the air. - Small timings: no body speed on the update a start clip begins; start clips one update shorter; root motion × the body scale (0.97) from the clip's first moving update, with no ramp; jump allowed during a start clip; land on the first update that starts with the feet 0.17 m or more below the floor, with the horizontal speed kept on that update (Characters); the fence climb's first clip ends against the fence (about 0.48 m), and its clock runs from the climb's first update, through the two snap updates, with no fade-in (11 updates in all); the first update of 441 and 442 does not move the body (Characters).
Open questions¶
- A
--traceoption forconey(answered):--play-level NAME --trace FILEwrites those columns per update (Running Coney). - The 0.25 m step at runtime (answered): a test step made in the street's collision mesh was walked onto at 0.10-0.245 m in one update and stopped the player from 0.255 m, at the distances the 0.4705 m sphere predicts with about 0.006 m clearance (Characters). A real kerb in a later level would corroborate it.
- The auto-follow option's default (answered): 1 for both bytes, so the auto-centre rule runs on a fresh boot
(Details); the default rule (
0x0012a400) runs only after the options menu turns it off. Still open: what a new profile saves. The "not seen" reading atlevel99checkpoint 1 is the blocked-view latch+0x45d, set by the walls at the start spot and held until the player stops (confirmed (runtime), Camera). - The sprint camera's code (answered):
0x00128cf0with the band's ease0x0012aae0, started by gait 5 and ended 250 ms after it (Camera). - The look-at height's ease (answered): the 20 % is the look-at point's distance limit (
0x00127d88); the 30 % read before is the camera's height hold, a different ease (Camera). - The camera's collision (answered): the face that pulled Coney's camera in is a disabled panel, which the original's ray skips near the look-at point (Camera), and the fence is skipped by material: the camera's rays exclude 30, 122 and 107 (Camera).
- The landing update (answered at runtime): the feet go on below the floor until an update starts 0.17 m or more under it, so the 0.19 m dip is real (Characters); why 0.17 m in the code is open.
- The circling rate (answered): about 191°/s running and 143°/s walking in the original, the rule's turn plus the leash's drag (Camera); Coney's 190°/s matches. The 122°/s compared before was the rule's share.
- The slow first updates (answered): the original's start clips and run stop move the body at the clip's root speed from their first moving update, with no ramp (Characters). Coney's were slow because it lerped from a clip's frame 0, whose root speed is 0; the original's cursor already stands on the key of the nearest frame, and every per-update speed of the three clips fits that reading (inferred from the runtime speeds, Coney's implementation). Still open: which way the original's half-frame ties go, and why.
- The fence climb's first clip (answered: 440 is 11 updates in the original because it starts the clip with the move to the start point and does not fade it in, Characters; Coney now does the same and gives 11). Still open: why the first update of 441 and 442 moves nothing.