diff --git a/src/content/__tests__/schema.test.ts b/src/content/__tests__/schema.test.ts index 49c7daf..1d2ad19 100644 --- a/src/content/__tests__/schema.test.ts +++ b/src/content/__tests__/schema.test.ts @@ -97,3 +97,30 @@ describe('costs and multi-yield', () => { expect(content.actionsById.forage.costs).toEqual([]); }); }); + +describe('unlock conditions', () => { + it('accepts optional minResources and requireStoryFlags', () => { + const actions = [ + { + id: 'forage', + name: 'Forage', + durationMs: 3000, + yields: [{ resourceId: 'gold', amount: 1 }], + unlock: { + minResources: { gold: 10 }, + requireStoryFlags: ['intro_complete'], + }, + }, + ]; + const content = buildContent({ resources: validResources, actions }); + expect(content.actionsById.forage.unlock).toEqual({ + minResources: { gold: 10 }, + requireStoryFlags: ['intro_complete'], + }); + }); + + it('defaults unlock to undefined when omitted', () => { + const content = buildContent({ resources: validResources, actions: validActions }); + expect(content.actionsById.forage.unlock).toBeUndefined(); + }); +}); diff --git a/src/content/schema.ts b/src/content/schema.ts index 2ac353f..5a92d62 100644 --- a/src/content/schema.ts +++ b/src/content/schema.ts @@ -20,16 +20,23 @@ export const resourceAmountSchema = z.object({ amount: z.number().positive(), }); +export const unlockDefSchema = z.object({ + minResources: z.record(z.string(), z.number().nonnegative()).optional(), + requireStoryFlags: z.array(z.string().min(1)).optional(), +}); + export const actionDefSchema = z.object({ id: z.string().min(1), name: z.string().min(1), durationMs: z.number().positive(), costs: z.array(resourceAmountSchema).default([]), yields: z.array(resourceAmountSchema).min(1), + unlock: unlockDefSchema.optional(), }); export type ResourceDef = z.infer; export type ResourceAmount = z.infer; +export type UnlockDef = z.infer; export type ActionDef = z.infer; export interface Content {