Minimap And Core Utilities
Hosanna Game includes focused utilities for common game-loop problems. They are deliberately allocation-conscious and do not decide your game rules.
Minimap
Hs2dMiniMap projects a world rectangle into a screen-space map. It supports a full-world view or a scrollable world viewport, a baked terrain surface, styled live markers, blinking and edge clamping, heading markers, and a camera-view outline.
Create and prepare it during level setup:
const minimap = new Hs2dMiniMap({
x: 24,
y: 520,
width: 220,
height: 160,
worldWidth,
worldHeight,
backgroundColor: 0x0b1220ff,
borderColor: 0x334155ff,
borderWidth: 2,
});
const playerStyle = minimap.defineMarkerStyle({
color: 0xffffffff,
size: 8,
});
const objectiveStyle = minimap.defineMarkerStyle({
color: 0xfacc15ff,
size: 7,
blinkPeriodMs: 600,
});
At level-build time, optionally call beginBackgroundPaint(fillColor, alphaEnabled?) and paint static world rectangles with paintBackgroundRect(...). At runtime:
- call
update(deltaMs)once; - call
draw(screen)for the frame and baked terrain; - call
drawMarker()ordrawHeadingMarker()for live entities; - optionally draw the camera viewport.
Do not repaint static terrain each frame. If surface allocation fails, draw() falls back to the configured flat background.
For a scrolling minimap, the baked surface covers the full world at the minimap viewport's projection scale, not just the visible map rectangle. Check the resulting surface dimensions against the target device's texture limits; omit the bake or use a game-specific segmented background when that surface would be too large.
The vertical shooter uses a deliberately non-uniform narrow radar strip. Hosanna Dungeon preserves the dungeon aspect ratio and draws several marker classes. Both are valid uses of the same projection API.
Deterministic Random Numbers
Hs2dLcg is a seeded Park–Miller generator:
const random = new Hs2dLcg(levelSeed);
const chance = random.nextFloat(); // [0, 1)
const x = random.nextRange(minX, maxX); // [minX, maxX)
const lane = random.nextInt(0, 4); // 0, 1, 2, or 3
Keep one explicit generator per deterministic simulation stream. Resetting to the same nonzero-normalized seed reproduces the sequence.
Logical Entity Pools
Hs2dEntityPool<T> allocates every logical slot in its constructor. It owns activation and deactivation, not entity behavior:
const projectiles = new Hs2dEntityPool({
id: 'projectiles',
capacity: 64,
create: (index) => ({ index, active: false, x: 0, y: 0 }),
onDeactivate: (projectile) => parkProjectileSprite(projectile.index),
});
Systems iterate the stable items array and skip inactive slots. When reuseOldestWhenFull is enabled, activate() reuses a slot; otherwise it returns undefined at capacity.
Despite the option name, the current implementation rotates through slots on full-pool reuse; it does not record and compare activation ages. The initial full-pool sequence behaves oldest-first because slots were activated in index order, but later deactivate/reactivate patterns can diverge. Depend on bounded reuse, not strict age ordering, unless the engine adds activation timestamps.
This is a logical pool. Use Hs2dSpritePool or a direct-sprite group for the corresponding render objects.
Shared Grid Flow Field
GridFlowField builds one breadth-first distance field toward a target tile so many agents can share the result. Prefer a retained row-major blockedCells mask on device:
const field = new GridFlowField({
width: columns,
height: rows,
blockedCells,
});
const isReady = field.rebuild(targetCellX, targetCellY, 96);
if (field.stepToward(enemyCellX, enemyCellY, scratchStep)) {
enemy.moveX = scratchStep.x;
enemy.moveY = scratchStep.y;
}
The optional rebuild budget spreads work over simulation steps. Call rebuild() again with the same target until it returns true; each call continues the unfinished breadth-first search. stepToward() writes into the caller's object and returns false for the target, unreachable cells, or cells not reached by an incomplete build. Call invalidate() after mutating the retained blocked mask.
Source References
| Source | What it proves |
|---|---|
../games/hosanna-ui/src/hosanna-game/core/Hs2dMiniMap.ts | Projection, viewport scrolling, baked surface, styles, markers, heading, and camera outline. |
../games/hosanna-ui/src/hosanna-game/core/Hs2dLcg.ts | Seed normalization and deterministic number ranges. |
../games/hosanna-ui/src/hosanna-game/core/Hs2dEntityPool.ts | Fixed logical slots, activation, callbacks, reuse, and stats. |
../games/hosanna-ui/src/hosanna-game/tile-map/GridFlowField.ts | Retained mask, budgeted BFS, invalidation, and allocation-free gradient steps. |
../hosanna-ui-game-samples-public/src/hosanna-game-examples/native-shoot-em-up/VerticalShooterLevelScene.ts | Radar-style minimap and deterministic gameplay random source. |