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.
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.
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.
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.
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
A player's recent chat lines show as speech bubbles above their skater: newest nearest the head, older lines stacking upward, each popping in with a slight overshoot before it fades. Emotes render as their images, a message that is nothing but a few emotes shows them jumbo, and a message longer than a handful of lines is cut with an ellipsis so one line can never wall the screen off.
Local display options live under Settings > Interface > Multiplayer (on/off, own messages, distance, duration and how many recent lines stack) and the console gains mp chat-bubbles, chat-bubbles-own, chat-bubbles-distance, chat-bubbles-duration and chat-bubbles-history.
The chat panel and the bubbles now share one rich-text module (chat_rich), and a filtered message keeps its emote names: the bad-word mask is applied, but emote tokens are put back from the original before they are parsed.
Skater slot, menu and throwdown fixes; MY MODS rework; lobby parties
Saved skaters (Extension/Customization, Extension/Skater)
- The selected slot, and slots before it, came up as the standard
skater after a start or map change. The game asks for a slot's saved
outfit once per level, and that happened before the cosmetics catalog
could be read. The first selection now waits for the catalog (60 s at
most), and later map changes check against the catalog already read.
- The retry from abdda77 is removed: the record it wrote to is a
temporary on the game's stack, so it could never work.
Pause menu (Extension/UI/NativeMenu)
- ReSkate's entries stopped working after enough map changes: each
level change took new slots in a fixed table of 1024 for the same
buttons. A button now keeps its slot, and a full table hands out the
slot that has gone longest unused.
Throwdowns (Extension/Throwdowns, Runtime/runtime_init.cpp)
- Multiplayer crashed when someone placed a throwdown after a map
change. The event types are freed with the level but were cached for
the process. They are now cleared when a level is left, checked
before use, and looked for again in each level.
MY MODS (Launcher/gui_mods.cpp, gui.cpp)
- Search, a filter and an order; a switch per mod; a menu per row.
- Multi-select with tick boxes, Shift-click and Ctrl+A, and a bar to
enable, disable, move, update or uninstall everything ticked.
Lobby parties (Extension/Multiplayer/Session)
- A lobby is no longer one party. Its host keeps parties the way a
dedicated server does: invite, accept, join, leave, kick, promote,
open and close, with "/p" party chat. The "Lobby party" switch is
gone. Protocol version unchanged (38).
Mod merge (Engine/Vfs), follow-ups to e715b9b
- Files rewritten into the merged patch are tracked by position, so
another mod's added assets no longer shift the lookup.
- Two mods adding different assets under one name is now noted, with
whose copy the maps get.
- mod_merge_unshift_tests compiles with the launcher tests on.