PRACTICE > TELEPORT now shows the waypoint the player placed on the
game's pause map, with a "Go to map waypoint" button. The console gets
`trainer waypoint [info]` and `trainer ground <x> <z>`.
Reading the waypoint (trainer_waypoint.cpp)
- It is a point of interest in the map's registry, the one ReSkate's
party markers register into (addr::native_party::map_manager), with
kind DingoMapPOIType_Waypoint (3) and its world matrix at @0.
- The registry is walked only while the TELEPORT card is drawn (the
page notes it, like the class list) or the command runs, every
250 ms at most. A player who never opens the card pays nothing.
- A registry the map has filled without a waypoint means it was
removed; an empty or unreadable one keeps the last waypoint seen. A
new level forgets it.
Landing on the surface (trainer_landing.h)
- The waypoint's height is not the ground: teleporting to it dropped
the skater through the map. local_ground_height() casts the park
editor's downward ray (editor::cast_surface) through the client
physics world and takes the topmost hit.
- The first ray starts at 1500 or 500 above the hint. A custom map
can sit higher than that (a waypoint at Y 12 over ground at Y 1939
was seen in game), so a miss is cast again from 20000.
- If collision there is still streaming in, the teleport goes to the
hint's height and a 12 s watch puts the skater on the surface when
it arrives (at most 6 corrections; the teleport is re-sent up to 3
times if it never arrives).
- Teleports still go through go_to(), so they follow the host's
noclip / teleport permission in a session.
The decisions (ray spans, the watch, remember/forget) have no game in
them and are tested by trainer_landing (DINGOSDK_BUILD_TRAINER_TESTS).
README and CHANGELOG updated.
Follow-ups to the trainer (PR 37), and one multiplayer change.
Off until asked for (Extension/Trainer)
- The jump read-out and the LB+RB controller shortcuts start off. Jumps
are logged only while the read-out or telemetry recording is on, and
trick launches only when the trainer scaled them. A saved trainer.json
keeps what the player chose.
Memory search on demand (trainer.cpp, trainer_classes.cpp)
- The search for the game's tuning classes reads all writable memory.
It ran for every player after a level loaded, and up to seven times
when it found nothing. It now runs only when a class value or the flip
speed is not the game's own (the player's, or a host's they skate
with) or the EVERYTHING list is open, and at most three times a level.
- For those players it runs again on each level, which brings fresh
copies; a search from an earlier level used to count as done.
Guests under enforced physics
- A guest is locked by the session's enforce setting, from the moment
of joining (Engine/Game/Multiplayer/session_physics.h), not by whether
the enforcement status text was set yet.
- A guest's class values no longer come back after a map change.
The host's whole setup reaches its guests (protocol 39)
- Only Gameplay/SkatePhysicsTuning travelled, so a host could push,
sprint or jump further than the guests it held to the game's own.
- New packet physics_extras (30): the host's class values, trick
multipliers and auto push (trainer_session.h), sent when they change
and to players who join later, taken from the host only. A dedicated
server's are the game's own and it ignores the packet.
- Under enforcement a guest's own trick multipliers stand down for the
host's, whatever the boosts switch says. With enforcement off nothing
changes.
- A guest refuses bytes that are not an encoding, holds values to the
trainer's own ranges, and leaves out class values written for another
game build's table.
- protocol_version 38 -> 39: released versions disconnect from a peer
that sends a packet they cannot decode.
Out-of-view players are posed every frame again (Session/session.cpp)
- Players outside the camera's view and past 8 m were sampled at 20 Hz
(b763631). The game's replays record each skater as it stood every
frame and their camera looks anywhere, so those players moved at
20 Hz in replays. Removed; the distance rule (20 Hz past 200 m, 10 Hz
past 350 m) stays. This gives back the client-tick time it saved on
busy servers.
All new code is in Extension/Trainer. The game thread owns the trainer's state; the menu
page only queues `trainer ...` console commands and reads two snapshots.
- physics_tuning_model keeps the field and curve names the game's EBX carries, so the
editable table is built at run time from the player's own data.
- physics_tuning exports game_tuning / read_live / write_live / refresh_skater, with the
same field whitelist and curve rules as the session sync.
- no_bail publishes the physics state the local skater's selector last chose (air time,
wipeouts).
- A guest under host tuning cannot edit; teleports follow the host's noclip permission.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>