@waica/archetype-platformer 0.3.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ayrton Marini and Waica contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
Binary file
Binary file
Binary file
package/dist/art.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import type { ArchetypeArt } from '@waica/engine';
2
+ /**
3
+ * The archetype's stock art, as pure data (no asset imports: node tooling
4
+ * like scripts/sync-scene.mjs imports this module directly).
5
+ *
6
+ * Demo projects materialize each sheet as a real file at `src/art/<file>`
7
+ * and reference that path; `uri` is the legacy registry key that in-package
8
+ * prefab defaults (and old projects) still use.
9
+ */
10
+ export declare const PLATFORMER_ART: ArchetypeArt[];
package/dist/art.js ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The archetype's stock art, as pure data (no asset imports: node tooling
3
+ * like scripts/sync-scene.mjs imports this module directly).
4
+ *
5
+ * Demo projects materialize each sheet as a real file at `src/art/<file>`
6
+ * and reference that path; `uri` is the legacy registry key that in-package
7
+ * prefab defaults (and old projects) still use.
8
+ */
9
+ export const PLATFORMER_ART = [
10
+ { file: 'waica-dog.png', uri: 'waica:dog' },
11
+ { file: 'waica-coin.png', uri: 'waica:coin' },
12
+ { file: 'waica-slime.png', uri: 'waica:slime' },
13
+ ];
@@ -0,0 +1,3 @@
1
+ import type { ArchetypeBundle } from '@waica/engine';
2
+ /** Role and state-code baseline installed for a platformer project. */
3
+ export declare const PLATFORMER_BUNDLE: ArchetypeBundle;
package/dist/bundle.js ADDED
@@ -0,0 +1,10 @@
1
+ import { CHASER_ROLE, NPC_ROLE, PATROLLER_ROLE, PLAYER_ROLE, } from '@waica/behaviors';
2
+ /** Role and state-code baseline installed for a platformer project. */
3
+ export const PLATFORMER_BUNDLE = {
4
+ roles: {
5
+ player: PLAYER_ROLE,
6
+ patroller: PATROLLER_ROLE,
7
+ chaser: CHASER_ROLE,
8
+ npc: NPC_ROLE,
9
+ },
10
+ };
@@ -0,0 +1,5 @@
1
+ import type { InputBindings } from '@waica/engine';
2
+ /** Platformer actions and the exact legacy keyboard defaults. */
3
+ export declare const PLATFORMER_BINDINGS: Readonly<InputBindings>;
4
+ /** Friendly labels shown by the editor's controls panel. */
5
+ export declare const PLATFORMER_ACTION_LABELS: Readonly<Record<string, string>>;
@@ -0,0 +1,12 @@
1
+ /** Platformer actions and the exact legacy keyboard defaults. */
2
+ export const PLATFORMER_BINDINGS = {
3
+ left: ['ArrowLeft', 'KeyA'],
4
+ right: ['ArrowRight', 'KeyD'],
5
+ jump: ['Space', 'ArrowUp', 'KeyW'],
6
+ };
7
+ /** Friendly labels shown by the editor's controls panel. */
8
+ export const PLATFORMER_ACTION_LABELS = {
9
+ left: 'Move left',
10
+ right: 'Move right',
11
+ jump: 'Jump',
12
+ };
@@ -0,0 +1,38 @@
1
+ import { Game, type Entity } from '@waica/engine';
2
+ export { PLATFORMER_BUNDLE } from './bundle.js';
3
+ export { PLATFORMER_ACTION_LABELS, PLATFORMER_BINDINGS } from './controls.js';
4
+ export { PLATFORMER_SCENE, PLATFORMER_BLANK_SCENE, DOG_SPRITE } from './scene-default.js';
5
+ export { PLATFORMER_PREFABS } from './prefabs.js';
6
+ export { PLATFORMER_UI } from './ui.js';
7
+ export { PLATFORMER_ART } from './art.js';
8
+ export { PLATFORMER_REGISTRY, PLATFORMER_PALETTE, PLATFORMER_ART_URLS } from './registry.js';
9
+ /** Browser-complete manifest exported by the package root. */
10
+ export declare const ARCHETYPE: {
11
+ id: string;
12
+ label: string;
13
+ scene: import("@waica/engine").SceneJson;
14
+ blankScene: import("@waica/engine").SceneJson;
15
+ palette: import("@waica/engine").EntityTemplate[];
16
+ prefabs: Record<string, import("@waica/engine").PrefabJson>;
17
+ art: import("@waica/engine").ArchetypeArt[];
18
+ entityIcons: Readonly<Record<string, string>>;
19
+ bindings: Readonly<import("@waica/engine").InputBindings>;
20
+ actionLabels: Readonly<Record<string, string>>;
21
+ bundle: import("@waica/engine").ArchetypeBundle;
22
+ registry: import("@waica/engine").SceneRegistry;
23
+ artUrls: Record<string, string>;
24
+ };
25
+ export interface PlatformerSetup {
26
+ player: Entity;
27
+ /** Collected-coin counter, for the HUD and tests. */
28
+ score: {
29
+ coins: number;
30
+ };
31
+ }
32
+ /**
33
+ * Sets up the platformer archetype's base scene by loading the default
34
+ * scene (real projects load their own src/scenes/*.json). The scene's
35
+ * 'coin-counter' UI piece renders the counter; the returned score just
36
+ * tracks it.
37
+ */
38
+ export declare function setupPlatformer(game: Game): PlatformerSetup;
package/dist/index.js ADDED
@@ -0,0 +1,34 @@
1
+ import { Game, loadScene, } from '@waica/engine';
2
+ import { ARCHETYPE as DATA_ARCHETYPE } from './manifest.js';
3
+ import { PLATFORMER_REGISTRY, PLATFORMER_ART_URLS } from './registry.js';
4
+ import { PLATFORMER_SCENE } from './scene-default.js';
5
+ export { PLATFORMER_BUNDLE } from './bundle.js';
6
+ export { PLATFORMER_ACTION_LABELS, PLATFORMER_BINDINGS } from './controls.js';
7
+ export { PLATFORMER_SCENE, PLATFORMER_BLANK_SCENE, DOG_SPRITE } from './scene-default.js';
8
+ export { PLATFORMER_PREFABS } from './prefabs.js';
9
+ export { PLATFORMER_UI } from './ui.js';
10
+ export { PLATFORMER_ART } from './art.js';
11
+ export { PLATFORMER_REGISTRY, PLATFORMER_PALETTE, PLATFORMER_ART_URLS } from './registry.js';
12
+ /** Browser-complete manifest exported by the package root. */
13
+ export const ARCHETYPE = {
14
+ ...DATA_ARCHETYPE,
15
+ registry: PLATFORMER_REGISTRY,
16
+ artUrls: PLATFORMER_ART_URLS,
17
+ };
18
+ /**
19
+ * Sets up the platformer archetype's base scene by loading the default
20
+ * scene (real projects load their own src/scenes/*.json). The scene's
21
+ * 'coin-counter' UI piece renders the counter; the returned score just
22
+ * tracks it.
23
+ */
24
+ export function setupPlatformer(game) {
25
+ loadScene(game, PLATFORMER_SCENE, PLATFORMER_REGISTRY);
26
+ const score = { coins: 0 };
27
+ game.events.on('collect', (value) => {
28
+ score.coins += typeof value === 'number' ? value : 1;
29
+ });
30
+ const player = game.find('Player');
31
+ if (!player)
32
+ throw new Error('default scene has no Player');
33
+ return { player, score };
34
+ }
@@ -0,0 +1,15 @@
1
+ /** Asset-import-free manifest for Node tooling. */
2
+ export declare const ARCHETYPE: {
3
+ id: string;
4
+ label: string;
5
+ scene: import("@waica/engine").SceneJson;
6
+ blankScene: import("@waica/engine").SceneJson;
7
+ registry: import("@waica/engine").SceneRegistry;
8
+ palette: import("@waica/engine").EntityTemplate[];
9
+ prefabs: Record<string, import("@waica/engine").PrefabJson>;
10
+ art: import("@waica/engine").ArchetypeArt[];
11
+ entityIcons: Readonly<Record<string, string>>;
12
+ bindings: Readonly<import("@waica/engine").InputBindings>;
13
+ actionLabels: Readonly<Record<string, string>>;
14
+ bundle: import("@waica/engine").ArchetypeBundle;
15
+ };
@@ -0,0 +1,26 @@
1
+ import { PLATFORMER_ART } from './art.js';
2
+ import { PLATFORMER_BUNDLE } from './bundle.js';
3
+ import { PLATFORMER_ACTION_LABELS, PLATFORMER_BINDINGS } from './controls.js';
4
+ import { PLATFORMER_PREFABS } from './prefabs.js';
5
+ import { PLATFORMER_PALETTE, PLATFORMER_REGISTRY_DATA } from './registry-data.js';
6
+ import { PLATFORMER_BLANK_SCENE, PLATFORMER_SCENE } from './scene-default.js';
7
+ const PLATFORMER_ENTITY_ICONS = {
8
+ PlatformerMotor: '🐕',
9
+ Collectible: '🪙',
10
+ Hazard: '👾',
11
+ };
12
+ /** Asset-import-free manifest for Node tooling. */
13
+ export const ARCHETYPE = {
14
+ id: 'platformer',
15
+ label: 'Platformer',
16
+ scene: PLATFORMER_SCENE,
17
+ blankScene: PLATFORMER_BLANK_SCENE,
18
+ registry: PLATFORMER_REGISTRY_DATA,
19
+ palette: PLATFORMER_PALETTE,
20
+ prefabs: PLATFORMER_PREFABS,
21
+ art: PLATFORMER_ART,
22
+ entityIcons: PLATFORMER_ENTITY_ICONS,
23
+ bindings: PLATFORMER_BINDINGS,
24
+ actionLabels: PLATFORMER_ACTION_LABELS,
25
+ bundle: PLATFORMER_BUNDLE,
26
+ };
@@ -0,0 +1,7 @@
1
+ import type { PrefabJson } from '@waica/engine';
2
+ /**
3
+ * The archetype's reusable entity templates, keyed by ref ('characters/slime').
4
+ * Scenes reference these and override per-entity props; the palette derives
5
+ * its pieces from this catalog.
6
+ */
7
+ export declare const PLATFORMER_PREFABS: Record<string, PrefabJson>;
@@ -0,0 +1,97 @@
1
+ import { PLAYER_STATE_GRAPH } from '@waica/behaviors';
2
+ import { DOG_SPRITE } from './scene-default.js';
3
+ /**
4
+ * The archetype's reusable entity templates, keyed by ref ('characters/slime').
5
+ * Scenes reference these and override per-entity props; the palette derives
6
+ * its pieces from this catalog.
7
+ */
8
+ export const PLATFORMER_PREFABS = {
9
+ 'characters/player': {
10
+ waicaPrefab: 1,
11
+ type: 'character',
12
+ components: [
13
+ { type: 'AnimatedSprite', props: DOG_SPRITE },
14
+ { type: 'PlatformerMotor' },
15
+ {
16
+ type: 'StateMachine',
17
+ props: {
18
+ role: 'player',
19
+ initial: PLAYER_STATE_GRAPH.initial,
20
+ states: PLAYER_STATE_GRAPH.states,
21
+ },
22
+ },
23
+ { type: 'Hitbox', props: { width: 0.9, height: 0.95 } },
24
+ { type: 'Respawnable', props: { killY: -12 } },
25
+ ],
26
+ },
27
+ 'characters/slime': {
28
+ waicaPrefab: 1,
29
+ type: 'character',
30
+ components: [
31
+ {
32
+ type: 'AnimatedSprite',
33
+ props: {
34
+ texture: 'waica:slime',
35
+ cols: 4,
36
+ rows: 1,
37
+ width: 1.1,
38
+ height: 1.1,
39
+ clips: { idle: { frames: [0, 1, 2, 3], fps: 6 } },
40
+ initialClip: 'idle',
41
+ },
42
+ },
43
+ { type: 'Patrol', props: { distance: 2, speed: 2 } },
44
+ {
45
+ type: 'StateMachine',
46
+ props: {
47
+ role: 'patroller',
48
+ initial: 'walk',
49
+ states: { walk: { clip: 'idle' } },
50
+ },
51
+ },
52
+ { type: 'Hitbox', props: { width: 0.9, height: 0.6 } },
53
+ { type: 'Hazard', props: { stompable: true, bounce: 10 } },
54
+ ],
55
+ },
56
+ 'objects/coin': {
57
+ waicaPrefab: 1,
58
+ type: 'object',
59
+ components: [
60
+ {
61
+ type: 'AnimatedSprite',
62
+ props: {
63
+ texture: 'waica:coin',
64
+ cols: 4,
65
+ rows: 1,
66
+ width: 0.6,
67
+ height: 0.6,
68
+ clips: { spin: { frames: [0, 1, 2, 3], fps: 8 } },
69
+ initialClip: 'spin',
70
+ },
71
+ },
72
+ { type: 'Hitbox', props: { width: 0.5, height: 0.5 } },
73
+ { type: 'Collectible', props: { value: 1 } },
74
+ ],
75
+ },
76
+ 'tiles/platform': {
77
+ waicaPrefab: 1,
78
+ type: 'tile',
79
+ components: [
80
+ { type: 'Sprite', props: { width: 3, height: 0.5, color: 0x2a9d8f } },
81
+ { type: 'Solid', props: { width: 3, height: 0.5 } },
82
+ ],
83
+ },
84
+ 'tiles/block': {
85
+ waicaPrefab: 1,
86
+ type: 'tile',
87
+ components: [
88
+ { type: 'Sprite', props: { width: 2, height: 2, color: 0x264653 } },
89
+ { type: 'Solid', props: { width: 2, height: 2 } },
90
+ ],
91
+ },
92
+ 'tiles/decor': {
93
+ waicaPrefab: 1,
94
+ type: 'tile',
95
+ components: [{ type: 'Sprite', props: { width: 1, height: 1, color: 0x8ecae6 } }],
96
+ },
97
+ };
@@ -0,0 +1,5 @@
1
+ import { type EntityTemplate, type SceneRegistry } from '@waica/engine';
2
+ /** Asset-import-free registry. Browser URL resolution is layered on separately. */
3
+ export declare const PLATFORMER_REGISTRY_DATA: SceneRegistry;
4
+ /** The editor palette: pieces you can drag into the viewport, one per prefab. */
5
+ export declare const PLATFORMER_PALETTE: EntityTemplate[];
@@ -0,0 +1,45 @@
1
+ import { AnimatedSprite, DynamicBody, Hitbox, Solid, Sprite, StateMachine, } from '@waica/engine';
2
+ import { Chaser, Collectible, Hazard, Lifetime, Patrol, PlatformerMotor, Respawnable, } from '@waica/behaviors';
3
+ import { PLATFORMER_ART } from './art.js';
4
+ import { PLATFORMER_PREFABS } from './prefabs.js';
5
+ import { PLATFORMER_UI } from './ui.js';
6
+ const PACKAGE_ASSETS = Object.fromEntries(PLATFORMER_ART.map((art) => [art.uri, `assets/${art.file}`]));
7
+ /** Asset-import-free registry. Browser URL resolution is layered on separately. */
8
+ export const PLATFORMER_REGISTRY_DATA = {
9
+ components: {
10
+ Sprite,
11
+ AnimatedSprite,
12
+ Solid,
13
+ Hitbox,
14
+ DynamicBody,
15
+ StateMachine,
16
+ PlatformerMotor,
17
+ Collectible,
18
+ Patrol,
19
+ Chaser,
20
+ Hazard,
21
+ Respawnable,
22
+ Lifetime,
23
+ },
24
+ resolveAsset: (uri) => PACKAGE_ASSETS[uri] ?? uri,
25
+ prefabs: PLATFORMER_PREFABS,
26
+ ui: PLATFORMER_UI,
27
+ };
28
+ const PALETTE_ICONS = {
29
+ player: '🐕',
30
+ slime: '👾',
31
+ coin: '🪙',
32
+ platform: '▬',
33
+ block: '■',
34
+ decor: '▢',
35
+ };
36
+ /** The editor palette: pieces you can drag into the viewport, one per prefab. */
37
+ export const PLATFORMER_PALETTE = Object.entries(PLATFORMER_PREFABS).map(([key, prefab]) => {
38
+ const base = key.slice(key.indexOf('/') + 1);
39
+ return {
40
+ label: base,
41
+ icon: PALETTE_ICONS[base] ?? '▣',
42
+ category: prefab.type,
43
+ make: () => ({ name: base.charAt(0).toUpperCase() + base.slice(1), prefab: key }),
44
+ };
45
+ });
@@ -0,0 +1,6 @@
1
+ import type { SceneRegistry } from '@waica/engine';
2
+ export { PLATFORMER_PALETTE } from './registry-data.js';
3
+ /** Browser URL per stock-art file; Node resolves these to packed file URLs. */
4
+ export declare const PLATFORMER_ART_URLS: Record<string, string>;
5
+ /** Browser registry with bundled asset resolution layered over the shared registry. */
6
+ export declare const PLATFORMER_REGISTRY: SceneRegistry;
@@ -0,0 +1,15 @@
1
+ import { PLATFORMER_ART } from './art.js';
2
+ import { PLATFORMER_REGISTRY_DATA } from './registry-data.js';
3
+ export { PLATFORMER_PALETTE } from './registry-data.js';
4
+ /** Browser URL per stock-art file; Node resolves these to packed file URLs. */
5
+ export const PLATFORMER_ART_URLS = {
6
+ 'waica-dog.png': new URL('../assets/waica-dog.png', import.meta.url).href,
7
+ 'waica-coin.png': new URL('../assets/waica-coin.png', import.meta.url).href,
8
+ 'waica-slime.png': new URL('../assets/waica-slime.png', import.meta.url).href,
9
+ };
10
+ const BUILTIN_ASSETS = Object.fromEntries(PLATFORMER_ART.map((art) => [art.uri, PLATFORMER_ART_URLS[art.file] ?? art.uri]));
11
+ /** Browser registry with bundled asset resolution layered over the shared registry. */
12
+ export const PLATFORMER_REGISTRY = {
13
+ ...PLATFORMER_REGISTRY_DATA,
14
+ resolveAsset: (uri) => BUILTIN_ASSETS[uri] ?? uri,
15
+ };
@@ -0,0 +1,40 @@
1
+ import type { SceneJson } from '@waica/engine';
2
+ /** Clips matching the platformer state graph, applied to the placeholder dog. */
3
+ export declare const DOG_SPRITE: {
4
+ texture: string;
5
+ cols: number;
6
+ rows: number;
7
+ width: number;
8
+ height: number;
9
+ clips: {
10
+ idle: {
11
+ frames: number[];
12
+ fps: number;
13
+ };
14
+ run: {
15
+ frames: number[];
16
+ fps: number;
17
+ };
18
+ jump: {
19
+ frames: number[];
20
+ fps: number;
21
+ loop: boolean;
22
+ };
23
+ fall: {
24
+ frames: number[];
25
+ fps: number;
26
+ };
27
+ };
28
+ initialClip: string;
29
+ };
30
+ /**
31
+ * The platformer archetype's starting scene, as data: prefab refs plus the
32
+ * per-entity overrides that differ from the prefab. This is what the wizard
33
+ * copies into `src/scenes/main.scene.json` and what the editor edits.
34
+ */
35
+ export declare const PLATFORMER_SCENE: SceneJson;
36
+ /**
37
+ * The blank-start variant: same camera framing, zero entities. No `follow`
38
+ * because there is no Player yet — the editor's palette places the first one.
39
+ */
40
+ export declare const PLATFORMER_BLANK_SCENE: SceneJson;
@@ -0,0 +1,93 @@
1
+ /** Clips matching the platformer state graph, applied to the placeholder dog. */
2
+ export const DOG_SPRITE = {
3
+ texture: 'waica:dog',
4
+ cols: 4,
5
+ rows: 4,
6
+ width: 1.4,
7
+ height: 1.4,
8
+ clips: {
9
+ idle: { frames: [0, 1, 2, 3], fps: 5 },
10
+ run: { frames: [4, 5, 6, 7], fps: 10 },
11
+ jump: { frames: [8, 9], fps: 8, loop: false },
12
+ fall: { frames: [12, 13], fps: 8 },
13
+ },
14
+ initialClip: 'idle',
15
+ };
16
+ /**
17
+ * The platformer archetype's starting scene, as data: prefab refs plus the
18
+ * per-entity overrides that differ from the prefab. This is what the wizard
19
+ * copies into `src/scenes/main.scene.json` and what the editor edits.
20
+ */
21
+ export const PLATFORMER_SCENE = {
22
+ waicaScene: 3,
23
+ camera: { position: [0, -1], zoom: 12, follow: 'Player' },
24
+ entities: [
25
+ { name: 'Player', prefab: 'characters/player', position: [0, -1] },
26
+ {
27
+ name: 'Ground-A',
28
+ prefab: 'tiles/platform',
29
+ position: [-6, -5],
30
+ overrides: { Sprite: { width: 16, height: 2 }, Solid: { width: 16, height: 2 } },
31
+ },
32
+ {
33
+ name: 'Ground-B',
34
+ prefab: 'tiles/platform',
35
+ position: [16, -5],
36
+ overrides: { Sprite: { width: 16, height: 2 }, Solid: { width: 16, height: 2 } },
37
+ },
38
+ {
39
+ name: 'Platform-1',
40
+ prefab: 'tiles/platform',
41
+ position: [5, -2.5],
42
+ overrides: { Sprite: { width: 4 }, Solid: { width: 4 } },
43
+ },
44
+ { name: 'Platform-2', prefab: 'tiles/platform', position: [9.5, -0.5] },
45
+ { name: 'Platform-3', prefab: 'tiles/platform', position: [-5.5, -1.5] },
46
+ {
47
+ name: 'Platform-4',
48
+ prefab: 'tiles/block',
49
+ position: [14, 1.5],
50
+ overrides: { Sprite: { width: 3, height: 0.5 }, Solid: { width: 3, height: 0.5 } },
51
+ },
52
+ {
53
+ name: 'Wall-Left',
54
+ prefab: 'tiles/block',
55
+ position: [-15.5, 0],
56
+ overrides: { Sprite: { height: 12 }, Solid: { height: 12 } },
57
+ },
58
+ {
59
+ name: 'Wall-Right',
60
+ prefab: 'tiles/block',
61
+ position: [25.5, 0],
62
+ overrides: { Sprite: { height: 12 }, Solid: { height: 12 } },
63
+ },
64
+ { name: 'Coin-1', prefab: 'objects/coin', position: [-5.5, -0.5] },
65
+ { name: 'Coin-2', prefab: 'objects/coin', position: [-2, -3.2] },
66
+ { name: 'Coin-3', prefab: 'objects/coin', position: [5, -1.7] },
67
+ { name: 'Coin-4', prefab: 'objects/coin', position: [9.5, 0.3] },
68
+ { name: 'Coin-5', prefab: 'objects/coin', position: [14, 2.3] },
69
+ { name: 'Coin-6', prefab: 'objects/coin', position: [19, -3.2] },
70
+ {
71
+ name: 'Slime-1',
72
+ prefab: 'characters/slime',
73
+ position: [-9, -3.55],
74
+ overrides: { Patrol: { speed: 1.5 } },
75
+ },
76
+ {
77
+ name: 'Slime-2',
78
+ prefab: 'characters/slime',
79
+ position: [17, -3.55],
80
+ overrides: { Patrol: { distance: 2.5, speed: 2.5 } },
81
+ },
82
+ ],
83
+ ui: ['coin-counter'],
84
+ };
85
+ /**
86
+ * The blank-start variant: same camera framing, zero entities. No `follow`
87
+ * because there is no Player yet — the editor's palette places the first one.
88
+ */
89
+ export const PLATFORMER_BLANK_SCENE = {
90
+ waicaScene: 3,
91
+ camera: { position: [0, -1], zoom: 12 },
92
+ entities: [],
93
+ };
package/dist/ui.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The archetype's default UI pieces: self-contained HTML fragments
3
+ * (markup + <style>, {{stat}} bindings) keyed by piece name. Projects
4
+ * override them with src/ui/<name>.html files; scenes list the pieces
5
+ * they start with in their "ui" field.
6
+ *
7
+ * TS template literals (not .html files) because this package builds
8
+ * with plain tsc — no bundler to inline raw imports.
9
+ */
10
+ export declare const PLATFORMER_UI: Record<string, string>;
package/dist/ui.js ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The archetype's default UI pieces: self-contained HTML fragments
3
+ * (markup + <style>, {{stat}} bindings) keyed by piece name. Projects
4
+ * override them with src/ui/<name>.html files; scenes list the pieces
5
+ * they start with in their "ui" field.
6
+ *
7
+ * TS template literals (not .html files) because this package builds
8
+ * with plain tsc — no bundler to inline raw imports.
9
+ */
10
+ export const PLATFORMER_UI = {
11
+ 'coin-counter': `<style>
12
+ .coin-counter {
13
+ position: absolute;
14
+ top: 12px;
15
+ left: 12px;
16
+ font: 600 20px system-ui, sans-serif;
17
+ color: #ffd166;
18
+ text-shadow: 0 1px 3px #000a;
19
+ user-select: none;
20
+ }
21
+ </style>
22
+ <div class="coin-counter">🪙 {{points}}</div>
23
+ `,
24
+ };
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@waica/archetype-platformer",
3
+ "version": "0.3.0",
4
+ "description": "Waica platformer archetype — opinionated setup for side-scrolling platformers",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/chichex/waica",
10
+ "directory": "packages/archetype-platformer"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "assets"
15
+ ],
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "default": "./dist/index.js"
20
+ },
21
+ "./manifest": {
22
+ "types": "./dist/manifest.d.ts",
23
+ "default": "./dist/manifest.js"
24
+ }
25
+ },
26
+ "dependencies": {
27
+ "@waica/engine": "^0.3.0",
28
+ "@waica/behaviors": "^0.3.0"
29
+ },
30
+ "scripts": {
31
+ "build": "node ../../scripts/clean-dist.mjs && tsc -p tsconfig.build.json",
32
+ "typecheck": "tsc --noEmit"
33
+ }
34
+ }