Playable retro portfolio world built with Vite, TypeScript, and Kaboom.
Live site: leonaderi.com
This project is a single-page pixel-world portfolio. Visitors move through a small town, interact with buildings and NPCs, and open external profile or business links through in-world dialogs.
The runtime source of truth is intentionally small:
index.htmlwires the HUD, onboarding, dialog shell, and SEO metadata.src/main.tscontains the Kaboom runtime, interactions, movement, UI wiring, and language toggle logic.src/game/world/mapData.tscontains map geometry, object placement, and NPC spawn data.src/content/glossary.tscontains POI metadata, labels, links, and dialog content backing the world.src/content/types.tsdefines the content model.src/style.csscontains all HUD/dialog/mobile-control styling.public/assets/**contains sprites, map composites, and profile imagery.
npm install
npm run devOpen the local Vite URL and use WASD, arrow keys, or the mobile controls.
npm run verifyThat command runs:
npm run lintnpm testnpm run build
To preview the production build locally:
npm run previewUse these files when updating the world without changing engine behavior:
src/content/glossary.tsfor POI copy, labels, actions, and metadata.src/game/world/mapData.tsfor building placement, NPC coordinates, and collision/map constants.public/assets/game/**for sprites and map object imagery.public/assets/pictures/**for HUD, dialog, and social preview images.
The app is deployment-ready as a static SPA.
- Vercel is configured through
vercel.json. - Production output is written to
dist/. - SPA routing is handled by rewriting unknown routes back to
index.html. vite.config.tsalso supports GitHub Pages-style subpath builds in CI by adjustingbasefromGITHUB_REPOSITORY.
Typical host settings:
- Build command:
npm run build - Output directory:
dist - Node version: current active LTS is recommended
No environment variables are required for the current public build.
The checked-in /.env.example is intentionally minimal to make that explicit.
If you want to build a similar playable portfolio world:
- Replace the profile images in
public/assets/pictures/. - Swap map sprites and buildings in
public/assets/game/. - Update POIs, links, labels, and dialogs in
src/content/glossary.ts. - Adjust world placement and NPC positions in
src/game/world/mapData.ts. - Run
npm run verifybefore deploying.
The current structure is intentionally simple so an LLM or another contributor can modify content and layout without needing to rewrite the engine.
- Keep changes minimal and preserve current movement, collision, and dialog behavior unless a change is explicitly intended.
- Prefer updating content data and assets over adding more hardcoded runtime branches.
- If you add new runtime-loaded assets, update the tests in
tests/so broken asset paths are caught before deployment.