Skip to content

Commit 9cab6de

Browse files
committed
Default the preview multiplayer server to the bevy engine
The bevy headless server is what production multiplayer now runs, so the preview spawned by `sdk-commands start` should exercise the same engine. Hammurabi remains reachable via DCL_SERVER_ENGINE=hammurabi and as the automatic fallback when bevy exits unavailable (78) — except when DCL_SERVER_PACKAGE overrides the spec, where falling back would just respawn the same overridden package. Rename the module accordingly and drop the never-populated PreviewComponents.hammurabiServer field.
1 parent 925eb7c commit 9cab6de

3 files changed

Lines changed: 24 additions & 26 deletions

File tree

packages/@dcl/sdk-commands/src/commands/start/index.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ import { Result } from 'arg'
2929
import { startValidations } from '../../logic/project-validations'
3030
import { runExplorerAlpha } from './explorer-alpha'
3131
import { getLanUrl } from './utils'
32-
import { spawnAuthServer } from './hammurabi-server'
33-
import { ChildProcess } from 'child_process'
32+
import { spawnAuthServer } from './multiplayer-server'
3433

3534
interface Options {
3635
args: Result<typeof args>
@@ -219,18 +218,16 @@ export async function main(options: Options) {
219218
}
220219
await startComponents()
221220

222-
// Start Hammurabi server if needed (stored outside components to avoid lifecycle management)
223-
let hammurabiServer: ChildProcess | undefined
221+
// Start the multiplayer server if needed (kept outside the components object to avoid lifecycle management)
224222
const project = workspace.projects[0]
225223
if (project) {
226224
const realm = `http://localhost:${port}`
227-
hammurabiServer = spawnAuthServer(components, project, realm)
225+
const multiplayerServer = spawnAuthServer(components, project, realm)
228226

229-
// Register cleanup handler for hammurabi server
230-
if (hammurabiServer) {
227+
if (multiplayerServer) {
231228
const cleanup = () => {
232-
if (hammurabiServer && !hammurabiServer.killed) {
233-
hammurabiServer.kill('SIGTERM')
229+
if (!multiplayerServer.killed) {
230+
multiplayerServer.kill('SIGTERM')
234231
}
235232
}
236233
components.signaler.programClosed.then(cleanup).catch(() => {})

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

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ const EXIT_UNAVAILABLE = 78
1818

1919
type ServerEngine = 'bevy' | 'hammurabi'
2020

21+
const DEFAULT_ENGINE: ServerEngine = 'bevy'
22+
2123
function selectedEngine(): ServerEngine {
2224
const requested = process.env.DCL_SERVER_ENGINE
23-
return requested === 'bevy' || requested === 'hammurabi' ? requested : 'hammurabi'
25+
return requested === 'bevy' || requested === 'hammurabi' ? requested : DEFAULT_ENGINE
2426
}
2527

2628
/**
@@ -52,11 +54,11 @@ function registerProcessCleanup(cleanup: () => void): () => void {
5254
/**
5355
* Starts the Multiplayer Server process using npx to install and run in one step
5456
*/
55-
export function startHammurabiServer(
57+
export function startMultiplayerServer(
5658
components: Pick<CliComponents, 'logger'>,
5759
workingDir: string,
5860
realm: string,
59-
engine: ServerEngine = 'hammurabi'
61+
engine: ServerEngine = DEFAULT_ENGINE
6062
): ChildProcess {
6163
const pkg = packageSpec(engine)
6264

@@ -75,40 +77,40 @@ export function startHammurabiServer(
7577

7678
// If npx-cli.js was found, run it directly via process.execPath (node in regular env,
7779
// Electron Helper with ELECTRON_RUN_AS_NODE=1 in Electron). Otherwise fall back to npx binary.
78-
const hammurabiProcess = npxCliJs
80+
const serverProcess = npxCliJs
7981
? spawn(process.execPath, [npxCliJs, ...npxArgs], { cwd: workingDir, shell: false, stdio: 'inherit', env })
8082
: spawn(getNpxBin(), npxArgs, { cwd: workingDir, shell: false, stdio: 'inherit', env })
8183

82-
hammurabiProcess.on('error', (error) => {
84+
serverProcess.on('error', (error) => {
8385
printWarning(components.logger, `Multiplayer Server process error: ${error.message}`)
8486
})
8587

8688
// Register cleanup handlers
8789
const cleanup = () => {
88-
if (!hammurabiProcess.killed) {
89-
hammurabiProcess.kill('SIGTERM')
90+
if (!serverProcess.killed) {
91+
serverProcess.kill('SIGTERM')
9092
}
9193
}
9294

9395
const removeCleanup = registerProcessCleanup(cleanup)
9496

95-
hammurabiProcess.on('close', (code) => {
97+
serverProcess.on('close', (code) => {
9698
removeCleanup()
9799
if (code !== 0 && code !== null) {
98100
printWarning(components.logger, `Multiplayer Server exited with code ${code}`)
99101
}
100102
})
101103

102-
return hammurabiProcess
104+
return serverProcess
103105
}
104106

105107
/**
106108
* Spawns the multiplayer server for the project.
107109
* In the auth-server SDK, all scenes are authoritative multiplayer.
108110
* Uses npx to handle installation and execution in a single step (works in Electron).
109111
*
110-
* Which implementation runs is chosen by DCL_SERVER_ENGINE (bevy | hammurabi). When bevy
111-
* reports itself unavailable on this machine, hammurabi is started instead.
112+
* Which implementation runs is chosen by DCL_SERVER_ENGINE (bevy | hammurabi), defaulting
113+
* to bevy. When bevy reports itself unavailable on this machine, hammurabi is started instead.
112114
*
113115
* @param components - Preview components including logger
114116
* @param project - The project to start the multiplayer server for
@@ -122,12 +124,14 @@ export function spawnAuthServer(
122124
): ChildProcess | undefined {
123125
const engine = selectedEngine()
124126
try {
125-
const child = startHammurabiServer(components, project.workingDirectory, realm, engine)
126-
if (engine === 'bevy') {
127+
const child = startMultiplayerServer(components, project.workingDirectory, realm, engine)
128+
// No fallback when DCL_SERVER_PACKAGE is set: packageSpec would resolve the
129+
// hammurabi retry to the same overridden package that just exited 78.
130+
if (engine === 'bevy' && !process.env.DCL_SERVER_PACKAGE) {
127131
child.on('close', (code) => {
128132
if (code === EXIT_UNAVAILABLE) {
129133
printWarning(components.logger, 'Bevy multiplayer server unavailable here — falling back to hammurabi')
130-
startHammurabiServer(components, project.workingDirectory, realm, 'hammurabi')
134+
startMultiplayerServer(components, project.workingDirectory, realm, 'hammurabi')
131135
}
132136
})
133137
}

packages/@dcl/sdk-commands/src/commands/start/types.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { RoomComponent } from '@dcl/mini-comms/dist/adapters/rooms'
99
import { WebSocketComponent } from './server/ws'
1010
import { CliComponents } from '../../components'
1111
import { ISignalerComponent } from '../../components/exit-signal'
12-
import { ChildProcess } from 'child_process'
1312

1413
export type PreviewComponents = CliComponents & {
1514
logs: ILoggerComponent
@@ -20,6 +19,4 @@ export type PreviewComponents = CliComponents & {
2019
rooms: RoomComponent
2120
ws: WebSocketComponent
2221
signaler: ISignalerComponent
23-
/** Authoritative Server process (@dcl/hammurabi-server) */
24-
hammurabiServer?: ChildProcess
2522
}

0 commit comments

Comments
 (0)