feat(packs): Medieval Town iso pack (2nd iso environment) + pack picker

Proves the packs-as-products loop end to end:
- Copied Kenney Isometric Medieval Town wood tiles (floor/floor2/wall/window/
  door/banner) into assets/kenney/iso-medieval/.
- Registered 'iso-medieval' as a 2nd iso RENDER pack (its own tile geometry —
  Medieval tiles are shorter than the dungeon set; reuses the dungeon characters).
  Strong on architecture; no medieval furniture at this scale, so furniture kinds
  fall back to floor for now (shines most in the dungeon).
- Catalog product: DEFAULT_CATALOG + migration 026, iso tier 2 / 15 credits.
- PACK PICKER in the tavern: when a projection has >1 unlocked pack, a selector
  appears to switch live (setActivePack -> re-render). Uses ?unlock=1 to preview.

So: switch Iso ★, and the pack picker lets you flip iso-dungeon <-> Medieval Town
live. Adding the next pack = assets + registerPack + a catalog row. Suite 58/419 green.
This commit is contained in:
jwinterm
2026-07-11 13:57:47 -04:00
parent 11b7fb1272
commit 3d9b5420ee
10 changed files with 75 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
-- 026: add the Medieval Town isometric pack as a catalog product.
-- A second iso environment (interchangeable across tavern + dungeon), sold at iso-tier: unlock by
-- 15 lifetime credits OR premium (tier 2). Idempotent.
INSERT INTO cosmetic_catalog (pack_id, label, kind, projection, tier, unlock_min_credits, grant_only, active, sort_order, metadata)
VALUES ('iso-medieval', 'Medieval Town (Isometric)', 'render-pack', 'iso', 2, 15, false, true, 40, '{}'::jsonb)
ON CONFLICT (pack_id) DO UPDATE
SET label = EXCLUDED.label, projection = EXCLUDED.projection, tier = EXCLUDED.tier,
unlock_min_credits = EXCLUDED.unlock_min_credits, active = true;
+4
View File
@@ -25,6 +25,10 @@ const DEFAULT_CATALOG = Object.freeze({
id: 'iso-dungeon', label: 'Kenney Isometric Dungeon', kind: 'render-pack',
projection: 'iso', tier: 2, unlockMinCredits: 10, grantOnly: false, premium: true
}),
'iso-medieval': Object.freeze({
id: 'iso-medieval', label: 'Medieval Town (Isometric)', kind: 'render-pack',
projection: 'iso', tier: 2, unlockMinCredits: 15, grantOnly: false, premium: true
}),
'kenney-3d-characters': Object.freeze({
id: 'kenney-3d-characters', label: 'Kenney Animated 3D Characters', kind: 'render-pack',
projection: '3d', tier: 3, unlockMinCredits: 25, grantOnly: false, premium: true