diff --git a/src/content/__tests__/definitions.test.ts b/src/content/__tests__/definitions.test.ts new file mode 100644 index 0000000..0a5eb91 --- /dev/null +++ b/src/content/__tests__/definitions.test.ts @@ -0,0 +1,24 @@ +import { describe, expect, it } from 'vitest'; +import { createGameState, enqueueAction, tickGame } from '../../engine/game'; +import { content } from '../index'; + +describe('M1 stub content pack', () => { + it('defines two resources and four to five actions with costs and unlocks', () => { + expect(content.resources).toHaveLength(2); + expect(content.actions.length).toBeGreaterThanOrEqual(4); + expect(content.actions.length).toBeLessThanOrEqual(5); + const withCosts = content.actions.filter((a) => a.costs.length > 0); + const withUnlocks = content.actions.filter((a) => a.unlock !== undefined); + expect(withCosts.length).toBeGreaterThanOrEqual(2); + expect(withUnlocks.length).toBeGreaterThanOrEqual(1); + }); + + it('can simulate a costed action without throwing', () => { + const state = createGameState(content); + const trade = content.actions.find((a) => a.costs.length > 0); + expect(trade).toBeDefined(); + enqueueAction(state, content, trade!.id); + tickGame(state, content, trade!.durationMs); + expect(state.activeActionId).toBeNull(); + }); +}); diff --git a/src/content/definitions.ts b/src/content/definitions.ts index d3779ef..fe5be01 100644 --- a/src/content/definitions.ts +++ b/src/content/definitions.ts @@ -1,17 +1,12 @@ -/** - * Walking-skeleton content: one resource, one timed action. - * - * M1 expands this into the real resource/action set and the story graph. Kept as - * plain data so it stays diffable and authorable without touching engine code. - */ - -export const resourceDefs = [{ id: 'gold', name: 'Gold', startAmount: 0 }]; +export const resourceDefs = [ + { id: 'supplies', name: 'Supplies', startAmount: 10 }, + { id: 'coin', name: 'Coin', startAmount: 0 }, +]; export const actionDefs = [ - { - id: 'forage', - name: 'Forage for coin', - durationMs: 3000, - yields: [{ resourceId: 'gold', amount: 1 }], - }, + { id: 'gather_supplies', name: 'Gather supplies', durationMs: 3000, yields: [{ resourceId: 'supplies', amount: 2 }] }, + { id: 'scout_path', name: 'Scout the path', durationMs: 5000, costs: [{ resourceId: 'supplies', amount: 2 }], yields: [{ resourceId: 'coin', amount: 1 }] }, + { id: 'trade_supplies', name: 'Trade at camp', durationMs: 4000, costs: [{ resourceId: 'supplies', amount: 3 }], yields: [{ resourceId: 'coin', amount: 2 }], unlock: { minResources: { coin: 1 } } }, + { id: 'fortify_camp', name: 'Fortify camp', durationMs: 8000, costs: [{ resourceId: 'supplies', amount: 5 }, { resourceId: 'coin', amount: 2 }], yields: [{ resourceId: 'supplies', amount: 4 }], unlock: { minResources: { supplies: 8 } } }, + { id: 'rest', name: 'Rest briefly', durationMs: 2000, yields: [{ resourceId: 'supplies', amount: 1 }] }, ];