cubeforge 0.3.11 → 0.3.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +27 -16
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -9,6 +9,8 @@ var ECSWorld = class {
9
9
  // Seeded RNG (LCG) for deterministic mode
10
10
  _rngState = 0;
11
11
  _deterministic = false;
12
+ /** Asset manager reference — set by Game, available in Script callbacks via world.assets */
13
+ assets;
12
14
  // Primary storage: archetypes keyed by sorted type string
13
15
  archetypes = /* @__PURE__ */ new Map();
14
16
  // Which archetype each entity lives in
@@ -343,6 +345,11 @@ var AssetManager = class {
343
345
  _loaded = 0;
344
346
  _total = 0;
345
347
  _progressListeners = /* @__PURE__ */ new Set();
348
+ /** Base URL prefix applied to all asset paths starting with '/'. Set by Game component. */
349
+ baseURL = "";
350
+ resolve(src) {
351
+ return this.baseURL && src.startsWith("/") ? this.baseURL + src : src;
352
+ }
346
353
  getAudioContext() {
347
354
  if (!this.audioCtx) {
348
355
  this.audioCtx = new AudioContext();
@@ -371,28 +378,29 @@ var AssetManager = class {
371
378
  return () => this._progressListeners.delete(cb);
372
379
  }
373
380
  async loadImage(src) {
374
- if (this.imagePromises.has(src)) return this.imagePromises.get(src);
381
+ const resolved = this.resolve(src);
382
+ if (this.imagePromises.has(resolved)) return this.imagePromises.get(resolved);
375
383
  this._total++;
376
384
  this.emitProgress();
377
385
  const promise = (async () => {
378
386
  const img = new Image();
379
- img.src = src;
387
+ img.src = resolved;
380
388
  try {
381
389
  await new Promise((resolve, reject) => {
382
390
  img.onload = () => resolve();
383
391
  img.onerror = () => reject(new Error(`Failed to load image: ${src}`));
384
392
  });
385
393
  } catch (err) {
386
- console.warn(`[Cubeforge] Failed to load image: ${src}`);
394
+ console.warn(`[Cubeforge] Failed to load image: ${resolved}`);
387
395
  throw err;
388
396
  } finally {
389
397
  this._loaded++;
390
398
  this.emitProgress();
391
399
  }
392
- this.images.set(src, img);
400
+ this.images.set(resolved, img);
393
401
  return img;
394
402
  })();
395
- this.imagePromises.set(src, promise);
403
+ this.imagePromises.set(resolved, promise);
396
404
  return promise;
397
405
  }
398
406
  /** Resolves once every image that has been requested via loadImage() is settled. */
@@ -400,23 +408,24 @@ var AssetManager = class {
400
408
  await Promise.allSettled([...this.imagePromises.values()]);
401
409
  }
402
410
  getImage(src) {
403
- return this.images.get(src);
411
+ return this.images.get(this.resolve(src));
404
412
  }
405
413
  /** Returns a read-only snapshot of all loaded images keyed by src. */
406
414
  getLoadedImages() {
407
415
  return this.images;
408
416
  }
409
417
  async loadAudio(src) {
410
- if (this.audio.has(src)) return this.audio.get(src);
418
+ const resolved = this.resolve(src);
419
+ if (this.audio.has(resolved)) return this.audio.get(resolved);
411
420
  const ctx = this.getAudioContext();
412
421
  try {
413
- const response = await fetch(src);
422
+ const response = await fetch(resolved);
414
423
  const arrayBuffer = await response.arrayBuffer();
415
424
  const audioBuffer = await ctx.decodeAudioData(arrayBuffer);
416
- this.audio.set(src, audioBuffer);
425
+ this.audio.set(resolved, audioBuffer);
417
426
  return audioBuffer;
418
427
  } catch (err) {
419
- console.warn(`[Cubeforge] Failed to load audio: ${src}`);
428
+ console.warn(`[Cubeforge] Failed to load audio: ${resolved}`);
420
429
  throw err;
421
430
  }
422
431
  }
@@ -3884,6 +3893,9 @@ function Game({
3884
3893
  const input = new InputManager();
3885
3894
  const events = new EventBus();
3886
3895
  const assets = new AssetManager();
3896
+ const viteEnv = import.meta.env;
3897
+ assets.baseURL = (viteEnv?.BASE_URL ?? "/").replace(/\/$/, "");
3898
+ ecs.assets = assets;
3887
3899
  const physics = new PhysicsSystem(gravity, events);
3888
3900
  const entityIds = /* @__PURE__ */ new Map();
3889
3901
  const renderSystem = new RenderSystem(canvas, entityIds);
@@ -4210,13 +4222,12 @@ function Sprite({
4210
4222
  });
4211
4223
  engine.ecs.addComponent(entityId, comp);
4212
4224
  if (src) {
4213
- const viteEnv = import.meta.env;
4214
- const base = (viteEnv?.BASE_URL ?? "/").replace(/\/$/, "");
4215
- const resolvedSrc = base && src.startsWith("/") ? base + src : src;
4216
- comp.src = resolvedSrc;
4217
- engine.assets.loadImage(resolvedSrc).then((img) => {
4225
+ engine.assets.loadImage(src).then((img) => {
4218
4226
  const c = engine.ecs.getComponent(entityId, "Sprite");
4219
- if (c) c.image = img;
4227
+ if (c) {
4228
+ c.image = img;
4229
+ c.src = img.src;
4230
+ }
4220
4231
  }).catch(console.error);
4221
4232
  }
4222
4233
  return () => engine.ecs.removeComponent(entityId, "Sprite");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cubeforge",
3
- "version": "0.3.11",
3
+ "version": "0.3.13",
4
4
  "description": "React-first 2D browser game engine",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",