Commit Graph
240 Commits
Author SHA1 Message Date
AyeZeeBB b229062400 Skater effects on other players: costume and board trails, and contact sparks and dust
Other players' skaters and skateboards showed none of the game's skater
effects: not the trail or fire a costume or deck comes with, and not the
sparks, dust and puffs of a skater touching the world.

Costume and skateboard effects. The game gives another player's skater and
skateboard the right effect sets by itself, but builds them before their
outfit is on, so nothing showed. They are now built again half a second after
the outfit is applied. An always-on effect that a skater's item puts on the
skateboard's wheel joints (the Ghost Skater trail) follows the skater's own
copy of those joints, which only this player's skater keeps up to date: for
other players it is taken out of the skater's sets and built on their
skateboard, which has the same joints.

Contact effects. They come from a skater touching the world, which only
happens in that player's own game. Each game now captures its skater's
contacts (position, velocity, surface normal, surface material) and sends up
to three a tick in a new unreliable packet, PacketKind::effects. Other games
play each through the game's own function, so the effect is still chosen from
the surface and the speed. A contact is shown as late as that player's poses
are, only within 30 m of their skater, and only for a material the level's
table has: the game reads that table without a bound.

Server. A dedicated server relays effects packets to players within 150 m of
the sender, at most one packet a tick from each player. New setting
players.sync_effects (default true), console and admin command
"effects on|off". Off: the server relays none, and the roster tells games
neither to send their contacts nor to build other players' costume and
skateboard effects. Player-hosted lobbies relay through the host and always
share them.

The roster carries one more byte for the setting. Still protocol 45, which
has not been released.

New console command "mp effects": what has been captured and played, and why
the last contact was refused if one was.
2026-10-09 00:10:11 -05:00
AyeZeeBB 574860da72 Binds for first person, the HUD, voice chat, time of day, No Bail, challenges, nametags and dots
Binds for first person, the HUD, voice chat, time of day, No Bail, challenges, nametags and dots

Eight more actions can be put on a keyboard key, a chord or a controller
combo, in the binds list beside the others. None is bound until the player
binds it.

- First person, Hide HUD, Voice chat on / off, Next time of day, No Bail,
  Show / hide challenges, Player nametags, Player dots.
- Each bind runs the console switch for it, so it follows the same rules as
  typing it: No Bail still answers to a server that has it off, and the time
  of day goes to the server for an admin where the server sets it.
- They are one table (action_binds): a bind is its name in the profile, the
  name "bind <name>" takes, its label and its command.
- "bind firstperson|hidehud|voicechat|tod|nobail|challenges|nametags|
  nametagdots <n>" sets one from the console; 0 clears it.
- They are not read while the menu, the console or the chat box is open.

Console, which the binds use and anyone can type:
- Every on/off switch takes "toggle" ("nobail toggle", "hideui toggle").
- "firstperson 0|1", which was only in the menu.
- "tod next": the time of day after the current one.
- "mp voice-chat on|off|toggle": the player's own voice chat, leaving the
  rest of their voice settings; it says which way it went in their chat.
2026-10-08 22:39:05 -05:00
AyeZeeBB 46cf65df0a Server: remove players who have been away too long
Server: remove players who have been away too long

A dedicated server can remove players who are away from their game.

- "afk_kick_minutes" in the config's "players" section: 1 to 1440, or 0
  (the default) for never. "afk-kick <minutes>|off" from the console or an
  admin; a change is saved and applies at once.
- Away is doing nothing a player at their game does: not moving or turning,
  not speaking, not sending chat, and not placing, moving or removing an
  object.
- A minute before the limit the player is told in chat; at the limit they
  are removed with a message saying why and that they can join again. The
  log has an "[afk]" line.
- Admins are never removed for it. The time starts once a player's game has
  loaded the map, and starts over after a map change and when the setting is
  changed.
2026-10-08 22:25:17 -05:00
AyeZeeBB 9ab985e778 Server: object scaling can be turned off
Server: object scaling can be turned off

A dedicated server can stop players resizing the objects they place.

- "allow_object_scaling" in the config's "players" section (default true),
  and "object-scaling on|off" from the console or an admin. A change is
  saved and applies at once.
- Off: the server shares every player's objects at their own size, whatever
  that player's game sent. Admins can still resize theirs, as with the
  object limit.
- The roster tells each game. In the park editor of a player on such a
  server the SCALE mode is not offered, its Y shortcut does nothing, the
  scale box is disabled with a note saying why, and what is placed or edited
  is its own size.
- An object resized before the setting was turned off is its own size for
  everyone else straight away; its owner sees it resized until they edit it.
2026-10-08 22:21:00 -05:00
AyeZeeBB c8c6cf16f2 Launcher: mod overviews show the README, in a larger two-column layout
The overview that opens when a mod is clicked, on both MY MODS and GET MODS,
now shows the mod's README and has more room for it.

README:
- GET MODS fetches a package's README from Thunderstore the first time its
  overview opens (/api/experimental/package/<owner>/<name>/<version>/readme/)
  and keeps it while the launcher runs.
- MY MODS shows the mod's own README.md from its folder, or the package's
  from Thunderstore when the folder has none.
- The markdown is laid out as plain text: headings in bold, lists, rules and
  code blocks kept; links keep their text; images and HTML are dropped; a
  table row shows its cells side by side. A README is cut at 400 lines, with
  a note that the rest is on the mod's page, and one over 512 KB is not read.

Layout:
- The overview is up to 1080 x 740, from 680 x 560.
- The header has a larger icon with the name, the author and the short
  description beside it. An installed mod shows its Thunderstore icon.
- Under the buttons the README has the wide column and the facts (version,
  downloads, updated, size, categories, folder, maps and so on) have a panel
  of their own on the right.
2026-10-08 22:12:48 -05:00
AyeZeeBB 5967124f3a Vote card above chat with rebindable Yes and No; fix full servers breaking on extra slots
Votes on a dedicated server show as a card above chat instead of being
followed through chat lines.

- The card has what is voted on, the Yes and No counts, how many are needed,
  a bar of how far Yes has got, and the seconds left. When the vote ends it
  shows Passed, Failed or Cancelled for four seconds.
- Yes and No are two buttons, labelled with the player's binds. The answer
  given is highlighted and can be changed. They can be clicked whenever the
  cursor is free (chat, menu or console open).
- Two new binds, "Vote yes" and "Vote no", in the binds list: F1 and F2
  unless changed, to keys or controller combos like the others. They are
  read only while a vote is running, and not while typing.
- /yes and /no still work and show on the card. The player a kick vote is
  about sees the card and has no vote in it.
- Console: "mp vote yes|no", "bind voteyes <n>", "bind voteno <n>".

Server:
- The roster carries the running vote (id, kind, tally, seconds left,
  starter, target, label) and the one just finished with how it ended.
- A chat line is no longer sent for each change of the tally; the lines for
  a vote starting and ending stay.

Fix: a dedicated server's roster may list more players than its limit.
The extra slots for reserved players and admins (33 of 32) made a roster the
protocol refused to encode, so with one in use the server logged
"Server error" every pass and stopped part-way through each one until
somebody left. Lobbies hosted by a player are still held to their size.
2026-10-08 21:54:45 -05:00
AyeZeeBBandClaude Opus 5.5 4f92ec0d22 Merge pull request #98 from Vebjorhk: keep the game off EA's online services
Without contrib/ea-watch.ps1, the script for recording what the game connects
to, and without the README line that pointed to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 21:37:42 -05:00
zeex64 5d1c7af6c0 Merge pull request #97 from xThrasherrr/fix/custom-maps-mod-loading
Make mod loading tolerate damaged mods and BOM manifests
2026-10-08 21:33:51 -05:00
zeex64 7cdd2eaede Merge pull request #132 from VexFlint/fix/mesh-tests-direct-join
Build the mesh tests again: their fake transport takes the direct address
2026-10-08 21:31:38 -05:00
AyeZeeBBandClaude Opus 5.5 254af5f303 Merge pull request #130 from ValveTextureFile: record the merge
The change itself went in with 29c4291, which was made as an ordinary commit
and so left the pull request's own commit out of main's history. This merge
adds it, with no change to any file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 21:30:25 -05:00
AyeZeeBBandClaude Opus 5.5 29c42911ff Merge pull request #130: server admin commands in their own file; one update loop
Conflicts in Server/server_host.cpp: main changed the command code after this
branch moved it to Server/server_commands.cpp. The moved copy now has what
main added since: the "chat-color" command, "park random", and its line in
the help text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 21:24:32 -05:00
zeex64 2c90fbec36 Merge pull request #43 from ComputerKWasTaken/codex/random-community-parks
Add random community park loading and launch randomization
2026-10-08 21:20:47 -05:00
zeex64 a243ece725 Merge pull request #33 from JusSkates/true-first-person
Keep the first-person view level and steady; optional third person on foot
2026-10-08 21:09:49 -05:00
zeex64 de90c302d7 Merge branch 'main' into true-first-person 2026-10-08 21:09:41 -05:00
zeex64 63ee53382a Merge pull request #63 from northdroplet/feat/gamepad-touchpad
Launcher: controller support and the Steam Deck trackpad as a mouse
2026-10-08 21:04:34 -05:00
AyeZeeBBandClaude Opus 5.5 a0b4d4c0aa Overlay: the PlayStation pad reader no longer needs the rest of the overlay to link
The reader's input-access counter was defined in input_capture.cpp. Built on
its own, as the launcher's controller support (#63) builds it, the reader
then failed to link with an unresolved overlay_input_access. The counter is
now defined beside the reader; the overlay uses the same one as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 21:02:12 -05:00
VexandClaude Opus 5.5 57c440507a Build the mesh tests again: their fake transport takes the direct address
38d86e1 gave SteamTransport::join a direct IP and port and added
take_direct_notes(), but the fake transport in mesh_tests.cpp kept the old
join and had no take_direct_notes, so the Windows test build failed. The
fake ignores the direct address and has no notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 22:53:11 -03:00
zeex64 30f000f90d Merge pull request #65 from Eplisium/trainer-map-waypoint
Trainer: teleport to the pause-map waypoint, onto the surface there
2026-10-08 20:52:22 -05:00
zeex64 f18b50913b Merge pull request #122 from Swagi-REDACTED/main
Added lots of new binds, allowed keys to be bound for controller back button support.
2026-10-08 20:49:59 -05:00
zeex64 4bfa71e94f Merge branch 'main' into main 2026-10-08 20:49:51 -05:00
zeex64 24762cf135 Merge pull request #100 from VexFlint/docs/linux-proton-client
Document running the game on Linux through Proton
2026-10-08 20:44:42 -05:00
zeex64 1ea7fc1d4a Merge pull request #101 from ComputerKWasTaken/codex/fix-fakie-forward-boost
Fix Forward Boost direction while riding Fakie
2026-10-08 20:44:11 -05:00
zeex64 b8942a16c7 Merge pull request #103 from wildesPepega/pterodactyl-egg
Add a Pterodactyl egg for the Linux dedicated server
2026-10-08 20:43:47 -05:00
AyeZeeBB 0b58163de5 Server: its chat lines in colours the owner chooses; protocol 45
Server: its chat lines in colours the owner chooses; protocol 45

A dedicated server's own lines in chat (its welcome, console messages and
answers) were made violet in #129. The owner can now pick the colours.

- "chat_color": the "Server" badge and name, as "#RRGGBB" (default
  "#8E5CFF", violet).
- "chat_text_color": the text of those lines (default "#D9C8FF", lavender).
- Both are in the config's "server" section; a value that is not a colour
  stops the server from starting and names the setting.
- Console: chat-color <#badge> [<#text>]. Saved, and sent to everyone on
  the server, so the next line uses it.
- With the defaults, chat looks as it did.

The colours travel in the roster, so this is protocol 45: servers and
games must both update. Lobbies hosted by a player are unchanged.
2026-10-08 20:42:51 -05:00
zeex64 e57bae499a Merge pull request #105 from lennyblk/main
Name the file and the reason when cannot open it for SHA-256 on Linux
2026-10-08 20:42:27 -05:00
zeex64 c434558a66 Merge pull request #111 from AlexanderPuglisi/fix/log-steam-offline-reason
Launcher: log why Steam counts as offline
2026-10-08 20:42:05 -05:00
zeex64 8d21a19b18 Merge pull request #131 from wilu222/board-wear-persist
Persist the board wear toggle across map changes and restarts
2026-10-08 20:38:39 -05:00
zeex64 8fe9964f73 Merge pull request #129 from moelrobi/claude/compassionate-heisenberg-ekazit
Chat: highlight server messages in violet
2026-10-08 20:34:48 -05:00
vtf fbb76133c9 server: admin commands in their own file; one update loop for both platforms. 2026-10-08 21:00:09 -04:00
wilu222 73e71a1be6 Keep the board wear toggle on across map changes and restarts 2026-10-08 20:54:47 -04:00
Robin MöllerandClaude Opus 5.5 bc21311ccf Chat: server lines stand out in violet
A dedicated server's own chat lines (its console, welcome message and
answers to this player) get a violet "Server" badge and name and
lavender text, in the open chat and the fading lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzTrhiZ2cNYyJgMHqTp1kf
2026-10-09 00:07:58 +00:00
AyeZeeBB f13995dfe8 Fix players freezing on dedicated servers; reserved slots are extra slots; bone scale limit 2
Fix players freezing on dedicated servers; reserved slots are extra slots; bone scale limit 2

Players stopping and jumping (1.1.6):
- The new sound messages begin with the same four bytes ("RMS1") as the
  pose updates games send each other over their direct links. The game
  took those pose updates for sound and discarded them, so a directly
  linked player moved only when a whole state arrived.
- Game: only messages from the dedicated server are read as its sound,
  pose or acknowledgement messages; anything from another player is
  decoded as what it is.
- Server: poses and sound go through the server to every player, whether
  or not two games have linked to each other. This fixes games still on
  1.1.6 without an update, at the cost of more outbound on small servers.

Reserved slots:
- "reserved_players_slots" no longer holds slots back. Anyone joins until
  max_players are on; the listed players and the admins can still join
  after that, each adding one slot beyond the limit (33/32 and so on).
- An admin who is also listed counts once, and the total never exceeds
  what a session can hold.
- The list holds up to 1024 players again. "reserved" in the console shows
  how many extra slots there are.

Server:
- "bone_scale_limit" is 2 by default. The game's own skater height is a
  bone scale, so 1 showed everyone at one height. A config that already
  has 1 written in it keeps it until changed.
v1.1.8
2026-10-08 17:12:41 -05:00
AyeZeeBB 2833ab1f88 config in sections
Server config:
- Written in sections, in reading order: server, access, maps, players,
  anti_cheat, network, votes. A config from an older version, flat and
  under older names, is read as it is and written back this way on first
  start; only settings that are really new are reported as new.
- Renamed: no_bail, noclip, boosts, parties, voice_chat to allow_*;
  global_bans to use_global_bans; welcome to welcome_message; speed_check
  to speed_hack; score_check to modified_scoring; score_allow to
  allowed_scoring_mods; map_pool and map_rotation_minutes to maps.pool and
  maps.rotation_minutes. Console and admin commands are unchanged.
- Bans are kept in data/bans.json beside the config. A config that holds
  them has them moved there; a bans file that cannot be read stops the
  server from starting.
- Reserved slots are one list, "reserved_players_slots": a slot is kept
  for each listed player who is not on. "reserved_slots" and the
  "reserved slots <n>" command are gone; admins may take a kept slot but
  none is kept for them.
- "tps" is no longer in the file: dedicated servers run at 20.
- "bone_scale_limit" is 1 by default: resized body parts are off unless a
  server allows them.
- New: "pack_ms" (10), how long Steam may hold a message to pack it with
  others; "finger_distance" (25); "steam_debug", which logs what Steam's
  networking says, for connection faults.
v1.1.7
2026-10-08 16:18:29 -05:00
Swagi-REDACTED b5d511fda2 Delete patch11.py 2026-10-08 13:48:42 -04:00
Swagi-Redacted 94e4df12ba Sync latest bind changes, added freecam bind, tp to freecam bind, and off board up boost 2026-10-08 13:40:35 -04:00
NorthDroplet f66c1e74db Launcher: the focus goes back to the mod after an install instead of the window buttons 2026-10-08 08:12:37 +00:00
NorthDroplet 93ff021d7e Launcher: the trackpad pointer measures from where the stick rests, so it does not creep 2026-10-08 08:04:48 +00:00
NorthDroplet 7a34ead2d5 Launcher: steadier trackpad pointer and list navigation
- The trackpad pointer follows the whole swipe; Steam stops the tilt when
  the thumb lifts, so nothing has to be cut off.
- Up and down stay inside the mod lists and leave a row from any of its
  parts (tick, switch, buttons) in one press.
- Left from anywhere in a list reaches the nearest rail tile, BACK included.
- The focus no longer falls back to a tab when ImGui lets go of a row the
  list only partly shows.
2026-10-08 07:21:05 +00:00
AyeZeeBB 38d86e1b72 New pose and sound formats for dedicated servers; direct connections; protocol 44
Poses and skater sound between a dedicated server and its players use new
formats. Lobbies and the links between games are unchanged.

Poses (pose_codec.h, pose_batch.h):
- A pose is rounded once (rotations to 0.08 degrees, positions to a
  millimetre) and sent as its differences from a pose of the same player
  the receiver has acknowledged. Several players' poses share one message.
- The receiver acknowledges messages once a tick; the sender builds only on
  acknowledged poses, or on the whole pose it sent reliably. Loss costs the
  poses in that packet and nothing more.
- Fingers are not sent to players further than "finger_distance" (25 m).
- Games upload their own poses the same way, and the server acknowledges.
- About 300 B a pose at full rate against about 660 B before.
- The server no longer rounds rotations by distance: it saved little.

Sound (sound_codec.h):
- Each sample is sent as what changed since the one before, numbers rounded
  to 1/1024. One reliable message a tick carries every skater a player can
  hear. A stream is sent whole at its start and every two seconds.
- About 106 B a message against 368 B before, on a recording of real play.

Direct connections:
- "connection": "relay" (default) or "direct", with "direct_address" and
  "direct_port". A direct server listens on UDP and is listed with its
  address; players still sign in through Steam.
- Games connect straight to servers that offer it and fall back to the
  relays after 5 s. Setting and "mp direct-connections" to turn it off.

Server:
- "bone_scale_limit" is 1 by default: resized body parts are off unless a
  server allows them.
- Logs Steam's relay network status at start-up and in "net", and watches
  the Steam sign-in.
- "pack_ms" (10): how long Steam may hold a message to pack it with others.
- "steam_debug": logs what Steam's networking says, for connection faults.
- "relay_everything": sends poses and sound through the server even between
  games that have linked, for testing with few players.
- "net" shows pose sizes by rate, the share sent without fingers, and whole
  poses sent.

Game:
- Only ReSkate's nametags are shown; the game's own are removed.
- "mp pose-dump <seconds>" records the local skater's poses and sound.

Tests: pose_codec_tests covers exact round trips, chains of differences,
held fingers, damaged input, the sender and receiver over a link that
delays, loses and reorders, and the sound format; with a recording as its
argument it prints sizes on real play.

Protocol 44: servers and games must both update.
2026-10-07 23:10:13 -05:00
AyeZeeBB 98e07f6899 Server: resized body parts are off unless a server allows them
- bone_scale_limit defaults to 1: every skater shows at the game's own
  proportions. A server that wants "big head" mods and the like to show
  sets a higher limit, or "bone-scale off"
v1.1.6
2026-10-07 19:46:23 -05:00
AyeZeeBB 91c939ea4f Server: limit how far a mod may resize part of a skater for other players
- bone_scale_limit in ReSkateServer.json, and the bone-scale command:
  the most a bone may be scaled in the poses the server passes on, 1 to
  8, and its inverse the least. 1 shows every skater at the game's own
  proportions; 0 (the default, "bone-scale off") is no limit
- A "big head" mod sets one joint's scale in the body's bind pose
  (animation/dingo/cas_rsp_body_bind, the head from 1 to 4). The game
  applies it to the bone, and the bone's scale travels in every pose,
  which is how players without the mod see it. The game's own skeleton
  has no scaled joint, so 1 changes nothing for anyone else
- The player with the mod still sees it on their own screen: the server
  decides only what the others are sent
- Changing it sends whole states again, so nobody keeps a reference
  with the old sizes in it
- Dedicated servers only; a lobby's host has no such setting
2026-10-07 19:42:48 -05:00
AlexandeeerandClaude Opus 5.5 6edb666011 Launcher: log why Steam counts as offline
ReSkate.log only said "Steam is not running or not signed in", even with
Steam open and signed in. steam_offline_reason() names the check that
failed (ActiveProcess pid or ActiveUser is 0, the process cannot be
opened or identified, has exited, or is not steam.exe) and start_game
appends it to that line. steam_signed_in() behaves as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VNYF3aYa2q3MkFXc5xYnDd
2026-10-08 00:30:52 +02:00
AyeZeeBB 7ee82b2771 Player distance and nametag settings; far players sent less and more coarsely; profiler addresses
Game
- Player distance (Settings > Interface, "player-distance"): how far
  away another player is still built as a skater, 50 to 1000 m, default
  120. Past it they keep their nametag or dot. All the way up shows
  everyone. A player already shown stays until 15% further out, so one
  skating along the edge is not built and taken down over and over. The
  game ran a full skater for every player on the server wherever they
  were, which is most of a frame on a full one
- Nametags are always ReSkate's own. The "ReSkate nametags" toggle, the
  "Nametag style" button and the nametag-style command are gone; the
  game's own nametags are never shown
- Nametag distance ("nametag-distance"): how far away a name still
  shows before it becomes a dot, 10 to 500 m. Default 120, was a fixed
  150, so by default the name and the skater go at the same distance
- Nametag dots ("nametag-dots"): off hides the dots for far players and
  the ones at the screen's edge for players off screen
- Friends' nametags only ("nametags-friends"): only Steam friends get a
  name or dot; chat bubbles still show for everyone

Server
- A player out of sight of another (half as far again as the low rate
  starts, 255 m by default) is sent to them once a second instead of
  five times. On a full server most players are out of each other's
  sight, and at five a second each they were most of what was sent
- Rotations are rounded before a pose is passed on, more coarsely the
  further away the recipient is: 0.04 degrees within the full rate's
  reach, 0.16 within the half rate's, a third of a degree past that,
  about 5 degrees out of sight. The pose is still an ordinary one. A
  bone that turned by less than a step is the same bytes as before, so
  the difference from the reference leaves it out, and the low bits of
  the ones that did turn pack away. By distance only: a player the
  crowd limit slowed keeps the fine rotations
- A recipient crossing from one precision to another is sent a whole
  state of that player, since a difference from a reference of another
  precision would carry every bone again
- "net" shows the size of the poses sent at each precision

Profiler
- A function in ReSkate.dll is reported by its address when the DLL has
  no symbols. A release build named every one of ours as the nearest of
  three exports, so a report could not say which was slow; the
  release's symbols name the address afterwards
2026-10-07 16:43:18 -05:00
AyeZeeBB d04920c793 Server: the nearest players always at the full rate; whole states once a minute; relay routes in net
- The crowd limit always sends a player the nearest 8 others at the
  full rate and the next 12 at ten a second, whatever the budget. It
  gave everyone the low rate first and the nearest what was left, and
  with enough players on (about 120 at the default budget, fewer at a
  lower one) nothing was left: nobody was at the full rate, and since a
  skater's sound follows the full rate, nobody was heard either
- Whole pose and sound states are sent every minute instead of every 8
  seconds. A whole pose measured 3.7 KB against 0.7 KB for a difference
  from one, however old the reference, and at every 8 seconds they were
  about a seventh of what a busy server sent
- "net" lists which of Steam's relay locations the connections go
  through, and "net <player>" that player's: Steam reports pings of
  several hundred ms on a server measured at 55-84 ms directly, and
  this says which way the route went
2026-10-07 16:02:26 -05:00
NorthDroplet 7b093429a2 Launcher: controller starts on PLAY and the open tab; rows and side moves in lists
- The focus starts on PLAY when the launcher opens with a pad connected, and
  on the open tab (GAME, MY MODS) when the pad opens Settings or the Mod
  manager.
- List rows act as one item: up and down go from row to row in one press,
  and a row's buttons take the focus only from the row (D-pad right).
- D-pad left and right between the rail and a list: ImGui looks to the side
  only along a thin band through the focus and missed items level with the
  gap between two rows, so a side move that finds nothing looks again across
  the focus's full height.
- The left stick scrolls the panel under the pointer directly instead of
  through wheel events, which queued behind the pointer's moves.
- On a Steam Deck (SteamDeck=1) the right stick gets a trackpad's feel: small
  swipes move the pointer, and the glide after the thumb lifts is cut.
2026-10-07 20:57:08 +00:00
AyeZeeBB d540b88640 Dedicated servers run at 20 TPS; still players at the low rate; message commands in the "/" menu
Server
- Dedicated servers run at 20 network updates a second, fixed for now:
  whatever tps says in ReSkateServer.json is read as 20, and the tps
  command no longer changes it. A busy server's traffic, in and out, is
  its players' poses, and 20 a second is a third less than 30. Lobbies
  keep their own choice
- A player who has not moved or turned for three seconds is sent on at
  five poses a second; the full rate is back with their first movement
- "net" shows what a pose costs as sent, and what it would cost against
  a reference renewed every second, every quarter second, and against
  the pose before, measured on every fourth pose that arrives. It only
  measures: a nearer reference packs smaller, and this says by how much
  before the server is made to send them that way
Game
- The "/" menu on a dedicated server lists /w for everyone, and /msg,
  /msg-party and /msg-admins for admins. The server already answered
  them; the menu is the game's own list and never had them
v1.1.5
2026-10-07 15:27:05 -05:00
AyeZeeBB 737c1611af Server: only change to a map the server has
- The map command, from the console or an admin, refuses a map the
  server does not have: the game's own maps are always allowed, a
  custom one only when its mod folder is in the server's Mods. It
  accepted any level path before, so a server could move everyone to a
  map it had no mod for
- A map setting in ReSkateServer.json that names a map the server does
  not have now stops the server at start, saying to add the map's mod
  or change the map
- The map change itself checks too, whatever asks for it. Votes,
  rotation and the map pool were already limited to known maps
2026-10-07 15:16:53 -05:00
AyeZeeBB 7050fad406 Launcher: trucks back on MODS; Thunderstore button reads as a link out
- The MODS tile shows the skate tool again, faded like the wheel on
  SETTINGS. Thunderstore's mark is no longer drawn there
- The mod manager's Thunderstore button is laid out as a link sign, the
  name, then Thunderstore's mark at the far end, so it is plainly a way
  out to a website. The sign is drawn (a box with an arrow leaving its
  corner); the name is no longer in capitals
- It keeps Thunderstore's green on its dark blue and its height
2026-10-07 15:12:35 -05:00
AyeZeeBB 56b687b058 Launcher: Thunderstore's mark on MODS and its button; ask about enabled mods' updates only
- The MODS tile shows Thunderstore's mark in its own green instead of
  the skate tool, which stays as the fallback when the mark is not
  built in
- "Open Thunderstore" in the mod manager is a branded button: the mark
  and name in Thunderstore green on its dark blue, taller than the
  plain buttons beside it
- The mark is a new asset, assets/launcher/icon_thunderstore.png,
  embedded like the other tile icons
- A disabled mod's update is no longer asked about before PLAY or
  counted on the MODS tile, and "UPDATE AND PLAY" no longer installs
  it. A disabled mod does not load, so its update stays on the Mods
  page, where it can still be updated by choice
2026-10-07 15:01:55 -05:00
AyeZeeBB c98c3f3207 Keep busy dedicated servers playable; hold stale skaters instead of rebuilding them
No protocol change: a server built from this still takes 1.1.4 players.

Server: what each player is sent
- A crowd limit: each player is sent at most crowd_budget poses a second
  (default 600, 0 for none; "crowd <n>|off"). Everyone at 5 a second at
  least, the nearest at the full rate, the next nearest at 10. Before,
  everyone within full-rate distance was sent at the full rate, which a
  crowd of 40 turned into more than a connection carries
- A skater's sound goes only to players within the full-rate distance,
  and in a crowd only from the nearest; it went to everyone
- A player who joins, or arrives after a map change, is shown the others
  about seven a second, nearest first, and none while what they were
  already sent is still on its way. Before, every outfit and every
  stream went at once (and to everyone at once after a map change)
- Whole pose and sound states every 8 seconds instead of 2, on the
  source's own clock, and slower pose rates sent on that clock too, so
  recipients share one patch and compression (DeltaCache) instead of one
  each. The settings survive a map change
- Object updates wait for a connection that is behind

Server: Steam connections
- send_rate (default 900 KB/s, "rate <KB/s>") is set as both Steam's
  minimum and maximum, for open connections and each new one. With only
  the maximum raised a connection stayed at Steam's 256 KB/s; set high,
  what was lost was resent until the connection was full of resends
  (about 1.1 MB/s reaches a player through the relays)
- A 4 MB send buffer, and a refused must-arrive message no longer ends
  the player's session at once: 15 seconds of refusals do (30 for object
  updates). A full queue used to drop everyone who was behind together

Server: seeing what is going on
- "net [player]": every connection's ping, delivery, queue and rate, the
  traffic by kind (poses, sound, voice, outfits, objects), who uploads
  most, and how busy the server's loop is
- A [network] line in the log every minute
- A leave or failed join says how it ended: closed by the player's game
  with Steam's reason, connection lost, or closed by the server and why
- The queue time no longer prints Steam's "unknown" as a number

Server: other
- Reserved slots: reserved_slots and reserved in ReSkateServer.json, and
  the "reserved" command; admins always have one
- The speed check flags a game at about 1.5x and over (was 1.06x), and
  tells only that player; for the admins it is in the log

Game
- A remote skater with no pose for a second stays where it was for up to
  eight seconds instead of being destroyed and rebuilt three seconds
  later. On a busy server one slow frame did that to many players at
  once, and the rebuilding made the next frames slower still
- Every waiting message is read each frame (at most 128 were)
- On an official server the role tags (Dev, Staff, Homie, Creator) show
  for every player, not only the few the game is connected to directly;
  community servers keep the old rule
- The server browser searches Steam at most every 15 seconds (45 after an
  empty answer) and keeps the last list for 15 minutes when Steam returns
  nothing, up from 2
- The game's own connections send at up to 900 KB/s
2026-10-07 14:43:45 -05:00