Commit Graph
6 Commits
Author SHA1 Message Date
CydandClaude Fable 5 4b25f89e6f Football: every player picks their own team and position
Closes the gap left by the football commit. Members publish their
picks as lobby member data (tm/ps) alongside their loadout, and the
owner publishes the scenario (sc) so members know when the picks
matter. The lobby room turns into a team sheet: each member row shows
their team and position, and MY TEAM / MY POSITION buttons cycle the
local pick and republish it live, so everyone watches the sides fill
out before the host launches.

The egg builder honors explicit picks and only fills gaps:
- pilots who chose a team get it; the rest are spread across the
  host team and one other so the sides stay balanced
- a team with no volunteer runner promotes its first UNPICKED member,
  never overriding someone who chose crusher or blocker
- if two pilots on a team both claim runner, the first keeps it and
  the second lines up
- colors stay derived: runner in the team runner color, everyone else
  in the team color

Verified: a three-pilot egg puts the host on crusher in team color
with an unpicked teammate promoted to runner in runner color, the
other side gets its own runner, and the teams/pilots blocks group
correctly; the lobby room cycles picks and repaints the roster; both
scenarios still pass their single-player regressions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 19:59:42 -05:00
CydandClaude Fable 5 3194d3f973 Martian Football: the second scenario is playable
The setup menu gains a SCENARIO group. Picking Football relayouts the
menu live: the track list swaps to the football-legal set (drops
Paingod Passage and the race build of Freezemoon Freeway, adds the
football build headmf - RPConfig per-scenario invalid lists), the
COLOR and BADGE columns become TEAM and POSITION, and the title
reads MARTIAN FOOTBALL.

The egg builder was restructured around one flat pilot table so both
scenarios share it. Football emits scenario=football, per-pilot team=
and position= entries, and the [teams] / [team::X] / [pilots::X] /
[teambitmap] blocks in RPFootballMission layout (team name bitmaps
generated by the same GDI plasma renderer as pilot names). Colors are
derived rather than chosen, as the arcade did it: the runner wears the
team runner color, crushers and blockers the team color. Multi-pod
games alternate pilots across two teams and give each team exactly one
runner, honoring the host own position pick.

Verified end to end: Football launches from the menu, the engine loads
the football mission (the cockpit shows the RUNNER - GO FOR POINTS
panel), the console marshals it to a scored finish, and the Death Race
path still passes its regression unchanged.

Known gap: lobby members cannot pick their own team or position yet -
the host pick seeds a deterministic assignment.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 19:42:33 -05:00
CydandClaude Fable 5 ff6ec8c56a SteamNetTransport: the Steam wire is implemented and live
Steamworks SDK 1.64 vendored at extern/steamworks_sdk_164 (headers +
win32 redistributables only; .gitignore trims the rest). Both projects
build with RP412_STEAM; activation stays behind the RP412STEAM=1
environment switch, so plain desktop runs never touch Steam.

L4STEAMTRANSPORT.cpp implements NetTransport on ISteamNetworkingSockets
with FakeIP: SteamNetTransport_Install brings up SteamAPI, relay
network access, and a two-port FakeIP identity (fake port 0 = console
channel, 1 = game mesh), then swaps the process wire; any failure logs
the reason and the game carries on over TCP. Addressing keeps the
engine untouched: all pods share the -net port convention, eggs carry
fakeip:engineport, and the transport alone translates engine ports to
Steam fake ports via the lobby-fed peer table (RegisterPeer). Connect
mirrors the TCP retry-while-refused loop; Receive normalizes message
lanes back into the stream semantics CheckBuffers expects.

Runtime verified on this box: RP412STEAM=1 under AppID 480 came up as
169.254.59.52 (fake ports 32256/32257); without Steam credentials it
falls back to TCP cleanly; default boot logs no Steam lines at all.
steam_api.dll ships in the dist.

Next: the lobby layer (ISteamMatchmaking member data -> RegisterPeer +
egg build + RPL4CONSOLE marshal), which needs a second account to test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 20:34:07 -05:00
CydandClaude Fable 5 7315f3488d Two-pod LAN mesh test: multiplayer verified through the seam
tools/two-pod-test.ps1 stands up two -net pods on loopback and
marshals them with a minimal console feeder speaking the Munga
protocol (TeslaSuite vendored Munga Net.dll): state polling, egg
chunk delivery with ACK-after-mesh, RunMission when both pods reach
WaitingForLaunch, StopMission(0) at time expiry, EndMission score
intake.

First run passed clean: pod A listened on its game port, pod B
connected from its bound port, both ACKed after the mesh completed,
raced the same 60s mission on Wiseguy's Wake, stopped on command,
and reported final scores. The deterministic TCP mesh works end to
end through the NetTransport seam - the feeder logic is exactly the
marshal the Steam lobby owner will run in-process.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 20:14:47 -05:00
CydandClaude Fable 5 22421fb418 NetTransport seam: the wire moves behind an interface
The Steam-multiplayer prerequisite from the design doc: L4NET keeps
hosts, message queues, and the deterministic mesh ordering, while
connect/listen/accept/close, send/receive, startup/cleanup, the local
interface list, and ip[:port] parsing move behind NetTransport
(L4NETTRANSPORT.h). WinsockNetTransport carries the existing TCP
behavior over verbatim - including the connect retry-while-refused
loop the egg-ACK ordering relies on - and is the process default;
NetTransport_Set installs a replacement before the network manager
comes up.

L4STEAMTRANSPORT.h documents the ISteamNetworkingSockets mapping
per method (FakeIP keeps [pilots] entries as IPv4 strings) behind
RP412_STEAM until the Steamworks SDK lands.

Also fixed in passing: the ExclusiveBroadcast path sent
sizeof(network_packet) - four bytes of pointer - instead of the
message size, which would have sheared the stream framing had it
ever fired.

Verified: single-player race cycle (menu, race, results, menu, race)
green; -net 8000 boots, listens for a console through the transport,
and idles stable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 19:38:37 -05:00
CydandClaude Fable 5 f842425452 Front-end design notes: TeslaConsole control code analysis + Steam plan
Findings from TeslaConsole.RedPlanet and L4NET: the pod lifecycle
(egg chunks/ACK, RunMission, telemetry, results), the egg as the entire
mission definition (NotationFile text incl. pre-rendered plasma name
bitmaps), the RPConfig.xml catalog, and the key topology finding -
every pod gets the same egg and builds a deterministic full TCP mesh
from the ordered pilots list (connect to earlier entries, listen for
later). Maps 1:1 onto Steam: lobby owner = console, SteamIDs = pilot
addresses, ISteamNetworkingSockets P2P = the mesh, with a NetTransport
seam at L4NET mirroring the RIOBase pattern. Implementation options and
open decisions listed for signoff.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 15:53:34 -05:00