Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
148 commits
Select commit Hold shift + click to select a range
231069d
Trace the shared traffic on every machine for desync measurements
lowlevelmetal Oct 9, 2026
80b8b8e
Trace every player's car as each machine draws it, and measure the di…
lowlevelmetal Oct 9, 2026
48d1a70
Let a car's simulation be saved, put back and run again on its own
lowlevelmetal Oct 9, 2026
2c8679c
Show the shared traffic at the client car's time, predicted along its…
lowlevelmetal Oct 9, 2026
5f2f10d
Carry the players' inputs to the host and its car states back
lowlevelmetal Oct 9, 2026
0ab89fe
Let the host run a network race's props for everyone
lowlevelmetal Oct 9, 2026
28683d3
Add mm2tool nettrace to measure the shared traffic's divergence
lowlevelmetal Oct 9, 2026
9cbb2d6
Let a client's car meet the host's flying props, and test the props' …
lowlevelmetal Oct 9, 2026
e6802c2
Let a client's car knock traffic loose at once, and predict cars by t…
lowlevelmetal Oct 9, 2026
8af6833
Share a knocked car's body that stands still as standing
lowlevelmetal Oct 9, 2026
de11039
Let only the host's copies of network cars break props
lowlevelmetal Oct 9, 2026
6d2bde6
Measure the second after a hit in mm2tool nettrace
lowlevelmetal Oct 9, 2026
2a97bb0
Keep the shared cars a client has when they do not all fit
lowlevelmetal Oct 9, 2026
217db24
Choose the shared cars that fit by their usual cost, not this message's
lowlevelmetal Oct 9, 2026
609a455
Give a prop what a car of the network car's mass would
lowlevelmetal Oct 9, 2026
30130da
Test that a big crash's props stay within one datagram
lowlevelmetal Oct 9, 2026
7593b19
Give the moving police cars' error in mm2tool nettrace
lowlevelmetal Oct 9, 2026
24dbd3d
Drive, queue and predict the players' cars one sample at a time
lowlevelmetal Oct 9, 2026
3f73059
Let the host simulate every player's car from its player's inputs
lowlevelmetal Oct 9, 2026
3292ac5
Keep the props' code and tests clear of MSVC's pitfalls
lowlevelmetal Oct 9, 2026
b3253f7
Document the host's props of a network race
lowlevelmetal Oct 9, 2026
a61f982
Document the shared traffic's prediction and the client's own knocks
lowlevelmetal Oct 9, 2026
9d0d8f6
Merge integration (the host simulates every player's car) into the props
lowlevelmetal Oct 9, 2026
bbf464c
Merge integration (the host simulates every player's car)
lowlevelmetal Oct 9, 2026
bb00328
Keep a tenth of the traffic budget for the cars a client has
lowlevelmetal Oct 9, 2026
753c12b
Show the shared traffic where the host will simulate the client's car
lowlevelmetal Oct 9, 2026
19e8271
Run a client's corrected samples against the other cars where they stood
lowlevelmetal Oct 9, 2026
ee48adc
Trace the props in OPENMM2_NET_TRACE and report them in syncreport
lowlevelmetal Oct 9, 2026
0791996
Let a replayed car meet the props with their mass
lowlevelmetal Oct 9, 2026
df5c7cf
Keep a car the client knocked loose until it comes to rest
lowlevelmetal Oct 9, 2026
8e1fafd
Trace every simulated car's damaging impacts, by car
lowlevelmetal Oct 9, 2026
4eb99e9
Test that only the host's knocks count, and document the merged props
lowlevelmetal Oct 9, 2026
276e508
Let the host alone decide Cops and Robbers' time and point limits
lowlevelmetal Oct 9, 2026
438fd01
Let a car the client knocked loose knock the next one loose
lowlevelmetal Oct 9, 2026
6764d4d
Keep a client's own pieces from moving the host's
lowlevelmetal Oct 9, 2026
921513d
Add a development hook that rounds a client's car differently
lowlevelmetal Oct 9, 2026
b01172e
Hand a knocked car back to the host's messages 3 m apart, not 5
lowlevelmetal Oct 9, 2026
71d9738
Record the props and damage desync work
lowlevelmetal Oct 9, 2026
e994720
Record the shared traffic's desync review
lowlevelmetal Oct 9, 2026
6c859c3
Bring the shared traffic's parity rows up to date
lowlevelmetal Oct 9, 2026
20c0030
Note protocol 6 in the multiplayer docs
lowlevelmetal Oct 9, 2026
127ac41
Let the host drop a client's inputs that piled up while it was busy
lowlevelmetal Oct 9, 2026
65733d3
Log what a network client's corrections cost
lowlevelmetal Oct 9, 2026
f92979f
Record the players' cars' desync and the host-authoritative cars
lowlevelmetal Oct 9, 2026
52aa601
List the network and interpolation files in the parity manifest
lowlevelmetal Oct 9, 2026
c48e3c6
Merge branch 'integration' into worktree-agent-aa20eb5f47fb73251
lowlevelmetal Oct 9, 2026
ecd675c
Keep the props' lines within 110 columns
lowlevelmetal Oct 9, 2026
235fe54
Merge integration (the shared traffic's desync work) into the props
lowlevelmetal Oct 9, 2026
c367288
Run a client's corrected samples against every body where it stood
lowlevelmetal Oct 9, 2026
784b3b1
Let a client's replay take the knocks its car really took
lowlevelmetal Oct 9, 2026
5e68aff
Test a replay just after a knock, and document the replays' props
lowlevelmetal Oct 9, 2026
cae6989
Record the final runs of the host-authoritative players' cars
lowlevelmetal Oct 9, 2026
6bfda02
Merge integration (the players' cars' final work) into the props
lowlevelmetal Oct 9, 2026
7766963
Test that a replay knocks and moves no prop for real
lowlevelmetal Oct 9, 2026
f1f3b56
Let a client's predicted pieces knock other props only while young
lowlevelmetal Oct 9, 2026
b06bba6
Document the client's chain knocks
lowlevelmetal Oct 9, 2026
c5c1b4c
Let a client simulate the players' cars near its own with it
lowlevelmetal Oct 9, 2026
51c9f89
Run a car's checkpoints through a tracker the host can share
lowlevelmetal Oct 9, 2026
6731eea
Decide a network race's rules on the host and correct the clients
lowlevelmetal Oct 9, 2026
9ab7293
Let the host decide every network race's rules (protocol 8)
lowlevelmetal Oct 9, 2026
59ca116
Let a client's replay meet a knocked prop's pieces after the knock
lowlevelmetal Oct 9, 2026
94d542a
Keep the players' cars in player order and run far ones again alone
lowlevelmetal Oct 9, 2026
c7e1cb1
Report how far apart the screens are once their delay is taken out
lowlevelmetal Oct 9, 2026
fb5dfb5
Record the props' final runs
lowlevelmetal Oct 9, 2026
8185a2e
Test the host's rules, a client's corrections and the rules message
lowlevelmetal Oct 9, 2026
78886cf
Let the host reset a client's car only where the game's rules do
lowlevelmetal Oct 9, 2026
38fcf08
Carry what a car's sample hands the next with its state
lowlevelmetal Oct 9, 2026
3f3d5e7
Record the props' final checks
lowlevelmetal Oct 9, 2026
14dc206
List the host-run props' files in the parity manifest
lowlevelmetal Oct 9, 2026
968a428
Report how far the machines agree on a network race's rules
lowlevelmetal Oct 9, 2026
e51e9bf
Run a client's corrected samples against the traffic where it was then
lowlevelmetal Oct 9, 2026
14854c3
Merge integration (the host's props, protocol 7)
lowlevelmetal Oct 9, 2026
4dfe65d
Merge branch 'integration' into worktree-agent-a21adb9f783eb40d3
lowlevelmetal Oct 9, 2026
619ce6f
Keep the player's impact callback under the autopilot
lowlevelmetal Oct 10, 2026
4128b00
Refuse a respawn at a checkpoint the host never counted
lowlevelmetal Oct 10, 2026
760c8b0
Check every gold event against the host's simulation in the report
lowlevelmetal Oct 10, 2026
1493217
End a race still counting down when the host times it out
lowlevelmetal Oct 10, 2026
dd41ea6
Keep a race this machine ended stopped through the host's word
lowlevelmetal Oct 10, 2026
60ddfd0
Run a client's corrected samples against the traffic where each sampl…
lowlevelmetal Oct 10, 2026
12fe633
Wrap two long lines
lowlevelmetal Oct 10, 2026
8c0a8d1
Test the rail cars standing elsewhere for a replay
lowlevelmetal Oct 10, 2026
657a493
Tell the report which counted hits a HUD shows
lowlevelmetal Oct 10, 2026
baf989a
Let automated Cops and Robbers runs draw the same first places
lowlevelmetal Oct 10, 2026
156908f
Count corrections a minute of the whole race
lowlevelmetal Oct 10, 2026
4ac627b
Let a client wait for the host when the gold is contested
lowlevelmetal Oct 10, 2026
04112e1
Record the second round of the players' cars' desync
lowlevelmetal Oct 10, 2026
d3ba498
Record the host's rules in the session audit and the cars review
lowlevelmetal Oct 10, 2026
b80cce3
Merge branch 'integration' into worktree-agent-a21adb9f783eb40d3
lowlevelmetal Oct 10, 2026
957374c
Wrap the host's rules' long lines
lowlevelmetal Oct 10, 2026
f2bdb04
Record the review of the host's rules
lowlevelmetal Oct 10, 2026
f7b76fa
List the host-decided rules' files in the parity manifest
lowlevelmetal Oct 10, 2026
782f469
Give the race start tests their own port block
lowlevelmetal Oct 10, 2026
0c96102
Trace when a client learns of its checkpoints and when the water rese…
lowlevelmetal Oct 10, 2026
557ade8
Send the players' cars' states every sample, with the inputs ahead
lowlevelmetal Oct 10, 2026
943f98b
Wrap three long lines
lowlevelmetal Oct 10, 2026
e168a58
Let the host decide the water, and tighten the rules' rough edges (pr…
lowlevelmetal Oct 10, 2026
83f5762
Put a client's car to the host's state whenever it runs again with ne…
lowlevelmetal Oct 10, 2026
8dbc9a3
Check that only the host's rules state reaches a player
lowlevelmetal Oct 10, 2026
da64b77
Report whether a client's own pickups showed before the host's word
lowlevelmetal Oct 10, 2026
86db4c6
Test a client waiting for the host when a car is about to reach the gold
lowlevelmetal Oct 10, 2026
da767c3
Keep Cops and Robbers' rules state at four messages a second
lowlevelmetal Oct 10, 2026
184c739
Carry the police and knocked cars in full, and every near car (protoc…
lowlevelmetal Oct 10, 2026
baa3c01
Simulate the host's police and knocked cars with the client's car
lowlevelmetal Oct 10, 2026
37d2123
Give the simulation its own sin, cos, atan2, exp, log and pow
lowlevelmetal Oct 10, 2026
ee94506
Build all of OpenMM2 without float contraction
lowlevelmetal Oct 10, 2026
222ee38
Collide a client's knocked traffic cars in id order
lowlevelmetal Oct 10, 2026
afa07bb
Prove in CI that the simulation is the same on every platform
lowlevelmetal Oct 10, 2026
8641ea3
Put an AI racer and cobbles in the determinism scenario
lowlevelmetal Oct 10, 2026
4eafbba
Record the determinism review
lowlevelmetal Oct 10, 2026
f8b0e73
Give the CI Wine prefix to the container's own user
lowlevelmetal Oct 10, 2026
993c285
Smooth the props' rough edges: each client its own area, near cars' k…
lowlevelmetal Oct 10, 2026
aeb303a
Send in full only the knocked cars the host's world runs
lowlevelmetal Oct 10, 2026
4cb28e1
Send in full only the police cars the host's world runs
lowlevelmetal Oct 10, 2026
93dca06
Record the Clang and MinGW runs of the determinism tests
lowlevelmetal Oct 10, 2026
0c94198
Compare OpenMM2's maths with the C runtime in mm2tool
lowlevelmetal Oct 10, 2026
b33bebc
List the simulation's own maths library in the parity manifest
lowlevelmetal Oct 10, 2026
92628b2
Send the police in full within 60 m only, chasing or not
lowlevelmetal Oct 10, 2026
efb3da4
Describe protocol 12's shared traffic
lowlevelmetal Oct 10, 2026
6555cc7
Merge branch 'integration' into worktree-agent-af5320a752138c430
lowlevelmetal Oct 10, 2026
f25438d
Merge branch 'integration' into worktree-agent-aa20eb5f47fb73251
lowlevelmetal Oct 10, 2026
9d90704
Merge integration (the cross-platform determinism work) into the props
lowlevelmetal Oct 10, 2026
1999c9f
Merge branch 'integration' into worktree-agent-a21adb9f783eb40d3
lowlevelmetal Oct 10, 2026
038e44a
Record the second round of the shared traffic's review
lowlevelmetal Oct 10, 2026
dcac542
Record the rules' second round
lowlevelmetal Oct 10, 2026
0dbe185
Let a client that fell behind the host's samples skip to them
lowlevelmetal Oct 10, 2026
134c979
List the full traffic state message in the parity manifest
lowlevelmetal Oct 10, 2026
601a35b
Carry a contact's bound and hardest pusher with a car's state
lowlevelmetal Oct 10, 2026
8e74c96
Check the race start test's go by frame order, not a time window
lowlevelmetal Oct 10, 2026
d94d88c
Merge integration (traffic round 2, protocol 12)
lowlevelmetal Oct 10, 2026
65529a6
Merge branch 'integration' into worktree-agent-a21adb9f783eb40d3
lowlevelmetal Oct 10, 2026
a179197
Record the props' rough edges round
lowlevelmetal Oct 10, 2026
e7f2f07
Merge integration (the shared traffic's second round) into the props
lowlevelmetal Oct 10, 2026
ba818ca
Describe the contact bookkeeping and the skip in the players' cars' s…
lowlevelmetal Oct 10, 2026
dcca773
Predict the knocks of the police and traffic a client simulates
lowlevelmetal Oct 10, 2026
ec7a39e
Merge integration (the host's rules, second round) into the props
lowlevelmetal Oct 10, 2026
22fcbfd
Merge integration (rules round 2, protocol 14)
lowlevelmetal Oct 10, 2026
ea3ec52
Wrap a long declaration
lowlevelmetal Oct 10, 2026
cd9a409
Let a near car's knock wait while the host has that car by the prop
lowlevelmetal Oct 10, 2026
482ac2c
Record the props' final runs of the rough edges round
lowlevelmetal Oct 10, 2026
4e41f5a
Merge integration (props round 2, protocol 16)
lowlevelmetal Oct 10, 2026
7944ac5
Draw another client's near car at this machine's time
lowlevelmetal Oct 10, 2026
852eaa2
Record the players' cars' rough edges round
lowlevelmetal Oct 10, 2026
7c4dcd0
Check the near set, the inputs ahead and a contact's bookkeeping in t…
lowlevelmetal Oct 10, 2026
ad3a8d2
Merge integration (the players' cars' third round) into the props
lowlevelmetal Oct 10, 2026
262c0eb
Send the pieces round a client's car in full (protocol 18)
lowlevelmetal Oct 10, 2026
1cfc71d
Record the props' third round
lowlevelmetal Oct 10, 2026
7db4424
Call this version 0.4.0
lowlevelmetal Oct 10, 2026
6ba4c79
Name the players' cars' wire header after what it carries
lowlevelmetal Oct 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,11 @@ jobs:
container: archlinux:latest
steps:
- name: Install build dependencies
# Wine runs the determinism tests (the toolchain file makes it the
# tests' emulator when it is installed at configure time).
run: |
pacman -Syu --noconfirm --needed \
base-devel git cmake ninja mingw-w64-gcc shaderc glslang
base-devel git cmake ninja mingw-w64-gcc shaderc glslang wine

- uses: actions/checkout@v7

Expand All @@ -178,6 +180,20 @@ jobs:
- name: Build
run: cmake --build --preset mingw-cross-release

# The simulation must give the same bits as the Linux and MSVC builds
# (docs/physics.md, "The same results on every platform"). Only these
# tests: the native jobs run the rest.
- name: Test determinism under Wine
env:
# A prefix of the container's own user (Wine refuses one it does
# not own), without the Mono and Gecko installers.
WINEPREFIX: /tmp/wineprefix
WINEDEBUG: -all
WINEDLLOVERRIDES: mscoree,mshtml=
run: |
wineboot --init
ctest --preset mingw-cross-release -R '^Determinism[.]'

- name: Package
run: cpack --preset mingw-portable

Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.25...4.0)

project(OpenMM2
VERSION 0.3.1
VERSION 0.4.0
DESCRIPTION "Open source reimplementation of Midtown Madness 2"
HOMEPAGE_URL "https://github.com/lowlevelmetal/OpenMM2"
LANGUAGES C CXX)
Expand Down
23 changes: 23 additions & 0 deletions cmake/CompilerOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,29 @@ add_library(OpenMM2::options ALIAS openmm2_options)

target_compile_features(openmm2_options INTERFACE cxx_std_23)

# Floating point: the same results on every compiler and platform, so that a
# host and its clients (and replays, tests and the opponent sweep) simulate a
# sample alike whichever toolchain built them (docs/physics.md, "The same
# results on every platform"). Every float and double operation is rounded
# as IEEE 754 says, in the order the source writes it:
# * no contraction of a * b + c into a fused multiply-add, which rounds
# once instead of twice: GCC defaults to -ffp-contract=fast for C++ and
# Clang to on, which fuse wherever the target has FMA (-march=native,
# x86-64-v3 distribution builds, every AArch64 build). MSVC 2022 and
# later fuse only with /fp:contract or /fp:fast, and x64 has no FMA
# below /arch:AVX2, which the project never sets;
# * no fast-math reassociation or reciprocal approximations;
# * SSE2 (x86-64) or AArch64 arithmetic, where float and double
# expressions are evaluated in their own type (FLT_EVAL_METHOD 0); a
# 32-bit x87 build would round differently and is not supported.
# The C runtime's sin, cos, atan2, exp, log and pow still differ between
# platforms; the simulation uses OpenMM2's own (src/core/Libm.h).
if(MSVC)
target_compile_options(openmm2_options INTERFACE /fp:precise)
else()
target_compile_options(openmm2_options INTERFACE -ffp-contract=off -fno-fast-math)
endif()

if(MSVC)
target_compile_options(openmm2_options INTERFACE
/W4 /permissive- /utf-8 /Zc:__cplusplus /Zc:preprocessor /EHsc
Expand Down
34 changes: 34 additions & 0 deletions docs/bangers.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,37 @@ room of the player's car (type 4), an opponent's or a network player's
its room, so a prop still moving vanishes when the cars leave it behind. A
prop still standing (`dgUnhitBangerInstance`) keeps lvlInstance's empty
Detach.

## Network games

MM2 sends nothing about props: every machine knocks its own with its own
simulation of every car (`mmNetObject`, `mmGameMulti`). OpenMM2's host is the
authority instead (docs/multiplayer.md, "Props"); BangerSet carries what that
needs, all of it inert in a single-player race:

* The placed props' indices name them on every machine (they are placed in
the same order everywhere); a hit instance remembers the placed prop it came
from (`Instance::source`, with `part` for a BREAKnn piece) or the tag its
thrower gave a car part (`Instance::tag`). The ring's slots count how often
they were handed out (`generation`). In a network race the ring grows by
40 slots, up to 40 a player, when it is about to wrap onto a prop that
still moves or was knocked less than 10 s ago (`setRingGrowth`; MM2's
ring of 40 makes such props disappear in a pile-up).
* `takeKnocks` (with `recordKnocks(true)`): the placed props that broke loose
(`dgUnhitBangerInstance::Impact`) and what hit them.
* A client (`setReplica`): only its own car and the cars it simulates with
it (the other players' near ones, the shared police and knocked traffic
cars) may touch its props, and the props it simulates one another but
no placed prop (`phys::Instance::acceptsContact`); `breakPlaced` takes a
prop out of its room as Impact does but without a body; `restoreStanding`
undoes a knock its car predicted that the host did not make (Reset for one
prop); `showMirror` / `hideMirror` show the host's ring slots in instances
of their own, drawn where the host has them. An active attached to a
mirror starts from the host's motion (`dgBangerActive::Attach` starts a
placed or resting prop at rest).
* A client replaying its car (`phys::World::replaySample`) meets a prop with
the body an active would give it (`heldInertia`: `dgBangerActive::Attach`'s
mass and inertia, a mirror's host motion), which the world moves through
the replay only; a prop its car broke loose in the last second stands
again for the samples up to the one that broke it loose (`replayGhost`),
its pieces left out; the later samples meet the pieces.
Loading
Loading