@alife-sdk/core 0.1.0 → 0.1.1

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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Framework-agnostic A-Life simulation and AI decision-making system.
4
4
 
5
- Zero external dependencies. Works with Phaser, Unity, Node.js, or any other runtime.
5
+ Zero external dependencies. Works with Phaser, PixiJS, Node.js, or any JavaScript runtime.
6
6
 
7
7
  ```
8
8
  npm install @alife-sdk/core
@@ -16,7 +16,7 @@ npm install @alife-sdk/core
16
16
 
17
17
  - **NPC AI** — finite state machines, GOAP planners, memory and perception systems
18
18
  - **A-Life simulation** — offline NPC brains, terrain selection, spawn cooldowns, faction diplomacy
19
- - **Game clock** — accelerated in-game time, day/night cycle, hour events
19
+ - **Game clock** — accelerated in-game time with configurable day/night cycle and time-change callbacks (HOUR_CHANGED, DAY_NIGHT_CHANGED events)
20
20
  - **World graph** — waypoint graph with A* pathfinding for offline NPC movement
21
21
  - **Plugin system** — extend the kernel with your own domain features
22
22
 
@@ -52,6 +52,8 @@ kernel.provide(Ports.PlayerPosition, { getPlayerPosition: () => ({ x: player.x,
52
52
  fullPreset(kernel);
53
53
 
54
54
  // 4. Register game data (before init)
55
+ // Plugins is a set of typed plugin tokens — alternative to string IDs
56
+ // e.g. kernel.getPlugin(Plugins.FACTIONS) is equivalent to kernel.getPlugin('factions')
55
57
  const factions = kernel.getPlugin(Plugins.FACTIONS).factions;
56
58
  factions.register('stalker', { name: 'Stalker', baseRelations: { bandit: -80 } });
57
59
  factions.register('bandit', { name: 'Bandit', baseRelations: { stalker: -80 } });
@@ -83,7 +85,7 @@ Each module has its own import path for optimal tree-shaking:
83
85
 
84
86
  | Import path | What's inside | Module docs |
85
87
  |-------------|--------------|-------------|
86
- | `@alife-sdk/core` | `ALifeKernel`, `Clock`, `SpatialGrid`, `Ports` | [core/](src/core/) |
88
+ | `@alife-sdk/core` | `ALifeKernel`, `Clock`, `SpatialGrid`, `Ports`, `PortRegistry`, `Vec2`, `createPortToken` | [core/](src/core/) |
87
89
  | `@alife-sdk/core/ai` | `StateMachine`, `MemoryBank`, `DangerManager`, `GOAPPlanner` | [ai/](src/ai/README.md) |
88
90
  | `@alife-sdk/core/combat` | `DamageInstance`, `MoraleTracker`, `ImmunityProfile` | [combat/](src/combat/README.md) |
89
91
  | `@alife-sdk/core/config` | `createDefaultConfig`, `IALifeConfig` | [config/](src/config/README.md) |
@@ -187,7 +189,7 @@ kernel.events.on(ALifeEvents.NPC_DIED, ({ npcId, killedBy }) => {
187
189
  });
188
190
  ```
189
191
 
190
- 38 typed events across 9 categories: A-Life, AI, Surge, Anomaly, Squad,
192
+ 41 typed events across 9 categories: A-Life, AI, Surge, Anomaly, Squad,
191
193
  Faction, Time, Social, Monster. See [`events/README.md`](src/events/README.md).
192
194
 
193
195
  ### AI — StateMachine + GOAP
@@ -231,6 +233,23 @@ kernel.restoreState() ← restore from save
231
233
  kernel.destroy() ← cleanup, call plugin.destroy() in reverse order
232
234
  ```
233
235
 
236
+ ### Save versioning and migrations
237
+
238
+ The kernel supports versioned saves. When a save file was created by an older
239
+ version of your game, you can register migration functions to transform the
240
+ state forward. Migrations are applied automatically during `restoreState()`.
241
+
242
+ ```ts
243
+ // Register a migration that upgrades state from version 0 → 1
244
+ kernel.registerMigration(0, (state) => {
245
+ // transform state as needed
246
+ return { ...state, version: 1, newField: 'default' };
247
+ });
248
+
249
+ // Later, restoreState() applies all needed migrations automatically
250
+ kernel.restoreState(oldSave);
251
+ ```
252
+
234
253
  ---
235
254
 
236
255
  ## Testing
@@ -1 +1 @@
1
- {"version":3,"file":"TimeManager.d.ts","sourceRoot":"","sources":["../../src/time/TimeManager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAGhE,MAAM,WAAW,kBAAkB;IACjC,qFAAqF;IACrF,MAAM,CAAC,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IACtC,yGAAyG;IACzG,WAAW,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,eAAe,GAAG,mBAAmB,CAAC,CAAC;CACzE;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2C;gBAEvD,MAAM,GAAE,kBAAuB;IAQ3C,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI7B,IAAI,KAAK,IAAI,KAAK,CAEjB;IAED,SAAS,IAAI,WAAW;IAIxB,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAIjC,OAAO,CAAC,eAAe;CAaxB"}
1
+ {"version":3,"file":"TimeManager.d.ts","sourceRoot":"","sources":["../../src/time/TimeManager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAGhE,MAAM,WAAW,kBAAkB;IACjC,qFAAqF;IACrF,MAAM,CAAC,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IACtC,yGAAyG;IACzG,WAAW,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,eAAe,GAAG,mBAAmB,CAAC,CAAC;CACzE;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2C;gBAEvD,MAAM,GAAE,kBAAuB;IAQ3C,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI7B,IAAI,KAAK,IAAI,KAAK,CAEjB;IAED,SAAS,IAAI,WAAW;IAIxB,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAIjC,OAAO,CAAC,eAAe;CAYxB"}
@@ -27,10 +27,9 @@ export class TimeManager {
27
27
  if (!this._events)
28
28
  return {};
29
29
  const events = this._events;
30
- const self = this;
31
30
  return {
32
31
  onHourChanged: (hour, day) => {
33
- events.emit(ALifeEvents.HOUR_CHANGED, { hour, day, isDay: self._clock.isDay });
32
+ events.emit(ALifeEvents.HOUR_CHANGED, { hour, day, isDay: this._clock.isDay });
34
33
  },
35
34
  onDayNightChanged: (isDay) => {
36
35
  events.emit(ALifeEvents.DAY_NIGHT_CHANGED, { isDay });
@@ -1 +1 @@
1
- {"version":3,"file":"TimeManager.js","sourceRoot":"","sources":["../../src/time/TimeManager.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,gCAAgC;AAChC,qFAAqF;AAErF,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAItC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AASpD,MAAM,OAAO,WAAW;IAItB,YAAY,SAA6B,EAAE;QACzC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,CAAC;YACtB,GAAG,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;YAC7B,GAAG,IAAI,CAAC,eAAe,EAAE;SAC1B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,OAAe;QACpB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;IACjC,CAAC;IAED,OAAO,CAAC,KAAkB;QACxB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;IAC/D,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC;QAClB,OAAO;YACL,aAAa,EAAE,CAAC,IAAY,EAAE,GAAW,EAAE,EAAE;gBAC3C,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;YACjF,CAAC;YACD,iBAAiB,EAAE,CAAC,KAAc,EAAE,EAAE;gBACpC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,iBAAiB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YACxD,CAAC;SACF,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"TimeManager.js","sourceRoot":"","sources":["../../src/time/TimeManager.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,gCAAgC;AAChC,qFAAqF;AAErF,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAItC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AASpD,MAAM,OAAO,WAAW;IAItB,YAAY,SAA6B,EAAE;QACzC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,CAAC;YACtB,GAAG,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;YAC7B,GAAG,IAAI,CAAC,eAAe,EAAE;SAC1B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,OAAe;QACpB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;IACjC,CAAC;IAED,OAAO,CAAC,KAAkB;QACxB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;IAC/D,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,OAAO;YACL,aAAa,EAAE,CAAC,IAAY,EAAE,GAAW,EAAE,EAAE;gBAC3C,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;YACjF,CAAC;YACD,iBAAiB,EAAE,CAAC,KAAc,EAAE,EAAE;gBACpC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,iBAAiB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YACxD,CAAC;SACF,CAAC;IACJ,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alife-sdk/core",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Framework-agnostic A-Life simulation and AI decision-making system",
5
5
  "type": "module",
6
6
  "sideEffects": false,