Skip to content

Commit 75b1e5d

Browse files
committed
feat: use field cache if possible in mulitplayer
1 parent e65fc5a commit 75b1e5d

File tree

3 files changed

+77
-5
lines changed

3 files changed

+77
-5
lines changed

fission/src/systems/multiplayer/MultiplayerSystem.ts

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import JOLT from "@/util/loading/JoltSyncLoader"
99
import PhysicsSystem from "../physics/PhysicsSystem"
1010
import World from "../World"
1111
import type {
12+
AssemblyRequestData,
1213
ClientInfo,
1314
CollisionData,
1415
EncodedAssembly,
@@ -18,6 +19,7 @@ import type {
1819
MetadataUpdateData,
1920
UpdateObjectData,
2021
} from "./types"
22+
import MirabufCachingService, { MiraType } from "@/mirabuf/MirabufLoader"
2123

2224
const COLLISION_TIMEOUT = 500
2325

@@ -210,6 +212,10 @@ class MultiplayerSystem {
210212
case "newObject":
211213
await this.handleNewObject(message.data, peerId)
212214
break
215+
case "needAssembly":
216+
await this.handleAssemblyRequest(message.data, peerId)
217+
break
218+
213219
case "metadataUpdate":
214220
await this.handleMetadataUpdate(message.data)
215221
}
@@ -320,7 +326,30 @@ class MultiplayerSystem {
320326
}
321327

322328
async handleNewObject(data: InitObjectData, peerId: string) {
323-
const assembly = mirabuf.Assembly.decode(data.assembly)
329+
const assemblyName = data.assemblyName
330+
let assembly: mirabuf.Assembly
331+
if (data.assembly) {
332+
assembly = mirabuf.Assembly.decode(data.assembly)
333+
} else {
334+
const cachedFields = Object.values(MirabufCachingService.getCacheMap(MiraType.FIELD))
335+
const fieldInfo = cachedFields.find(f => f.name === assemblyName)
336+
if (fieldInfo) {
337+
const fieldAssembly = await MirabufCachingService.get(fieldInfo.id, MiraType.FIELD)
338+
if (fieldAssembly) {
339+
assembly = fieldAssembly
340+
} else {
341+
this.send(peerId, {
342+
type: "needAssembly",
343+
data: { assemblyName, sceneObjectKey: data.sceneObjectKey },
344+
})
345+
return
346+
}
347+
} else {
348+
this.send(peerId, { type: "needAssembly", data: { assemblyName, sceneObjectKey: data.sceneObjectKey } })
349+
return
350+
}
351+
}
352+
324353
const object = await createMirabuf(assembly)
325354
if (object == null) return
326355

@@ -334,6 +363,36 @@ class MultiplayerSystem {
334363
this._clientToObjectMap.get(peerId)?.push(object.id) || this._clientToObjectMap.set(peerId, [object.id])
335364
}
336365

366+
async handleAssemblyRequest(data: AssemblyRequestData, peerId: string) {
367+
const assemblyName = data.assemblyName
368+
const sceneObjectKey = data.sceneObjectKey
369+
370+
const cachedFields = Object.values(MirabufCachingService.getCacheMap(MiraType.FIELD))
371+
const assemblyInfo = cachedFields.find(n => n.name === assemblyName)
372+
if (!assemblyInfo) {
373+
console.error(`Cannot find requested assembly in cache: ${assemblyName}`)
374+
return
375+
}
376+
const assembly = await MirabufCachingService.get(assemblyInfo.id, MiraType.FIELD)
377+
if (!assembly) {
378+
console.error(`Failed to get assembly: ${assemblyName} from cache`)
379+
return
380+
}
381+
382+
const encodedAssembly = mirabuf.Assembly.encode(assembly).finish() as EncodedAssembly
383+
384+
const message: Message = {
385+
type: "newObject",
386+
data: {
387+
sceneObjectKey,
388+
assembly: encodedAssembly,
389+
assemblyName,
390+
},
391+
}
392+
393+
this.send(peerId, message)
394+
}
395+
337396
async handleMetadataUpdate(data: MetadataUpdateData) {
338397
const sceneObject = World.sceneRenderer.sceneObjects.get(data.sceneObjectKey)
339398
if (!sceneObject || !(sceneObject instanceof MirabufSceneObject)) return

fission/src/systems/multiplayer/types.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,18 @@ interface MessageType {
2626
metadataUpdate: MetadataUpdateData
2727
collision: CollisionData
2828
newObject: InitObjectData
29+
needAssembly: AssemblyRequestData
2930
robotLeft: RobotLeftData
3031
ping: PingData
3132
pong: PingData
3233
}
3334

35+
export type Message = { [K in keyof MessageType]: { type: K; data: MessageType[K] } }[keyof MessageType]
36+
3437
// biome-ignore lint: We're using this for type safety
3538
export type EncodedAssembly = Uint8Array & { __: "encodedassembly" }
3639
export type EncodedRootBody = string
3740

38-
export type Message = { [K in keyof MessageType]: { type: K; data: MessageType[K] } }[keyof MessageType]
39-
4041
export type ClientInfo = {
4142
displayName: string
4243
clientId: string
@@ -46,7 +47,13 @@ export type ClientInfo = {
4647

4748
export type InitObjectData = {
4849
sceneObjectKey: number
49-
assembly: EncodedAssembly
50+
assembly?: EncodedAssembly
51+
assemblyName: string
52+
}
53+
54+
export type AssemblyRequestData = {
55+
sceneObjectKey: number
56+
assemblyName: string
5057
}
5158

5259
export type MetadataUpdateData = {

fission/src/ui/panels/mirabuf/ImportMirabufPanel.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,17 @@ function spawnCachedMira(info: MirabufCacheInfo, type: MiraType, progressHandle?
107107
World.sceneRenderer.registerSceneObject(x)
108108

109109
if (World.multiplayerSystem != null) {
110+
const encodedAssembly =
111+
x.miraType !== MiraType.FIELD
112+
? (mirabuf.Assembly.encode(assembly).finish() as EncodedAssembly)
113+
: undefined
114+
110115
const message: Message = {
111116
type: "newObject",
112117
data: {
113118
sceneObjectKey: x.id,
114-
assembly: mirabuf.Assembly.encode(assembly).finish() as EncodedAssembly,
119+
assembly: encodedAssembly,
120+
assemblyName: assembly.info?.name ?? "",
115121
},
116122
}
117123
World.multiplayerSystem?.broadcast(message)

0 commit comments

Comments
 (0)