feat: initial prototype — core game systems (#30)
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 1m1s
CI / Lint, Build & Test (push) Successful in 1m6s

## Summary

This PR represents the full v1 prototype, implementing the core game systems for Elysium.

- Full idle/clicker RPG loop: resource collection, crafting, boss fights, exploration, and quests
- Adventurer hiring with batch size selector and progressive tier cost scaling
- Prestige, transcendence, and apotheosis systems with auto-prestige support
- Character sheet, titles, leaderboards, companion system, and daily login bonuses
- Auto-quest and auto-boss toggles
- Discord webhook notifications on prestige/transcendence/apotheosis
- Discord role awarded on apotheosis
- Responsive design and overarching story/lore system
- In-game sound effects and browser notifications for key events
- Support link button in the resource bar
- Full test coverage (100% on `apps/api` and `packages/types`)
- CI pipeline: lint → build → test

## Closes

Closes #1
Closes #2
Closes #3
Closes #4
Closes #5
Closes #6
Closes #7
Closes #8
Closes #9
Closes #10
Closes #11
Closes #12
Closes #13
Closes #14
Closes #16
Closes #19
Closes #20
Closes #21
Closes #22
Closes #23
Closes #24
Closes #25
Closes #26
Closes #27
Closes #29

 This issue was created with help from Hikari~ 🌸

Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com>
Reviewed-on: #30
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
This commit was merged in pull request #30.
This commit is contained in:
2026-03-08 15:53:39 -07:00
committed by Naomi Carrigan
parent c69e155de3
commit 29c817230d
172 changed files with 50706 additions and 0 deletions
+57
View File
@@ -0,0 +1,57 @@
/**
* @file About route providing API version and release information.
* @copyright nhcarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
/* eslint-disable stylistic/max-len -- URL cannot be shortened */
/* eslint-disable require-atomic-updates -- Simple cache; race condition is acceptable */
import { Hono } from "hono";
import type { AboutResponse, GiteaRelease } from "@elysium/types";
// eslint-disable-next-line capitalized-comments -- v8 ignore
/* v8 ignore next -- @preserve */
const apiVersion = process.env.npm_package_version ?? "unknown";
const giteaReleasesUrl = "https://git.nhcarrigan.com/api/v1/repos/nhcarrigan/elysium/releases";
const cacheTtlMs = 5 * 60 * 1000;
interface ReleasesCache {
data: Array<GiteaRelease>;
timestamp: number;
}
let releasesCache: ReleasesCache = { data: [], timestamp: 0 };
const fetchReleases = async(): Promise<Array<GiteaRelease>> => {
const now = Date.now();
if (releasesCache.data.length > 0 && now - releasesCache.timestamp < cacheTtlMs) {
return releasesCache.data;
}
try {
const response = await fetch(giteaReleasesUrl);
if (!response.ok) {
return releasesCache.data;
}
const rawData: unknown = await response.json();
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- External API response */
const data = rawData as Array<GiteaRelease>;
releasesCache = { data: data, timestamp: now };
return releasesCache.data;
} catch {
return releasesCache.data;
}
};
const aboutRouter = new Hono();
aboutRouter.get("/", async(context) => {
const releases = await fetchReleases();
const body: AboutResponse = {
apiVersion,
releases,
};
return context.json(body);
});
export { aboutRouter };