Commit Graph
414 Commits
Author SHA1 Message Date
KalmarvandClaude Opus 5.5 c22feca912 Console: "perf textures" is "textures"
The streamed-texture reading is one of the perf readings, and perf textures is where it gets
looked for. It is now an alias, so Tab under perf offers it too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 18:29:08 -06:00
AyeZeeBB 5e43dc2871 Multiplayer: a chain of resized bones is held to the bone-scale limit as a whole
Each bone's scale was held to the limit (a server's bone-scale, 2x by
default; 8x on every client), but a bone shows at its own size times its
parents' and the whole skater's. A modified client resized each bone of
a chain to the limit: four neck bones at 2x showed a neck 16 times as
long, within every per-bone check.

- skater_bone_parents.h: the parent of each of the skater rig's 386 bones,
  read from the game's data (animbase_default_renderskeleton), which the
  pose's skater bones follow.
- limit_bone_scale then holds each bone to what its parents leave of the
  limit: the size it shows stays within 1/limit to limit. A single resized
  bone (a bigger head) is unchanged; bones past the rig's have no parent
  and keep the per-bone limit.
- Servers and clients already hold every pose to their limit with it, so
  the combined limit follows each server's bone-scale setting, and every
  client's 8x where a server allows more.
- Tests: a neck chain at 2x each shows at 2x; a resized skater's bones are
  held to what its own size leaves them.
2026-10-15 19:00:37 -05:00
AyeZeeBB 228ce65f84 Launcher: changing the update settings checks again without a restart
Turning "Install ReSkate updates" or "Test pre-releases" on or off took
effect at the next start. Closing settings after changing either now runs
the update check again: a pre-release is offered as soon as it is wanted,
the latest release when it no longer is, and a pending update is dropped
when updates are turned off.

- Not while a download, an update or a launch is under way, while the game
  runs, or while a merge waits on an answer about mods; nor as the launcher
  closes. The next check or start picks the change up then.
- The "Test pre-releases" help says the check happens when settings close.
2026-10-15 18:43:11 -05:00
AyeZeeBB 3faa58bb42 Render-resource pool: the other renderer is allocated room for its metadata pointers
719cba1 stopped writing the metadata pointers into the other renderer
(0x2daa00 bytes, Skate.exe+0x30c64cc, kept at 0x75f2700), taking them for
the state owner's alone. They are not: the other renderer's own code reads
them through the patched view (0x030e6bff, called from 0x30a7e18) and
append (0x03e94fe6, called from 0x30d8ebb). Without the write, it read
whatever lay 18 MB past its end. With it, as in every release before, that
memory was overwritten, or the write faulted when nothing was mapped there
(the store_field crash).

- The other renderer's allocation is patched to the state owner's
  0x11ab080 bytes (0x030c64cc, mov ecx), so +0x11aae28/+0x11aae30 are
  inside it.
- Both renderers' metadata pointers are written again, before and after
  the native constructor. The resource-state and relation-mask vectors stay
  the state owner's alone: the other renderer keeps fields of its own at
  +0x2da920.
- The contract's comment says which renderer reads what, and where.
2026-10-15 18:16:22 -05:00
AyeZeeBB 719cba1166 Freezes and crashes: the game's threads no longer wait on ReSkate's slow work
Players reported the game hanging for about a second while skating. A
profile showed the memory line in the log walking every heap
(HeapSummary) on the client thread, 0.5 to 2 s every two minutes. An
audit of everything that runs on the game's update and render threads
found more of the same, and Sentry's top crashes had causes of ours.

Freezes:
- Memory log line: no heap walk or thread snapshot; the GPU part and the
  write happen on a thread of their own.
- Profile database: synchronous=NORMAL in WAL mode. A save is still kept
  when the game crashes; every play event no longer waits for the disk
  inside the game's hooks.
- ReSkate's own preferences and values (menu clicks, session sliders,
  Discord) are saved by a background writer in order; reads see a value
  until it is saved.
- Input: the foreground window and the keyboard are sampled on a thread
  of their own (GetAncestor and GetAsyncKeyState stalled the client tick
  40-50 ms when another program held Windows' lock); flight input uses
  the sample; ClipCursor at most twice a second while a menu has the
  pointer.
- Hooks installed while the game runs go in one transaction per place
  (HookBatch): throwdowns, remote players, the party, Hall of Meat.
- Off the update thread: the host's map package lookup (one table read in
  the background, not the Mods folder per offer), the trainer's map file
  and settings save, Board Break's settings save, mod music playlists and
  their covers, the Spotify station covers.
- Off the render thread: the Modding page's and the deck card's Mods
  folder reads. The overlay's three startup waits share five seconds.
- Less work per frame: Steam names reused while one a frame is asked
  again, 2 friends a tick, steam_api64.dll checked once per process,
  cosmetic names read in place rather than a system call per character,
  an outfit load no longer copies the inventory per slot, the throwdown
  type scan runs at background priority over resident memory, the Board
  Break deck label is kept a minute.

Crashes:
- Render-resource pool: the metadata fields are written to the state
  owner only. The other renderer is 0x2daa00 bytes, and +0x11aae28 is far
  past its end (store_field crash; heap corruption in every release).
- Other players' skateboard effects: a stale skateboard component is no
  longer followed, and the joint lookup is walked with a bound first (an
  endless loop in reused memory ended in GameStall).
- Launcher: Oodle decodes into the buffer it asks for with corrupt data
  possible, and its assertions no longer stop the process (heap corruption
  in the store-copy scan; a breakpoint in oo2core).

Timings (Send performance timings):
- A frame of half a second or more in a level is sent as game.freeze:
  where the time went (ReSkate's tick, the game's frame, or outside it),
  whether the renderer kept presenting, and ReSkate's busiest zones.
- Closing the game sends the level session it was in.

Music after a connection drop:
- Spotify device: an account Spotify could not be reached with is kept and
  tried again (3 s doubling to a minute); a session that drops is taken
  up again. Only an account Spotify refuses is asked for anew.
- YouTube playlist pictures that could not be fetched are tried again,
  from 30 s to 10 minutes apart.
2026-10-15 18:10:53 -05:00
AyeZeeBB 310922556c Launcher: a setting to test pre-releases
Settings > Launcher > "Test pre-releases" (off by default). On, the update
check takes the newest GitHub release that is not a draft and carries a
launcher.json, pre-release or not, in place of the latest full release:
a pre-release newer than the last release is installed, pinned by size
and SHA-256 as any release is. Turned off, the next check goes back to
the latest release, whose files then replace the pre-release's.

- The update notice says "Pre-release" for one, and the log names which
  kind of release was taken.
- The changelog shows the release the setting picks, marked as a
  pre-release, and is fetched again when the setting changes.
- --no-gui launches follow the same setting.
2026-10-15 14:23:06 -05:00
AyeZeeBB 94a616feb9 Map downloads: one that has begun goes on when the session stops waiting
Follow-up to #225. The session still waits 30 minutes in all for a map
(checking, the two-minute question, download, install, apply, join), and
servers and lobbies still let a player go at 30 minutes. But a download
that has begun is no longer cut off at 27 minutes: a large map on a slow
connection never came at all that way.

- Once the download has begun, the session's deadline is the session's
  alone. The download goes on (up to its own four hours, as before #225),
  installs and is applied, and the player is told to join again; no
  rejoin is tried past the deadline, where the server would turn them
  away. "Map still downloading" says so when the session stops waiting.
- Before the download, the deadline still ends the check and the question.
  Declining or cancelling still stops it and removes the partial file.
- A download whose session has gone is not cancelled by joining another
  session; a new map need is turned away until it is done.
- The 27-minute transfer budget and its completion reserve are gone from
  map_fetch_policy.h, with their tests; the map download tests cover the
  new behaviour.
- The HTTPS timeout test compiles with warnings as errors (a signed and
  unsigned comparison), and get_text's stale-file removal is indented again.
- README: map downloads described as they now are.
2026-10-15 14:23:06 -05:00
zeex64 e88853add8 Merge pull request #242 from Kalmarv/pr/help-v2
Console: "help perf" lists the perf commands
v2.1.0-pre
2026-10-15 14:15:45 -05:00
zeex64 b6f3ea3c30 Merge pull request #228 from davad00/fix/playstation-report-age
Fix PlayStation reports briefly dropping after HID reads
2026-10-15 14:14:56 -05:00
zeex64 1094e4dc86 Merge pull request #237 from AlexanderPuglisi/fix/unreadable-script-keeps-toc
Mod merge: an unreadable script no longer drops the rest of its mod's TOC from other mods' copies
2026-10-15 14:14:01 -05:00
zeex64 e7c6df0df6 Merge pull request #225 from Jean-LucTch/dev
Fix multiplayer custom map download and join timeout handling
2026-10-15 14:03:06 -05:00
AyeZeeBB 164fdffbd0 Descriptor heaps: dense custom maps no longer overflow the GPU's descriptor heap and crash it
The renderer gives each frame 131,072 shader-visible descriptors past a persistent 120,000, in
heaps of 333,333. Dense custom maps (the Los Santos City sublevels, San Andreas) draw more than
that in a frame, and the renderer wrote past the end of the heap: shaders read garbage
descriptors, which faulted or hung the GPU (page faults at nonsense addresses, in draws, texture
fetches and ray tracing alike). ReSkate now patches the device setup at boot so each heap is
D3D12's 1,000,000 and a frame may use 524,288; heaps are 644,288 descriptors. LS-B2, LS-B3 and
San Andreas (210,000 a frame at its peak) now hold.

Also in this change:
- Memory: perf memory owners/heap/gpu/report, a ledger of who commits the game's RAM; the
  render-resource pool no longer allocates its 115 MB twice; the EadpErrorsData arena is
  capped at 32 MiB (EA's error reporting is blocked anyway).
- Crash reports: tagged with the map, destination, graphics card and driver version (protocol
  v3), so Sentry can group GPU hangs by map and card.
- GPU diagnostics (--gpu-diagnostics): a fuller DRED report, the device-removal and video
  memory watches, a large-draw watch, a record of which game code made and freed each GPU heap
  and resource, checks of every GPU address bound, and a meter of each descriptor heap's use.
- World pools: peak use of entity pages, render instances and spatial blocks in the log.
- dingosdk_mod_mesh_check: checks every MeshSet a mod ships against its geometry; the MeshSet
  reader now knows static meshes' layout.
2026-10-15 13:57:11 -05:00
zeex64 67d84d5bd7 Merge pull request #227 from neekgate/fpv-drone-pr
ReSkate FPV Drone
2026-10-15 13:20:11 -05:00
zeex64 1acde3b9b3 Merge pull request #232 from Belcross-Dev/grind-exit-playstation-pads
Grind exits: fix triggers not registering on DualShock and DualSense controllers and improve curved grind exits
2026-10-15 13:19:59 -05:00
zeex64 32a83d429e Merge pull request #241 from Kalmarv/pr/command-crash-fix-v2
Console: mp map-markers, mp puppet-savings, throwdown-hud and throwdown-offboard no longer crash when typed alone
2026-10-15 13:19:12 -05:00
zeex64 dc43a50a47 Merge pull request #243 from Kalmarv/pr/lights-v2
Lights: a level with more lights of one kind than the game holds no longer crashes
2026-10-15 13:17:39 -05:00
zeex64 de272c1439 Merge pull request #257 from FourthStudio/board-break/wear-and-tear
Board Break: wear and tear, rail snaps, break and body sounds, settings
2026-10-15 13:14:03 -05:00
Fourth Studio b999f37e7b Board Break: wear and tear, rail snaps, break and body sounds, settings
Boards wear: hard landings, hits onto rails and ledges, grinding and
slams wear the board of the deck in the game, kept per deck. From a fifth
worn it steers lazier and its trucks go soft (the game's own physics
tuning, outside multiplayer sessions only); a worn board breaks from less
and, worn out, can give way under the rider. A board that broke is a new
one once it is whole again, and the game's own board wear is cleared with
it.

A boardslide, lipslide or darkslide that comes down too hard onto a rail
can snap the board, and the rider goes down with it: No Bail can now be
asked for a wipeout, which goes in as a cause before the selector picks.

Sounds play through XAudio2: a crack by the size of the break, metal when
the board broke on metal (the material comes from the game's contact
effects; which are metal is marked in play or listed by a pack), and the
body's hits in a bail by how hard they land.

The settings are a card on the overlay's Skater page, two rows in Mod
Options and console verbs, kept in BoardBreak.settings. A deck may name
itself and set its wheels wider apart in a deck.ini; Old School and Pig
join the decks the feature knows.
2026-10-15 19:22:21 +02:00
AyeZeeBB 6df4f9a7bd Replay export: videos are encoded at 100 Mbps whichever quality is chosen
he export dialog's quality setting picks 8, 12 or 18 Mbps for the H.264
encoder (three mov eax immediates at Skate.exe+0x62c24f, +0x62c256 and
+0x62c25d in the 20260929 build). All three are now 100000 kbps.
- The code around them must match the supported build's bytes, and each
  value must be the game's own or already 100000; otherwise nothing is
  written and the log says the change was skipped.
- The log says whether the bitrate change or the frame-pacing hook was
  skipped. start() reports success if either one is in place, so
  replay_export_initialized can say active while the hook is off.
- The fix that encodes every rendered frame is unchanged.
2026-10-14 20:11:01 -05:00
AldoandClaude Opus 5.5 301b7b220f Drone: turning the goggle display off hides it
The `osd` setting (Show the goggle display) was saved but never read, so
the readouts stayed. Off now hides every readout: battery, armed, timer,
throttle, altitude, speed and signal. The range warnings (NO SIGNAL,
FAILSAFE) still show, and the sticks, crosshair and analogue look keep
their own switches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MArBL6UbYZPsp9rMnq2Ks5
2026-10-14 19:45:05 +01:00
KalmarvandClaude Opus 5.5 3468f556b0 Lights: a level with more of one kind than the game's table holds no longer crashes it
The game keeps each kind of light (PbrSpotLight, PbrSphereLight, ...) in a
table of 8,192 and crashes at Skate.exe+0x4ea4094 when a level makes more.
- Each kind's light factory is hooked: once the kind's table is nearly full
  it gives no entity, as the game's own factory does for a light it should
  not make. The light is not drawn and the game goes on.
- Said in the log: the kind of light and how many were left out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 09:40:06 -06:00
KalmarvandClaude Opus 5.5 99e79f123a Console: "help perf" lists the perf commands, and a wrong word after a command says where to look
help <command> showed only that command when it was also the first word of others: help
perf showed the HUD toggle and not perf hud, perf status, perf sample and the rest, and the
same held for help log, music, reset, boardbreak and roadrash. help listed a family only
when no command had the family's name. It now lists them after the command's own details,
by name or by alias (Registry::under).
"perf hdu" answered "Too many arguments. Usage: perf"; when the command has others under
it, the error now ends "Use help perf for the commands under it."

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 09:36:32 -06:00
KalmarvandClaude Opus 5.5 e5557d914e Multiplayer console: map-markers, puppet-savings and the throwdown switches work by themselves
mp map-markers, mp puppet-savings, throwdown-hud and throwdown-offboard take an optional
argument and, without one, say what they are set to. Each read values[0] unchecked, and an
optional argument that is not given adds no value, so typed by itself each indexed an empty
vector. They check now, as mp collision and challenge-invite beside them do.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-14 08:56:47 -06:00
AldoandClaude Opus 5.5 76c0fd0903 Drone: settings move into the ReSkate menu (DRONE page)
The drone's own floating window becomes a DRONE page in the ReSkate menu
(Insert), after TRAINER, built from the menu's cards, ON/OFF rows, fields
and option strips like every other page. Its tabs are the window's:
FLY, HANDLING, RATES, DISPLAY, CONTROLLER and LOBBY. `dronemenu` now opens
the menu on that page.

The FLY tab ends with a small credit line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MArBL6UbYZPsp9rMnq2Ks5
2026-10-14 13:33:52 +01:00
AlexandeeerandClaude Fable 5.1 eacfbd72dd Mod merge: an unreadable script no longer drops the rest of its mod's TOC from other mods' copies
Since the mods are read on several threads (0ae0e71), read_mod reads every
script a mod replaces: whether a higher mod's version stands is only known
once the mods are settled. Before, a script a higher mod had replaced was
never read. When such a read fails, the TOC's catch noted it and gave up the
rest of that TOC, so the mod's later changes and additions were left out of
other mods' copies, with a note blaming the mod where nothing used to be read.

The read now has a try of its own. A failure is kept with the script and
settled with the rest: where a higher mod's version stands it goes, note and
all, as if never read; where the script is wanted, the note stands and only
that script is missing, the rest of the TOC having been read on.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VNYF3aYa2q3MkFXc5xYnDd
2026-10-14 06:24:19 +02:00
AyeZeeBB 84940ee571 Stations: songs get their own names back before a map change, and the names shown no longer pile up
While a Spotify, YouTube Music or External Audio station is on, a song of
the game's is made to read as the track that is playing.
Crash on changing map
- The game keeps each song in its registry under its artist and title, and
  takes it out by them when its bundle unloads. A song that read as
  Spotify's was looked for under Spotify's words and not found, so its own
  entry stayed behind, pointing at an asset that was freed. Registering the
  song again for the next map read that asset (Skate.exe+0x3dd1db0 from
  0x43e260, joining a session with a station on).
- Before a level transition every such song is given its own artist and
  title back, and none is held on to: they are the old map's.
Memory
- The artist and title a song is made to read were copied afresh on every
  call, and kept. That is once a track, but every frame while the station's
  song cannot be made to read (its asset gone after a map change, or 64
  songs shown already): two copies a frame for as long as the station was
  on. Each text is now kept once.
Memory log
- The "Memory:" line also says how much is in the process's heaps (what
  ReSkate, the Spotify library and Windows' libraries allocate, apart from
  the game's own pools) and how many threads and handles there are, and it
  is written every two minutes as well as when memory moves by a quarter of
  a gigabyte.
2026-10-13 19:08:38 -05:00
Belcross 72aa7b87c0 Grind exits: work with DualShock 4 and DualSense pads read natively
skate. reads a DualShock 4 or DualSense without Steam Input through its
own HID reports, not XInput, and the gamepad filter only ran on XInput
reads. With such a pad grind exit triggers never saw a trigger: no side
was picked, and the grab and lean guards did nothing.

The filter now also runs on the game's own native PlayStation reads that
the capture already follows (the ones it neutralises while a menu holds
the input): the report is parsed into XInput's layout, filtered, and the
changed triggers (with their L2/R2 digital bits) and left stick X are
written back in the report's own layout, the Bluetooth CRC refreshed.
The CRC code is shared with the neutral report's.
2026-10-14 01:04:38 +01:00
AyeZeeBB 6c45e9666d World layers: a server's catalog must be the supported build's, and a player is not put out over one that is not
2.0.8's dedicated server was released with a world-layers.json scanned from
a game Steam had updated: 263 layers, where every player's game has 261. A
server that shares its layers (world_layer_sync) sends one choice for each,
the player's game turned the message down as unreadable, and nobody could
join such a server ("Join code, sender identity, or multiplayer protocol
did not match", and "Disconnected." in the server's log).
- supported_build::world_layer_count (261): how many layers the supported
  build's levels have.
- Server: a world-layers.json of another count is not used; the log says
  why and layer sync stays off, where before every player was turned away.
- --export-world-layers refuses a game folder whose count differs, so a
  release cannot be built from an updated game again.
- Player's game: a layer list of another length is left unread and every
  layer stays as the player has it; the rest of the message is taken and
  they join.
2026-10-13 18:45:37 -05:00
AyeZeeBB 9f93c3cbb2 Shader tables: mods' are merged as in 2.0.7 again, and the game's song scorer stays within its list
Shader tables
- Reverts a61f82c ("Shader crash fix"). Since 2.0.8 a mod's own shader
  programs were copied into the merged table, and the tables that cosmetic
  bundles carry were merged across mods. Each such bundle then held other
  mods' programs, and the game built them as the bundle loaded, before the
  files with their compiled variants were there. That was 2.0.8's most
  reported crash (Skate.exe+0x3f86da6, some forty machines in ten minutes).
  2.0.9's guard passed such a program over, and the same players then
  crashed a little later in cosmetic loading (+0x3f7bb65, +0x16fe1a6,
  +0x3dc07ed).
- Whatever crash a61f82c fixed comes back with this for the mods that
  needed it.
- The guard stays.

Music
- The game's read of one song for its scorer (0x14f23a0) is replaced by the
  same read with the check it lacks: a place past the end of the playlist
  asset's songs has no song, which the game already answers with 0. 2.0.9's
  check in music_select_next_hook looked at what the queue held before the
  game was asked and did not see these; the game asked for places such as
  0xd570 and crashed reading them (7 reports on 6 machines).
- Said in the log the first eight times.

Not confirmed in game: neither change has been run by a player who was
crashing.
2026-10-13 18:44:15 -05:00
AyeZeeBB 83f148390a Spotify device and streams: secure connections of their own, not Windows'
nder Wine and Proton the Spotify device signed in but was never taken up
by Spotify as a device to play on: librespot never logged "active device
is ...", nothing could be started on it, and after a minute and a half its
control connection failed ("Websocket connection failed: Remote sent after
having closed"). Its HTTPS and websocket went through Windows' security
layer, which there is Wine's own.
librespot and reqwest are now built with rustls and its built-in
certificate authorities (rustls-tls-webpki-roots, ring) in place of
native-tls, so the same code makes the connections on Windows and under
Proton. This covers the Spotify device, online radio and anything else
fetched through the helper. Not yet confirmed on Proton.
Cargo.lock changes with it. ReSkate.dll is about 2.5 MB larger.
v2.0.9
2026-10-13 18:05:06 -05:00
dave peace fcd90f586f Fix PlayStation report age sampling after HID reads
Take the freshness clock after draining all connected pads so a newly
received report cannot underflow an unsigned age and briefly disappear.
2026-10-14 01:45:13 +03:00
AyeZeeBB f356c1eafd Music screen: large playlists no longer empty it, and two logs say why things fail
Music screen: large playlists no longer empty it, and two logs say why things fail
Music screen
- The screen's list was turned down whole, and came up empty (the game's own
  Featured row too), once it held more than 1,024 songs: a few large YouTube
  Music, Spotify or local playlists went over that. The most is now 2,000
  songs and 16,384 places in playlists (music_ui_most_songs,
  music_ui_most_places); 2,000 because the screen's own table of songs is
  read only up to 2,048.
- The rows of the player's playlists are counted as they are registered and
  held under that: with no room left, the rest of a playlist is left out of
  its list (it still plays) and the screen is never empty for it.
- A row whose "artist - title" is longer than the screen takes is left out;
  one such row turned the whole list down as well.
- Said in the log: how many songs were left unlisted, and, should the list
  still be turned down, what it held.
Logs
- Spotify device: librespot's own warnings and errors are written at the
  warning level again; only the rest of what it says stays at debug. A
  player whose Spotify connects and stays silent had nothing to send.
- Multiplayer: a message turned down with "Join code, sender identity, or
  multiplayer protocol did not match" now says which of the three it was,
  its size and first bytes, and whether it came from a dedicated server.
2026-10-13 17:38:50 -05:00
AyeZeeBB 2e40aeb6e2 Game data of another build: the launcher asks for a verify, and mods are looked at again
After Steam updated skate., some installs had the supported Skate.exe over
the new build's data (a copied game, or a download that stopped part-way).
The launcher called that ready, every mod was left out as "made for game
build 29544144, not the installed 29663206; rebuild it with ReSkate Studio",
and the mods stayed out after the game files were put right.
Launcher
- Ready now also needs the game's data to be the supported build, read from
  Data\layout.toc against supported_build::game_data_changelist (29544144).
  Data of another build, or none, reads "Game files need verifying".
- DOWNLOAD in that state checks every file (-validate) instead of fetching
  only what is missing. A download that fails part-way no longer ends on
  ready because Skate.exe arrived.
- Data whose build cannot be read does not block.
Mods
- A mod left out because the game was of another build is no longer
  remembered in .reskate-excluded.json: it is checked on every launch. One
  already remembered for it is looked at again.
- When it is the game that is not the supported build, the mod's message
  says to verify the game files in the launcher, not to rebuild the mod.
v2.0.8
2026-10-13 16:31:09 -05:00
AldoandClaude Opus 5.5 57d98307a7 Skater: FPV drone mode
An FPV drone flown from the free camera: real quad physics (thrust,
gravity, drag, Betaflight "Actual" rates), collisions with the world, and
a goggle-style display. Open it with `dronemenu` (or the drone window's
Start flying).

Flying
- Keyboard and mouse, gamepads, or USB RC radios (EdgeTX etc. in Joystick
  mode). "Set up controller" learns each stick and switch by asking for
  one at a time, reversed axes and springing gamepad throttles included.
  While a controller flies the drone, the game is kept off it, as
  freecam's controller mode does.
- Presets (Tinywhoop, Toothpick, 5 inch), arm/disarm, back to takeoff,
  and every setting live through `dronetune`, saved in the profile.
- Optional range: the picture breaks up and is lost with distance from
  the takeoff point; past it, failsafe cuts the motors.
- OSD, on-screen sticks, an analogue video look, synthesised motor sound.
- Goggles: the pilot's skater wears eyewear from the game's catalog while
  flying, and gets their own back on landing (Road Rash aware).
- Start flying hides the game UI, Stop flying brings it back.

Multiplayer
- New packet `drone` (36): where a player's drone is and which way it
  faces, 15 times a second, unreliable, relayed like effects. Markers
  glide between updates. Protocol version 52.
- FLYING DRONE above the name of a player who is flying.
- Players choose whether to share their drone and whether to see others'.
- Dedicated servers: `sync_drones` (players section) and `drones on|off`.
  Off: no drone packets are relayed, and players are told in the roster.

Changes to existing code
- `flyspeed` takes any speed from 0.6 to 1500, not only the seven listed
  (the drone's presets and top speed slider use speeds of their own).
- Overlay: begin/end_input_access, so the drone's controller read sees
  the device while the game is kept off it.
- Profile: local_surface_hit, the park editor's ray from one point to
  another, for the drone's collisions.

Tests: Skater/Test/drone_radio_tests (controller setup), and the drone
packet and roster rule in Multiplayer/Test/protocol_tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MArBL6UbYZPsp9rMnq2Ks5
2026-10-13 21:59:49 +01:00
AyeZeeBB 9124869ba4 Launcher: a failed Steam download writes DepotDownloader's last lines to the log
"The Steam download did not finish" is the launcher's message for any
failed download, and what DepotDownloader said (the account does not own
the game, Steam refused the sign-in, the disk is full) was only written at
the debug level, so Open logs showed nothing to go on.
When a download fails, its last 40 lines are now written to the log as
warnings, after the exit code. The Steam login name is still left out, and
so are the rows of a QR code and the progress lines.
2026-10-13 15:53:55 -05:00
AyeZeeBB 3cc9a8d26a Merge branch 'main' of https://github.com/Dingo-Shenanigans/ReSkate 2026-10-13 15:38:38 -05:00
AyeZeeBB 9b81c821e4 Kicks: a popup for the player who was put out, and vote kicks last 5 minutes
A player kicked or banned only found out why from the status line of the
multiplayer menu, if they opened it.
- What the host or server says as it puts a player out ("You were
  kicked...", "You are banned...", away too long, a mod or cheat it does
  not allow) is now shown in the middle of the screen with an OK button,
  under YOU WERE KICKED, BANNED or REMOVED. The same when they are refused
  on trying to join again early. A link that is simply lost shows nothing
  new.
- Answered with A or B on a controller, Enter or Esc, or a click on OK. The
  game's input is held while it is up, as for the vote for the next map, so
  the button that answers is not also a press in the game.
- Console: "popup test" shows it with a sample message, to try it without
  being kicked.
Server: a kick by a vote has a time of its own, votes.kick_minutes, 5 by
default (1-1440, or 0 for until the server restarts); it no longer goes by
players.kick_minutes, which is now an admin's kick only and is still until
the restart by default. Console: votes kick-minutes <minutes>|restart, and
"votes" shows it. A config without the key takes the 5 minutes.
2026-10-13 15:38:36 -05:00
zeex64 9fb0d7fb40 Merge pull request #216 from Belcross-Dev/grind-exit-pop-out-strength
Grind exits: pop-out strength slider
2026-10-13 15:31:22 -05:00
AyeZeeBB 8cad9f2c13 Launcher: no exception for Proton, it has a folder of its own there too
- The launcher refuses to start from a Steam library folder under
  Wine/Proton as well; the check is no longer skipped there.
- README, Linux (Proton): the launcher and ReSkate.dll go in a new, empty
  folder, and the Steam launch option swaps in the launcher's full path in
  place of EA's anti-cheat launcher. Noted as not yet tested on Proton; the
  earlier test was with the launcher beside Skate.exe.
2026-10-13 15:14:51 -05:00
AyeZeeBB 375605b9fe Launcher: ReSkate lives in a folder of its own, not Steam's skate. folder
Launcher: ReSkate lives in a folder of its own, not Steam's skate. folder
- The launcher refuses to start from a Steam library folder
  (...\steamapps\common\<game>): it shows an error saying to move
  ReSkateLauncher.exe and ReSkate.dll to a new, empty folder, then closes.
  Checked before anything is read or written there. Not under Wine: on
  Proton, Steam starts the launcher from the game's folder.
- The "not in your skate. folder" error no longer tells players to put the
  files beside Skate.exe in Steam's folder; it now says to keep them together
  in a folder of their own.
- README: Getting started says to extract into a new, empty folder, where the
  launcher installs its own copy of the game, so a Steam update cannot break
  it. The Proton section says why it is the one exception.
2026-10-13 15:00:19 -05:00
Jean-Luc T. bf2e883681 Unify multiplayer custom-map download and join deadlines merge
Unify multiplayer custom-map download and join deadlines
2026-10-13 13:41:49 +02:00
Jean-Luc T.andCopilot Autofix powered by AI 573aab4bdb Add cleanup of stale temporary files before download
Remove stale temporary files before downloading.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-10-13 13:41:07 +02:00
copilot-swe-agent[bot]andJean-LucTch 80242c0ec8 Cover deadline boundaries, safe cancellation and fresh join races
Co-authored-by: Jean-LucTch <88255067+Jean-LucTch@users.noreply.github.com>
2026-10-13 11:27:08 +00:00
copilot-swe-agent[bot]andJean-LucTch 8eddcab142 Coordinate custom-map downloads with the multiplayer deadline
Co-authored-by: Jean-LucTch <88255067+Jean-LucTch@users.noreply.github.com>
2026-10-13 11:11:27 +00:00
AyeZeeBB 28118efc27 Objects: other players' objects are ghosts by default, and their card is a visitor's
Objects other players place are spawned locally, so the game took every one
for the local player's own: all were solid, and their card offered the
owner's buttons and named the wrong player.
- Other players' objects are ghosts the skater passes through, as in the
  game's own sessions. Each player's row in the session menu has an
  "Objects: solid / ghost" switch, remembered by Steam ID; a dedicated
  server's own objects (its parks) are solid unless switched off.
  `mp objects-solid <SteamID64|server> on|off` does the same.
- The card's own Disable and Enable on one object stand over that player's
  setting until the setting is changed.
- The card on an object someone else placed no longer offers Edit or
  Delete: the game's "is this mine" and "may this be edited" checks answer
  for who really placed it. It offers Disable instead.
- The card names the owner of the object it is for, read from the card's
  own script, instead of the owner of the object nearest the skater.
- A dedicated server has a player card of its own, "Server", shown on what
  it placed.
Server: the Mods folder is kept when the configuration is reloaded. A park
mod was reported as not being in the Mods folder after a reload.
2026-10-13 03:37:45 -05:00
Belcross 883bdb985f Grind exits: a trigger pressed up to 1 s before a grind counts
The window in which a trigger pressed before the grind connects still
picks the exit side goes from 0.4 s to 1 s. Pressing it as you ollie up
to a rail often came more than 0.4 s before landing on it, and the
trigger was then ignored for that grind. The console's limit goes up to
2 s to match (grindexit prewindow <0-2>).
2026-10-13 08:54:24 +01:00
Belcross 64bfefbf68 Grind exits: pop-out strength slider
A Pop-out strength setting (10-100%, kept) scales the sideways speed of
trigger-set grind exits, for rails next to a wall, where the full exit
carries the skater into it. 100% is the default and exactly the previous
behaviour.

- ReSkate menu: a slider in the GRIND EXITS card, sent when it is let go,
  in steps of 5.
- skate.'s Mod Options and the tools menu: a row stepping 100 / 75 / 50 /
  25%.
- Console: grindexit strength <10-100>; kept in control.txt with the
  other grind exit settings.
- Below 100%, an exit the game was already sending toward the chosen side
  is scaled too, so the setting applies to every trigger-set exit.
2026-10-13 07:59:13 +01:00
AyeZeeBB 30a320ff62 Throwdowns: a grouped line score is no longer cut at its first separator
A Jam Session takes the score of the line just landed from the score HUD's
text, with the script native ParseInt, which is the C library's atoi. atoi
stops at the first character that is not a digit, so a line shown as 5,432
was read as 5 and added 5 to the player's total. Reported for Jam Sessions
and Spot Battles: lines of 5,000 and more adding one or two points.

ParseInt now reads groups of three digits whole, set apart by a comma, a
full stop, an apostrophe or a space: "5,432" is 5432. Text that is not a
grouped number is read exactly as before. The first few grouped scores are
logged, to confirm the cause in play.
2026-10-13 01:14:01 -05:00
AyeZeeBB 180cdc9c85 Objects: the placed-object prompt names who placed the object 2026-10-13 01:04:13 -05:00
AyeZeeBB 0e542fc5a2 Server: kicks can be timed, by a setting and for one kick 2026-10-13 00:58:35 -05:00