Commit Graph
488 Commits
Author SHA1 Message Date
AyeZeeBB 6bad0e95d2 Plugins: joysticks are read on a thread of their own, with all 8 radio channels, and a plugin picks which one
reskate.input.joystick() scanned Windows' 16 winmm slots inside the plugin's call whenever no
controller was cached; on some PCs empty slots made one scan take over 50 ms, and the FPV drone
was stopped for its tick running long after switching to a radio with none plugged in. A thread
now finds the controllers (every 2 s) and reads them (250 a second) through DirectInput, only
while a plugin has asked in the last 2 s, and a call copies its last reading.

DirectInput gives the eight axes a radio sends, where winmm gave six: axes are now X, Y, Z, Rx,
Ry, Rz and the two sliders. A plugin that saved axis numbers should let players set them again.

reskate.input.joysticks() lists every controller plugged in ({device, name}), and
reskate.input.joystick(device) reads that one, so a player with a gamepad and a radio picks which
flies; with no argument it still reads the first, a radio first. The list and the device field
follow neekgate's plugin-joystick-pick branch.
2026-10-27 16:44:45 -05:00
zeex64 be7a72d816 Merge pull request #360 from andrewnakas/fixes-212
Trainer: fixes for ReSkate 2.1.2 (shuvit speed, pops near rails, preset names, quick settings)
2026-10-26 17:51:20 -05:00
zeex64 04c7192f17 Merge pull request #371 from jeffreymckishen/pr/ds4-547-fix
Input: a DualShock 4 over Bluetooth keeps its menu, filter and Dark Pop handling in its 547-byte reads
2026-10-26 17:50:39 -05:00
zeex64 93a06d21ad Merge pull request #377 from FredrikHi/fix/318-line-label-after-hud-corner
HUD corner: the LINE label comes back after a plugin gives the corner…
2026-10-26 17:49:05 -05:00
zeex64 6b064020a2 Merge pull request #381 from shumsic/patch-3
Multiplayer: check a player's distance when their first pose places t…
2026-10-26 17:48:21 -05:00
zeex64 7b7d63f931 Merge pull request #372 from ryanc2112/build/external-player-probe-links
Music: the external player probe links again, with Plex, Spotify Connect and YouTube Music off
2026-10-26 17:47:03 -05:00
zeex64 ab3376ba06 Merge pull request #370 from ValveTextureFile/server-lua-api
Plugins: Enums (LogLevel, Align, GrindSide, Stance, Pop, Space, etc.)
2026-10-26 17:46:19 -05:00
shumsic 845e4cb6ba Multiplayer: check a player's distance when their first pose places them, before spawning a skater
### Problem
1. **Unplaced first-pose phantom spawns (`render`):**
   In the 500 ms distance loop (`s.next_shown_rank`), `p.shown_wanted` is set to `everyone || !p.placed || nearest_distance(...) <= ...` so that before a peer's first pose arrives (`!p.placed`, `sampled == false`), their status reads `"Waiting for player poses."` rather than `"Further away than players are shown."`.
   However, when their first pose packet arrives in `each_active_peer` (`const bool sampled = ...`), `if (sampled) p.placed = true;` flips `p.placed` to `true` while `p.shown_wanted` is still `true` from when `!p.placed` was true. Because `nearest_distance` has not yet been checked against the newly populated `p.render_pose`, `show_remote()` is immediately called on that frame for every newly-placed player on the server — spawning a full 395-bone 3D skater, 16-bone skateboard, and cosmetics for players 300–500 m across the map, only for the next 500 ms `s.next_shown_rank` pass to evaluate `nearest_distance > s.player_distance` and immediately destroy them (`remove_remote()`).

2. **Follow-camera orbit shifting the distance boundary (`nearest_distance`):**
   `nearest_distance(p, local, view)` takes the nearer of `local.pose.root.position` and `view` (the camera). While `view` is needed when the camera is detached from the local skater (spectating another player across the map, replay camera, or flying a drone), during ordinary skating the follow camera orbits ~3–5 m around the local skater. Rotating the camera around the skater shifts the effective `player_distance` boundary by ~8–10 m (consuming the 15% hysteresis band at 50 m) and causes clusters of players near the boundary (such as a Spot Battle crowd) to spawn and despawn as the camera turns.

### Solution
1. When a peer's first pose transitions `p.placed` from `false` to `true` (`if (sampled && !std::exchange(p.placed, true))`), immediately update `p.shown_wanted` from `nearest_distance(p, local, view) <= s.player_distance` before evaluating `spawning` and `show_remote()`. Peers before their first pose still keep `p.shown_wanted = true` (`"Waiting for player poses."`), nearby peers still spawn on their first pose frame without waiting for the 500 ms tick, and far-away peers never phantom-spawn on arrival.
2. In `nearest_distance()`, consider `view` when `!local.ready` or when the camera is more than 12 m from `local.pose.root.position` (spectating, replay, or drone), keeping the distance radius anchored to the local skater during normal third-person follow-camera rotation.

### Verification
- Tested in-game in 44–78 player online lobbies with active Spot Battle throwdowns (`ReSkate.dll` runtime verification).
- Verified in `ReSkate.log` that far-away peers no longer trigger `creating a remote skater` / `Skater component factory` spawns on their first pose packet and that rotating the camera toward a Spot Battle huddle near the 50 m / 70 m boundary no longer triggers a spawn storm.
2026-10-26 15:54:44 -04:00
gbgyo 550887162f Effects: release stale resources and require resident assets
Resolve private effects only from the level-wide Game compartment and validate
their resident declarations with the same parser used by the mod merge.

Release surviving native services during world changes, check decal realm
ownership before cleanup, defer ordinary off-thread releases, and prune expired
VM handles so they return their quota. Size the temporary decal allowance from
the live count while preserving external settings changes.

Gate contact geometry behind events.physics.geometry, document the manifest
migration, and test Blood impacts through the plugin host using its own manifest.
Add regression coverage for residency, lifetime, quota and draw-budget handling.

Validation: Release builds of the runtime and plugin/effect test targets succeed.
The plugins, effect_geometry and effect_lifetime tests pass. Existing MSBuild
asset-directory dependency warnings remain; native visuals need an in-game check.
2026-10-26 22:19:43 +03:00
gbgyo b9c30d120a Effects: merge main while preserving plugin resource cleanup
Merge main into feature/effects. Keep both effects and declared board material cleanup in the shared plugin test fixture.
2026-10-26 18:13:08 +03:00
Fredrik HillbertandClaude Opus 5.5 039901c7ac HUD corner: the LINE label comes back after a plugin gives the corner back
hold_score's own publish of the "down" value goes through the UI model write hook too, and the field
was already taken, so the hook kept our value as what the game meant. Given back, the corner then
restored "down". HudWidgetActive is written again often enough that the ring and trick list came
back, but ExtraInfoStyle rarely is, so the LINE label stayed hidden for the session (Hall of Meat's
card, or any plugin hiding the corner). The hook now leaves what the game meant alone while
hold_score publishes. Not checked in the game.

Fixes #318

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 14:51:40 +01:00
jeffandClaude Opus 5.5 6e02f634c9 Input: a game handle read 547 bytes at a time is checked for a DualShock 4 over Bluetooth
A handle the game reads from without having asked HidD_GetAttributes about it is identified by
the read: a read of a Sony pad's size makes ReSkate ask the handle's vendor and product. Only reads
of 10 to 512 bytes were asked about, and a DualShock 4 over Bluetooth is read 547 bytes at a time,
so on such a handle none of the menu, gamepad filter or Dark Pop handling ran. Reads up to 547
bytes are now asked about.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 08:13:48 -04:00
jeffandClaude Opus 5.5 a1c6ba2bd6 Input: a changed DualShock 4 Bluetooth report gets a new CRC in its 547-byte read too
Windows pads every read of a DualShock 4 over Bluetooth to that pad's longest input report, 547
bytes. The full report (0x11) inside it is 78 bytes and ends in a CRC-32, and the CRC was refreshed
only when a read was exactly 78 bytes. A report the overlay changed on such a pad (made neutral
under a menu, passed through the gamepad filter, or its D-pad hidden by Dark Pop) kept its old
CRC, and the game's reader discards a report whose CRC does not match, so the change never reached
it. The CRC now goes at offset 74, over the 0xA1 input prefix and the 74 bytes before it, in a
78-byte read or a padded 547-byte one, and the padding is left alone.

The CRC moves to playstation_report.h as refresh_playstation_bluetooth_crc, where the PlayStation
report test checks it against a separate table-driven CRC and two zlib answers, and the copy Dark
Pop kept for itself is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 08:13:48 -04:00
Ryan CampbellandClaude Opus 5.5 d7e8493dfa Music: the external player probe links again, with Plex, Spotify Connect and YouTube Music off
external_player.cpp now asks plex_web, spotify_device and youtube_music what is playing, so
dingosdk_external_player_probe (multiplayer tests, Windows) failed to link with 10 unresolved
externals. Linking those players would bring in the overlay, the log and HTTPS, so the probe gets
stubs that report them switched off and keeps reading only the Windows media session.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 10:01:28 +00:00
vtfandClaude Opus 5.5 6cb595512e Merge upstream/main into server-lua-api
grind_exit gave way to shape_launch upstream, so Enums.GrindSide becomes
Enums.Launch, the words shape_launch checks; Delete joins Enums.Key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 23:40:50 -04:00
vtf b1e61caa75 Plugins: Enums (LogLevel, Align, GrindSide, Stance, Pop, Space, etc.) 2026-10-25 22:34:48 -04:00
AyeZeeBB 3d706383a1 Skater: a pose is sent to the others with its scale, and no joint further than 4 m from its parent
skater.pose's places are worked out with the pose's scale in them (keep_children, or a joint placed
relative to another joint or the world under a scaled one), but the others were sent only rotation
and position, so such a joint landed up to a thousand times its distance away on their screens. A
place may also be far off in the parent's frame, which drew a skater's arms and head across the map
for everyone. The sent pose now carries each joint's scale (0.001 to 10), and a joint's offset from
its parent is cut to 4 m in what is sent. What the player sees locally is unchanged.
2026-10-25 14:50:37 -05:00
AyeZeeBB ee830586b7 Board materials: one mod's broken reskate-materials.json leaves only that mod out, not every mod's declared colours
Since the declarations were read from the applied catalogue, a file that could not be read or
parsed threw out of the whole refresh, so no mod's declared inputs applied (from launch, or after a
live apply). Each file is read on its own again: a broken one is logged with its mod and skipped,
and only a failed read of item ownership keeps the previous set.
2026-10-25 14:50:36 -05:00
AyeZeeBB 7170938799 Merge pull request #358 from hypnomalice/runtime/declared-board-materials
Plugins: support declared colour inputs on mod-owned board materials

Conflicts with #363 resolved by keeping both: reconcile_variant_additions beside
active_mod_sources in mod_catalog.h, and both test targets in cmake/Apps.cmake.
2026-10-25 14:38:17 -05:00
zeex64 25fdb73a6d Merge pull request #365 from mauwpix/pose-place
skater.pose can fully control a joint, not only add to the game's animation
2026-10-25 14:36:35 -05:00
zeex64 80a9251cc0 Merge pull request #363 from hypnomalice/runtime/variant-additions-cooperation
Mods: permit checked private additions beside opted-in variants
2026-10-25 14:35:48 -05:00
gbgyo 632bb3c56d Plugins: revalidate effect assets and release effects after startup fails 2026-10-25 13:41:10 +03:00
hypnomalice e17aabe37c Materials: refresh declarations only after applied sources or files change 2026-10-25 10:31:57 +00:00
hypnomalice bcee9b0e49 Mods: withdraw stale variant admissions after exclusions and retries 2026-10-25 08:36:19 +00:00
gbgyo 4f07b448a3 Plugins: render private particles and decals with physics geometry
Add permission-gated effect handles, native surface attachments, and world lifetime cleanup. Extend physics_step with optional contact geometry and body poses. Document the generic API and validate it with self-contained plugin and geometry fixtures.
2026-10-25 10:56:59 +03:00
mauwpixandClaude Opus 5.5 8fe5d01942 Plugins: skater.pose can fully control a joint (its own place, relative to its parent, another joint, the skater or the world) instead of only adding to the game's animation
So far a plugin could only add to what the game's animation does with a joint. Now it can give the
joint its own transform, which the animation's is replaced by: its own animations, joints reused for
body parts the skater doesn't have, joints moved by a simulation in Luau, joints pinned to a point.
A joint's entry takes place = {position, rotation | angles, relative_to} and keep_children = true
(its children stay where they were); a pose takes up to 128 joints. Each frame the place is turned
into the joint's value under its real parent, the joints posed in an order that puts each after its
posed parents and the joint it is placed relative to; a pose without such an order is refused with
the reason.

Extension/Skater/pose_place.h/.cpp hold the maths, with pose_place_tests; skater_animation applies it
after a joint's offsets; plugin_api_world reads it and sorts the joints.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 05:27:48 +01:00
AyeZeeBB 8e5fb74498 Multiplayer: a remote skater whose parent link is one byte short is put right and destroyed, instead of crashing at map exit
2.1.2 left such an actor alive and forgotten. When the level went, the game released its parent
through the same pointer, took one off the byte below the parent's vtable pointer and called
through it (Skate.exe+0x2b8092f and +0x2b7fcfb, every report after the "link ... is damaged"
warning with the same bus). A link exactly one less than the parent the bus also holds at +0x48 is
now repaired before the destroy; other damage is still left alive. What shortens the link is not
known yet.
2026-10-24 22:47:02 -05:00
AyeZeeBB e0d85cae11 Multiplayer: another player on a Studio map's own surface sounds like the default surface instead of crashing the game
The skater sound state sent the packed material words of the surfaces under a skater as they were.
A Studio map's surfaces are appended to the root grid from slot 116 on, numbered by each install's
own set of map mods, so the same word named another surface on the other side, or a slot past the
end of its grid, and the game's material lookups (0x7111c0, 0x45e120) read past MaterialIndexMap
(Skate.exe+0x41da7b and +0x6fc93b, 240 installs in a day on 55a7342, on Tokyo 2026, Community
Center, Olay Way and other maps with their own surfaces). Those words now cross as the grid's
default, when sent and when received, so older clients sending their own numbers are covered too.
2026-10-24 22:47:02 -05:00
zeex64 0abdae8710 Merge pull request #364 from mauwpix/outfit-costume
Fix outfit.worn filtering out full-body costumes
2026-10-24 21:53:18 -05:00
zeex64 1d80e77b11 Merge pull request #362 from mauwpix/pose-own-values
Fix skater.pose changes being applied twice (jittering avatars)
2026-10-24 21:53:10 -05:00
zeex64 c16facc8eb Merge pull request #361 from Vebjorhk/fix/startup-failure-reason
Launcher: when ReSkate stops while starting, say why instead of blaming anti-virus
2026-10-24 21:52:54 -05:00
zeex64 dd2218dbc7 Merge pull request #357 from hypnomalice/fix/capture-shoe-depth
Capture: preserve shoes in depth cut-outs against curved floors
2026-10-24 21:52:06 -05:00
mauwpixandClaude Opus 5.5 61092a4950 Customization: outfit.worn lists a full-body costume instead of filtering it out as a body part
reskate.outfit.worn() is meant to list full-body costumes: it has a "Costume" slot for them, between
the head and the feet. But no costume ever reached it. With a costume on, the list came back without
it, so a plugin that goes with a costume mod could not tell whether its costume was worn. Now it is
listed like any other item: {slot = "Costume", item = "Own_Hobkin", title = "Hobkin"}.

Why: the list leaves out the body's own parts (head shape, nose, skin...) by their catalog categories,
which start with "cust" (custhead, custnoses, custbodies...) or name the body. A full-body costume's
category is "cust_fullBodyCostume", so it matched both and was dropped before its slot was looked up.
A category that names a costume is now kept; everything else is decided as before.

The rule (category to slot) moves out of worn_items.cpp into outfit_kind.h as it was, so it can be
tested without the game: outfit_kind_tests (with the plugin tests) checks clothes by their slots, the
costume, the body's own parts, and an unknown category.

Checked in the game: with a costume mod's costume on, outfit.worn() returns
Costume | Own_Hobkin | Hobkin, where it returned nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 03:13:19 +01:00
mauwpixandClaude Opus 5.5 c7457c10a1 Skater: plugin poses apply once a frame instead of twice every third frame
skater.pose changes the skater relative to the game's animation. Some of those changes were applied
twice every third frame, so a posed skater shook in a three-frame rhythm, and their board with them.
The more a plugin changed, the worse it got: an avatar with the hips scaled and offsets on most of
the body needed workarounds in its plugin to hold still. Now every pose is applied exactly once, and
a plugin can give skater.pose the values it means.

Why: ReSkate draws a pose by writing it into the game's bone buffer just before the render, and the
game evaluates the next frame from that same buffer without overwriting all of it. Two of three
frames it resets the buffer itself; in the third the pose drawn was still there and the next pose
went on top of it. Now the game's own values go back as soon as the renderer has its copy, so the
game, the body physics and the next animation update only ever see the game's pose.

This replaces own_scale, the earlier fix for the same cause (the Filmer's forearm at 0.001 shrinking
to nothing). It covered only scale, and put it back after the game had already run on the posed
values, so rotations and offsets still doubled. The new way covers every part of every joint, for
pose, carry and reach, with nothing to track per joint and nothing to clean up after a pose ends.

Checked in the game: the avatar with the hips at 0.667 and offsets on 48 joints holds still with
only skater.pose (shoulder distance 0.117 m every frame, where it was 0.117 0.117 0.067 ...). The
Filmer 1.0.0's camcorder preview looks and measures as on main, and the skater is back to normal
after it.

Details: the renderer copies the bones in submit_render_pose (0x4c7e7a0), which the render pose
caller (0x2c20d99) calls right after render_pose with the same render data; found with a guard page
on the bone buffer that logged every access with its call stack. native_skater hooks it and, for the
render data the pose override just wrote, calls the new set_pose_override_drawn_listener.
skater_animation keeps what on_render wrote over and puts it back in on_drawn.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 02:31:13 +01:00
AyeZeeBB d47a7c8492 Mod Manager: a download queue, and a new look for the featured card
Installs, updates and uninstalls are jobs run one after another in the order asked for: asking for
one while another runs queues it instead of being refused. A job waits while the mods are applied or
a session's map downloads, and works out what its mod needs when it starts, from the Mods folder as
it is then. Buttons say ADD TO QUEUE while a job runs and QUEUED once in line; the foot of the page
says how many wait, and CANCEL ALL empties the queue.

The carousel's middle card: the mod's picture as its backdrop, darkened, and big as a tipped sticker
beside the text; a FEATURED and INSTALLED / UPDATE AVAILABLE tag, the facts as chips, as much of the
description as fits above the buttons, and the buttons under the text with the pad's prompts beside
them.
2026-10-24 20:25:55 -05:00
AyeZeeBB 6b14e0e19c Mod Manager: a row on BROWSE for every category, not mod packs, libraries, tools or AI generated
The front page stopped after four category rows. Now every category has one, the biggest first,
after Most popular, Recently updated and New; mod packs, libraries, tools and AI generated stay off
the front page (still found by search and the CATEGORIES panel).
2026-10-24 20:25:55 -05:00
AyeZeeBB 4b850d190f Live mods: a map added by a live apply has its picture in the map grids
The map grids (Mod Options' MAPS, the ReSkate menu's world page) found a custom map's icon among the
mods merged at launch, so a map installed or switched on since had none. The live apply now keeps
which mod each level comes from (live_mods::level_mod_directory), and map_icons asks it, falling
back to the launch's list before any live apply.
2026-10-24 20:25:55 -05:00
AyeZeeBB e47c91d13a Multiplayer: applying mods in a session reloads your own map and keeps you in it
The reload after a live apply was a console "load", which in a session either ended it (a guest's
map going away is "your local map changed"), was refused (a guest without map rights), or moved
everyone (a server admin's load changes the server's map; a lobby host's reload sent every guest
through it too).

Now client_tick tells the session first (multiplayer::begin_local_reload) and loads the same map
locally with no multiplayer rule (queue_local_load). The session keeps the reload as travelling in
the same world: a guest keeps telling the host or server it is loading (world_ready, so it does not
time out) and that it is back; a host says it is not in the world for that long, so its guests wait
instead of moving, and nothing is a host map change. A reload refused by the loader is taken back
(cancel_local_reload); one that never starts ends after 20 s; in no state to reload (changing maps,
joining) the mods show at the next level load. The dedicated server already handles a player
reloading on their own.
2026-10-24 19:56:09 -05:00
AyeZeeBB 725c18ef3d Mod Manager: a pause menu tab after Mod Options to browse, install, update and switch mods in game
A third ReSkate tab in the game's pause menu (native_menu.cpp slot 2, the Store's tab art), drawn by
the overlay as the other two are (mod_manager_page.inl, included into hub_page.cpp):

- BROWSE: search, categories in a panel of their own (shown only, hidden or either, kept in the
  profile), sort, a featured carousel and rows (most popular, recently updated, new, the biggest
  categories), a grid for results, and a mod's own page with its README, what it brings with it,
  and INSTALL, switch on or off and uninstall. Works from a controller: the carousel's card is
  one stop that left and right turn, and B goes back from a mod's page (the page's Back is held
  meanwhile).
- MY MODS: the Mods folder with the states the ReSkate menu shows; UPDATES: Update all.
- The foot of the page shows the install's progress and the apply's, and Apply (View on a pad).
  Leaving the menu with changes not applied asks first (a two-answer card in message_card.cpp,
  answered by the runtime as the message is); LATER closes the menu.

Behind it, Extension/Assets/mod_store: Thunderstore's listing (cached on disk), the installed mods,
and a queue that downloads and installs packages with their dependencies, updates and uninstalls
them. An update or uninstall of a mod the game holds open waits in Mods/.reskate-pending and the
launcher makes it before the next start (launcher_mods::apply_pending). Package icons load into
their own SRV slots (store_icons.cpp), sharing the launcher's icon cache.

Tests: mod_store_view (search, categories, the front page's rows, install plans), the pending
updates and uninstalls in mod_manager_tests, and the third tab in native_menu_view_tests.
2026-10-24 19:55:56 -05:00
hypnomalice c29cffdf9b Plugins: enforce declared input ownership and preserve holds through rebuilds 2026-10-25 00:01:46 +01:00
hypnomalice 0d91f6adf9 Capture: bound backdrop fitting cost and reject depth outliers 2026-10-25 00:01:44 +01:00
AyeZeeBB 403702126c Merge branch 'main' of https://github.com/Dingo-Shenanigans/ReSkate 2026-10-24 17:59:50 -05:00
zeex64 86968515d3 Merge pull request #320 from shumsic/patch-1
[Bug Fix] Throwdowns: fall back to full region scan when QueryWorkingSetEx reports no resident pages (#319)
2026-10-24 17:54:55 -05:00
AyeZeeBB 7dabd99a40 Crashes: the Trainer no longer writes into freed memory, throwdown models go before a level unload, and a gone texture draws nothing instead of crashing
From the first 6k Sentry reports of 55a7342 (2026-10-24), whose top sites were all new since 2.1.1:

- Trainer: scale_underflip_bands wrote the underflip rate bands' MinScale and MaxScale every tick on
  every copy it had ever found, checking only that the address was readable. A level's copies go back
  to the game's heap with it, so 1.0 and 0.6 landed in the upper half of whatever the game made there
  next (Skate.exe+0x157f930, +0x12a1549, +0x10084de, +0x11ef49e, +0x3db81ea, +0x12c21ca: about a
  third of the crashes, every dump with a pointer whose high dword is one of those floats). A copy is
  now written only while it still is that band and holds the game's band or the last one written;
  any other is forgotten.
- Throwdowns: models the page released were destroyed 3 s later by the menu tick, which does not run
  while a level loads, so the game's own flush of the unloaded level's types destroyed them after
  their assets were freed (Skate.exe+0x3dc5eaa, 18%). Before a level unload they are destroyed at
  once, as the native menu's own are.
- Textures: the guard's "default for the id" is the entry itself, so for a dead entry resolve gave a
  null texture, and the texture view cache asked it for its key (Skate.exe+0x3e6ddc1, 17%, every
  report with TheVlixOne-Nike_Pack). A stub at the cache insert hands back the empty view the cache
  already built when the texture is null; the guard is on only when that patch applies.
- Physics: the wake guard widens every pass because ReSkate raises the owner pool to 160000; its log
  line now says so once instead of claiming a prevented crash thousands of times a session.

Built; not yet checked in the game.
2026-10-24 17:19:32 -05:00
andrewnakasandClaude Opus 5.5 433cd6f4f7 Trainer 0.8.7: fixes for ReSkate 2.1.2
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 16:08:11 -06:00
andrewnakasandClaude Opus 5.5 710fad5aea Trainer: lock-on rows say Grind Assist works on top of them; trainer livedump
Measured with the new diagnostic `trainer livedump <name>` (what the game holds
live: its tuning, the class values and the two assist settings): at Grind Assist
0, 50 and 100 all 3801 values read the same, so the setting works in the game's
grind code on top of the tuning. The lock-on rows' tooltips now say so.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 16:05:37 -06:00
hypnomalice 4c2b500a99 Plugins: hold declared colour inputs on mod-owned board materials 2026-10-24 22:51:59 +01:00
VebjorhkandClaude Opus 5.5 97f2406bea Launcher: when ReSkate stops while starting, the STATUS tile says why instead of blaming anti-virus
DingoSDKDebugInitialize answers the launcher with a bare TRUE or FALSE. On
FALSE the launcher threw "DingoSDKDebugInitialize returned FALSE", which the
STATUS tile turned into "ReSkate could not attach to Skate" with anti-virus
advice, although the attach had worked and the runtime had logged its reason.

ReSkate.dll now exports DingoSDKStartupFailure, a 1 KB buffer that every
FALSE path fills with its reason (the first one stays). The launcher reads it
out of Skate before closing it. With an older ReSkate.dll it reads the ERROR
lines that Skate process wrote to ReSkate.log during the call instead, and
with neither it says it was not told why. problem.h explains these messages
before the attach rules: a save in use or a folder another game holds says
Skate is already running, hook and overlay failures keep the attach advice,
and anything else leads with the runtime's own reason. Bootstrap and the
local profile hand their reason back, and the profile checks that used to
return false without a word now log one.

Fixes #90, fixes #346.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 23:51:12 +02:00
andrewnakasandClaude Opus 5.5 fe0db52d2b Trainer: Grind lock-on is the game's own Grind Assist
The GRINDS section's Grind lock-on row now shows and sets egf_grindassistamount,
the same number as the game's Settings menu (trainer grind assist <0-100>). It
is the player's own setting: never MODIFIED, in no preset or reset. Sticky
Grinds stays as a switch; the lock-on tuning values are rows of their own.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 15:50:40 -06:00
andrewnakasandClaude Opus 5.5 96aa7ea6e8 Trainer: QUICK SETTINGS rows of the trainer's own settings can be changed in the full screen menu
They drew a mouse-only drag box there, so from a pad they could only be changed
in their own section. They now use the full screen menu's switch, list and
slider rows like the sections do.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 15:46:59 -06:00