@vylos/core 0.4.4 → 0.5.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/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # @vylos/core
2
+
3
+ The engine, types, stores, and components for [Vylos](https://github.com/DevOpsBenjamin/Vylos) — a checkpoint-based visual novel engine built with Vue 3 and TypeScript.
4
+
5
+ [![npm](https://img.shields.io/npm/v/@vylos/core)](https://www.npmjs.com/package/@vylos/core)
6
+
7
+ ## Features
8
+
9
+ - **Checkpoint-based execution** — `engine.say()` and `engine.choice()` pause via async/await, rollback via re-execute + fast-forward (like Ren'Py)
10
+ - **Rollback & history** — full forward/back navigation through past dialogue
11
+ - **Save/load with mid-event resume** — checkpoint system preserves exact position
12
+ - **Inventory system** — bag-based `engine.inventory.add/remove/has/count/list/clear`
13
+ - **Location & action managers** — time-of-day backgrounds, linked locations, conditional actions
14
+ - **Drawable events** — clickable characters/objects on screen
15
+ - **i18n** — `string | Record<string, string>` for multi-language support
16
+ - **Plugin system** — DI-based (tsyringe) manager and component overrides
17
+ - **Dev console** — `window.Vylos` for debugging and cheating (state, inventory, engine)
18
+ - **H key** — hide all UI to view artwork (Ren'Py style)
19
+ - **AZERTY/QWERTY auto-detect** — keyboard input adapts automatically
20
+
21
+ ## Install
22
+
23
+ ```bash
24
+ pnpm add @vylos/core
25
+ ```
26
+
27
+ Requires Vue 3 and Pinia.
28
+
29
+ ## Usage
30
+
31
+ ```typescript
32
+ import {
33
+ createEngine,
34
+ GameShell,
35
+ useEngineStateStore,
36
+ ENGINE_INJECT_KEY,
37
+ type VylosEvent,
38
+ type VylosAPI,
39
+ type VylosGameState,
40
+ } from '@vylos/core';
41
+ ```
42
+
43
+ ### Writing events
44
+
45
+ ```typescript
46
+ const intro: VylosEvent = {
47
+ id: 'intro',
48
+ conditions: (state) => !state.flags['intro_done'],
49
+ async execute(engine: VylosAPI, state: VylosGameState) {
50
+ await engine.say('Welcome!');
51
+
52
+ const pick = await engine.choice([
53
+ { text: 'Start', value: 'start' },
54
+ { text: 'Learn more', value: 'more' },
55
+ ]);
56
+
57
+ if (pick === 'more') {
58
+ await engine.say('Events pause at each say() and choice().');
59
+ }
60
+
61
+ state.flags['intro_done'] = true;
62
+ },
63
+ };
64
+ ```
65
+
66
+ ### Extending types
67
+
68
+ ```typescript
69
+ import type { VylosCharacter, VylosGameState } from '@vylos/core';
70
+
71
+ interface Character extends VylosCharacter {
72
+ portrait?: string;
73
+ }
74
+
75
+ interface GameState extends VylosGameState {
76
+ player: Character;
77
+ energy: number;
78
+ }
79
+ ```
80
+
81
+ ### Inventory
82
+
83
+ ```typescript
84
+ async execute(engine: VylosAPI, state: GameState) {
85
+ engine.inventory.add('backpack', 'potion', 3);
86
+
87
+ if (engine.inventory.has('backpack', 'key')) {
88
+ engine.inventory.remove('backpack', 'key', 1);
89
+ await engine.say('You used the key.');
90
+ }
91
+ }
92
+ ```
93
+
94
+ ## Key bindings
95
+
96
+ | Key | Action |
97
+ |-----|--------|
98
+ | Space / Enter / E | Advance dialogue |
99
+ | D / Arrow Right | Forward |
100
+ | A / Q / Arrow Left | Back |
101
+ | H | Toggle UI visibility |
102
+ | S | Toggle skip mode |
103
+ | Escape | Pause menu |
104
+
105
+ ## Documentation
106
+
107
+ Full docs and examples: [github.com/DevOpsBenjamin/Vylos](https://github.com/DevOpsBenjamin/Vylos)
108
+
109
+ ## License
110
+
111
+ [MIT](https://github.com/DevOpsBenjamin/Vylos/blob/main/LICENSE)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vylos/core",
3
- "version": "0.4.4",
3
+ "version": "0.5.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/DevOpsBenjamin/Vylos"
@@ -10,20 +10,23 @@
10
10
  <template v-if="!engineState.uiHidden">
11
11
  <!-- z-15–25: HUD (hidden during dialogue/choices) -->
12
12
  <template v-if="!hideHud">
13
- <DrawableOverlay />
14
- <LocationOverlay />
15
- <ActionOverlay />
16
- <TopBar />
13
+ <component :is="drawableOverlayComponent" />
14
+ <component :is="locationOverlayComponent" />
15
+ <component :is="actionOverlayComponent" />
16
+ <component :is="topBarComponent" />
17
17
  </template>
18
18
 
19
19
  <!-- z-30: Dialogue box -->
20
- <DialogueBox />
20
+ <component :is="dialogueBoxComponent" />
21
21
 
22
22
  <!-- z-35: Choice panel (inside DialogueBox z-range) -->
23
- <ChoicePanel />
23
+ <component :is="choicePanelComponent" />
24
24
 
25
25
  <!-- z-40: Custom overlay -->
26
26
  <CustomOverlay />
27
+
28
+ <!-- z-45: Project HUD (always visible when UI is shown) -->
29
+ <slot name="hud" />
27
30
  </template>
28
31
  </div>
29
32
  </template>
@@ -31,16 +34,24 @@
31
34
  <script setup lang="ts">
32
35
  import { computed } from 'vue';
33
36
  import { useEngineStateStore } from '../../stores/engineState';
37
+ import { getComponentOverride } from '../../engine/core/EngineFactory';
34
38
  import BackgroundLayer from '../core/BackgroundLayer.vue';
35
39
  import ForegroundLayer from '../core/ForegroundLayer.vue';
36
- import DrawableOverlay from '../core/DrawableOverlay.vue';
37
- import DialogueBox from '../core/DialogueBox.vue';
38
- import ChoicePanel from '../core/ChoicePanel.vue';
40
+ import DefaultDrawableOverlay from '../core/DrawableOverlay.vue';
41
+ import DefaultDialogueBox from '../core/DialogueBox.vue';
42
+ import DefaultChoicePanel from '../core/ChoicePanel.vue';
39
43
  import CustomOverlay from '../core/CustomOverlay.vue';
40
- import ActionOverlay from '../menu/ActionOverlay.vue';
41
- import LocationOverlay from '../menu/LocationOverlay.vue';
42
- import TopBar from '../menu/TopBar.vue';
44
+ import DefaultActionOverlay from '../menu/ActionOverlay.vue';
45
+ import DefaultLocationOverlay from '../menu/LocationOverlay.vue';
46
+ import DefaultTopBar from '../menu/TopBar.vue';
43
47
 
44
48
  const engineState = useEngineStateStore();
45
49
  const hideHud = computed(() => !!engineState.dialogue || !!engineState.choices);
50
+
51
+ const topBarComponent = computed(() => getComponentOverride('TopBar') ?? DefaultTopBar);
52
+ const actionOverlayComponent = computed(() => getComponentOverride('ActionOverlay') ?? DefaultActionOverlay);
53
+ const locationOverlayComponent = computed(() => getComponentOverride('LocationOverlay') ?? DefaultLocationOverlay);
54
+ const dialogueBoxComponent = computed(() => getComponentOverride('DialogueBox') ?? DefaultDialogueBox);
55
+ const choicePanelComponent = computed(() => getComponentOverride('ChoicePanel') ?? DefaultChoicePanel);
56
+ const drawableOverlayComponent = computed(() => getComponentOverride('DrawableOverlay') ?? DefaultDrawableOverlay);
46
57
  </script>