Skip to content

Commit 4a9abba

Browse files
committed
refactor to use appViewer in playground
1 parent 9a4cfd3 commit 4a9abba

File tree

2 files changed

+37
-90
lines changed

2 files changed

+37
-90
lines changed

renderer/playground/baseScene.ts

Lines changed: 29 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
1212
// eslint-disable-next-line import/no-named-as-default
1313
import GUI from 'lil-gui'
1414
import _ from 'lodash'
15-
import { GraphicsBackendConfig } from '../../src/appViewer'
16-
import { ResourcesManager } from '../../src/resourcesManager'
1715
import supportedVersions from '../../src/supportedVersions.mjs'
1816
import { toMajorVersion } from '../../src/utils'
1917
import { BlockNames } from '../../src/mcDataTypes'
@@ -74,22 +72,17 @@ export class BasePlaygroundScene {
7472
enableCameraOrbitControl = true
7573
controls: OrbitControls | undefined
7674

77-
// Renderer infrastructure (modern architecture)
78-
resourcesManager: ResourcesManager
79-
graphicsBackend: ReturnType<typeof createGraphicsBackend> | undefined
75+
// Renderer infrastructure - use appViewer instead of duplicating
8076
worldRenderer: WorldRendererThree | undefined
8177
worldView: WorldDataEmitter | undefined
8278

83-
// World config - must be a valtio proxy for reactive updates
84-
_worldConfig = proxy({ ...defaultWorldRendererConfig })
79+
// World config - syncs with appViewer.inWorldRenderingConfig
8580
get worldConfig () {
86-
return this._worldConfig
81+
return appViewer.inWorldRenderingConfig
8782
}
8883
set worldConfig (value) {
89-
// Merge the new values into the existing proxy to maintain reactivity
90-
Object.assign(this._worldConfig, value)
91-
// World config is passed via DisplayWorldOptions, not directly on worldRenderer
92-
// We'll update it when recreating the world if needed
84+
// Merge the new values into appViewer's config to maintain reactivity
85+
Object.assign(appViewer.inWorldRenderingConfig, value)
9386
}
9487

9588
constructor (config: PlaygroundSceneConfig = {}) {
@@ -106,14 +99,12 @@ export class BasePlaygroundScene {
10699
if (config.enableCameraControls !== undefined) this.enableCameraControls = config.enableCameraControls
107100
if (config.enableCameraOrbitControl !== undefined) this.enableCameraOrbitControl = config.enableCameraOrbitControl
108101
if (config.worldConfig) {
109-
// Merge config into the proxy to maintain reactivity
110-
Object.assign(this._worldConfig, config.worldConfig)
102+
appViewer.inWorldRenderingConfig.showHand = false
103+
// Merge config into appViewer's config to maintain reactivity
104+
Object.assign(appViewer.inWorldRenderingConfig, config.worldConfig)
111105
}
112106
if (config.continuousRender !== undefined) this.continuousRender = config.continuousRender
113107

114-
// Initialize resources manager
115-
this.resourcesManager = new ResourcesManager()
116-
117108
void this.initData().then(() => {
118109
this.addKeyboardShortcuts()
119110
})
@@ -220,41 +211,18 @@ export class BasePlaygroundScene {
220211

221212
this.initGui()
222213

223-
// Create world view
224-
const worldView = new WorldDataEmitter(world, this.viewDistance, this.targetPos)
225-
worldView.addWaitTime = 0
226-
this.worldView = worldView
227-
window.worldView = worldView
228-
229-
// Initialize resources manager
230-
this.resourcesManager.currentConfig = { version: this.version, noInventoryGui: true }
231-
await this.resourcesManager.loadSourceData(this.version)
232-
await this.resourcesManager.updateAssetsData({})
233-
234-
// Create graphics backend using modern architecture
235-
const graphicsConfig: GraphicsBackendConfig = {
236-
sceneBackground: 'lightblue',
237-
powerPreference: undefined,
238-
fpsLimit: undefined,
239-
statsVisible: 0,
240-
timeoutRendering: false
241-
}
214+
// Use appViewer for resource management and world rendering
215+
// worldConfig is already synced with appViewer.inWorldRenderingConfig via getter/setter
242216

243-
const initOptions = {
244-
resourcesManager: this.resourcesManager as any, // Type assertion needed for playground mode
245-
config: graphicsConfig,
246-
rendererSpecificSettings: {},
247-
callbacks: {
248-
displayCriticalError (error: Error) {
249-
console.error('Graphics error:', error)
250-
},
251-
setRendererSpecificSettings () {},
252-
fireCustomEvent () {}
253-
}
254-
}
217+
// Initialize resources manager via appViewer
218+
appViewer.resourcesManager.currentConfig = { version: this.version, noInventoryGui: true }
219+
await appViewer.resourcesManager.loadSourceData(this.version)
220+
await appViewer.resourcesManager.updateAssetsData({})
255221

256-
// Create graphics backend (it creates DocumentRenderer internally and sets up render loop)
257-
this.graphicsBackend = await createGraphicsBackend(initOptions)
222+
// Load backend if not already loaded
223+
if (!appViewer.backend) {
224+
await appViewer.loadBackend(createGraphicsBackend)
225+
}
258226

259227
// Canvas is created by DocumentRenderer inside graphicsBackend
260228
// Ensure it has the right ID
@@ -263,41 +231,13 @@ export class BasePlaygroundScene {
263231
rendererCanvas.id = 'viewer-canvas'
264232
}
265233

266-
// Create display options for world
267-
const playerStateReactive = proxy(getInitialPlayerState())
268-
const rendererState = proxy({
269-
world: {
270-
chunksLoaded: new Set<string>(),
271-
heightmaps: new Map<string, Uint8Array>(),
272-
allChunksLoaded: false,
273-
mesherWork: false,
274-
intersectMedia: null
275-
},
276-
renderer: 'threejs',
277-
preventEscapeMenu: false
278-
})
279-
const nonReactiveState = {
280-
world: {
281-
chunksLoaded: new Set<string>(),
282-
chunksTotalNumber: 0
283-
}
284-
}
285-
286-
const displayOptions = {
287-
version: this.version,
288-
worldView: worldView as any,
289-
inWorldRenderingConfig: this.worldConfig,
290-
playerStateReactive,
291-
rendererState,
292-
nonReactiveState
293-
}
294-
295-
// Start world using graphics backend
296-
// This creates WorldRendererThree internally and sets window.world
297-
await this.graphicsBackend.startWorld(displayOptions)
234+
// Start world using appViewer
235+
// This creates WorldDataEmitter, GraphicsBackend, and WorldRendererThree internally
236+
await appViewer.startWorld(world, this.viewDistance, proxy(getInitialPlayerState()), this.targetPos)
298237

299-
// Get world renderer from window.world (set by graphicsBackend.startWorld)
238+
// Get world renderer and world view from appViewer
300239
this.worldRenderer = window.world as WorldRendererThree
240+
this.worldView = appViewer.worldView
301241
window.viewer = this.worldRenderer // For backward compatibility with old scenes
302242

303243
if (!this.worldRenderer) {
@@ -313,11 +253,14 @@ export class BasePlaygroundScene {
313253
this.render()
314254
}
315255

316-
// Setup world
256+
// Setup world (adds blocks, etc.)
317257
this.setupWorld()
318258

319-
// Initialize world view
320-
await worldView.init(this.targetPos)
259+
// Initialize world view with target position (loads chunks after setup)
260+
if (this.worldView) {
261+
this.worldView.addWaitTime = 0
262+
await this.worldView.init(this.targetPos)
263+
}
321264

322265
// Setup camera controls
323266
if (this.enableCameraControls) {

src/appViewer.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,11 @@ export class AppViewer {
172172
const { method, args } = this.currentState
173173
this.backend[method](...args)
174174
if (method === 'startWorld') {
175-
void this.worldView!.init(bot.entity.position)
175+
// Only auto-init if bot exists (main app mode)
176+
// Playground mode will call init explicitly with its position
177+
if (bot?.entity?.position) {
178+
void this.worldView!.init(bot.entity.position)
179+
}
176180
// void this.worldView!.init(args[0].playerState.getPosition())
177181
}
178182
}
@@ -194,11 +198,11 @@ export class AppViewer {
194198
}
195199
}
196200

197-
async startWorld (world, renderDistance: number, playerStateSend: PlayerStateRenderer = this.playerState.reactive) {
201+
async startWorld (world, renderDistance: number, playerStateSend: PlayerStateRenderer = this.playerState.reactive, startPosition?: Vec3) {
198202
if (this.currentDisplay === 'world') throw new Error('World already started')
199203
this.currentDisplay = 'world'
200-
const startPosition = bot.entity?.position ?? new Vec3(0, 64, 0)
201-
this.worldView = new WorldDataEmitter(world, renderDistance, startPosition)
204+
const finalStartPosition = startPosition ?? bot?.entity?.position ?? new Vec3(0, 64, 0)
205+
this.worldView = new WorldDataEmitter(world, renderDistance, finalStartPosition)
202206
this.worldView.panicChunksReload = () => {
203207
if (!options.experimentalClientSelfReload) return
204208
if (process.env.NODE_ENV === 'development') {

0 commit comments

Comments
 (0)