Restructure into pnpm monorepo with game shell, docs, and SpacetimeDB backend
- Restructure flat static prototype into pnpm workspace monorepo - apps/game: playable shell with R3F 3D scene, HUD, SpacetimeDB connection - apps/docs: design docs and prototypes - apps/site: landing page - packages/ui: shared Button and Panel primitives - services/spacetimedb: backend module (9 tables, 11 reducers) - Archive legacy static files to archive/legacy-static/ - Game loop: connect, undock, target, approach, dock, mine, sell - Add pnpm-workspace.yaml, tsconfig.base.json, spacetime.json
This commit is contained in:
12
apps/site/index.html
Normal file
12
apps/site/index.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>VOID::NAV</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
26
apps/site/package.json
Normal file
26
apps/site/package.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "@void-nav/site",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --host 0.0.0.0",
|
||||
"build": "tsc --noEmit && vite build",
|
||||
"check": "tsc --noEmit",
|
||||
"preview": "vite preview --host 0.0.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/vite": "^4.3.0",
|
||||
"@void-nav/ui": "workspace:*",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-router-dom": "^6.30.1",
|
||||
"tailwindcss": "^4.3.0",
|
||||
"vite": "^7.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.3.23",
|
||||
"@types/react-dom": "^18.3.7",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
}
|
||||
17
apps/site/src/main.tsx
Normal file
17
apps/site/src/main.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import { BrowserRouter, Route, Routes } from "react-router-dom";
|
||||
import { LandingPage } from "./pages/LandingPage";
|
||||
import { NotFoundPage } from "./pages/NotFoundPage";
|
||||
import "./styles/tailwind.css";
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
<React.StrictMode>
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route path="/" element={<LandingPage />} />
|
||||
<Route path="*" element={<NotFoundPage />} />
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
</React.StrictMode>,
|
||||
);
|
||||
47
apps/site/src/pages/LandingPage.tsx
Normal file
47
apps/site/src/pages/LandingPage.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import { Button, Panel } from "@void-nav/ui";
|
||||
|
||||
const docsUrl = import.meta.env.VITE_DOCS_URL ?? "http://localhost:5173/docs";
|
||||
const gameUrl = import.meta.env.VITE_GAME_URL ?? "http://localhost:5175";
|
||||
|
||||
export function LandingPage() {
|
||||
return (
|
||||
<main className="min-h-screen overflow-y-auto bg-[radial-gradient(circle_at_20%_10%,rgba(34,211,238,0.14),transparent_26rem),linear-gradient(180deg,#070b12_0%,#080c14_72%,#10151f_100%)] px-6 py-8 text-fg md:px-10">
|
||||
<section className="mx-auto grid min-h-[calc(100vh-4rem)] max-w-6xl content-center gap-10 pb-12 lg:grid-cols-[1.05fr_0.95fr] lg:items-center">
|
||||
<div>
|
||||
<p className="mb-3 font-mono text-xs uppercase tracking-[0.12em] text-accent">Persistent browser space game</p>
|
||||
<h1 className="m-0 font-display text-5xl font-bold leading-none text-fg-bright md:text-7xl">VOID::NAV</h1>
|
||||
<p className="mt-6 max-w-2xl text-lg leading-8 text-fg-dim">
|
||||
A multiplayer industrial space game built around pilot identity, station life, ship fitting,
|
||||
market pressure, and a persistent galaxy backend.
|
||||
</p>
|
||||
<div className="mt-8 flex flex-wrap gap-3">
|
||||
<Button href={gameUrl} tone="primary">Open Game</Button>
|
||||
<Button href={docsUrl}>Read Docs</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Panel className="grid gap-5">
|
||||
<div>
|
||||
<p className="m-0 font-mono text-xs uppercase tracking-[0.12em] text-cyan">Current build focus</p>
|
||||
<h2 className="m-0 mt-2 text-2xl text-fg-bright">From prototype hub to live game shell</h2>
|
||||
</div>
|
||||
<div className="grid gap-3 text-sm text-fg-dim">
|
||||
<StatusLine label="Backend" value="SpacetimeDB TypeScript module" />
|
||||
<StatusLine label="Client" value="Standalone game shell" />
|
||||
<StatusLine label="Docs" value="Living design docs and demos" />
|
||||
<StatusLine label="Next" value="Connect shell state, then migrate gameplay systems" />
|
||||
</div>
|
||||
</Panel>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
function StatusLine({ label, value }: { label: string; value: string }) {
|
||||
return (
|
||||
<div className="grid grid-cols-[7.5rem_1fr] gap-3 border-t border-border pt-3">
|
||||
<span className="font-mono text-xs uppercase tracking-[0.08em] text-muted">{label}</span>
|
||||
<span>{value}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
14
apps/site/src/pages/NotFoundPage.tsx
Normal file
14
apps/site/src/pages/NotFoundPage.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Button, Panel } from "@void-nav/ui";
|
||||
|
||||
export function NotFoundPage() {
|
||||
return (
|
||||
<main className="grid min-h-screen place-items-center bg-bg px-6 text-fg">
|
||||
<Panel className="max-w-md">
|
||||
<p className="m-0 font-mono text-xs uppercase tracking-[0.12em] text-red">Route unavailable</p>
|
||||
<h1 className="m-0 mt-2 text-3xl text-fg-bright">Page not found</h1>
|
||||
<p className="mb-6 mt-3 text-fg-dim">The public site only serves the landing page right now.</p>
|
||||
<Button href="/" tone="primary">Back to home</Button>
|
||||
</Panel>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
8
apps/site/src/styles/tailwind.css
Normal file
8
apps/site/src/styles/tailwind.css
Normal file
@@ -0,0 +1,8 @@
|
||||
@import "tailwindcss";
|
||||
@import "@void-nav/ui/styles.css";
|
||||
|
||||
@source "../../../packages/ui/src";
|
||||
|
||||
#root {
|
||||
min-height: 100vh;
|
||||
}
|
||||
7
apps/site/tsconfig.json
Normal file
7
apps/site/tsconfig.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"types": ["vite/client"]
|
||||
},
|
||||
"include": ["src", "vite.config.ts"]
|
||||
}
|
||||
10
apps/site/tsconfig.node.json
Normal file
10
apps/site/tsconfig.node.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"skipLibCheck": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
||||
10
apps/site/vite.config.ts
Normal file
10
apps/site/vite.config.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { defineConfig } from "vite";
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [tailwindcss()],
|
||||
esbuild: {
|
||||
jsx: "automatic",
|
||||
jsxImportSource: "react",
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user