@almadar/ui 5.51.0 → 5.53.0
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.
- package/dist/avl/index.cjs +46 -17
- package/dist/avl/index.js +46 -17
- package/dist/components/index.cjs +25 -3
- package/dist/components/index.js +25 -3
- package/dist/providers/index.cjs +25 -3
- package/dist/providers/index.js +25 -3
- package/dist/runtime/createClientEffectHandlers.d.ts +12 -1
- package/dist/runtime/index.cjs +46 -17
- package/dist/runtime/index.js +46 -17
- package/package.json +1 -1
package/dist/avl/index.cjs
CHANGED
|
@@ -31382,6 +31382,7 @@ function PlatformerCanvas({
|
|
|
31382
31382
|
const canvasRef = React90.useRef(null);
|
|
31383
31383
|
const eventBus = useEventBus();
|
|
31384
31384
|
const keysRef = React90.useRef(/* @__PURE__ */ new Set());
|
|
31385
|
+
const lastPlatCountRef = React90.useRef(-1);
|
|
31385
31386
|
const imageCache = React90.useRef(/* @__PURE__ */ new Map());
|
|
31386
31387
|
const [loadedImages, setLoadedImages] = React90.useState(/* @__PURE__ */ new Set());
|
|
31387
31388
|
const loadImage = React90.useCallback((url) => {
|
|
@@ -31537,6 +31538,18 @@ function PlatformerCanvas({
|
|
|
31537
31538
|
camX = Math.max(0, Math.min(px - cw / 2, ww - cw));
|
|
31538
31539
|
camY = Math.max(0, Math.min(py - ch / 2 - 50, wh - ch));
|
|
31539
31540
|
}
|
|
31541
|
+
if (plats.length !== lastPlatCountRef.current) {
|
|
31542
|
+
lastPlatCountRef.current = plats.length;
|
|
31543
|
+
canvasLog.debug("draw:platforms", {
|
|
31544
|
+
platformCount: plats.length,
|
|
31545
|
+
camX,
|
|
31546
|
+
camY,
|
|
31547
|
+
player: { x: px, y: py },
|
|
31548
|
+
worldWidth: ww,
|
|
31549
|
+
canvasWidth: cw,
|
|
31550
|
+
followCamera: fc
|
|
31551
|
+
});
|
|
31552
|
+
}
|
|
31540
31553
|
const bgImage = bgImg ? loadImage(bgImg) : null;
|
|
31541
31554
|
if (bgImage) {
|
|
31542
31555
|
ctx.drawImage(bgImage, 0, 0, cw, ch);
|
|
@@ -31662,13 +31675,14 @@ function PlatformerCanvas({
|
|
|
31662
31675
|
}
|
|
31663
31676
|
);
|
|
31664
31677
|
}
|
|
31665
|
-
var PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR;
|
|
31678
|
+
var canvasLog, PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR;
|
|
31666
31679
|
var init_PlatformerCanvas = __esm({
|
|
31667
31680
|
"components/game/molecules/PlatformerCanvas.tsx"() {
|
|
31668
31681
|
init_cn();
|
|
31669
31682
|
init_useEventBus();
|
|
31670
31683
|
init_verificationRegistry();
|
|
31671
31684
|
init_useRenderInterpolation();
|
|
31685
|
+
canvasLog = logger.createLogger("almadar:ui:game:platformer-canvas");
|
|
31672
31686
|
PLATFORM_COLORS = {
|
|
31673
31687
|
ground: "#4a7c59",
|
|
31674
31688
|
platform: "#7c6b4a",
|
|
@@ -46605,14 +46619,20 @@ function PlatformerBoard({
|
|
|
46605
46619
|
grounded: false,
|
|
46606
46620
|
facingRight: true
|
|
46607
46621
|
};
|
|
46608
|
-
const
|
|
46609
|
-
const platforms = propPlatforms ?? entityPlatforms ?? [
|
|
46622
|
+
const platforms = propPlatforms ?? [
|
|
46610
46623
|
{ x: 0, y: 368, width: 800, height: 32, type: "ground" },
|
|
46611
46624
|
{ x: 150, y: 280, width: 160, height: 16, type: "platform" },
|
|
46612
46625
|
{ x: 420, y: 220, width: 160, height: 16, type: "platform" },
|
|
46613
46626
|
{ x: 580, y: 300, width: 80, height: 16, type: "hazard" },
|
|
46614
46627
|
{ x: 700, y: 340, width: 64, height: 28, type: "goal" }
|
|
46615
46628
|
];
|
|
46629
|
+
boardLog.debug("platforms-resolve", {
|
|
46630
|
+
propPlatformsCount: Array.isArray(propPlatforms) ? propPlatforms.length : null,
|
|
46631
|
+
usedFallback: propPlatforms === void 0,
|
|
46632
|
+
finalCount: platforms.length,
|
|
46633
|
+
player: { x: player.x, y: player.y, vx: player.vx, vy: player.vy, grounded: player.grounded },
|
|
46634
|
+
result
|
|
46635
|
+
});
|
|
46616
46636
|
const handleRestart = React90.useCallback(() => {
|
|
46617
46637
|
if (playAgainEvent) {
|
|
46618
46638
|
eventBus.emit(`UI:${playAgainEvent}`, {});
|
|
@@ -46691,6 +46711,7 @@ function PlatformerBoard({
|
|
|
46691
46711
|
}
|
|
46692
46712
|
);
|
|
46693
46713
|
}
|
|
46714
|
+
var boardLog;
|
|
46694
46715
|
var init_PlatformerBoard = __esm({
|
|
46695
46716
|
"components/game/organisms/PlatformerBoard.tsx"() {
|
|
46696
46717
|
"use client";
|
|
@@ -46701,6 +46722,7 @@ var init_PlatformerBoard = __esm({
|
|
|
46701
46722
|
init_Typography();
|
|
46702
46723
|
init_Stack();
|
|
46703
46724
|
init_PlatformerCanvas();
|
|
46725
|
+
boardLog = logger.createLogger("almadar:ui:game:platformer-board");
|
|
46704
46726
|
PlatformerBoard.displayName = "PlatformerBoard";
|
|
46705
46727
|
}
|
|
46706
46728
|
});
|
|
@@ -57351,7 +57373,7 @@ function convertFnFormLambdasInProps(props) {
|
|
|
57351
57373
|
}
|
|
57352
57374
|
var log10 = logger.createLogger("almadar:ui:effects:client-handlers");
|
|
57353
57375
|
function createClientEffectHandlers(options) {
|
|
57354
|
-
const { eventBus, slotSetter, navigate, notify, callService } = options;
|
|
57376
|
+
const { eventBus, slotSetter, navigate, notify, callService, liveEntity } = options;
|
|
57355
57377
|
return {
|
|
57356
57378
|
emit: (event, payload) => {
|
|
57357
57379
|
const prefixedEvent = event.startsWith("UI:") ? event : `UI:${event}`;
|
|
@@ -57360,8 +57382,12 @@ function createClientEffectHandlers(options) {
|
|
|
57360
57382
|
persist: async () => {
|
|
57361
57383
|
log10.warn("persist is server-side only, ignored on client");
|
|
57362
57384
|
},
|
|
57363
|
-
set: () => {
|
|
57364
|
-
|
|
57385
|
+
set: (_entityId, field, value) => {
|
|
57386
|
+
if (!liveEntity) {
|
|
57387
|
+
log10.warn("set is server-side only, ignored on client (no live entity)");
|
|
57388
|
+
return;
|
|
57389
|
+
}
|
|
57390
|
+
liveEntity[field] = value;
|
|
57365
57391
|
},
|
|
57366
57392
|
callService: async (service, action, params) => {
|
|
57367
57393
|
if (callService) return callService(service, action, params);
|
|
@@ -57629,6 +57655,11 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
57629
57655
|
const traitName = binding.trait.name;
|
|
57630
57656
|
const linkedEntity = binding.linkedEntity || "";
|
|
57631
57657
|
const entityId = payload?.entityId;
|
|
57658
|
+
let liveEntity = traitFieldStatesRef.current.get(traitName);
|
|
57659
|
+
if (!liveEntity) {
|
|
57660
|
+
liveEntity = {};
|
|
57661
|
+
traitFieldStatesRef.current.set(traitName, liveEntity);
|
|
57662
|
+
}
|
|
57632
57663
|
const effects = syncOnly ? params.effects.filter(
|
|
57633
57664
|
(e) => Array.isArray(e) && SYNC_TICK_OPERATORS.has(String(e[0]))
|
|
57634
57665
|
) : params.effects;
|
|
@@ -57651,7 +57682,12 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
57651
57682
|
},
|
|
57652
57683
|
navigate: optionsRef.current?.navigate,
|
|
57653
57684
|
notify: optionsRef.current?.notify,
|
|
57654
|
-
callService: optionsRef.current?.callService
|
|
57685
|
+
callService: optionsRef.current?.callService,
|
|
57686
|
+
// The canonical client `set` writes `(set @entity.X)` straight into
|
|
57687
|
+
// the trait's one live store — the same object bound below. This is
|
|
57688
|
+
// what makes a [runtime] entity's set (from ticks AND events) reach
|
|
57689
|
+
// the render-ui + next tick + guards.
|
|
57690
|
+
liveEntity
|
|
57655
57691
|
});
|
|
57656
57692
|
const persistence = syncOnly ? void 0 : optionsRef.current?.persistence;
|
|
57657
57693
|
let handlers = clientHandlers;
|
|
@@ -57662,7 +57698,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
57662
57698
|
// uses below. `@payload.*` resolves from `payload` separately,
|
|
57663
57699
|
// so dropping the prior `payload as EntityRow` cast loses
|
|
57664
57700
|
// nothing — it just stops mislabelling the payload as an entity.
|
|
57665
|
-
entity:
|
|
57701
|
+
entity: liveEntity,
|
|
57666
57702
|
payload: payload || {},
|
|
57667
57703
|
state: previousState
|
|
57668
57704
|
};
|
|
@@ -57702,24 +57738,17 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
57702
57738
|
handlers = {
|
|
57703
57739
|
...handlers,
|
|
57704
57740
|
set: async (targetId, field, value) => {
|
|
57705
|
-
|
|
57706
|
-
if (!fieldState) {
|
|
57707
|
-
fieldState = {};
|
|
57708
|
-
traitFieldStatesRef.current.set(traitName, fieldState);
|
|
57709
|
-
}
|
|
57710
|
-
fieldState[field] = value;
|
|
57741
|
+
if (baseSet) await baseSet(targetId, field, value);
|
|
57711
57742
|
log15.debug("set:write", {
|
|
57712
57743
|
traitName,
|
|
57713
57744
|
field,
|
|
57714
57745
|
value: JSON.stringify(value),
|
|
57715
57746
|
transition: `${previousState}->${newState}`
|
|
57716
57747
|
});
|
|
57717
|
-
if (baseSet) await baseSet(targetId, field, value);
|
|
57718
57748
|
}
|
|
57719
57749
|
};
|
|
57720
|
-
const entityForBinding = traitFieldStatesRef.current.get(traitName) ?? {};
|
|
57721
57750
|
const bindingCtx = {
|
|
57722
|
-
entity:
|
|
57751
|
+
entity: liveEntity,
|
|
57723
57752
|
payload: payload || {},
|
|
57724
57753
|
state: previousState
|
|
57725
57754
|
};
|
package/dist/avl/index.js
CHANGED
|
@@ -31335,6 +31335,7 @@ function PlatformerCanvas({
|
|
|
31335
31335
|
const canvasRef = useRef(null);
|
|
31336
31336
|
const eventBus = useEventBus();
|
|
31337
31337
|
const keysRef = useRef(/* @__PURE__ */ new Set());
|
|
31338
|
+
const lastPlatCountRef = useRef(-1);
|
|
31338
31339
|
const imageCache = useRef(/* @__PURE__ */ new Map());
|
|
31339
31340
|
const [loadedImages, setLoadedImages] = useState(/* @__PURE__ */ new Set());
|
|
31340
31341
|
const loadImage = useCallback((url) => {
|
|
@@ -31490,6 +31491,18 @@ function PlatformerCanvas({
|
|
|
31490
31491
|
camX = Math.max(0, Math.min(px - cw / 2, ww - cw));
|
|
31491
31492
|
camY = Math.max(0, Math.min(py - ch / 2 - 50, wh - ch));
|
|
31492
31493
|
}
|
|
31494
|
+
if (plats.length !== lastPlatCountRef.current) {
|
|
31495
|
+
lastPlatCountRef.current = plats.length;
|
|
31496
|
+
canvasLog.debug("draw:platforms", {
|
|
31497
|
+
platformCount: plats.length,
|
|
31498
|
+
camX,
|
|
31499
|
+
camY,
|
|
31500
|
+
player: { x: px, y: py },
|
|
31501
|
+
worldWidth: ww,
|
|
31502
|
+
canvasWidth: cw,
|
|
31503
|
+
followCamera: fc
|
|
31504
|
+
});
|
|
31505
|
+
}
|
|
31493
31506
|
const bgImage = bgImg ? loadImage(bgImg) : null;
|
|
31494
31507
|
if (bgImage) {
|
|
31495
31508
|
ctx.drawImage(bgImage, 0, 0, cw, ch);
|
|
@@ -31615,13 +31628,14 @@ function PlatformerCanvas({
|
|
|
31615
31628
|
}
|
|
31616
31629
|
);
|
|
31617
31630
|
}
|
|
31618
|
-
var PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR;
|
|
31631
|
+
var canvasLog, PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR;
|
|
31619
31632
|
var init_PlatformerCanvas = __esm({
|
|
31620
31633
|
"components/game/molecules/PlatformerCanvas.tsx"() {
|
|
31621
31634
|
init_cn();
|
|
31622
31635
|
init_useEventBus();
|
|
31623
31636
|
init_verificationRegistry();
|
|
31624
31637
|
init_useRenderInterpolation();
|
|
31638
|
+
canvasLog = createLogger("almadar:ui:game:platformer-canvas");
|
|
31625
31639
|
PLATFORM_COLORS = {
|
|
31626
31640
|
ground: "#4a7c59",
|
|
31627
31641
|
platform: "#7c6b4a",
|
|
@@ -46558,14 +46572,20 @@ function PlatformerBoard({
|
|
|
46558
46572
|
grounded: false,
|
|
46559
46573
|
facingRight: true
|
|
46560
46574
|
};
|
|
46561
|
-
const
|
|
46562
|
-
const platforms = propPlatforms ?? entityPlatforms ?? [
|
|
46575
|
+
const platforms = propPlatforms ?? [
|
|
46563
46576
|
{ x: 0, y: 368, width: 800, height: 32, type: "ground" },
|
|
46564
46577
|
{ x: 150, y: 280, width: 160, height: 16, type: "platform" },
|
|
46565
46578
|
{ x: 420, y: 220, width: 160, height: 16, type: "platform" },
|
|
46566
46579
|
{ x: 580, y: 300, width: 80, height: 16, type: "hazard" },
|
|
46567
46580
|
{ x: 700, y: 340, width: 64, height: 28, type: "goal" }
|
|
46568
46581
|
];
|
|
46582
|
+
boardLog.debug("platforms-resolve", {
|
|
46583
|
+
propPlatformsCount: Array.isArray(propPlatforms) ? propPlatforms.length : null,
|
|
46584
|
+
usedFallback: propPlatforms === void 0,
|
|
46585
|
+
finalCount: platforms.length,
|
|
46586
|
+
player: { x: player.x, y: player.y, vx: player.vx, vy: player.vy, grounded: player.grounded },
|
|
46587
|
+
result
|
|
46588
|
+
});
|
|
46569
46589
|
const handleRestart = useCallback(() => {
|
|
46570
46590
|
if (playAgainEvent) {
|
|
46571
46591
|
eventBus.emit(`UI:${playAgainEvent}`, {});
|
|
@@ -46644,6 +46664,7 @@ function PlatformerBoard({
|
|
|
46644
46664
|
}
|
|
46645
46665
|
);
|
|
46646
46666
|
}
|
|
46667
|
+
var boardLog;
|
|
46647
46668
|
var init_PlatformerBoard = __esm({
|
|
46648
46669
|
"components/game/organisms/PlatformerBoard.tsx"() {
|
|
46649
46670
|
"use client";
|
|
@@ -46654,6 +46675,7 @@ var init_PlatformerBoard = __esm({
|
|
|
46654
46675
|
init_Typography();
|
|
46655
46676
|
init_Stack();
|
|
46656
46677
|
init_PlatformerCanvas();
|
|
46678
|
+
boardLog = createLogger("almadar:ui:game:platformer-board");
|
|
46657
46679
|
PlatformerBoard.displayName = "PlatformerBoard";
|
|
46658
46680
|
}
|
|
46659
46681
|
});
|
|
@@ -57304,7 +57326,7 @@ function convertFnFormLambdasInProps(props) {
|
|
|
57304
57326
|
}
|
|
57305
57327
|
var log10 = createLogger("almadar:ui:effects:client-handlers");
|
|
57306
57328
|
function createClientEffectHandlers(options) {
|
|
57307
|
-
const { eventBus, slotSetter, navigate, notify, callService } = options;
|
|
57329
|
+
const { eventBus, slotSetter, navigate, notify, callService, liveEntity } = options;
|
|
57308
57330
|
return {
|
|
57309
57331
|
emit: (event, payload) => {
|
|
57310
57332
|
const prefixedEvent = event.startsWith("UI:") ? event : `UI:${event}`;
|
|
@@ -57313,8 +57335,12 @@ function createClientEffectHandlers(options) {
|
|
|
57313
57335
|
persist: async () => {
|
|
57314
57336
|
log10.warn("persist is server-side only, ignored on client");
|
|
57315
57337
|
},
|
|
57316
|
-
set: () => {
|
|
57317
|
-
|
|
57338
|
+
set: (_entityId, field, value) => {
|
|
57339
|
+
if (!liveEntity) {
|
|
57340
|
+
log10.warn("set is server-side only, ignored on client (no live entity)");
|
|
57341
|
+
return;
|
|
57342
|
+
}
|
|
57343
|
+
liveEntity[field] = value;
|
|
57318
57344
|
},
|
|
57319
57345
|
callService: async (service, action, params) => {
|
|
57320
57346
|
if (callService) return callService(service, action, params);
|
|
@@ -57582,6 +57608,11 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
57582
57608
|
const traitName = binding.trait.name;
|
|
57583
57609
|
const linkedEntity = binding.linkedEntity || "";
|
|
57584
57610
|
const entityId = payload?.entityId;
|
|
57611
|
+
let liveEntity = traitFieldStatesRef.current.get(traitName);
|
|
57612
|
+
if (!liveEntity) {
|
|
57613
|
+
liveEntity = {};
|
|
57614
|
+
traitFieldStatesRef.current.set(traitName, liveEntity);
|
|
57615
|
+
}
|
|
57585
57616
|
const effects = syncOnly ? params.effects.filter(
|
|
57586
57617
|
(e) => Array.isArray(e) && SYNC_TICK_OPERATORS.has(String(e[0]))
|
|
57587
57618
|
) : params.effects;
|
|
@@ -57604,7 +57635,12 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
57604
57635
|
},
|
|
57605
57636
|
navigate: optionsRef.current?.navigate,
|
|
57606
57637
|
notify: optionsRef.current?.notify,
|
|
57607
|
-
callService: optionsRef.current?.callService
|
|
57638
|
+
callService: optionsRef.current?.callService,
|
|
57639
|
+
// The canonical client `set` writes `(set @entity.X)` straight into
|
|
57640
|
+
// the trait's one live store — the same object bound below. This is
|
|
57641
|
+
// what makes a [runtime] entity's set (from ticks AND events) reach
|
|
57642
|
+
// the render-ui + next tick + guards.
|
|
57643
|
+
liveEntity
|
|
57608
57644
|
});
|
|
57609
57645
|
const persistence = syncOnly ? void 0 : optionsRef.current?.persistence;
|
|
57610
57646
|
let handlers = clientHandlers;
|
|
@@ -57615,7 +57651,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
57615
57651
|
// uses below. `@payload.*` resolves from `payload` separately,
|
|
57616
57652
|
// so dropping the prior `payload as EntityRow` cast loses
|
|
57617
57653
|
// nothing — it just stops mislabelling the payload as an entity.
|
|
57618
|
-
entity:
|
|
57654
|
+
entity: liveEntity,
|
|
57619
57655
|
payload: payload || {},
|
|
57620
57656
|
state: previousState
|
|
57621
57657
|
};
|
|
@@ -57655,24 +57691,17 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
57655
57691
|
handlers = {
|
|
57656
57692
|
...handlers,
|
|
57657
57693
|
set: async (targetId, field, value) => {
|
|
57658
|
-
|
|
57659
|
-
if (!fieldState) {
|
|
57660
|
-
fieldState = {};
|
|
57661
|
-
traitFieldStatesRef.current.set(traitName, fieldState);
|
|
57662
|
-
}
|
|
57663
|
-
fieldState[field] = value;
|
|
57694
|
+
if (baseSet) await baseSet(targetId, field, value);
|
|
57664
57695
|
log15.debug("set:write", {
|
|
57665
57696
|
traitName,
|
|
57666
57697
|
field,
|
|
57667
57698
|
value: JSON.stringify(value),
|
|
57668
57699
|
transition: `${previousState}->${newState}`
|
|
57669
57700
|
});
|
|
57670
|
-
if (baseSet) await baseSet(targetId, field, value);
|
|
57671
57701
|
}
|
|
57672
57702
|
};
|
|
57673
|
-
const entityForBinding = traitFieldStatesRef.current.get(traitName) ?? {};
|
|
57674
57703
|
const bindingCtx = {
|
|
57675
|
-
entity:
|
|
57704
|
+
entity: liveEntity,
|
|
57676
57705
|
payload: payload || {},
|
|
57677
57706
|
state: previousState
|
|
57678
57707
|
};
|
|
@@ -29178,6 +29178,7 @@ function PlatformerCanvas({
|
|
|
29178
29178
|
const canvasRef = React76.useRef(null);
|
|
29179
29179
|
const eventBus = useEventBus();
|
|
29180
29180
|
const keysRef = React76.useRef(/* @__PURE__ */ new Set());
|
|
29181
|
+
const lastPlatCountRef = React76.useRef(-1);
|
|
29181
29182
|
const imageCache = React76.useRef(/* @__PURE__ */ new Map());
|
|
29182
29183
|
const [loadedImages, setLoadedImages] = React76.useState(/* @__PURE__ */ new Set());
|
|
29183
29184
|
const loadImage = React76.useCallback((url) => {
|
|
@@ -29333,6 +29334,18 @@ function PlatformerCanvas({
|
|
|
29333
29334
|
camX = Math.max(0, Math.min(px - cw / 2, ww - cw));
|
|
29334
29335
|
camY = Math.max(0, Math.min(py - ch / 2 - 50, wh - ch));
|
|
29335
29336
|
}
|
|
29337
|
+
if (plats.length !== lastPlatCountRef.current) {
|
|
29338
|
+
lastPlatCountRef.current = plats.length;
|
|
29339
|
+
canvasLog.debug("draw:platforms", {
|
|
29340
|
+
platformCount: plats.length,
|
|
29341
|
+
camX,
|
|
29342
|
+
camY,
|
|
29343
|
+
player: { x: px, y: py },
|
|
29344
|
+
worldWidth: ww,
|
|
29345
|
+
canvasWidth: cw,
|
|
29346
|
+
followCamera: fc
|
|
29347
|
+
});
|
|
29348
|
+
}
|
|
29336
29349
|
const bgImage = bgImg ? loadImage(bgImg) : null;
|
|
29337
29350
|
if (bgImage) {
|
|
29338
29351
|
ctx.drawImage(bgImage, 0, 0, cw, ch);
|
|
@@ -29458,13 +29471,14 @@ function PlatformerCanvas({
|
|
|
29458
29471
|
}
|
|
29459
29472
|
);
|
|
29460
29473
|
}
|
|
29461
|
-
var PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR;
|
|
29474
|
+
var canvasLog, PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR;
|
|
29462
29475
|
var init_PlatformerCanvas = __esm({
|
|
29463
29476
|
"components/game/molecules/PlatformerCanvas.tsx"() {
|
|
29464
29477
|
init_cn();
|
|
29465
29478
|
init_useEventBus();
|
|
29466
29479
|
init_verificationRegistry();
|
|
29467
29480
|
init_useRenderInterpolation();
|
|
29481
|
+
canvasLog = logger.createLogger("almadar:ui:game:platformer-canvas");
|
|
29468
29482
|
PLATFORM_COLORS = {
|
|
29469
29483
|
ground: "#4a7c59",
|
|
29470
29484
|
platform: "#7c6b4a",
|
|
@@ -45267,14 +45281,20 @@ function PlatformerBoard({
|
|
|
45267
45281
|
grounded: false,
|
|
45268
45282
|
facingRight: true
|
|
45269
45283
|
};
|
|
45270
|
-
const
|
|
45271
|
-
const platforms = propPlatforms ?? entityPlatforms ?? [
|
|
45284
|
+
const platforms = propPlatforms ?? [
|
|
45272
45285
|
{ x: 0, y: 368, width: 800, height: 32, type: "ground" },
|
|
45273
45286
|
{ x: 150, y: 280, width: 160, height: 16, type: "platform" },
|
|
45274
45287
|
{ x: 420, y: 220, width: 160, height: 16, type: "platform" },
|
|
45275
45288
|
{ x: 580, y: 300, width: 80, height: 16, type: "hazard" },
|
|
45276
45289
|
{ x: 700, y: 340, width: 64, height: 28, type: "goal" }
|
|
45277
45290
|
];
|
|
45291
|
+
boardLog.debug("platforms-resolve", {
|
|
45292
|
+
propPlatformsCount: Array.isArray(propPlatforms) ? propPlatforms.length : null,
|
|
45293
|
+
usedFallback: propPlatforms === void 0,
|
|
45294
|
+
finalCount: platforms.length,
|
|
45295
|
+
player: { x: player.x, y: player.y, vx: player.vx, vy: player.vy, grounded: player.grounded },
|
|
45296
|
+
result
|
|
45297
|
+
});
|
|
45278
45298
|
const handleRestart = React76.useCallback(() => {
|
|
45279
45299
|
if (playAgainEvent) {
|
|
45280
45300
|
eventBus.emit(`UI:${playAgainEvent}`, {});
|
|
@@ -45353,6 +45373,7 @@ function PlatformerBoard({
|
|
|
45353
45373
|
}
|
|
45354
45374
|
);
|
|
45355
45375
|
}
|
|
45376
|
+
var boardLog;
|
|
45356
45377
|
var init_PlatformerBoard = __esm({
|
|
45357
45378
|
"components/game/organisms/PlatformerBoard.tsx"() {
|
|
45358
45379
|
"use client";
|
|
@@ -45363,6 +45384,7 @@ var init_PlatformerBoard = __esm({
|
|
|
45363
45384
|
init_Typography();
|
|
45364
45385
|
init_Stack();
|
|
45365
45386
|
init_PlatformerCanvas();
|
|
45387
|
+
boardLog = logger.createLogger("almadar:ui:game:platformer-board");
|
|
45366
45388
|
PlatformerBoard.displayName = "PlatformerBoard";
|
|
45367
45389
|
}
|
|
45368
45390
|
});
|
package/dist/components/index.js
CHANGED
|
@@ -29132,6 +29132,7 @@ function PlatformerCanvas({
|
|
|
29132
29132
|
const canvasRef = useRef(null);
|
|
29133
29133
|
const eventBus = useEventBus();
|
|
29134
29134
|
const keysRef = useRef(/* @__PURE__ */ new Set());
|
|
29135
|
+
const lastPlatCountRef = useRef(-1);
|
|
29135
29136
|
const imageCache = useRef(/* @__PURE__ */ new Map());
|
|
29136
29137
|
const [loadedImages, setLoadedImages] = useState(/* @__PURE__ */ new Set());
|
|
29137
29138
|
const loadImage = useCallback((url) => {
|
|
@@ -29287,6 +29288,18 @@ function PlatformerCanvas({
|
|
|
29287
29288
|
camX = Math.max(0, Math.min(px - cw / 2, ww - cw));
|
|
29288
29289
|
camY = Math.max(0, Math.min(py - ch / 2 - 50, wh - ch));
|
|
29289
29290
|
}
|
|
29291
|
+
if (plats.length !== lastPlatCountRef.current) {
|
|
29292
|
+
lastPlatCountRef.current = plats.length;
|
|
29293
|
+
canvasLog.debug("draw:platforms", {
|
|
29294
|
+
platformCount: plats.length,
|
|
29295
|
+
camX,
|
|
29296
|
+
camY,
|
|
29297
|
+
player: { x: px, y: py },
|
|
29298
|
+
worldWidth: ww,
|
|
29299
|
+
canvasWidth: cw,
|
|
29300
|
+
followCamera: fc
|
|
29301
|
+
});
|
|
29302
|
+
}
|
|
29290
29303
|
const bgImage = bgImg ? loadImage(bgImg) : null;
|
|
29291
29304
|
if (bgImage) {
|
|
29292
29305
|
ctx.drawImage(bgImage, 0, 0, cw, ch);
|
|
@@ -29412,13 +29425,14 @@ function PlatformerCanvas({
|
|
|
29412
29425
|
}
|
|
29413
29426
|
);
|
|
29414
29427
|
}
|
|
29415
|
-
var PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR;
|
|
29428
|
+
var canvasLog, PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR;
|
|
29416
29429
|
var init_PlatformerCanvas = __esm({
|
|
29417
29430
|
"components/game/molecules/PlatformerCanvas.tsx"() {
|
|
29418
29431
|
init_cn();
|
|
29419
29432
|
init_useEventBus();
|
|
29420
29433
|
init_verificationRegistry();
|
|
29421
29434
|
init_useRenderInterpolation();
|
|
29435
|
+
canvasLog = createLogger("almadar:ui:game:platformer-canvas");
|
|
29422
29436
|
PLATFORM_COLORS = {
|
|
29423
29437
|
ground: "#4a7c59",
|
|
29424
29438
|
platform: "#7c6b4a",
|
|
@@ -45221,14 +45235,20 @@ function PlatformerBoard({
|
|
|
45221
45235
|
grounded: false,
|
|
45222
45236
|
facingRight: true
|
|
45223
45237
|
};
|
|
45224
|
-
const
|
|
45225
|
-
const platforms = propPlatforms ?? entityPlatforms ?? [
|
|
45238
|
+
const platforms = propPlatforms ?? [
|
|
45226
45239
|
{ x: 0, y: 368, width: 800, height: 32, type: "ground" },
|
|
45227
45240
|
{ x: 150, y: 280, width: 160, height: 16, type: "platform" },
|
|
45228
45241
|
{ x: 420, y: 220, width: 160, height: 16, type: "platform" },
|
|
45229
45242
|
{ x: 580, y: 300, width: 80, height: 16, type: "hazard" },
|
|
45230
45243
|
{ x: 700, y: 340, width: 64, height: 28, type: "goal" }
|
|
45231
45244
|
];
|
|
45245
|
+
boardLog.debug("platforms-resolve", {
|
|
45246
|
+
propPlatformsCount: Array.isArray(propPlatforms) ? propPlatforms.length : null,
|
|
45247
|
+
usedFallback: propPlatforms === void 0,
|
|
45248
|
+
finalCount: platforms.length,
|
|
45249
|
+
player: { x: player.x, y: player.y, vx: player.vx, vy: player.vy, grounded: player.grounded },
|
|
45250
|
+
result
|
|
45251
|
+
});
|
|
45232
45252
|
const handleRestart = useCallback(() => {
|
|
45233
45253
|
if (playAgainEvent) {
|
|
45234
45254
|
eventBus.emit(`UI:${playAgainEvent}`, {});
|
|
@@ -45307,6 +45327,7 @@ function PlatformerBoard({
|
|
|
45307
45327
|
}
|
|
45308
45328
|
);
|
|
45309
45329
|
}
|
|
45330
|
+
var boardLog;
|
|
45310
45331
|
var init_PlatformerBoard = __esm({
|
|
45311
45332
|
"components/game/organisms/PlatformerBoard.tsx"() {
|
|
45312
45333
|
"use client";
|
|
@@ -45317,6 +45338,7 @@ var init_PlatformerBoard = __esm({
|
|
|
45317
45338
|
init_Typography();
|
|
45318
45339
|
init_Stack();
|
|
45319
45340
|
init_PlatformerCanvas();
|
|
45341
|
+
boardLog = createLogger("almadar:ui:game:platformer-board");
|
|
45320
45342
|
PlatformerBoard.displayName = "PlatformerBoard";
|
|
45321
45343
|
}
|
|
45322
45344
|
});
|
package/dist/providers/index.cjs
CHANGED
|
@@ -28774,6 +28774,7 @@ function PlatformerCanvas({
|
|
|
28774
28774
|
const canvasRef = React82.useRef(null);
|
|
28775
28775
|
const eventBus = useEventBus();
|
|
28776
28776
|
const keysRef = React82.useRef(/* @__PURE__ */ new Set());
|
|
28777
|
+
const lastPlatCountRef = React82.useRef(-1);
|
|
28777
28778
|
const imageCache = React82.useRef(/* @__PURE__ */ new Map());
|
|
28778
28779
|
const [loadedImages, setLoadedImages] = React82.useState(/* @__PURE__ */ new Set());
|
|
28779
28780
|
const loadImage = React82.useCallback((url) => {
|
|
@@ -28929,6 +28930,18 @@ function PlatformerCanvas({
|
|
|
28929
28930
|
camX = Math.max(0, Math.min(px - cw / 2, ww - cw));
|
|
28930
28931
|
camY = Math.max(0, Math.min(py - ch / 2 - 50, wh - ch));
|
|
28931
28932
|
}
|
|
28933
|
+
if (plats.length !== lastPlatCountRef.current) {
|
|
28934
|
+
lastPlatCountRef.current = plats.length;
|
|
28935
|
+
canvasLog.debug("draw:platforms", {
|
|
28936
|
+
platformCount: plats.length,
|
|
28937
|
+
camX,
|
|
28938
|
+
camY,
|
|
28939
|
+
player: { x: px, y: py },
|
|
28940
|
+
worldWidth: ww,
|
|
28941
|
+
canvasWidth: cw,
|
|
28942
|
+
followCamera: fc
|
|
28943
|
+
});
|
|
28944
|
+
}
|
|
28932
28945
|
const bgImage = bgImg ? loadImage(bgImg) : null;
|
|
28933
28946
|
if (bgImage) {
|
|
28934
28947
|
ctx.drawImage(bgImage, 0, 0, cw, ch);
|
|
@@ -29054,13 +29067,14 @@ function PlatformerCanvas({
|
|
|
29054
29067
|
}
|
|
29055
29068
|
);
|
|
29056
29069
|
}
|
|
29057
|
-
var PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR;
|
|
29070
|
+
var canvasLog, PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR;
|
|
29058
29071
|
var init_PlatformerCanvas = __esm({
|
|
29059
29072
|
"components/game/molecules/PlatformerCanvas.tsx"() {
|
|
29060
29073
|
init_cn();
|
|
29061
29074
|
init_useEventBus();
|
|
29062
29075
|
init_verificationRegistry();
|
|
29063
29076
|
init_useRenderInterpolation();
|
|
29077
|
+
canvasLog = logger.createLogger("almadar:ui:game:platformer-canvas");
|
|
29064
29078
|
PLATFORM_COLORS = {
|
|
29065
29079
|
ground: "#4a7c59",
|
|
29066
29080
|
platform: "#7c6b4a",
|
|
@@ -44406,14 +44420,20 @@ function PlatformerBoard({
|
|
|
44406
44420
|
grounded: false,
|
|
44407
44421
|
facingRight: true
|
|
44408
44422
|
};
|
|
44409
|
-
const
|
|
44410
|
-
const platforms = propPlatforms ?? entityPlatforms ?? [
|
|
44423
|
+
const platforms = propPlatforms ?? [
|
|
44411
44424
|
{ x: 0, y: 368, width: 800, height: 32, type: "ground" },
|
|
44412
44425
|
{ x: 150, y: 280, width: 160, height: 16, type: "platform" },
|
|
44413
44426
|
{ x: 420, y: 220, width: 160, height: 16, type: "platform" },
|
|
44414
44427
|
{ x: 580, y: 300, width: 80, height: 16, type: "hazard" },
|
|
44415
44428
|
{ x: 700, y: 340, width: 64, height: 28, type: "goal" }
|
|
44416
44429
|
];
|
|
44430
|
+
boardLog.debug("platforms-resolve", {
|
|
44431
|
+
propPlatformsCount: Array.isArray(propPlatforms) ? propPlatforms.length : null,
|
|
44432
|
+
usedFallback: propPlatforms === void 0,
|
|
44433
|
+
finalCount: platforms.length,
|
|
44434
|
+
player: { x: player.x, y: player.y, vx: player.vx, vy: player.vy, grounded: player.grounded },
|
|
44435
|
+
result
|
|
44436
|
+
});
|
|
44417
44437
|
const handleRestart = React82.useCallback(() => {
|
|
44418
44438
|
if (playAgainEvent) {
|
|
44419
44439
|
eventBus.emit(`UI:${playAgainEvent}`, {});
|
|
@@ -44492,6 +44512,7 @@ function PlatformerBoard({
|
|
|
44492
44512
|
}
|
|
44493
44513
|
);
|
|
44494
44514
|
}
|
|
44515
|
+
var boardLog;
|
|
44495
44516
|
var init_PlatformerBoard = __esm({
|
|
44496
44517
|
"components/game/organisms/PlatformerBoard.tsx"() {
|
|
44497
44518
|
"use client";
|
|
@@ -44502,6 +44523,7 @@ var init_PlatformerBoard = __esm({
|
|
|
44502
44523
|
init_Typography();
|
|
44503
44524
|
init_Stack();
|
|
44504
44525
|
init_PlatformerCanvas();
|
|
44526
|
+
boardLog = logger.createLogger("almadar:ui:game:platformer-board");
|
|
44505
44527
|
PlatformerBoard.displayName = "PlatformerBoard";
|
|
44506
44528
|
}
|
|
44507
44529
|
});
|
package/dist/providers/index.js
CHANGED
|
@@ -28727,6 +28727,7 @@ function PlatformerCanvas({
|
|
|
28727
28727
|
const canvasRef = useRef(null);
|
|
28728
28728
|
const eventBus = useEventBus();
|
|
28729
28729
|
const keysRef = useRef(/* @__PURE__ */ new Set());
|
|
28730
|
+
const lastPlatCountRef = useRef(-1);
|
|
28730
28731
|
const imageCache = useRef(/* @__PURE__ */ new Map());
|
|
28731
28732
|
const [loadedImages, setLoadedImages] = useState(/* @__PURE__ */ new Set());
|
|
28732
28733
|
const loadImage = useCallback((url) => {
|
|
@@ -28882,6 +28883,18 @@ function PlatformerCanvas({
|
|
|
28882
28883
|
camX = Math.max(0, Math.min(px - cw / 2, ww - cw));
|
|
28883
28884
|
camY = Math.max(0, Math.min(py - ch / 2 - 50, wh - ch));
|
|
28884
28885
|
}
|
|
28886
|
+
if (plats.length !== lastPlatCountRef.current) {
|
|
28887
|
+
lastPlatCountRef.current = plats.length;
|
|
28888
|
+
canvasLog.debug("draw:platforms", {
|
|
28889
|
+
platformCount: plats.length,
|
|
28890
|
+
camX,
|
|
28891
|
+
camY,
|
|
28892
|
+
player: { x: px, y: py },
|
|
28893
|
+
worldWidth: ww,
|
|
28894
|
+
canvasWidth: cw,
|
|
28895
|
+
followCamera: fc
|
|
28896
|
+
});
|
|
28897
|
+
}
|
|
28885
28898
|
const bgImage = bgImg ? loadImage(bgImg) : null;
|
|
28886
28899
|
if (bgImage) {
|
|
28887
28900
|
ctx.drawImage(bgImage, 0, 0, cw, ch);
|
|
@@ -29007,13 +29020,14 @@ function PlatformerCanvas({
|
|
|
29007
29020
|
}
|
|
29008
29021
|
);
|
|
29009
29022
|
}
|
|
29010
|
-
var PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR;
|
|
29023
|
+
var canvasLog, PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR;
|
|
29011
29024
|
var init_PlatformerCanvas = __esm({
|
|
29012
29025
|
"components/game/molecules/PlatformerCanvas.tsx"() {
|
|
29013
29026
|
init_cn();
|
|
29014
29027
|
init_useEventBus();
|
|
29015
29028
|
init_verificationRegistry();
|
|
29016
29029
|
init_useRenderInterpolation();
|
|
29030
|
+
canvasLog = createLogger("almadar:ui:game:platformer-canvas");
|
|
29017
29031
|
PLATFORM_COLORS = {
|
|
29018
29032
|
ground: "#4a7c59",
|
|
29019
29033
|
platform: "#7c6b4a",
|
|
@@ -44359,14 +44373,20 @@ function PlatformerBoard({
|
|
|
44359
44373
|
grounded: false,
|
|
44360
44374
|
facingRight: true
|
|
44361
44375
|
};
|
|
44362
|
-
const
|
|
44363
|
-
const platforms = propPlatforms ?? entityPlatforms ?? [
|
|
44376
|
+
const platforms = propPlatforms ?? [
|
|
44364
44377
|
{ x: 0, y: 368, width: 800, height: 32, type: "ground" },
|
|
44365
44378
|
{ x: 150, y: 280, width: 160, height: 16, type: "platform" },
|
|
44366
44379
|
{ x: 420, y: 220, width: 160, height: 16, type: "platform" },
|
|
44367
44380
|
{ x: 580, y: 300, width: 80, height: 16, type: "hazard" },
|
|
44368
44381
|
{ x: 700, y: 340, width: 64, height: 28, type: "goal" }
|
|
44369
44382
|
];
|
|
44383
|
+
boardLog.debug("platforms-resolve", {
|
|
44384
|
+
propPlatformsCount: Array.isArray(propPlatforms) ? propPlatforms.length : null,
|
|
44385
|
+
usedFallback: propPlatforms === void 0,
|
|
44386
|
+
finalCount: platforms.length,
|
|
44387
|
+
player: { x: player.x, y: player.y, vx: player.vx, vy: player.vy, grounded: player.grounded },
|
|
44388
|
+
result
|
|
44389
|
+
});
|
|
44370
44390
|
const handleRestart = useCallback(() => {
|
|
44371
44391
|
if (playAgainEvent) {
|
|
44372
44392
|
eventBus.emit(`UI:${playAgainEvent}`, {});
|
|
@@ -44445,6 +44465,7 @@ function PlatformerBoard({
|
|
|
44445
44465
|
}
|
|
44446
44466
|
);
|
|
44447
44467
|
}
|
|
44468
|
+
var boardLog;
|
|
44448
44469
|
var init_PlatformerBoard = __esm({
|
|
44449
44470
|
"components/game/organisms/PlatformerBoard.tsx"() {
|
|
44450
44471
|
"use client";
|
|
@@ -44455,6 +44476,7 @@ var init_PlatformerBoard = __esm({
|
|
|
44455
44476
|
init_Typography();
|
|
44456
44477
|
init_Stack();
|
|
44457
44478
|
init_PlatformerCanvas();
|
|
44479
|
+
boardLog = createLogger("almadar:ui:game:platformer-board");
|
|
44458
44480
|
PlatformerBoard.displayName = "PlatformerBoard";
|
|
44459
44481
|
}
|
|
44460
44482
|
});
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @packageDocumentation
|
|
7
7
|
*/
|
|
8
|
-
import type { EventPayload, ServiceParams } from '@almadar/core';
|
|
8
|
+
import type { EventPayload, EntityRow, ServiceParams } from '@almadar/core';
|
|
9
9
|
import type { EffectHandlers } from '@almadar/runtime';
|
|
10
10
|
export interface ClientEventBus {
|
|
11
11
|
emit: (type: string, payload?: EventPayload) => void;
|
|
@@ -19,6 +19,17 @@ export interface CreateClientEffectHandlersOptions {
|
|
|
19
19
|
slotSetter: SlotSetter;
|
|
20
20
|
navigate?: (path: string, params?: Record<string, unknown>) => void;
|
|
21
21
|
notify?: (message: string, type: 'success' | 'error' | 'warning' | 'info') => void;
|
|
22
|
+
/**
|
|
23
|
+
* Live client-entity write target for `[runtime]` entities. `(set
|
|
24
|
+
* @entity.<field> value)` runs entirely in the browser for in-memory
|
|
25
|
+
* entities (game boards, wizards): there is no server row to persist to,
|
|
26
|
+
* so the canonical client `set` must mutate THIS object — the same object
|
|
27
|
+
* `EffectExecutor` reads `@entity.*` from for the current `executeAll` and
|
|
28
|
+
* the next tick seeds from. When omitted, `set` is a no-op (bridge mode:
|
|
29
|
+
* the server owns persistence). One store, read live by render-ui, guards,
|
|
30
|
+
* and ticks — no guard-vs-render split.
|
|
31
|
+
*/
|
|
32
|
+
liveEntity?: EntityRow;
|
|
22
33
|
/**
|
|
23
34
|
* Optional consumer-supplied call-service handler. When set, it runs
|
|
24
35
|
* instead of the default mock fallback — use to wire the playground
|
package/dist/runtime/index.cjs
CHANGED
|
@@ -28472,6 +28472,7 @@ function PlatformerCanvas({
|
|
|
28472
28472
|
const canvasRef = React81.useRef(null);
|
|
28473
28473
|
const eventBus = useEventBus();
|
|
28474
28474
|
const keysRef = React81.useRef(/* @__PURE__ */ new Set());
|
|
28475
|
+
const lastPlatCountRef = React81.useRef(-1);
|
|
28475
28476
|
const imageCache = React81.useRef(/* @__PURE__ */ new Map());
|
|
28476
28477
|
const [loadedImages, setLoadedImages] = React81.useState(/* @__PURE__ */ new Set());
|
|
28477
28478
|
const loadImage = React81.useCallback((url) => {
|
|
@@ -28627,6 +28628,18 @@ function PlatformerCanvas({
|
|
|
28627
28628
|
camX = Math.max(0, Math.min(px - cw / 2, ww - cw));
|
|
28628
28629
|
camY = Math.max(0, Math.min(py - ch / 2 - 50, wh - ch));
|
|
28629
28630
|
}
|
|
28631
|
+
if (plats.length !== lastPlatCountRef.current) {
|
|
28632
|
+
lastPlatCountRef.current = plats.length;
|
|
28633
|
+
canvasLog.debug("draw:platforms", {
|
|
28634
|
+
platformCount: plats.length,
|
|
28635
|
+
camX,
|
|
28636
|
+
camY,
|
|
28637
|
+
player: { x: px, y: py },
|
|
28638
|
+
worldWidth: ww,
|
|
28639
|
+
canvasWidth: cw,
|
|
28640
|
+
followCamera: fc
|
|
28641
|
+
});
|
|
28642
|
+
}
|
|
28630
28643
|
const bgImage = bgImg ? loadImage(bgImg) : null;
|
|
28631
28644
|
if (bgImage) {
|
|
28632
28645
|
ctx.drawImage(bgImage, 0, 0, cw, ch);
|
|
@@ -28752,13 +28765,14 @@ function PlatformerCanvas({
|
|
|
28752
28765
|
}
|
|
28753
28766
|
);
|
|
28754
28767
|
}
|
|
28755
|
-
var PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR;
|
|
28768
|
+
var canvasLog, PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR;
|
|
28756
28769
|
var init_PlatformerCanvas = __esm({
|
|
28757
28770
|
"components/game/molecules/PlatformerCanvas.tsx"() {
|
|
28758
28771
|
init_cn();
|
|
28759
28772
|
init_useEventBus();
|
|
28760
28773
|
init_verificationRegistry();
|
|
28761
28774
|
init_useRenderInterpolation();
|
|
28775
|
+
canvasLog = logger.createLogger("almadar:ui:game:platformer-canvas");
|
|
28762
28776
|
PLATFORM_COLORS = {
|
|
28763
28777
|
ground: "#4a7c59",
|
|
28764
28778
|
platform: "#7c6b4a",
|
|
@@ -44104,14 +44118,20 @@ function PlatformerBoard({
|
|
|
44104
44118
|
grounded: false,
|
|
44105
44119
|
facingRight: true
|
|
44106
44120
|
};
|
|
44107
|
-
const
|
|
44108
|
-
const platforms = propPlatforms ?? entityPlatforms ?? [
|
|
44121
|
+
const platforms = propPlatforms ?? [
|
|
44109
44122
|
{ x: 0, y: 368, width: 800, height: 32, type: "ground" },
|
|
44110
44123
|
{ x: 150, y: 280, width: 160, height: 16, type: "platform" },
|
|
44111
44124
|
{ x: 420, y: 220, width: 160, height: 16, type: "platform" },
|
|
44112
44125
|
{ x: 580, y: 300, width: 80, height: 16, type: "hazard" },
|
|
44113
44126
|
{ x: 700, y: 340, width: 64, height: 28, type: "goal" }
|
|
44114
44127
|
];
|
|
44128
|
+
boardLog.debug("platforms-resolve", {
|
|
44129
|
+
propPlatformsCount: Array.isArray(propPlatforms) ? propPlatforms.length : null,
|
|
44130
|
+
usedFallback: propPlatforms === void 0,
|
|
44131
|
+
finalCount: platforms.length,
|
|
44132
|
+
player: { x: player.x, y: player.y, vx: player.vx, vy: player.vy, grounded: player.grounded },
|
|
44133
|
+
result
|
|
44134
|
+
});
|
|
44115
44135
|
const handleRestart = React81.useCallback(() => {
|
|
44116
44136
|
if (playAgainEvent) {
|
|
44117
44137
|
eventBus.emit(`UI:${playAgainEvent}`, {});
|
|
@@ -44190,6 +44210,7 @@ function PlatformerBoard({
|
|
|
44190
44210
|
}
|
|
44191
44211
|
);
|
|
44192
44212
|
}
|
|
44213
|
+
var boardLog;
|
|
44193
44214
|
var init_PlatformerBoard = __esm({
|
|
44194
44215
|
"components/game/organisms/PlatformerBoard.tsx"() {
|
|
44195
44216
|
"use client";
|
|
@@ -44200,6 +44221,7 @@ var init_PlatformerBoard = __esm({
|
|
|
44200
44221
|
init_Typography();
|
|
44201
44222
|
init_Stack();
|
|
44202
44223
|
init_PlatformerCanvas();
|
|
44224
|
+
boardLog = logger.createLogger("almadar:ui:game:platformer-board");
|
|
44203
44225
|
PlatformerBoard.displayName = "PlatformerBoard";
|
|
44204
44226
|
}
|
|
44205
44227
|
});
|
|
@@ -51279,7 +51301,7 @@ var init_UISlotRenderer = __esm({
|
|
|
51279
51301
|
});
|
|
51280
51302
|
var log = logger.createLogger("almadar:ui:effects:client-handlers");
|
|
51281
51303
|
function createClientEffectHandlers(options) {
|
|
51282
|
-
const { eventBus, slotSetter, navigate, notify, callService } = options;
|
|
51304
|
+
const { eventBus, slotSetter, navigate, notify, callService, liveEntity } = options;
|
|
51283
51305
|
return {
|
|
51284
51306
|
emit: (event, payload) => {
|
|
51285
51307
|
const prefixedEvent = event.startsWith("UI:") ? event : `UI:${event}`;
|
|
@@ -51288,8 +51310,12 @@ function createClientEffectHandlers(options) {
|
|
|
51288
51310
|
persist: async () => {
|
|
51289
51311
|
log.warn("persist is server-side only, ignored on client");
|
|
51290
51312
|
},
|
|
51291
|
-
set: () => {
|
|
51292
|
-
|
|
51313
|
+
set: (_entityId, field, value) => {
|
|
51314
|
+
if (!liveEntity) {
|
|
51315
|
+
log.warn("set is server-side only, ignored on client (no live entity)");
|
|
51316
|
+
return;
|
|
51317
|
+
}
|
|
51318
|
+
liveEntity[field] = value;
|
|
51293
51319
|
},
|
|
51294
51320
|
callService: async (service, action, params) => {
|
|
51295
51321
|
if (callService) return callService(service, action, params);
|
|
@@ -51683,6 +51709,11 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51683
51709
|
const traitName = binding.trait.name;
|
|
51684
51710
|
const linkedEntity = binding.linkedEntity || "";
|
|
51685
51711
|
const entityId = payload?.entityId;
|
|
51712
|
+
let liveEntity = traitFieldStatesRef.current.get(traitName);
|
|
51713
|
+
if (!liveEntity) {
|
|
51714
|
+
liveEntity = {};
|
|
51715
|
+
traitFieldStatesRef.current.set(traitName, liveEntity);
|
|
51716
|
+
}
|
|
51686
51717
|
const effects = syncOnly ? params.effects.filter(
|
|
51687
51718
|
(e) => Array.isArray(e) && SYNC_TICK_OPERATORS.has(String(e[0]))
|
|
51688
51719
|
) : params.effects;
|
|
@@ -51705,7 +51736,12 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51705
51736
|
},
|
|
51706
51737
|
navigate: optionsRef.current?.navigate,
|
|
51707
51738
|
notify: optionsRef.current?.notify,
|
|
51708
|
-
callService: optionsRef.current?.callService
|
|
51739
|
+
callService: optionsRef.current?.callService,
|
|
51740
|
+
// The canonical client `set` writes `(set @entity.X)` straight into
|
|
51741
|
+
// the trait's one live store — the same object bound below. This is
|
|
51742
|
+
// what makes a [runtime] entity's set (from ticks AND events) reach
|
|
51743
|
+
// the render-ui + next tick + guards.
|
|
51744
|
+
liveEntity
|
|
51709
51745
|
});
|
|
51710
51746
|
const persistence = syncOnly ? void 0 : optionsRef.current?.persistence;
|
|
51711
51747
|
let handlers = clientHandlers;
|
|
@@ -51716,7 +51752,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51716
51752
|
// uses below. `@payload.*` resolves from `payload` separately,
|
|
51717
51753
|
// so dropping the prior `payload as EntityRow` cast loses
|
|
51718
51754
|
// nothing — it just stops mislabelling the payload as an entity.
|
|
51719
|
-
entity:
|
|
51755
|
+
entity: liveEntity,
|
|
51720
51756
|
payload: payload || {},
|
|
51721
51757
|
state: previousState
|
|
51722
51758
|
};
|
|
@@ -51756,24 +51792,17 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51756
51792
|
handlers = {
|
|
51757
51793
|
...handlers,
|
|
51758
51794
|
set: async (targetId, field, value) => {
|
|
51759
|
-
|
|
51760
|
-
if (!fieldState) {
|
|
51761
|
-
fieldState = {};
|
|
51762
|
-
traitFieldStatesRef.current.set(traitName, fieldState);
|
|
51763
|
-
}
|
|
51764
|
-
fieldState[field] = value;
|
|
51795
|
+
if (baseSet) await baseSet(targetId, field, value);
|
|
51765
51796
|
log14.debug("set:write", {
|
|
51766
51797
|
traitName,
|
|
51767
51798
|
field,
|
|
51768
51799
|
value: JSON.stringify(value),
|
|
51769
51800
|
transition: `${previousState}->${newState}`
|
|
51770
51801
|
});
|
|
51771
|
-
if (baseSet) await baseSet(targetId, field, value);
|
|
51772
51802
|
}
|
|
51773
51803
|
};
|
|
51774
|
-
const entityForBinding = traitFieldStatesRef.current.get(traitName) ?? {};
|
|
51775
51804
|
const bindingCtx = {
|
|
51776
|
-
entity:
|
|
51805
|
+
entity: liveEntity,
|
|
51777
51806
|
payload: payload || {},
|
|
51778
51807
|
state: previousState
|
|
51779
51808
|
};
|
package/dist/runtime/index.js
CHANGED
|
@@ -28425,6 +28425,7 @@ function PlatformerCanvas({
|
|
|
28425
28425
|
const canvasRef = useRef(null);
|
|
28426
28426
|
const eventBus = useEventBus();
|
|
28427
28427
|
const keysRef = useRef(/* @__PURE__ */ new Set());
|
|
28428
|
+
const lastPlatCountRef = useRef(-1);
|
|
28428
28429
|
const imageCache = useRef(/* @__PURE__ */ new Map());
|
|
28429
28430
|
const [loadedImages, setLoadedImages] = useState(/* @__PURE__ */ new Set());
|
|
28430
28431
|
const loadImage = useCallback((url) => {
|
|
@@ -28580,6 +28581,18 @@ function PlatformerCanvas({
|
|
|
28580
28581
|
camX = Math.max(0, Math.min(px - cw / 2, ww - cw));
|
|
28581
28582
|
camY = Math.max(0, Math.min(py - ch / 2 - 50, wh - ch));
|
|
28582
28583
|
}
|
|
28584
|
+
if (plats.length !== lastPlatCountRef.current) {
|
|
28585
|
+
lastPlatCountRef.current = plats.length;
|
|
28586
|
+
canvasLog.debug("draw:platforms", {
|
|
28587
|
+
platformCount: plats.length,
|
|
28588
|
+
camX,
|
|
28589
|
+
camY,
|
|
28590
|
+
player: { x: px, y: py },
|
|
28591
|
+
worldWidth: ww,
|
|
28592
|
+
canvasWidth: cw,
|
|
28593
|
+
followCamera: fc
|
|
28594
|
+
});
|
|
28595
|
+
}
|
|
28583
28596
|
const bgImage = bgImg ? loadImage(bgImg) : null;
|
|
28584
28597
|
if (bgImage) {
|
|
28585
28598
|
ctx.drawImage(bgImage, 0, 0, cw, ch);
|
|
@@ -28705,13 +28718,14 @@ function PlatformerCanvas({
|
|
|
28705
28718
|
}
|
|
28706
28719
|
);
|
|
28707
28720
|
}
|
|
28708
|
-
var PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR;
|
|
28721
|
+
var canvasLog, PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR;
|
|
28709
28722
|
var init_PlatformerCanvas = __esm({
|
|
28710
28723
|
"components/game/molecules/PlatformerCanvas.tsx"() {
|
|
28711
28724
|
init_cn();
|
|
28712
28725
|
init_useEventBus();
|
|
28713
28726
|
init_verificationRegistry();
|
|
28714
28727
|
init_useRenderInterpolation();
|
|
28728
|
+
canvasLog = createLogger("almadar:ui:game:platformer-canvas");
|
|
28715
28729
|
PLATFORM_COLORS = {
|
|
28716
28730
|
ground: "#4a7c59",
|
|
28717
28731
|
platform: "#7c6b4a",
|
|
@@ -44057,14 +44071,20 @@ function PlatformerBoard({
|
|
|
44057
44071
|
grounded: false,
|
|
44058
44072
|
facingRight: true
|
|
44059
44073
|
};
|
|
44060
|
-
const
|
|
44061
|
-
const platforms = propPlatforms ?? entityPlatforms ?? [
|
|
44074
|
+
const platforms = propPlatforms ?? [
|
|
44062
44075
|
{ x: 0, y: 368, width: 800, height: 32, type: "ground" },
|
|
44063
44076
|
{ x: 150, y: 280, width: 160, height: 16, type: "platform" },
|
|
44064
44077
|
{ x: 420, y: 220, width: 160, height: 16, type: "platform" },
|
|
44065
44078
|
{ x: 580, y: 300, width: 80, height: 16, type: "hazard" },
|
|
44066
44079
|
{ x: 700, y: 340, width: 64, height: 28, type: "goal" }
|
|
44067
44080
|
];
|
|
44081
|
+
boardLog.debug("platforms-resolve", {
|
|
44082
|
+
propPlatformsCount: Array.isArray(propPlatforms) ? propPlatforms.length : null,
|
|
44083
|
+
usedFallback: propPlatforms === void 0,
|
|
44084
|
+
finalCount: platforms.length,
|
|
44085
|
+
player: { x: player.x, y: player.y, vx: player.vx, vy: player.vy, grounded: player.grounded },
|
|
44086
|
+
result
|
|
44087
|
+
});
|
|
44068
44088
|
const handleRestart = useCallback(() => {
|
|
44069
44089
|
if (playAgainEvent) {
|
|
44070
44090
|
eventBus.emit(`UI:${playAgainEvent}`, {});
|
|
@@ -44143,6 +44163,7 @@ function PlatformerBoard({
|
|
|
44143
44163
|
}
|
|
44144
44164
|
);
|
|
44145
44165
|
}
|
|
44166
|
+
var boardLog;
|
|
44146
44167
|
var init_PlatformerBoard = __esm({
|
|
44147
44168
|
"components/game/organisms/PlatformerBoard.tsx"() {
|
|
44148
44169
|
"use client";
|
|
@@ -44153,6 +44174,7 @@ var init_PlatformerBoard = __esm({
|
|
|
44153
44174
|
init_Typography();
|
|
44154
44175
|
init_Stack();
|
|
44155
44176
|
init_PlatformerCanvas();
|
|
44177
|
+
boardLog = createLogger("almadar:ui:game:platformer-board");
|
|
44156
44178
|
PlatformerBoard.displayName = "PlatformerBoard";
|
|
44157
44179
|
}
|
|
44158
44180
|
});
|
|
@@ -51232,7 +51254,7 @@ var init_UISlotRenderer = __esm({
|
|
|
51232
51254
|
});
|
|
51233
51255
|
var log = createLogger("almadar:ui:effects:client-handlers");
|
|
51234
51256
|
function createClientEffectHandlers(options) {
|
|
51235
|
-
const { eventBus, slotSetter, navigate, notify, callService } = options;
|
|
51257
|
+
const { eventBus, slotSetter, navigate, notify, callService, liveEntity } = options;
|
|
51236
51258
|
return {
|
|
51237
51259
|
emit: (event, payload) => {
|
|
51238
51260
|
const prefixedEvent = event.startsWith("UI:") ? event : `UI:${event}`;
|
|
@@ -51241,8 +51263,12 @@ function createClientEffectHandlers(options) {
|
|
|
51241
51263
|
persist: async () => {
|
|
51242
51264
|
log.warn("persist is server-side only, ignored on client");
|
|
51243
51265
|
},
|
|
51244
|
-
set: () => {
|
|
51245
|
-
|
|
51266
|
+
set: (_entityId, field, value) => {
|
|
51267
|
+
if (!liveEntity) {
|
|
51268
|
+
log.warn("set is server-side only, ignored on client (no live entity)");
|
|
51269
|
+
return;
|
|
51270
|
+
}
|
|
51271
|
+
liveEntity[field] = value;
|
|
51246
51272
|
},
|
|
51247
51273
|
callService: async (service, action, params) => {
|
|
51248
51274
|
if (callService) return callService(service, action, params);
|
|
@@ -51636,6 +51662,11 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51636
51662
|
const traitName = binding.trait.name;
|
|
51637
51663
|
const linkedEntity = binding.linkedEntity || "";
|
|
51638
51664
|
const entityId = payload?.entityId;
|
|
51665
|
+
let liveEntity = traitFieldStatesRef.current.get(traitName);
|
|
51666
|
+
if (!liveEntity) {
|
|
51667
|
+
liveEntity = {};
|
|
51668
|
+
traitFieldStatesRef.current.set(traitName, liveEntity);
|
|
51669
|
+
}
|
|
51639
51670
|
const effects = syncOnly ? params.effects.filter(
|
|
51640
51671
|
(e) => Array.isArray(e) && SYNC_TICK_OPERATORS.has(String(e[0]))
|
|
51641
51672
|
) : params.effects;
|
|
@@ -51658,7 +51689,12 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51658
51689
|
},
|
|
51659
51690
|
navigate: optionsRef.current?.navigate,
|
|
51660
51691
|
notify: optionsRef.current?.notify,
|
|
51661
|
-
callService: optionsRef.current?.callService
|
|
51692
|
+
callService: optionsRef.current?.callService,
|
|
51693
|
+
// The canonical client `set` writes `(set @entity.X)` straight into
|
|
51694
|
+
// the trait's one live store — the same object bound below. This is
|
|
51695
|
+
// what makes a [runtime] entity's set (from ticks AND events) reach
|
|
51696
|
+
// the render-ui + next tick + guards.
|
|
51697
|
+
liveEntity
|
|
51662
51698
|
});
|
|
51663
51699
|
const persistence = syncOnly ? void 0 : optionsRef.current?.persistence;
|
|
51664
51700
|
let handlers = clientHandlers;
|
|
@@ -51669,7 +51705,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51669
51705
|
// uses below. `@payload.*` resolves from `payload` separately,
|
|
51670
51706
|
// so dropping the prior `payload as EntityRow` cast loses
|
|
51671
51707
|
// nothing — it just stops mislabelling the payload as an entity.
|
|
51672
|
-
entity:
|
|
51708
|
+
entity: liveEntity,
|
|
51673
51709
|
payload: payload || {},
|
|
51674
51710
|
state: previousState
|
|
51675
51711
|
};
|
|
@@ -51709,24 +51745,17 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51709
51745
|
handlers = {
|
|
51710
51746
|
...handlers,
|
|
51711
51747
|
set: async (targetId, field, value) => {
|
|
51712
|
-
|
|
51713
|
-
if (!fieldState) {
|
|
51714
|
-
fieldState = {};
|
|
51715
|
-
traitFieldStatesRef.current.set(traitName, fieldState);
|
|
51716
|
-
}
|
|
51717
|
-
fieldState[field] = value;
|
|
51748
|
+
if (baseSet) await baseSet(targetId, field, value);
|
|
51718
51749
|
log14.debug("set:write", {
|
|
51719
51750
|
traitName,
|
|
51720
51751
|
field,
|
|
51721
51752
|
value: JSON.stringify(value),
|
|
51722
51753
|
transition: `${previousState}->${newState}`
|
|
51723
51754
|
});
|
|
51724
|
-
if (baseSet) await baseSet(targetId, field, value);
|
|
51725
51755
|
}
|
|
51726
51756
|
};
|
|
51727
|
-
const entityForBinding = traitFieldStatesRef.current.get(traitName) ?? {};
|
|
51728
51757
|
const bindingCtx = {
|
|
51729
|
-
entity:
|
|
51758
|
+
entity: liveEntity,
|
|
51730
51759
|
payload: payload || {},
|
|
51731
51760
|
state: previousState
|
|
51732
51761
|
};
|