3 Commits

Author SHA1 Message Date
hikari eec93e442b chore: add vampire expansion implementation TODO 2026-03-24 19:51:59 -07:00
naomi 9926e7f639 release: v0.3.2
CI / Lint, Build & Test (push) Successful in 1m13s
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 2m17s
2026-03-24 18:50:37 -07:00
hikari 6bf1ac5e7d feat: grant Elysian role on auth and prompt non-members to join (#134)
CI / Lint, Build & Test (push) Has been cancelled
Security Scan and Upload / Security & DefectDojo Upload (push) Has been cancelled
## Summary

- Grants the Elysian Discord role to players on login/registration and persists an `inGuild` flag on the Player record
- Connects to the Discord Gateway via WebSocket to keep `inGuild` in sync as players join or leave the server
- Shows a dismissible "Join our community" modal to players who are not yet in the guild
- Hardens `inGuild` exposure through the load endpoint and game context
- Moves all non-secret Discord IDs (guild, role, client, redirect URI) out of env vars and into hardcoded constants; removes them from `prod.env`

## Test plan

- [ ] Lint, build, and test pipeline passes (100% coverage maintained)
- [ ] New player auth grants Elysian role and sets `inGuild: true`
- [ ] Existing player auth re-attempts role grant and updates `inGuild`
- [ ] Join community modal appears for players not in the guild
- [ ] Modal does not reappear within the same browser session after dismissal
- [ ] Gateway correctly sets `inGuild: true/false` on member add/remove events

✨ This issue was created with help from Hikari~ 🌸

Reviewed-on: #134
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
2026-03-24 18:49:51 -07:00
5 changed files with 139 additions and 4 deletions
+135
View File
@@ -0,0 +1,135 @@
# Vampire Expansion β€” Implementation TODO
Branch: `feat/expansions`
Thematic currency names:
- Gold β†’ **Blood**
- Essence β†’ **Ichor**
- Crystals β†’ **Soul Shards**
- Runestones β†’ **Bloodstones**
- Echoes β†’ **Whispers**
- Click action β†’ **Hunt**
- Adventurers β†’ **Thralls**
- Prestige β†’ **Siring** (working name)
- Transcendence β†’ **The Awakening** (working name)
- Apotheosis β†’ **Eternal Sovereignty** (role ID: 1486144657023959180)
CDN prefix for all vampire art: `https://cdn.nhcarrigan.com/elysium/vampire/<folder>/<id>.jpg`
Local scratch dir (delete before committing): `img/vampire/`
---
## Phase 1 β€” Types
- [ ] Add `VampireExpansionState` interface to `packages/types/src/interfaces/` mirroring full `GameState` structure (zones, bosses, quests, adventurers, upgrades, equipment, achievements, prestige, transcendence, apotheosis, exploration, resources, baseClickPower, lastTickAt, dailyChallenges, codex, autoQuest, autoBoss, autoAdventurer, companions, story)
- [ ] Add `ExpansionsState` interface: `{ vampire?: VampireExpansionState }`
- [ ] Add `expansions?: ExpansionsState` field to `GameState`
- [ ] Export new types from `packages/types/src/index.ts`
---
## Phase 2 β€” Data files (vampire content)
All data files go in `apps/api/src/data/vampire/`.
Same content scale as base game; use vampire theming throughout.
- [ ] `zones.ts` β€” 18 vampire-themed zones (crypts, blood forests, cursed castles, etc.)
- [ ] `bosses.ts` β€” 72 vampire-themed bosses (4 per zone)
- [ ] `quests.ts` β€” match base game quest count (~95); vampire-themed names/descriptions
- [ ] `adventurers.ts` β€” 32 thrall tiers with progressive stats
- [ ] `upgrades.ts` β€” match base game upgrade count (~57); vampire-themed
- [ ] `equipment.ts` β€” match base game equipment count (~53); vampire-themed sets
- [ ] `equipmentSets.ts` β€” vampire equipment sets
- [ ] `achievements.ts` β€” match base game count (~40); vampire-themed conditions
- [ ] `explorations.ts` β€” 72 areas across 18 vampire lore zones
- [ ] `materials.ts` β€” match base game material count (~54); vampire-themed
- [ ] `recipes.ts` β€” match base game recipe count (~36); vampire-themed
- [ ] `prestigeUpgrades.ts` β€” 25 "Siring" upgrades
- [ ] `transcendenceUpgrades.ts` β€” 15 "Awakening" upgrades
- [ ] `dailyChallenges.ts` β€” 10 vampire daily challenges
- [ ] `initialState.ts` β€” `initialVampireState()` function mirroring `initialGameState` structure
---
## Phase 3 β€” Art generation & CDN upload
For each category below, generate images via Gemini API (`gemini-3-pro-image-preview`),
save locally to `img/vampire/<folder>/`, upload to R2, then delete local files.
Use soft-shaded anime style; vampire/gothic aesthetic; crimson/black/dark purple palette.
- [ ] Zone banners (18) β†’ `img/vampire/zones/` β†’ CDN `vampire/zones/`
- [ ] Boss portraits (72) β†’ `img/vampire/bosses/` β†’ CDN `vampire/bosses/`
- [ ] Quest banners (match count) β†’ `img/vampire/quests/` β†’ CDN `vampire/quests/`
- [ ] Adventurer/thrall portraits (32) β†’ `img/vampire/adventurers/` β†’ CDN `vampire/adventurers/`
- [ ] Equipment icons (match count) β†’ `img/vampire/equipment/` β†’ CDN `vampire/equipment/`
- [ ] Achievement icons (match count) β†’ `img/vampire/achievements/` β†’ CDN `vampire/achievements/`
- [ ] Exploration area art (72) β†’ `img/vampire/explorations/` β†’ CDN `vampire/explorations/`
- [ ] Material icons (match count) β†’ `img/vampire/materials/` β†’ CDN `vampire/materials/`
- [ ] Story chapter banners (match count) β†’ `img/vampire/story-chapters/` β†’ CDN `vampire/story-chapters/`
---
## Phase 4 β€” API changes
- [ ] Add `inGuild` to Prisma `Player` model β†’ update `initialGameState` if needed (already done in #134 β€” verify migration)
- [ ] Update Prisma schema: no DB changes needed (expansion state is inside the `GameState` JSON blob)
- [ ] Update `initialState.ts` to include `expansions: {}` in `initialGameState`
- [ ] Update `sync-new-content` debug route to inject/patch vampire expansion content when expansion is unlocked
- [ ] Add vampire-specific unlock trigger: when base-game apotheosis count β‰₯ 1, set `expansions.vampire` to `initialVampireState()` and `unlocked: true`
- [ ] Update the load endpoint to pass expansion state through to the client
- [ ] Ensure prestige/transcendence/apotheosis routes only reset state for their own expansion (base game routes must NOT touch `expansions.*`)
- [ ] Add vampire prestige, transcendence, and apotheosis routes (mirrors of base game routes, scoped to `expansions.vampire`)
- [ ] Grant `Eternal Sovereignty` role (ID: `1486144657023959180`) on vampire apotheosis
---
## Phase 5 β€” Frontend changes
### Expansion switcher
- [ ] Add expansion toggle buttons below the Early Access warning in the sidebar
- [ ] Always render all expansion buttons; disable any where `unlocked !== true`
- [ ] Active expansion stored in React state (not game state); defaults to `"base"`
- [ ] Switching expansion updates which data the UI panels display
### Resource bar
- [ ] Show ALL currencies from ALL expansions as separate labelled lines
- [ ] Vampire currencies use distinct icons/colours (crimson tint for blood, etc.)
- [ ] The "expand" button label shows the gold-equivalent currency of the active expansion
### Thematic UI
- [ ] When vampire expansion is active, swap labels: gold β†’ Blood, essence β†’ Ichor, etc.
- [ ] Apply `.vampire-mode` CSS class to game container when vampire is active
- [ ] Vampire colour palette: deep crimsons (`#5C0A1A`), rich crimson (`#C41E3A`), blacks, desaturated purples
### Tick engine
- [ ] Update `apps/web/src/engine/tick.ts` to compute passive income for all unlocked expansions every tick (not just base game)
- [ ] Offline income calculation must also cover all expansions
### Profile
- [ ] Profile panel: tab stats by expansion (base game tab + one tab per unlocked expansion)
- [ ] Show correct thematic prestige/transcendence/apotheosis badge names per expansion
- [ ] Lifetime stats (gold earned, clicks, etc.) tracked separately per expansion
### About / How to Play
- [ ] Update `aboutPanel.tsx` `HOW_TO_PLAY` array to document the expansion system
---
## Phase 6 β€” Tests & CI
- [ ] Unit tests for all new data files (at minimum, validate structure/required fields)
- [ ] Unit tests for `initialVampireState()`
- [ ] Tests for vampire unlock trigger route
- [ ] Tests for vampire prestige/transcendence/apotheosis routes
- [ ] Tests for updated tick engine (expansion income)
- [ ] Maintain 100% coverage on `apps/api` and `packages/types`
- [ ] Full pipeline: lint β†’ build β†’ test passing before PR
---
## Phase 7 β€” Final
- [ ] Delete `img/vampire/` directory before committing
- [ ] Update `MEMORY.md` with new content counts
- [ ] Open PR β†’ request review
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@elysium/api",
"version": "0.3.1",
"version": "0.3.2",
"private": true,
"type": "module",
"main": "./prod/src/index.js",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@elysium/web",
"version": "0.3.1",
"version": "0.3.2",
"private": true,
"type": "module",
"scripts": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "elysium",
"version": "0.3.1",
"version": "0.3.2",
"private": true,
"type": "module",
"scripts": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@elysium/types",
"version": "0.3.1",
"version": "0.3.2",
"private": true,
"type": "module",
"main": "./prod/src/index.js",