@waica/archetype-isometric 0.24.0 → 0.25.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.
@@ -92,6 +92,31 @@ remain at the human-approved 16 texels per render unit.
92
92
  | `waica-iso-tree.png` | `(768,208,832,304)`, transparent bottom trimmed | 64×94 |
93
93
  | `waica-iso-rock.png` | `(784,868,814,890)`, padded at `(1,10)` | 32×32 |
94
94
  | `waica-iso-crate.png` | `(896,832,960,896)`, nearest-resized | 32×32 |
95
+ | `waica-iso-wall.png` | `(448,1152,512,1216)`, the grey-blue stone cube (4th of the row of four); pixels outside its hexagon `(32,0) (64,16) (64,48) (32,64) (0,48) (0,16)` cleared (52 pixels of the neighbouring tile's tip) | 64×64 |
96
+
97
+ The dungeon (issue #78) draws its stone floor with index 4 (`border`) of
98
+ `waica-iso-ground.png`, the grey stone with a cross at `(960,640,1024,672)`:
99
+ no new floor art. The wall cube is native at 32 texels per render unit (2×2
100
+ units), so its base diamond is exactly one 64×32 cell; its Sprite sets
101
+ `anchorY: 0.25`, the base diamond's centre.
102
+
103
+ ## Animated Pixel Torch
104
+
105
+ - **Animated Pixel Torch** by XLIVE99
106
+ - Source: https://opengameart.org/content/animated-pixel-torch
107
+ - Licence: **Creative Commons Zero (CC0)**.
108
+ - Source file: `Torch/Torch_Sheet.png` (96×64, 3 columns × 2 rows of 32×32
109
+ frames). Only that PNG was used; its pixels were copied into a fresh PNG
110
+ with no ancillary chunks. None of the pack's other files ships.
111
+
112
+ | Output file | Source | Output size |
113
+ |---|---|---:|
114
+ | `waica-iso-torch.png` | the whole sheet, pixels unchanged | 96×64 |
115
+
116
+ Each frame is native at 32 texels per render unit (1×1 unit). The torch's
117
+ handle ends at row 30 of each frame, so its AnimatedSprite sets
118
+ `anchorY: 2/32`. Rows 10–15 around columns 15–16 are flame in all six
119
+ frames: the dungeon e2e samples the flame there.
95
120
 
96
121
  ## Click-to-move destination marker
97
122
 
Binary file
Binary file
package/dist/art.js CHANGED
@@ -8,6 +8,8 @@ export const ISOMETRIC_ART = [
8
8
  { file: 'waica-iso-rock.png', uri: 'waica:iso-rock', kind: 'image' },
9
9
  { file: 'waica-iso-crate.png', uri: 'waica:iso-crate', kind: 'image' },
10
10
  { file: 'waica-iso-click-marker.png', uri: 'waica:iso-click-marker', kind: 'image' },
11
+ { file: 'waica-iso-wall.png', uri: 'waica:iso-wall', kind: 'image' },
12
+ { file: 'waica-iso-torch.png', uri: 'waica:iso-torch', kind: 'image' },
11
13
  { file: 'waica-iso-sword-swing.ogg', uri: 'waica:iso-sword-swing', kind: 'sound' },
12
14
  { file: 'waica-iso-hit.ogg', uri: 'waica:iso-hit', kind: 'sound' },
13
15
  { file: 'waica-iso-hurt.ogg', uri: 'waica:iso-hurt', kind: 'sound' },
@@ -0,0 +1,25 @@
1
+ import type { PrefabJson, SceneJson } from '@waica/engine';
2
+ /** The dungeon's ground: 10×10, a stone floor (`tiles/ground` index 4) and walls. */
3
+ export declare const ISOMETRIC_DUNGEON_MAP_WIDTH = 10;
4
+ export declare const ISOMETRIC_DUNGEON_MAP_HEIGHT = 10;
5
+ export declare const ISOMETRIC_DUNGEON_GROUND_CELLS: (1 | 4)[];
6
+ /**
7
+ * A stone wall cube (hawkbirdtree, CC0): 64×64 at 32 texels per unit, so its
8
+ * base diamond is exactly one cell; anchorY 0.25 sets the base diamond's
9
+ * centre on the entity. Collision and occlusion come from the cell's solid
10
+ * tile, not from this Sprite.
11
+ */
12
+ export declare const ISOMETRIC_WALL_PREFAB: PrefabJson;
13
+ /**
14
+ * A torch (issue #78; art "Animated Pixel Torch" by XLIVE99, CC0): six 32×32
15
+ * frames, Emissive so the flame stays bright whatever the Ambient Light, and
16
+ * a warm Light that the walls stop — a pool of light, not the whole room.
17
+ */
18
+ export declare const ISOMETRIC_TORCH_PREFAB: PrefabJson;
19
+ /**
20
+ * The third demo scene (issue #78 CA-14): a dark dungeon reached from the
21
+ * cave. Two torches on the floor light the hall; the wall down its middle
22
+ * keeps the chamber behind it dark, and a vignette closes the frame. A fixed
23
+ * camera frames the whole room.
24
+ */
25
+ export declare const ISOMETRIC_DUNGEON_SCENE: SceneJson;
@@ -0,0 +1,113 @@
1
+ /** The dungeon's ground: 10×10, a stone floor (`tiles/ground` index 4) and walls. */
2
+ export const ISOMETRIC_DUNGEON_MAP_WIDTH = 10;
3
+ export const ISOMETRIC_DUNGEON_MAP_HEIGHT = 10;
4
+ /** The grey stone with a cross: the floor. */
5
+ const STONE = 4;
6
+ /** Under every wall cube: flat dirt nobody sees, the dungeon's only solid tile. */
7
+ const WALL = 1;
8
+ /** The wall between the torch-lit hall and the dark chamber, open at its far end. */
9
+ const WALL_COLUMN = 5;
10
+ const WALL_GAP_ROW = 8;
11
+ function isWall(column, row) {
12
+ const width = ISOMETRIC_DUNGEON_MAP_WIDTH;
13
+ const height = ISOMETRIC_DUNGEON_MAP_HEIGHT;
14
+ if (column === 0 || row === 0 || column === width - 1 || row === height - 1)
15
+ return true;
16
+ return column === WALL_COLUMN && row !== WALL_GAP_ROW;
17
+ }
18
+ export const ISOMETRIC_DUNGEON_GROUND_CELLS = Array.from({ length: ISOMETRIC_DUNGEON_MAP_WIDTH * ISOMETRIC_DUNGEON_MAP_HEIGHT }, (_, index) => isWall(index % ISOMETRIC_DUNGEON_MAP_WIDTH, Math.floor(index / ISOMETRIC_DUNGEON_MAP_WIDTH)) ? WALL : STONE);
19
+ /** One wall cube per solid cell, on the cell's centre (the Tilemap draws only flat cells). */
20
+ function wallEntities() {
21
+ return ISOMETRIC_DUNGEON_GROUND_CELLS.flatMap((tile, index) => {
22
+ if (tile !== WALL)
23
+ return [];
24
+ const column = index % ISOMETRIC_DUNGEON_MAP_WIDTH;
25
+ const row = Math.floor(index / ISOMETRIC_DUNGEON_MAP_WIDTH);
26
+ return [{ name: `Wall-${column}-${row}`, prefab: 'objects/wall', position: [column + 0.5, row + 0.5] }];
27
+ });
28
+ }
29
+ /**
30
+ * A stone wall cube (hawkbirdtree, CC0): 64×64 at 32 texels per unit, so its
31
+ * base diamond is exactly one cell; anchorY 0.25 sets the base diamond's
32
+ * centre on the entity. Collision and occlusion come from the cell's solid
33
+ * tile, not from this Sprite.
34
+ */
35
+ export const ISOMETRIC_WALL_PREFAB = {
36
+ waicaPrefab: 1,
37
+ type: 'object',
38
+ components: [
39
+ { type: 'Sprite', props: { texture: 'waica:iso-wall', pixelArt: true, width: 2, height: 2, anchorY: 0.25 } },
40
+ ],
41
+ };
42
+ /**
43
+ * A torch (issue #78; art "Animated Pixel Torch" by XLIVE99, CC0): six 32×32
44
+ * frames, Emissive so the flame stays bright whatever the Ambient Light, and
45
+ * a warm Light that the walls stop — a pool of light, not the whole room.
46
+ */
47
+ export const ISOMETRIC_TORCH_PREFAB = {
48
+ waicaPrefab: 1,
49
+ type: 'object',
50
+ components: [
51
+ {
52
+ type: 'AnimatedSprite',
53
+ props: {
54
+ texture: 'waica:iso-torch',
55
+ cols: 3,
56
+ rows: 2,
57
+ pixelArt: true,
58
+ width: 1,
59
+ height: 1,
60
+ anchorY: 2 / 32,
61
+ clips: { burn: { frames: [0, 1, 2, 3, 4, 5], fps: 8 } },
62
+ initialClip: 'burn',
63
+ emissive: true,
64
+ },
65
+ },
66
+ {
67
+ type: 'Light',
68
+ props: { radius: 3, color: 0xffb366, intensity: 1, softness: 0.25 },
69
+ },
70
+ ],
71
+ };
72
+ /**
73
+ * The third demo scene (issue #78 CA-14): a dark dungeon reached from the
74
+ * cave. Two torches on the floor light the hall; the wall down its middle
75
+ * keeps the chamber behind it dark, and a vignette closes the frame. A fixed
76
+ * camera frames the whole room.
77
+ */
78
+ export const ISOMETRIC_DUNGEON_SCENE = {
79
+ waicaScene: 3,
80
+ render: {
81
+ sort: 'y',
82
+ projection: 'isometric',
83
+ lighting: { ambient: { color: '#5a6a9a', intensity: 0.3 } },
84
+ post: { vignette: { intensity: 0.45, radius: 0.35 } },
85
+ },
86
+ camera: { position: [0, -5], zoom: 12 },
87
+ entities: [
88
+ {
89
+ name: 'Ground',
90
+ prefab: 'tiles/ground',
91
+ position: [0, 0],
92
+ overrides: {
93
+ Tilemap: {
94
+ mapWidth: ISOMETRIC_DUNGEON_MAP_WIDTH,
95
+ mapHeight: ISOMETRIC_DUNGEON_MAP_HEIGHT,
96
+ cells: ISOMETRIC_DUNGEON_GROUND_CELLS,
97
+ solidTiles: [WALL],
98
+ },
99
+ },
100
+ },
101
+ { name: 'Player', prefab: 'characters/player', position: [2, 8] },
102
+ { name: 'Torch-1', prefab: 'objects/torch', position: [3.5, 3.5] },
103
+ { name: 'Torch-2', prefab: 'objects/torch', position: [3.5, 5.5] },
104
+ {
105
+ name: 'Door',
106
+ prefab: 'objects/door',
107
+ position: [1.5, 1.5],
108
+ overrides: { SceneTransition: { scene: 'cave' } },
109
+ },
110
+ ...wallEntities(),
111
+ ],
112
+ ui: ['health'],
113
+ };
package/dist/index.d.ts CHANGED
@@ -12,6 +12,7 @@ export declare const ARCHETYPE: {
12
12
  scene: import("@waica/engine").SceneJson;
13
13
  extraScenes: {
14
14
  cave: import("@waica/engine").SceneJson;
15
+ dungeon: import("@waica/engine").SceneJson;
15
16
  };
16
17
  blankScene: import("@waica/engine").SceneJson;
17
18
  palette: import("@waica/engine").EntityTemplate[];
@@ -5,6 +5,7 @@ export declare const ARCHETYPE: {
5
5
  scene: import("@waica/engine").SceneJson;
6
6
  extraScenes: {
7
7
  cave: import("@waica/engine").SceneJson;
8
+ dungeon: import("@waica/engine").SceneJson;
8
9
  };
9
10
  blankScene: import("@waica/engine").SceneJson;
10
11
  registry: import("@waica/engine").SceneRegistry;
package/dist/manifest.js CHANGED
@@ -5,6 +5,7 @@ import { ISOMETRIC_ACTION_LABELS, ISOMETRIC_BINDINGS } from './controls.js';
5
5
  import { ISOMETRIC_PREFABS } from './prefabs.js';
6
6
  import { ISOMETRIC_PALETTE, ISOMETRIC_REGISTRY_DATA } from './registry-data.js';
7
7
  import { ISOMETRIC_BLANK_SCENE, ISOMETRIC_CAVE_SCENE, ISOMETRIC_SCENE } from './scene-default.js';
8
+ import { ISOMETRIC_DUNGEON_SCENE } from './dungeon.js';
8
9
  export const ISOMETRIC_ENTITY_ICONS = {
9
10
  IsoMotor: '🧭',
10
11
  Tilemap: '💎',
@@ -18,7 +19,7 @@ export const ARCHETYPE = {
18
19
  id: 'isometric',
19
20
  label: 'Isometric',
20
21
  scene: ISOMETRIC_SCENE,
21
- extraScenes: { cave: ISOMETRIC_CAVE_SCENE },
22
+ extraScenes: { cave: ISOMETRIC_CAVE_SCENE, dungeon: ISOMETRIC_DUNGEON_SCENE },
22
23
  blankScene: ISOMETRIC_BLANK_SCENE,
23
24
  registry: ISOMETRIC_REGISTRY_DATA,
24
25
  palette: ISOMETRIC_PALETTE,
package/dist/prefabs.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { ISO_PLAYER_STATE_GRAPH, NPC_STATE_GRAPH, PATROLLER_STATE_GRAPH, } from '@waica/behaviors';
2
2
  import { ISOMETRIC_EFFECT_PREFABS, SWORD_SPARKS } from './effect-prefabs.js';
3
+ import { ISOMETRIC_TORCH_PREFAB, ISOMETRIC_WALL_PREFAB } from './dungeon.js';
3
4
  const SHIPPED_DIRECTIONS = ['n', 'ne', 'e', 'se', 's'];
4
5
  /** One row per shipped facing: idle · walk×3 · attack×3 · hurt×2 · death×2. */
5
6
  const SHEET_COLUMNS = 11;
@@ -238,6 +239,8 @@ export const ISOMETRIC_PREFABS = {
238
239
  ],
239
240
  },
240
241
  ...ISOMETRIC_EFFECT_PREFABS,
242
+ 'objects/torch': ISOMETRIC_TORCH_PREFAB,
243
+ 'objects/wall': ISOMETRIC_WALL_PREFAB,
241
244
  'objects/door': {
242
245
  waicaPrefab: 1,
243
246
  type: 'object',
@@ -1,4 +1,4 @@
1
- import { AnimatedSprite, Hitbox, ParticleEmitter, Solid, Sprite, StateMachine, Tilemap, } from '@waica/engine';
1
+ import { AnimatedSprite, Hitbox, Light, ParticleEmitter, Solid, Sprite, StateMachine, Tilemap, } from '@waica/engine';
2
2
  import { Chaser, ClickToMove, Collectible, DamagePuff, Hazard, Health, Interactable, IsoMotor, Lifetime, MeleeAttack, Patrol, Respawnable, SceneTransition, SwingSparks, } from '@waica/behaviors';
3
3
  import { ISOMETRIC_ART } from './art.js';
4
4
  import { ISOMETRIC_PREFABS } from './prefabs.js';
@@ -9,6 +9,7 @@ export const ISOMETRIC_REGISTRY_DATA = {
9
9
  Sprite,
10
10
  AnimatedSprite,
11
11
  ParticleEmitter,
12
+ Light,
12
13
  Tilemap,
13
14
  Solid,
14
15
  Hitbox,
@@ -42,6 +43,8 @@ const PALETTE_ICONS = {
42
43
  wind: '🌬️',
43
44
  'hurt-smoke': '💨',
44
45
  'cave-dust': '✨',
46
+ torch: '🔥',
47
+ wall: '🧱',
45
48
  ground: '💎',
46
49
  };
47
50
  export const ISOMETRIC_PALETTE = Object.entries(ISOMETRIC_PREFABS).map(([key, prefab]) => {
package/dist/registry.js CHANGED
@@ -9,6 +9,8 @@ export const ISOMETRIC_ART_URLS = {
9
9
  'waica-iso-tree.png': new URL('../assets/waica-iso-tree.png', import.meta.url).href,
10
10
  'waica-iso-rock.png': new URL('../assets/waica-iso-rock.png', import.meta.url).href,
11
11
  'waica-iso-crate.png': new URL('../assets/waica-iso-crate.png', import.meta.url).href,
12
+ 'waica-iso-wall.png': new URL('../assets/waica-iso-wall.png', import.meta.url).href,
13
+ 'waica-iso-torch.png': new URL('../assets/waica-iso-torch.png', import.meta.url).href,
12
14
  'waica-iso-click-marker.png': new URL('../assets/waica-iso-click-marker.png', import.meta.url).href,
13
15
  'waica-iso-sword-swing.ogg': new URL('../assets/waica-iso-sword-swing.ogg', import.meta.url).href,
14
16
  'waica-iso-hit.ogg': new URL('../assets/waica-iso-hit.ogg', import.meta.url).href,
@@ -114,6 +114,14 @@ export const ISOMETRIC_CAVE_SCENE = {
114
114
  position: [8, 2],
115
115
  overrides: { SceneTransition: { scene: 'main' } },
116
116
  },
117
+ // Down to the torch-lit dungeon (issue #78 CA-14), clear of the
118
+ // Player's entry, the rocks and the way back to the meadow.
119
+ {
120
+ name: 'DungeonDoor',
121
+ prefab: 'objects/door',
122
+ position: [7, 7],
123
+ overrides: { SceneTransition: { scene: 'dungeon' } },
124
+ },
117
125
  // An enclosed room has no wind: a few faint motes drift instead.
118
126
  {
119
127
  name: 'Dust',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waica/archetype-isometric",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "description": "Waica isometric archetype — logical-grid action adventures with screen-relative movement",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -24,7 +24,7 @@
24
24
  }
25
25
  },
26
26
  "dependencies": {
27
- "@waica/behaviors": "^0.24.0",
28
- "@waica/engine": "^0.24.0"
27
+ "@waica/behaviors": "^0.25.0",
28
+ "@waica/engine": "^0.25.0"
29
29
  }
30
30
  }