Commit Graph
538 Commits
Author SHA1 Message Date
andrewnakasandClaude Opus 5.5 c2d86f2ffa Trainer 0.8.2: Underflip speed, Underflip part only, a speed for each underflip
- Underflip speed: the game holds the underflip's two playback rate controllers
  (cdbchooser_onboard_underflips_(pbrate) 1-1.2, ..._toair(pbrate) 0.6-1.2) to a band it
  copies into each controller as it is made; the trainer scales that band, and the state
  copy that starts the underflip, so the slider sets the whole underflip.
- Underflip part only: the band spans the flip's speed and Underflip speed from the start;
  where the board turns back the trainer scales the rate the game computes for its rate
  controllers every tick (0x10dd2f0, called by their update 0x10de730) until the landing.
- A speed for each underflip at the bottom of Advanced trick speed (kickflip, heelflip, pop
  shuvit, FS pop shuvit and the four impossible underflips), times Underflip speed, and the
  Late flip slider beside them.
- Late flip speed in the TRICKS card; dial sliders reach 0; Underflip speed named on the
  MODIFIED line and shared by a session's host (session extras version 2).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 23:20:59 -06:00
andrewnakasandClaude Opus 5.5 f9c6dbdda2 Trainer 0.8.1
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011m6eM3ps6bttTbZqo9Gz6Y
2026-10-18 20:51:36 -06:00
andrewnakasandClaude Opus 5.5 e01d8c2307 Dials go to 0 (Grind lock-on at 0 = no lock-on)
A preset's dial refused 0 in its box and in `trainer dial` (it works on a log scale). A factor of
0 now sets every value the dial moves to 0; a value that moves the other way stays stock instead
of going to infinity.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011m6eM3ps6bttTbZqo9Gz6Y
2026-10-18 20:11:44 -06:00
andrewnakasandClaude Opus 5.5 7dc0b6cce3 Gravity: landings on time; the landing countdown follows the trainer's gravity
The game plans each flight's landing with its own gravity and the air pose reaches for the ground
as that countdown runs out. Above x1 the skater came down early, the body sank into the ground
before the wheels touched and the landing came late (x3: a flat ollie bailed). The countdown is
now set to this flight's time down to the planned height at the trainer's gravity.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011m6eM3ps6bttTbZqo9Gz6Y
2026-10-18 16:56:59 -06:00
andrewnakasandClaude Opus 5.5 14cc8b17b1 Boosts start at 0 (off), so RESET EVERYTHING reads STOCK
The forward, up and off-board up boost speeds defaulted to +20, which counted as not
stock. They now default to 0: the boost adds nothing until a speed is set, and resets
(RESET EVERYTHING, the console resets, restore_debug) put them back to 0.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 11:29:09 -06:00
andrewnakasandClaude Opus 5.5 5f0b2de4af Cheats: boosts past the sliders; cheats and addons in QUICK SETTINGS and on the MODIFIED line
Forward, up and off-board up boosts take a typed value up to 10000 (sliders still end
at 300 / 25), Revert Boost strength up to x100. Noclip, No Bail, Dark Pop, a boost
that is not +20, Revert Boost, grind exit triggers and Board Break are listed at the
top of QUICK SETTINGS with their values (Go to, Reset), make the SANDBOX line say
MODIFIED, and RESET EVERYTHING turns them back.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 10:42:29 -06:00
andrewnakasandClaude Opus 5.5 6c5689dedb Trainer changelog: typed values, slide or step, help on every value (0.8.0)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 03:04:00 -06:00
andrewnakasandClaude Opus 5.5 038f42a8b6 Sandbox: type any number, slide or step in the full screen menu, help on every value
- Full screen sliders (stepper): a click still steps, press and move slides the
  value; a number box beside each (the controller's focus skips it). A typed
  value past a slider's end stays there, and stepping does not snap it back.
- No slider end is a limit for a typed number: game speed, return delay, the
  full screen value rows (their bar now spans 0 to 4x the game's own), and the
  trainer's own limits behind the commands (gravity 0.001 to 1000, flip speed to
  1000, pump power and bending boost to 1e6, transition and grind numbers, the
  bending rules).
- Help: the 74 named rows that had none now explain themselves; every slider's
  explanation shows on hover and in the full screen bottom bar; unnamed rows
  say what they are.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 02:56:06 -06:00
andrewnakasandClaude Opus 5.5 f5e1a2775a Four files back to upstream's line endings: the diff against ReSkate is only their real changes
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 01:37:04 -06:00
andrewnakasandClaude Opus 5.5 c99b454749 Trainer docs: the SANDBOX page and Skater > Cheats, 0.8.0 changelog
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 00:19:34 -06:00
andrewnakas 24179ed529 Merge remote-tracking branch 'origin/main' into physics-210 2026-10-18 00:13:57 -06:00
andrewnakasandClaude Opus 5.5 0bcb0ba2ac Merge ReSkate v2.1.0 into the trainer, in its new menu layout
The trainer keeps upstream's page and naming (SANDBOX; noclip, No Bail and
the boosts on Skater > Cheats; the full screen controller menu) with its own
TUNE sections, presets card and search inside. The MOVEMENT tab is gone:
`trainer open movement` opens Skater > Cheats, where the Revert Boost rows
now sit. Upstream's Hardcore preset sits beside Realistic; saving
trainer.json and reading the map file stay off the client thread.

Board Break's wear and the trainer no longer undo each other: wear writes
four tuning values itself, and every trainer write used to put them back to
the trainer's copy (and a level loaded on a worn board took them as stock).
board_break::handling_value() tells the trainer what wear wants; values the
player has not changed are handed back to it, their stock is the game's own.

Tests: Hardcore's check follows the sections (topic, not the old lists);
the session test pokes a flip speed past the trainer's own limit (100).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 00:13:49 -06:00
AyeZeeBB 99467f4b31 Official mods: an installed one can be uninstalled on the OFFICIAL tab
UNINSTALL, under OPEN FOLDER, takes the mod's stamp away first (a folder
without it is no mod to the game), then its folder, and clears whether it
was turned off so an install brings it back on. The card says UNINSTALLING
meanwhile, and UNINSTALL FAILED when Windows keeps the files (Skate still
running). Cards are as tall as their buttons.
2026-10-17 21:42:44 -05:00
AyeZeeBB ceb21e0b92 Official mods: installed by the player on the OFFICIAL tab instead of downloaded on every launch
The launcher still reads the list at start and looks up each mod's latest
version, moves in a copy installed from Thunderstore and takes away retired
mods, but it downloads nothing by itself. Each card on the OFFICIAL tab says
NOT INSTALLED, INSTALLED, UPDATE AVAILABLE, DOWNLOADING or UPDATING, with an
INSTALL or UPDATE TO vX button (official_mods::install, on a thread of its
own), OPEN FOLDER once installed, and the On / Off switch beside its pills.
The banner counts how many are installed. Play waits for an install under
way.

Board Break and Road Rash start only when their official mod is installed
and on (mods::official_in_use), and say in the log which it is not; the
menus leave them out otherwise, as when turned off.

The live test (RESKATE_OFFICIAL_LIVE) checks that nothing downloads until
asked, then installs each.
2026-10-17 21:39:50 -05:00
AyeZeeBB 129dc637be Drone: the motor hum is quieter by default (volume 0.09 from 0.5)
Other players' drones go by the same setting. A volume the player set
themselves is kept.
2026-10-17 21:03:53 -05:00
AyeZeeBB a65f94b55a Customization: a mod item's card sits under the info sign
The game's info sign shows on the first of the notice's three reserved
lines, where the mod's icon covered it. The icon, tag, name and details
now take the two lines under it, the icon 40 instead of 46 so it still
ends on the card's bottom text margin.
2026-10-17 21:03:53 -05:00
AyeZeeBB 675ad087f2 Official mods: each can be turned off in the launcher, and then the game leaves it and its feature out
The OFFICIAL tab has an on/off switch on each mod's card, with an OFF pill
while it is off. The list of those turned off is
Mods/.reskate-official/official-off.txt, one folder name a line, which the
launcher's sync never removes. A mod turned off stays downloaded and kept
up to date, but official_packs() leaves it out, so nothing merges it, no
deck comes from it and the in-game Mods page does not list it.

Board Break and Road Rash do not start while their official mod is off,
and say so in the log. The menu model carries that as `off`, and the side
rail, the addon tabs and tiles, the home tiles, the pause menu's settings
and the native tools menu leave them out without a gap. category_tabs
takes a list built at run time for that.

Tests: an official mod turned off stays in place and is left out, comes
back when turned on, and only a plain folder name is written.
2026-10-17 20:55:52 -05:00
AyeZeeBB a64cd93d82 Drone: other players' drones are markers only, without a model
A model made for another player's drone crashed the game a few seconds
later in the per-frame update of its shader sections (Skate.exe+0x505b04b,
2.1.0): 28 of 29 reports there came right after one was made. Real
players' drones show as markers and are heard as before until that is
found; the pretend one from dronemodeltest remote still gets its model.
2026-10-17 20:32:28 -05:00
AyeZeeBB 2b5772bdf5 Customization: a mod item's card shows the info sign instead of an empty icon
The warning sign on a mod item's description notice was cleared by writing
an empty IconOverride. The game resolves that override again later in its
UI update and crashed on the empty one (Skate.exe+0x3e897fb, a lookup that
finds nothing): about a quarter of 2.1.0's crash reports, all of them after
the sign was cleared.

The notice now gets the game's own info sign (img_generic_info_64), set the
way the favorites star is. When that texture is not loaded the warning sign
stays and it is looked for again two seconds later; an empty override is
never written. Texture assets are matched by name ignoring case.
2026-10-17 20:32:28 -05:00
AyeZeeBB c7bf7a1edf Launcher: the agreement's summary wraps, and reads "skate" without the period
BulletText does not wrap, so the crash-report line ran past the window; each line is now a bullet
and wrapped text beside it.
2026-10-17 18:29:52 -05:00
AyeZeeBB 4f1f5a882e Launcher: the privacy policy and terms of service, and an "I agree" before playing
Both documents come from the ReSkate backend (GET /api/v1/legal/privacy and /terms, edited on its
Legal page), so a change reaches players without a release. Settings has a button for each, opening
a panel like the changelogs': title, version and date, the Markdown drawn as the README viewer draws
it, and a switch to the other one.

Each launch looks up the current versions (GET /api/v1/legal) in the background. One newer than
the player agreed to, or none agreed to yet, puts up an agreement over the home screen: a short
summary, a way into each document, QUIT and I AGREE, which saves the versions agreed to
(accepted_privacy_version, accepted_terms_version in the launcher's settings). A backend that
cannot be reached holds nobody up. Launches that skip the window (--no-gui, Discord joins) are
not asked.
2026-10-17 18:25:22 -05:00
AyeZeeBB d15e51e558 Custom maps: the mesh pool follows the map's own meshes, coarser LODs when it is short, and old maps' textures stream
The merge measures each custom map's own meshes, every level of detail of every MeshSet in its
level bundles, into Mods/.reskate/reskate-map-meshes.json. A custom map's mesh streaming pool is
the game's 520 MB and half as much again as those meshes, at most half the video memory free (as
before): most maps have 25 to 70 MB of meshes and reserved 1 to 2 GB for them. When the map needs
more than the card has room for, Mesh.GlobalLodScale goes from the quality preset's 1.25 or 1.5
to 1, so coarser levels take over nearer; the game's value comes back for the next map that fits.

A map's world textures (texture group Worlds_*) flagged to stream that keep every mip with the
bundle, as an older Studio built them (404 MB of PQS Cordoba's), are made to stream as the game's
own do: the bundle keeps the mip tail from a 64 KB block, both first-mip fields of the header and
the chunk record say so, and the sharper mips stream from the chunk the map's TOC lists in full.
Only in a map's own level bundles (Studio keeps cosmetics whole; changing those left a load at
Starting server), and only for chunks whose guid marks them compressed (the streamer reads any
other as raw pixels and copied past what it read).
2026-10-17 17:04:18 -05:00
AyeZeeBB 7fd2563087 Mesh streaming: a custom map's pool is measured again once the map it leaves has gone
The pool was sized from the video memory free when the load was asked for, while the map being
left still held its textures and meshes. From one custom map to the next it came out smaller each
time (1846 MB down to 1253 MB over five maps on an 8 GB RTX 5050), until The Mashup loaded to a
black screen. A custom map's pool is now measured again at Starting level load, after the old map
has left and before the pools are re-created from the new level's data (FUN_14507a2d0), and raised
when more is free then; it is never lowered there. The log says which measurement the load used.
2026-10-17 15:08:51 -05:00
AyeZeeBB ba1245a5af Menu: the window's side rail lists every addon in EXTRAS, with no ADDONS overview page
The window listed one ADDONS row that opened an overview of tiles, and showed the addons under it
only while that page was open. EXTRAS now lists Drone, Board Break, Road Rash, Hall of Meat, Grind
Exits and Music as rows of their own, always; a window left on the overview (switched from full
screen on ALL ADDONS) shows Drone. Every row of the rail is as tall as fits it without scrolling,
from 28 to 36. Full screen keeps its ADDONS page and ALL ADDONS tab.
v2.1.0
2026-10-17 14:47:35 -05:00
AyeZeeBB 4d8b86519d Replay export: the game's idle kick is off too, so a long export no longer ends at the splash screen
With the in-game connection timeouts off, players were still dropped to the splash screen by a long
export: the game also ends a session after a stretch without input (DingoOnline.InactivityTimeOut*,
SecureReason_InteractivityTimeout), and no one touches the pad while an export runs.
DingoOnline.InactivityTimeOutEnabled is set to false at startup with the connection timeouts, as
the game's own disableAllTimeouts config does. The loading timeouts that config also clears are
left alone, so a load that never finishes still ends.
2026-10-17 14:42:04 -05:00
AyeZeeBB 2ec25df23b Mod merge: costume presets that crash the game's load are repaired, and material rows past the shader programs left out
Master Chief and TASM2 Spider-Man ship appearance presets whose EBX lists a type reference on the
slot of an import, which the game's load reads as a type index and crashes on (Skate.exe+0x3def285
and +0x3def262 in Sentry). The merge now checks every mod's own EBX, including bundles it would pass
through whole, and takes such entries (or a repeated one) out of the copy in the merged patch and of
the copies carried into other mods' bundles; the mod's original still feeds any combine, and the
merge notes say how many per mod and bundle. The check reads only the fixup lists.

A material lookup row pointing past the shader programs the game ships is left out of the merged
lookup, with a note, instead of reaching the shader registry. Tests for both.
2026-10-17 14:27:20 -05:00
AyeZeeBB 7676c1d5ea Shader registry guard: no registration of a destroyed database, no lookup index past its records
The shader expression registry registers a database from a queued job, and builds its per-key item
lists from the database's lookup without a bounds check. A database destroyed before its job ran,
or a lookup index past its items, left the registry holding pointers that crash it later
(Skate.exe+0x3f7cf33, +0x3f7ceed, +0x20960b in Sentry). The guard skips a registration for a
database already destroyed and points an out-of-range index at a valid item of the same key,
logging each.
2026-10-17 14:27:20 -05:00
AyeZeeBB 9780af3cf5 Mesh streaming: a custom map's pool follows the graphics card's free memory instead of 520 MB
A custom map's mesh streaming pool is half the video memory the card has free (its budget less what
is in use, counting the pool itself), never under the stock 520 MB; the game's own maps keep the
stock pool. It is set for each load and the size is logged. Large maps ran out of the fixed pool on
8 GB cards and ended in the game's DirectX error box (KERNELBASE+0xc408a in Sentry).
2026-10-17 14:27:19 -05:00
AyeZeeBB e1e6baca8c Launcher: warn before starting from a game folder with non-ASCII characters in its path
The game finds its own folder with the ANSI GetModuleFileNameA and decodes it as UTF-8, so a path
with Cyrillic, accented or Japanese characters (often a OneDrive folder) crashes it on start
(Skate.exe+0x18df4cf in Sentry). The launcher now says so and asks before starting; No is the default.
2026-10-17 14:27:19 -05:00
AyeZeeBB 93528884b3 Park editor: a session with object scaling off keeps saved scales without resizing
On a dedicated server with object scaling off, a loaded park's scaled objects were resized anyway
(and after a refused resize the pose poll saved 1x over their scale), and a scaled paste, set or
undo ended in a resize the server would not take, so the edit waited on it. The placements now
know whether this game may resize (set by the session from the server's setting and the role, the
host and roles that may always build exempt, allowed outside a session): where it may not, objects
stay 1x in the world, nothing waits on a resize, and the layout keeps their scale for when scaling
is allowed again. A transaction test pastes a scaled object with scaling off.
2026-10-17 13:26:16 -05:00
zeex64 8bed866f92 Merge pull request #221 from tsullivan13/park-object-sets
Park editor: saved object sets, plus fixes for multi-object edits
2026-10-17 13:18:42 -05:00
AyeZeeBB 38c5166533 Board Break: a board breaks from something the rider did, never at random
A light slam had a flat 25% chance to break a board (about 50% worn), a bail with no recorded
force counted as light, and any board could give way on a timer while just riding. Now a slam
under 60% of the breaking force never breaks it and the chance rises smoothly to certain (a new
board: never under 6, half the time at 8, always from 10); a bail of unknown force never breaks it;
and the riding timer is gone: a board that is done (85% worn) gives way on a hard landing instead,
from a big drop as it becomes done down to a curb's when worn out. The player is told when the
board becomes beat and done, and each break's cause is logged at info level.
2026-10-17 13:10:23 -05:00
zeex64 5a4c8a980c Merge pull request #185 from miflow13/trainer-hardcore-preset
Trainer: Hardcore preset, beside Realistic
2026-10-17 12:53:24 -05:00
AyeZeeBB 1ba5c8ef28 Server: an admin's tool locks outlast leaving, and a throwdown-locks change mid-throwdown changes only the difference
A lock an admin sets is kept for the player's SteamID until unlocked or the server restarts, so
leaving and joining again no longer lifts it: they are locked again and told on joining. lock and
unlock take a player who is not here by SteamID64 (unlock also by the name they had), and locks
lists them as not here. A throwdown's own locks still end when the player leaves. Changing
throwdown-locks while a throwdown runs unlocks and locks just the tools that changed for its
players, saying the setting changed instead of that their throwdown is over.
2026-10-17 12:50:31 -05:00
zeex64 2f506016c3 Merge pull request #218 from moelrobi/server-tool-locks
Server: Per-player tool locks
2026-10-17 12:45:52 -05:00
AyeZeeBBandcodejunky 364c6198df Launcher: Steam found on macOS through a Wine-based compatibility tool, and a macOS setup guide
Steam for Mac with NotProton or CrossOver passes the compatibility tool a path inside its app
bundle, below the folder with config/loginusers.vdf, and the tool's stand-in keeps no record of the
running client, so the launcher said Steam was not running and started offline. It now looks up
from that path for config/loginusers.vdf, and when started by the native Steam client under Wine
takes its most recent account where the running-client checks fail. Windows and Proton, where those
checks pass, are unchanged. The offline panel's hint about the launch option shows only under Wine.
MACOS-SETUP.md gives the launch option (/bin/bash, ROSETTA_ADVERTISE_AVX=1 for the game's CPU
check) for the launcher in a folder of its own.

Based on https://github.com/Dingo-Shenanigans/ReSkate/pull/219.

Co-authored-by: codejunky <pmp.codejunky@gmail.com>
2026-10-17 12:36:03 -05:00
AyeZeeBB d75d34614b Keyframe smoothing: key slots built once per rebuild, no playback hook, smoothness in the menus
A rebuild builds one segment per key and each needed every key's slot, so a long replay built
them once per segment: the game's rebuild is hooked too and the slots built for its first segment
are kept for the rest of it (per Behaviour and Subject). The segment player is no longer hooked
(it only counted plays for keysmooth status, every frame). The smoothness is a slider beside the
switch in the overlay (sent when let go, as each change rebuilds the open replay's camera) and
Keyframe smoothness (100, 75, 50, 25%) in the pause menu and Mod Options > Visuals. The startup
line logs on the runtime channel.
2026-10-17 12:29:53 -05:00
zeex64 e071d99ffa Merge pull request #282 from takku-dev/replay-keyframes
Keyframe smoothing for the replay editor's free camera
2026-10-17 12:20:45 -05:00
AyeZeeBB ab8c9dc6ae Customization: a mod's item card shows the mod, with its icon, inside the game's item card
A mod's item (or one of the game's own a mod changes) keeps three empty description lines, so
the game's item card, which grows upward from a fixed bottom edge, always has room in the same
place; the overlay draws the mod there: its icon (decoded off the render thread into a fourth
texture slot, the last 32 kept), a MOD or CHANGED BY MOD tag, its name, author, version and how
many items it has. The card is placed as the game places its own, measured at many window sizes:
by the smaller of its scales, a 21:9 frame centred on wider screens (the search bar follows it
too). The warning sign the game's focus script gives any description is taken off that notice
each tick while it shows the reserved lines.

The merge's item list records each mod's version and folder (an older list falls back to the mods
loaded at launch). The item grids now run every client tick instead of at the 500 ms
customization pace, follow the highlight between their 40 ms passes, and let go of a grid as soon
as its screen closes, so the card, the search bar and favorites keep up with the player.
2026-10-17 12:04:38 -05:00
AyeZeeBB 4cbec93a3e Customization: a mod's item says which mod it is from
The merge keeps the items the store-copy check reads in every mod and writes them to
Mods/.reskate/reskate-items.json (highest priority first, so an item two mods ship is the one
whose copy the game uses); a live merge keeps the entries of the mods it did not read again, and a
patch built before the file existed is built again once. The game reads it when it builds its
item catalogue: an item a mod adds says "From: <mod> by <author>" under its name, one of the
game's own that a mod changes "Changed by <mod>", unless it has a description of its own.
2026-10-17 10:53:45 -05:00
AyeZeeBB d9aee11957 Drone: dronemodeltest remote flies a pretend other player's drone, and a missing model says why
The pretend drone goes into the beacon as a received one would, so other players' drone models
and markers can be checked without a second player. A drone flying 3 s without its model now logs
what is waited for (the engine, the local skater, or the thread's job context) instead of waiting
silently.
2026-10-17 10:41:31 -05:00
samitakkulaandClaude Opus 5.5 51dddf3d91 Keyframe smoothing for the replay editor's free camera
The game plays the replay camera's framing keys as cubic Hermite segments whose speed changes at
every key (the acceleration jumps there, and it brakes where a channel slows or turns back), so a
free-camera shot surges and settles around each key. keysmooth on rewrites each segment as the game
builds it, so that the game's own player plays the natural cubic spline through every key: speed
and acceleration carry on through the keys, and every key is still met exactly, at its time.

- keysmooth on|off (off by default), keysmooth amount 0..1 (1 by default; 0 is the game's curve)
  and keysmooth status; kept in %LOCALAPPDATA%\ReSkate\KeySmooth.settings. Only the free camera
  (Behaviour 1) is smoothed; the other camera modes keep the game's curve.
- A switch in Mod Options > Visuals and in the overlay's Skater > Freecam.
- The curve apart from the game, with tests (DINGOSDK_BUILD_REPLAY_KEYFRAMES_TESTS); the hooked
  functions are fingerprinted, and a build that differs gets no hook.
- contrib/keyframe-smoothing.md: what it does, how, and what was seen in game.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 08:33:32 -07:00
AyeZeeBB 6780fe55c1 Merge branch 'main' of https://github.com/Dingo-Shenanigans/ReSkate 2026-10-17 10:23:50 -05:00
AyeZeeBB 1e91b8851b Pause menu: the maps as a grid of pictures on one MAPS tab
The ReSkate page of the pause menu listed the maps as rows of names on two tabs. They are now one
MAPS tab of cards in the page's own style, each with its map's picture (an official map's loading
screen, a custom map's mod icon, from the same pictures as the ReSkate menu's map grid) and its
name: the game's maps, then the custom ones under their own heading. The one pointed at says
LOAD (or why not), the D-pad moves across the grid, and a map that cannot be loaded now is dimmed.
Tutorial Island is left out, and the note on why travel is unavailable sits beside the title.
2026-10-17 10:23:44 -05:00
zeex64 ece3aa5f0d Merge pull request #277 from DreadHeadHippy/plex-link
Music: link a Plex account, with now-playing, album art and transport controls
2026-10-17 01:53:14 -05:00
AyeZeeBB 36ce7cc263 Launcher: "Test pre-releases" only shows when there is one, and either update switch checks again at once
The update check reads GitHub's release list either way (one call, as before) and notes whether a
pre-release newer than the latest release is there; the setting is offered only then, or while it
is on so it can be turned off. Unreachable GitHub keeps what the last check found.

Flipping "Install ReSkate updates" or "Test pre-releases" saves and checks again straight away, so
PLAY or the update button changes to match: updates off while one is offered goes back to PLAY,
pre-releases on offers the pre-release, off the latest release. A flip while a check is running is
checked as soon as it ends (each frame asks; it only compares two settings).
2026-10-17 01:50:50 -05:00
AyeZeeBB d0f76bfd61 GPU diagnostics: a resource creation that takes 20 ms or more is said in the log
With what was made (heap type and flags, size, format, flags) and the game code that asked, at
most 40 times. Small buffers and textures took 120 to 170 ms each, two threads at the same moment,
which showed the 5 s stall was the GPU or driver held up by something outside the game, not the
size of what the game made.
2026-10-17 01:44:22 -05:00
AyeZeeBB d6b56fa1e8 Profiler: a present sample lists its slowest frames, from one present to the next
A hitch on the render side never showed in a report: the client report lists slow client frames
only, and a present sample had no frames at all. While a present sample runs, the present hook
notes when each frame is presented; the report then lists the longest gaps between presents, each
with what the present thread's samples in it spent their time in and how many were waiting. This
is what found a 170 ms stall every 5 s: the game's batched GPU uploads blocking in the driver.
2026-10-17 01:44:22 -05:00
AyeZeeBB 1456c1fa51 Customization: a preset with a parameter type the game cannot read is left out, not applied
Scrolling shirts onto Yudi-Yuddispack's philippleinshirt_ap crashed the game (Skate.exe+0x3dc07ed):
one of the preset's set parameters has a type of 0x0c07010304040502 (null in another crash). The
game type-checks every set parameter when it next applies a preset to a material, reading the
type unchecked, and catching that crash inside addEsShaderPreset was too late: the preset was on
the material already and the next update crashed on it.

addEsShaderPreset's guard now checks the preset first, as that type check reads it: the TypeInfo,
its data, a word at +4. A preset with a parameter whose type cannot be read is left out as a
preset that is not loaded is (the item shows without it), and named in the log once with that
parameter's key. Many of the game's own types are built at run time, so the test is that the
type reads, not that it lies in the game's image.
2026-10-17 00:48:40 -05:00
AyeZeeBB 21d9b0d993 Profile: cosmetic ownership is a rule, not a list of every item ever seen
With "unlock all cosmetics" (and objects) on, the default, ReSkate wrote every installed item into
the profile as owned and never removed one, so every mod a player ever tried stayed in the save:
8765 cosmetics and 520 objects in one profile, past the limit that left a player with no items.

What is owned is now worked out from what is installed (installed_item_owned): a paid store copy
never, every other item while the kind's unlock option is on, and with it off what the profile
saved. The catalog given to the game, the owned list, saved outfits, the player card, the Build
object browser and the park editor all ask it. Nothing per item is saved any more, and a profile
with an option on drops the rows earlier versions saved, once, on the next start.

profile_migration_tests checks that drop on a copy of a real save: the rows stay with the options
off, are gone after a restart with them on, and nothing else in the profile changes.
2026-10-17 00:29:27 -05:00