An interactive, explorable 3D portfolio for Cosmic Crusader. Visitors can pilot a procedural scout ship through a miniature solar system or use the conventional menu and complete 2D fallback.
Production domain: https://portfolio.mycosmic.dev/
- Vite multi-page static build
- Strict TypeScript
- Modular vanilla Three.js
- Three.js native postprocessing (
EffectComposer, restrained bloom, vignette) - Semantic HTML/CSS overlays for HUD, dialogs, mobile controls, and fallback content
- Vitest and ESLint
- GitHub Pages deployment through GitHub Actions
No server, database, VPS, runtime scraping, external 3D model, texture pack, or audio file is required.
Requirements: Node.js 22 or newer and npm.
npm ci
npm run devThe development server uses http://127.0.0.1:4173/spaceshipportfolio/, matching the repository-path base configured for ordinary GitHub project-site builds.
Useful commands:
npm run check # TypeScript + ESLint
npm test # Unit tests
npm run build # Production build in dist/
npm run preview # Preview dist/ on 127.0.0.1:4174
npm run build -- --base=/ # Custom-domain artifact, as used by PagesDesktop:
W/S: forward and reverse thrustA/D: yaw- Mouse: steer while pointer lock is active
- Arrow up/down: pitch without a mouse
Q/E: roll; near an inspectable object,Einspects insteadShift: boostSpace: brakeXor primary click: fire twin laser bolts; the first canvas click also captures the pointerF: chase/cockpit cameraEnteror nearbyE: inspectM: solar-system mapR: reset the shipEsc: release pointer lock or close the active surface
Touch:
- Virtual joystick for thrust and yaw
- Drag the scene to steer
- Adjustable cruise-speed slider
- Large Fire, Boost, Brake, Inspect, Camera, and Map controls
- Guided mode is enabled by default on coarse-pointer devices
Verified portfolio content lives in src/data/portfolio.ts. It contains the real biography, team links, three projects, two achievements, current writing state, contact links, and presentation-safe destination coordinates.
The project never scrapes the live site at runtime. Vite injects the structured data into the production HTML during the build so crawlers, no-JavaScript visitors, and the 2D fallback receive the important text directly.
To add a future post:
- Add a real static post route.
- Add its verified title, date, description, and URL to
portfolio.posts. - Run
npm run check,npm test, andnpm run build.
The posts list and writing panel update from that data automatically.
src/core/: app orchestration, settings, shared typessrc/scene/: renderer, procedural world, stars, shipsrc/shaders/: solar/atmosphere and postprocessing shaderssrc/systems/: input, flight, proximity, quality, pure mathsrc/ui/: HUD, radar markers, dialogs, menu/map/settings, touch controlssrc/audio/: muted-by-default procedural Web Audiosrc/styles/: game UI, fallback, and posts stylingsrc/tests/: content, quality, and proximity testspublic/: custom domain, robots policy, sitemap, manifest, social image
See ARCHITECTURE.md for system boundaries and frame order.
- Semantic portfolio content is present in built HTML.
- All important sections have direct links and menu access.
- Native modal dialogs trap focus; focus returns when they close.
- Visible keyboard focus, high-contrast mode, reduced motion, reduced camera movement, and postprocessing disable controls are available.
- WebGL failure, slow initialization, or a visitor preference can switch to the complete 2D portfolio.
- The posts page remains an independently usable normal web page.
Low, Medium, High, and Auto presets control pixel ratio, particle counts, asteroid instances, projectile secondary effects, and postprocessing. Auto considers viewport size, pointer type, device pixel ratio, CPU concurrency, and sampled frame rate. Animation work pauses while the tab is hidden, repeating objects and laser effects are pooled/instanced, and the Three.js application is lazy-loaded after the HTML/CSS shell.
The workflow in .github/workflows/deploy.yml checks, tests, builds, and deploys dist/ to GitHub Pages.
Repository setup:
- Push this project to
CosmicCrusader23/spaceshipportfolio. - In GitHub: Settings → Pages → Build and deployment → Source → GitHub Actions.
- Recommended: verify
mycosmic.devin Settings → Pages → Verified domains, then add GitHub's TXT record in Cloudflare. This helps prevent another GitHub account from claiming the domain. - Set the custom domain in GitHub Pages to
portfolio.mycosmic.dev. - In Cloudflare create:
- Type:
CNAME - Name:
portfolio - Target:
CosmicCrusader23.github.io - Proxy status: DNS only initially
- TTL:
Auto
- Type:
- Wait for GitHub to provision the certificate, then enable Enforce HTTPS.
vite.config.ts uses /spaceshipportfolio/ for a normal GitHub project-site build. The deployment workflow intentionally runs Vite with --base=/, because the custom domain is served from its own root. Do not remove that workflow override or the deployed asset URLs will point at a nonexistent /spaceshipportfolio/ directory on the subdomain.
The repository includes public/CNAME as a record of the intended host, but GitHub ignores CNAME files when Pages is published by a custom Actions workflow. Set portfolio.mycosmic.dev in Settings → Pages → Custom domain as described above. The DNS target must not include the repository name.
Runtime 3D art and audio are procedural and source-authored. All external software/font sources and the generated social preview are documented in ASSET_CREDITS.md.