Skip to content

Commit ae5aa0e

Browse files
committed
Allow the bevy engine to serve authoritative scenes in preview
DCL_SERVER_ENGINE selects the implementation and defaults to hammurabi, so this is inert until the bevy packages are published. Exit code 78 from the bevy launcher means it can never run on this machine, so fall back rather than leave the preview without a server.
1 parent 5ffe873 commit ae5aa0e

1 file changed

Lines changed: 35 additions & 5 deletions

File tree

packages/@dcl/sdk-commands/src/commands/start/hammurabi-server.ts

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,20 @@ import { isElectronEnvironment, getSpawnEnv, findNpxCliJs, getNpxBin } from './u
99
const HAMMURABI_PACKAGE = '@dcl/hammurabi-server'
1010
const HAMMURABI_VERSION = 'next'
1111

12+
const BEVY_PACKAGE = '@dcl/bevy-headless-server'
13+
const BEVY_VERSION = 'next'
14+
15+
// The bevy server exits with this when it can never run here (unsupported platform,
16+
// missing binary, bad arguments), which is our cue to fall back to hammurabi.
17+
const EXIT_UNAVAILABLE = 78
18+
19+
type ServerEngine = 'bevy' | 'hammurabi'
20+
21+
function selectedEngine(): ServerEngine {
22+
const requested = process.env.DCL_SERVER_ENGINE
23+
return requested === 'bevy' || requested === 'hammurabi' ? requested : 'hammurabi'
24+
}
25+
1226
/**
1327
* Registers cleanup handlers on the global process object
1428
* Returns a function to remove the handlers
@@ -31,14 +45,17 @@ function registerProcessCleanup(cleanup: () => void): () => void {
3145
export function startHammurabiServer(
3246
components: Pick<CliComponents, 'logger'>,
3347
workingDir: string,
34-
realm: string
48+
realm: string,
49+
engine: ServerEngine = 'hammurabi'
3550
): ChildProcess {
51+
const pkg = engine === 'bevy' ? `${BEVY_PACKAGE}@${BEVY_VERSION}` : `${HAMMURABI_PACKAGE}@${HAMMURABI_VERSION}`
52+
3653
printProgressInfo(
3754
components.logger,
38-
`Starting ${colors.bold('Multiplayer Server')} with realm: ${colors.bold(realm)}`
55+
`Starting ${colors.bold('Multiplayer Server')} (${engine}) with realm: ${colors.bold(realm)}`
3956
)
4057

41-
const npxArgs = ['--yes', `${HAMMURABI_PACKAGE}@${HAMMURABI_VERSION}`, `--realm=${realm}`]
58+
const npxArgs = ['--yes', pkg, `--realm=${realm}`]
4259
const npxCliJs = findNpxCliJs()
4360

4461
// In Electron, override npm_config_prefix because npm derives its prefix from process.execPath,
@@ -80,18 +97,31 @@ export function startHammurabiServer(
8097
* In the auth-server SDK, all scenes are authoritative multiplayer.
8198
* Uses npx to handle installation and execution in a single step (works in Electron).
8299
*
100+
* Which implementation runs is chosen by DCL_SERVER_ENGINE (bevy | hammurabi). When bevy
101+
* reports itself unavailable on this machine, hammurabi is started instead.
102+
*
83103
* @param components - Preview components including logger
84104
* @param project - The project to start the multiplayer server for
85-
* @param realm - The realm URL to pass to the hammurabi server
105+
* @param realm - The realm URL to pass to the server
86106
* @returns The ChildProcess if started, undefined otherwise
87107
*/
88108
export function spawnAuthServer(
89109
components: PreviewComponents,
90110
project: ProjectUnion,
91111
realm: string
92112
): ChildProcess | undefined {
113+
const engine = selectedEngine()
93114
try {
94-
return startHammurabiServer(components, project.workingDirectory, realm)
115+
const child = startHammurabiServer(components, project.workingDirectory, realm, engine)
116+
if (engine === 'bevy') {
117+
child.on('close', (code) => {
118+
if (code === EXIT_UNAVAILABLE) {
119+
printWarning(components.logger, 'Bevy multiplayer server unavailable here — falling back to hammurabi')
120+
startHammurabiServer(components, project.workingDirectory, realm, 'hammurabi')
121+
}
122+
})
123+
}
124+
return child
95125
} catch (error: any) {
96126
printWarning(components.logger, `Failed to start Multiplayer Server: ${error.message}`)
97127
return undefined

0 commit comments

Comments
 (0)