Skip to content

Multiplayer Support [AARD-2024, AARD-2021] #1252

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 96 commits into from
Aug 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
0aaa439
init: multiplayer subsystem
azaleacolburn Jul 29, 2025
9ec9239
feat: update multiplayer system to use fission types
azaleacolburn Jul 29, 2025
02bbb4f
feat: base multiplayer lobby system
rutmanz Jul 29, 2025
21ebb2d
fix: make initWorld use broadcast
rutmanz Jul 29, 2025
cf5330c
Merge
azaleacolburn Jul 30, 2025
7149d29
feat: handle peer info and world initialization
azaleacolburn Jul 30, 2025
4baad96
feat(wip): move multiplayer to world
azaleacolburn Jul 30, 2025
c99d6f0
feat: add multiplayer start menu
rutmanz Jul 30, 2025
2d56d2a
feat: collision handling hook
azaleacolburn Jul 30, 2025
30a11ba
feat: add multiplayer hud
rutmanz Jul 30, 2025
46168b1
refactor: use discriminated union tpye
rutmanz Jul 30, 2025
a0947ea
feat: show info nicely on HUD
rutmanz Jul 30, 2025
a0e6d67
feat: add host transitioning
rutmanz Jul 30, 2025
652f294
feat: new object handling
azaleacolburn Jul 30, 2025
990df6d
chore: format
azaleacolburn Jul 31, 2025
f1afdd0
feat: newObject message works
azaleacolburn Jul 31, 2025
3ede77f
feat: persistent client ids and names, increased room security, check…
rutmanz Jul 31, 2025
e884eea
feat: updating object velocity, position, rotation works
azaleacolburn Aug 1, 2025
10ca6d7
feat: add multiplayer nametags
rutmanz Aug 1, 2025
74328e4
feat: send metadata between multiplayer clients
rutmanz Aug 1, 2025
f70da18
feat: allow multiple objects per client
rutmanz Aug 1, 2025
e65fc5a
feat: intaking and ejecting game pieces across multiplayer
azaleacolburn Aug 4, 2025
7089985
feat: use field cache if possible in mulitplayer
azaleacolburn Aug 4, 2025
11a170d
chore: remove comments in handlePeerUpdate
azaleacolburn Aug 4, 2025
7663a13
feat: send initial configuration with new objects
azaleacolburn Aug 5, 2025
6ea074b
feat: preferences are sent on update
azaleacolburn Aug 5, 2025
714b11c
Merge remote-tracking branch 'origin/dev' into colbura/2024/multiplayer
rutmanz Aug 5, 2025
12cb3e2
feat: finish migrating to UI refactor, fix circular import
rutmanz Aug 5, 2025
8f1b742
fix: import correctly
rutmanz Aug 5, 2025
f7ce472
feat: add multiplayer tests
rutmanz Aug 5, 2025
800aa6b
Merge branch 'dev' of github.com:Autodesk/synthesis into colbura/2024…
azaleacolburn Aug 6, 2025
08667b3
feat: remove printing in tests and make server exit gracefully
rutmanz Aug 6, 2025
a4f0a72
Merge remote-tracking branch 'origin/dev' into colbura/2024/multiplayer
rutmanz Aug 6, 2025
55760d9
Merge remote-tracking branch 'origin/dev' into colbura/2024/multiplayer
rutmanz Aug 6, 2025
0437128
Merge branch 'colbura/2024/multiplayer' into zachr/2023/multiplayer-m…
rutmanz Aug 6, 2025
de50ba7
feat: add singleplayer button back, fix default scene order and filen…
rutmanz Aug 7, 2025
f898e4f
feat: add match mode timer support
rutmanz Aug 7, 2025
e2a4f02
Merge branch 'colbura/2024/multiplayer' into zachr/2023/multiplayer-m…
rutmanz Aug 7, 2025
4966d1b
fix: make scoring zones work
rutmanz Aug 7, 2025
a0d4ebd
fix: make scoring zones work
rutmanz Aug 7, 2025
9951c95
Merge branch 'dev' of github.com:Autodesk/synthesis into colbura/2024…
azaleacolburn Aug 8, 2025
3812029
feat: make sending fields work
rutmanz Aug 8, 2025
44c443e
feat: update all bodies in sceneobject (doesn't map bodyIds yet)
azaleacolburn Aug 8, 2025
1af481c
fix(build): use and cast ArrayBuffer from encoded assembly
azaleacolburn Aug 8, 2025
c4e6142
feat: make caching and sending assets work correctly
rutmanz Aug 8, 2025
cdaf0d6
refactor: getAllBodies functions on MirabufSceneObject
azaleacolburn Aug 8, 2025
1b76fc5
fix: unit tests
rutmanz Aug 8, 2025
545b399
fix: make old caches not die
rutmanz Aug 8, 2025
92ba46d
fix: also remove old localstorage keys
rutmanz Aug 8, 2025
044351a
Merge branch 'zachr/2023/multiplayer-matchmode' into colbura/2024/mul…
rutmanz Aug 8, 2025
c5e8460
fix: use MaxSafeInteger instead of Infinity
rutmanz Aug 8, 2025
dfffb8e
fix: make port work, clean up code
rutmanz Aug 8, 2025
85a38f9
feat: handle disabling and enabling correctly
azaleacolburn Aug 8, 2025
95824bc
feat: allow loading directly from memory cache as fallback
rutmanz Aug 11, 2025
4b5a4e7
feat: calculate dimension penalties only for own robots
rutmanz Aug 11, 2025
97340c5
refactor: move handlers to separate function
azaleacolburn Aug 11, 2025
995ba01
Merge branch 'colbura/2024/multiplayer' of github.com:Autodesk/synthe…
azaleacolburn Aug 11, 2025
9ef49cd
fix(build): remove unimplemented functions from multiplayer system
azaleacolburn Aug 11, 2025
ac13107
fix: avoid exporting all handlers individually
rutmanz Aug 11, 2025
cee1b8f
refactor: move score counting out of SimulationSystem (why was it the…
rutmanz Aug 11, 2025
080b772
feat: allow removing scene objects
rutmanz Aug 11, 2025
d30c8db
fix: consolidate robotLeft and deleteObject
rutmanz Aug 11, 2025
0035d52
fix: run formatter
rutmanz Aug 11, 2025
bedef36
fix: revert accidental exporter changes
rutmanz Aug 11, 2025
a4b72fe
feat: improve styling on multiplayer HUD
rutmanz Aug 11, 2025
d65d335
fix: make initial configuration of robot respect alliance and station
rutmanz Aug 11, 2025
c1bea06
fix: missing parenthesis
rutmanz Aug 11, 2025
45a7e63
fix: remove event listener passivity warning
rutmanz Aug 11, 2025
db2259d
feat: improve metadata sharing and display
rutmanz Aug 11, 2025
3097285
feat: support joining room with assets
rutmanz Aug 11, 2025
ed043af
feat: add progress handles to multiplayer assets
rutmanz Aug 11, 2025
d86fcd8
fix: make match mode start and end transitions safer
rutmanz Aug 11, 2025
b0e0044
feat: initial body map implementation
azaleacolburn Aug 11, 2025
bb771d6
fix: use console.assert
azaleacolburn Aug 11, 2025
edf9151
fix: construct newObjects on connect correctly
azaleacolburn Aug 11, 2025
3134090
fix: send metadata
azaleacolburn Aug 12, 2025
9d88aef
fix: clients can no longer get context menus for peer robots
azaleacolburn Aug 12, 2025
5a22b0a
chore: remove Button.tsx
azaleacolburn Aug 12, 2025
d17a843
fix(maybe): ejector preferences
azaleacolburn Aug 12, 2025
0ca8194
fix: make memory cache actually used
rutmanz Aug 12, 2025
ac0015a
fix: send existing assets again
rutmanz Aug 13, 2025
770d829
feat: prevent configuring other users' assets
rutmanz Aug 13, 2025
8d3eae7
feat: preventing initial config panel from being opened for fields
azaleacolburn Aug 13, 2025
34ee834
Merge branch 'dev' of github.com:Autodesk/synthesis into colbura/2024…
azaleacolburn Aug 13, 2025
99d70c6
fix: build
azaleacolburn Aug 13, 2025
5a7a79a
Merge branch 'dev' of github.com:Autodesk/synthesis into colbura/2024…
azaleacolburn Aug 14, 2025
440a3b4
fix(build): import things correctly
azaleacolburn Aug 14, 2025
4277c7d
fix: build + style
azaleacolburn Aug 14, 2025
99d4077
Merge branch 'dev' of github.com:Autodesk/synthesis into colbura/2024…
azaleacolburn Aug 18, 2025
ec6cade
fix: send preferences on assembly configuration
azaleacolburn Aug 18, 2025
4d9e2d0
feat: only focus on assets that you spawned
azaleacolburn Aug 21, 2025
9444923
fix: build + format
azaleacolburn Aug 21, 2025
ff80a59
Merge branch 'dev' of github.com:Autodesk/synthesis into colbura/2024…
azaleacolburn Aug 21, 2025
1204cf5
Merge remote-tracking branch 'origin/dev' into colbura/2024/multiplayer
rutmanz Aug 21, 2025
00a6b40
fix(build): use moved hashBuffer
azaleacolburn Aug 21, 2025
41cd3d4
fix: make robots reset to spawn positions in multiplayer
rutmanz Aug 22, 2025
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
271 changes: 175 additions & 96 deletions fission/bun.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion fission/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"electron-squirrel-startup": "^1.0.1",
"framer-motion": "^10.18.0",
"lygia": "^1.3.3",
"peerjs": "^1.5.5",
"msw": "^2.10.4",
"notistack": "^3.0.2",
"playwright": "^1.54.2",
Expand Down Expand Up @@ -96,11 +97,11 @@
"eslint-plugin-react-refresh": "^0.4.20",
"jsdom": "^24.1.3",
"pako": "^2.1.0",
"peer": "^1.0.2",
"postcss": "^8.5.6",
"protobufjs": "^7.5.3",
"protobufjs-cli": "^1.1.3",
"rollup": "^4.46.2",
"sirv": "^3.0.1",
"tailwindcss": "^3.4.17",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.9.2",
Expand Down
56 changes: 42 additions & 14 deletions fission/src/Synthesis.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { AnimatePresence } from "framer-motion"
import { SnackbarProvider } from "notistack"
import { useCallback, useEffect, useRef, useState } from "react"
import { globalAddToast } from "@/components/GlobalUIControls.ts"
import MainHUD from "@/components/MainHUD"
import MultiplayerHUD from "@/components/MultiplayerHUD.tsx"
import Scene from "@/components/Scene.tsx"
import MultiplayerStartModal from "@/modals/MultiplayerStartModal.tsx"
import MultiplayerSystem from "@/systems/multiplayer/MultiplayerSystem.ts"
import World from "@/systems/World.ts"
import { UIRenderer } from "@/ui/UIRenderer.tsx"
import PreferencesSystem from "./systems/preferences/PreferencesSystem.ts"
Expand All @@ -23,34 +27,57 @@
const [consentPopupDisable, setConsentPopupDisable] = useState<boolean>(true)

const mainLoopHandle = useRef(0)
const startMainLoop = async () => {
await World.initWorld()
if (!PreferencesSystem.getGlobalPreference("ReportAnalytics") && !import.meta.env.DEV) {
setConsentPopupDisable(false)
}

const mainLoop = () => {
mainLoopHandle.current = requestAnimationFrame(mainLoop)
World.updateWorld()
}

mainLoop()
}
useEffect(() => {
const urlParams = new URLSearchParams(document.location.search)
if (urlParams.has("code")) {
window.opener.convertAuthToken(urlParams.get("code"))
window.close()
return
}
const startSingleplayerCallback = () => {
World.initWorld()

if (!PreferencesSystem.getGlobalPreference("ReportAnalytics") && !import.meta.env.DEV) {
setConsentPopupDisable(false)
}

const mainLoop = () => {
mainLoopHandle.current = requestAnimationFrame(mainLoop)
World.updateWorld()
}

mainLoop()
}
globalOpenModal(MainMenuModal, { startSingleplayerCallback })
globalOpenModal(MainMenuModal, {
startSingleplayerCallback: async () => await startMainLoop(),
startMultiplayerCallback: () => {
globalOpenModal(MultiplayerStartModal, {
startWorldCallback: async (name, room) => {
const isHost = room == null
if (room == null) {
room = Math.random().toString(10).substring(2, 8)

Check warning on line 58 in fission/src/Synthesis.tsx

View check run for this annotation

Autodesk Chorus / security/semgrep

app.chorus.semgrep.rules.njsscan.crypto.node_insecure_random_generator

crypto.pseudoRandomBytes()/Math.random() is a cryptographically weak random number generator.

Check warning on line 58 in fission/src/Synthesis.tsx

View check run for this annotation

Autodesk Chorus / security/semgrep

app.chorus.semgrep.rules.njsscan.semantic_grep.crypto.node_insecure_random_generator

crypto.pseudoRandomBytes()/Math.random() is a cryptographically weak random number generator.
}
PreferencesSystem.setGlobalPreference("MultiplayerUsername", name)
PreferencesSystem.savePreferences()
const success = await MultiplayerSystem.setup(room, name, isHost)
if (success) {
if (isHost) {
globalAddToast("info", "Room Code", room)
}
await startMainLoop()
return true
}
return false
},
})
},
})
// Cleanup
return () => {
// TODO: Teardown literally everything
cancelAnimationFrame(mainLoopHandle.current)
World.destroyWorld()
World.multiplayerSystem?.destroy()
// World.SceneRenderer.RemoveAllSceneObjects();
}
}, [])
Expand All @@ -75,6 +102,7 @@
<Scene useStats={import.meta.env.DEV} key="scene-in-toast-provider" />
<SceneOverlay />
<ContextMenu />
<MultiplayerHUD />
<MainHUD key={"main-hud"} />
<UIRenderer />
<ProgressNotifications key={"progress-notifications"} />
Expand Down
18 changes: 11 additions & 7 deletions fission/src/mirabuf/EjectableSceneObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type MirabufSceneObject from "./MirabufSceneObject"
import ScoringZoneSceneObject from "./ScoringZoneSceneObject"

class EjectableSceneObject extends SceneObject {
private _parentAssembly: MirabufSceneObject
private _parentSceneObject: MirabufSceneObject
private _gamePieceBodyId?: Jolt.BodyID

private _parentBodyId?: Jolt.BodyID
Expand Down Expand Up @@ -44,25 +44,29 @@ class EjectableSceneObject extends SceneObject {
return this._parentBodyId
}

public get parentSceneObject(): MirabufSceneObject {
return this._parentSceneObject
}

public constructor(parentAssembly: MirabufSceneObject, gamePieceBody: Jolt.BodyID) {
super()

console.debug("Trying to create ejectable...")

this._parentAssembly = parentAssembly
this._parentSceneObject = parentAssembly
this._gamePieceBodyId = gamePieceBody
}

public setup(): void {
if (this._parentAssembly.ejectorPreferences && this._gamePieceBodyId) {
this._parentBodyId = this._parentAssembly.mechanism.nodeToBody.get(
this._parentAssembly.ejectorPreferences.parentNode ?? this._parentAssembly.rootNodeId
if (this._parentSceneObject.ejectorPreferences && this._gamePieceBodyId) {
this._parentBodyId = this._parentSceneObject.mechanism.nodeToBody.get(
this._parentSceneObject.ejectorPreferences.parentNode ?? this._parentSceneObject.rootNodeId
)

this._deltaTransformation = convertArrayToThreeMatrix4(
this._parentAssembly.ejectorPreferences.deltaTransformation
this._parentSceneObject.ejectorPreferences.deltaTransformation
)
this._ejectVelocity = this._parentAssembly.ejectorPreferences.ejectorVelocity
this._ejectVelocity = this._parentSceneObject.ejectorPreferences.ejectorVelocity

// Record start transform at the game piece center of mass
const gpBody = World.physicsSystem.getBody(this._gamePieceBodyId)
Expand Down
Loading
Loading