Skip to content

Universal Armor Menu and Sync Between Players - #345

Closed
jcompto95-tech wants to merge 2 commits into
OpenCommunityEdition:mainfrom
jcompto95-tech:armor-menu
Closed

jcompto95-tech wants to merge 2 commits into
OpenCommunityEdition:mainfrom
jcompto95-tech:armor-menu

Conversation

@jcompto95-tech

Copy link
Copy Markdown

Armor menu, with every choice synced between players

Adds ARMOR as the first button of every pause menu (multiplayer, co-op and
campaign). It holds:

  • Armor Color
  • Armor Lights
  • Visor Color
  • Show Players Custom Armor and Show Players Custom Flashlights
  • Reset to Classic

Everything is Classic (the stock look) by default, and both Show switches
start off.

Full customization sync

Every choice in the menu syncs between players (armor, lights, visor,
flashlight and shield), in the lobby and mid-match, in multiplayer and
co-op. If you change your look from the pause menu mid-game, the other
players see it within a few seconds.

How it works (armor_sync.c, two new message kinds, 91 and 92):

  1. Each machine sends its choices to the host, one byte each, when they
    differ from what the host has for it.
  2. The host keeps one table of every machine's choices. It sends that
    table to everyone when it changes, immediately to anyone who joins or
    finishes loading the map, and every 10 seconds as a backstop.
  3. Each machine draws the other players' Spartans from the table, but only
    if its own Show Players Custom Armor switch is on. Otherwise everyone
    else looks stock.

Team games keep the team colors for armor. Lights, visor, flashlight and
shield still apply.

Safety

  • Validated input: the host accepts a machine's choices only from that
    machine's own connection, only valid color indices, and at most once a
    second. Clients check every value in the table they receive.
  • No stale looks: the host clears a departed player's row, so a new
    player in that slot doesn't inherit the old look.
  • Small messages: the table only covers occupied player slots, about
    90 bytes for a 16-player game.
  • Drawing only: nothing in the game state changes. With nothing chosen,
    no work is done for any object.
  • Older builds: they ignore the new message kinds, so the network
    version is unchanged.

Supersedes the visor color and shield color sync PRs.

Checked

  • Every changed file compiles on Linux; menu and wire-format tests pass.
  • armor_sync.c tested against a fake network with sanitizers: valid and
    corrupt messages, rate limit, join, leave, game end.
  • Not yet tested between two machines.

jcompto95-tech and others added 2 commits October 13, 2026 20:02
…with Show Custom Visors (off)

Video Setup > FOV and Viewmodels gets VISOR COLOR (display.visor_color,
default: the gold) and SHOW CUSTOM VISORS (display.others_visor_colors, off
by default: the others' gold, as stock). The visor is recolored as it is
drawn ("characters\cyborg\shaders\visor" and the multiplayer cyborg's, found
by their tags): each of its passes in the chosen color at the pass's own
brightness (d3d8_gl_set_recolor, a pixel shader key bit), its light and
reflections alike; black curves the brightness down steeply, a deep glossy
black as an ODST's. In multiplayer your own players' visors, kept on their
bodies once dead; in a campaign every Spartan's, so a cutscene's Master
Chief has it too. No new assets.

In a network game each machine sends its color to the host reliably while
the host has another for it; the host takes it only from that machine's own
stream, and only an armor color's index or none, and sends every machine's
to each machine reliably when one changes and every ten seconds, in the
lobby and in the game, taken before the checks that a game is running as
voice chat's are. Builds without it drop both new kinds (91 and 92, clear of
the kinds the text chat and vote-ban pull requests take) as unknown, so the
network version is unchanged; network_format.txt records them. Nothing the
game already sends changes: the network player's fields are untouched (the
shield color's icon_index is the player colors pull request's).

Checked: the changed units compile with the Linux build's flags (and with
implicit declarations warned), the declarations visor_color.c makes match
their definitions (the web build's link checks them); menus regenerated,
only FOV and Viewmodels changed; test_menu_settings_exist and
test_config_has_each_section_once pass; the wire format is the one recorded.
Not built in full here (no 32-bit libraries) and not yet played in a
network game.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015jtk9vPUKbWd48oBMzXuzd
…flashlight and shield colors, synced in multiplayer and co-op

ARMOR is the first button of the pause menu of multiplayer, co-op and a
campaign. It holds Armor Color (the multiplayer colors and Blackout),
Armor Lights, Visor Color, Flashlight and Shield Color, each Classic (the
game's own) by default; Show Players Custom Armor and Show Players Custom
Flashlights (both off); and RESET TO CLASSIC. Visor Color and Shield Color
move there from FOV and Viewmodels, and Show Players Custom Armor takes the
place of Show Custom Visors.

spartan_colors.c draws each Spartan (a biped of the Spartan's model) as its
player chose: the change colors of its body and first-person arms; Blackout
drawn black by the pixel shader with its reflection dimmed; the lights drawn
by the pixel shader as LEDs (d3d8_gl_set_glow), bloomed over the view before
the HUD where they are seen (halo_screen_light_bloom; not in the ES builds),
with a faint light on each knee; the flashlight's color. Cutscenes' Master
Chief too. Only the drawing changes: nothing of the game's state. With
nothing chosen and no one else's shown, nothing is looked up for any object.

One table carries every choice (armor_sync.c, kinds 91 and 92, in place of
the visor's own): each machine sends its armor, lights, flashlight, shield
and visor choices to the host while the host has others for it (every three
seconds at most), and the host sends the table to every machine when it
changes (half a second apart at the soonest), to a machine as soon as it is
in the game and has not had it, and every ten seconds; in the lobby and
mid-game, in multiplayer and co-op, so a change in the pause menu reaches
the others within seconds. The host takes a machine's choices only from its
own stream, in the lobby too (network_server_message_handler.c), only
indices in range, and a change at most once a second; it clears the row of a
machine that leaves, so another in its slot does not show them; it sends
only the rows up to the last machine in the game (five bytes each). A client
checks the table's indices as it reads them. Builds without the kinds drop
them as unknown, so the network version is unchanged. Others are drawn as
they chose only with Show Players Custom Armor; a team game keeps the teams'
armor colors, the rest still applies. The shield glow takes the color the
flare is drawn in.

The pause box gets a frame for multiplayer's five buttons and one for a
campaign's six rows (the redraw's box, from port_settings.py). Co-op's
pause menu, a campaign's, gets ARMOR and SETTINGS too.

Checked: the changed files compile (Linux); the menus regenerate; the menu
and wire format tests pass; armor_sync.c compiled natively against a fake
network under AddressSanitizer and UBSan: a host and a client, valid and
corrupt choices and tables (out of range, short, oversized, not from the
stream, from a machine that is not the host), the rate limit, a newcomer, a
machine leaving, the game ending (each check fails with its fault put back
in). The armor shader and model names are the same in the campaign's and
multiplayer's maps. Not yet run between two machines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015jtk9vPUKbWd48oBMzXuzd
@jcompto95-tech jcompto95-tech changed the title Universal Armor Menu Universal Armor Menu and Sync Between Players Oct 14, 2026
@VerySmuggy VerySmuggy added enhancement New feature or request priority: low Nice to have / when time allows labels Oct 19, 2026
@cybersecurity

Copy link
Copy Markdown
Collaborator

New messages with no network version bump, and an ARMOR button always added to every pause menu.

FractumSeraph pushed a commit to FractumSeraph/OpenCE that referenced this pull request Oct 20, 2026
…stall-defaults

New-install defaults: 2x multisampling, 256 shadows, Android audio buffer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request priority: low Nice to have / when time allows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants