Table of Contents
- Architecture
- Overview
- Tech Stack
- Project Structure
- Pages (src/pages/)
- Components (src/components/)
- Business Logic (src/lib/)
- What is the lib/ Directory?
- Generators (lib/generators/)
- Database (lib/db/)
- Stellar Calculations (lib/stellar/)
- Export/Import (lib/export/, lib/import/)
- Data Models (src/models/)
- Data Flow
- PWA Features
- External References
Architecture
Overview
Mneme World Generator (MWG) is a Progressive Web Application (PWA) built with React 19, TypeScript, and Vite 7. It generates fictional worlds for tabletop RPGs based on the Mneme World Generator rulebook.
Tech Stack
| Layer | Technology | Description |
|---|---|---|
| Frontend Framework | React 19 + TypeScript | Component-based UI library with static typing |
| Build Tool | Vite 7 | Next-generation frontend build tool with hot module replacement |
| UI Components | shadcn/ui (Radix UI primitives) | Accessible, unstyled component primitives |
| Styling | Tailwind CSS v4 | Utility-first CSS framework |
| Routing | React Router DOM v7 | Declarative routing for React SPAs |
| Database | IndexedDB via Dexie | Client-side NoSQL database for offline storage |
| Icons | Lucide React | Open-source icon library |
What These Technologies Do
React + TypeScript
React is a JavaScript library for building user interfaces using components—reusable, self-contained pieces of UI. Each component is a function that returns JSX (HTML-like syntax in JavaScript).
TypeScript adds static types to JavaScript, catching errors at compile-time rather than runtime. Types define the shape of data (e.g., "a star must have a name and a class").
Vite
Vite is a build tool that serves code during development with near-instant hot module replacement (HMR). When you save a file, changes appear in the browser immediately without a full page reload.
Tailwind CSS
Tailwind uses utility classes directly in HTML/JSX instead of writing CSS files. Example: className="text-xl font-bold text-blue-500" applies font size, weight, and color.
Project Structure
src/
├── assets/ # Static assets (images, fonts)
├── components/ # React components
│ ├── layout/ # Layout components (header, footer, nav)
│ ├── shared/ # Reusable components across pages
│ ├── stellar/ # Star/stellar-specific components
│ └── ui/ # Base UI components (shadcn/ui)
├── lib/ # Business logic and utilities
│ ├── db/ # Database layer (IndexedDB)
│ │ └── queries/ # Database query functions
│ ├── export/ # Export to JSON/other formats
│ ├── generators/ # World generation algorithms
│ ├── import/ # Import from external sources
│ └── stellar/ # Stellar calculations
├── models/ # TypeScript types and interfaces
│ ├── common/ # Shared types
│ ├── stellar/ # Star-related types
│ │ ├── data/ # Constants (spectral classes, etc.)
│ │ └── types/ # Type definitions and enums
│ └── world/ # World/planet types
├── pages/ # Route page components
├── App.tsx # Root application component
├── routes.tsx # Route definitions
├── main.tsx # Application entry point
└── index.css # Global styles
Pages (src/pages/)
What is a Page?
A page is a React component that represents an entire screen in the application. Pages map 1:1 with URL routes—when you navigate to /create-primary-star, the CreatePrimaryStar page component renders.
Pages are composed of smaller components and connect to business logic (generators, database queries).
How Pages Work
- Route Definition: Routes are defined in
routes.tsxusing React Router - Component Rendering: When a URL matches, React Router renders the corresponding page component
- State Management: Pages use React hooks (
useState,useEffect,useCallback) to manage local state - Data Flow: Pages call functions from
lib/to generate data and save to the database
Page Components
| Page | Route | Purpose |
|---|---|---|
Home.tsx |
/ |
Landing page with navigation to create or open worlds |
CreateNew.tsx |
/create-new |
Start new world creation wizard |
CreatePrimaryStar.tsx |
/create-primary-star |
Configure the system's primary star |
CreateCompanionStar.tsx |
/create-companion-star |
Add companion stars to the system |
CreateWorldContext.tsx |
/create-world-context |
Set world context and parameters |
CreateCircumstellarDisks.tsx |
/create-disks |
Generate asteroid belts and debris disks |
CreatePlanetarySystem.tsx |
/create-planetary-system |
Generate planets in the system |
CreateMainWorld.tsx |
/create-main-world |
Configure the primary habitable world |
CreateSecondaryPlanets.tsx |
/create-secondary-planets |
Add additional planets |
CreateMoons.tsx |
/create-moons |
Generate moons for planets |
CreateHabitability.tsx |
/create-habitability |
Calculate world habitability |
CreateInhabitants.tsx |
/create-inhabitants |
Define world population |
CreateWorldCulture.tsx |
/create-culture |
Generate cultural attributes |
CreateWorldStarport.tsx |
/create-starport |
Generate starport facilities |
CreatePosition.tsx |
/create-position |
Set galactic position |
MyWorlds.tsx |
/my-worlds |
View and manage saved worlds |
QuickGenerate.tsx |
/quick-generate |
One-click full world generation |
Anatomy of a Page Component
Using CreatePrimaryStar.tsx as an example:
export function CreatePrimaryStar() {
// 1. HOOKS - React state and effects
const navigate = useNavigate(); // Router navigation
const [starName, setStarName] = useState(""); // Local state
const [selectedClass, setSelectedClass] = useState("G");
// 2. DATABASE QUERIES - Reactive data from IndexedDB
const stellarProperty = useLiveQuery(
() => getStellarProperty(selectedClass, classGrade),
[selectedClass, classGrade]
);
// 3. DERIVED DATA - Computed from state/queries
const starData = useMemo(() => ({
color: stellarProperty?.color,
mass: stellarProperty?.mass,
}), [stellarProperty]);
// 4. EVENT HANDLERS - User interactions
const handleRandom = useCallback(() => {
// Call generator, update state
}, []);
// 5. EFFECTS - Side effects (save to localStorage, etc.)
useEffect(() => {
saveData();
}, [saveData]);
// 6. RENDER - Return JSX
return (
<div>
<StarNameEditor name={starName} onNameChange={setStarName} />
<StarClassSelector selectedClass={selectedClass} />
</div>
);
}
Key React Concepts Used
| Concept | Description | Reference |
|---|---|---|
useState |
Store and update component state | React useState |
useEffect |
Perform side effects (API calls, subscriptions) | React useEffect |
useCallback |
Memoize functions to prevent unnecessary re-renders | React useCallback |
useMemo |
Memoize computed values | React useMemo |
useNavigate |
Programmatic navigation | React Router useNavigate |
useLiveQuery |
Reactive database queries (Dexie) | Dexie useLiveQuery |
Components (src/components/)
What is a Component?
A React component is a reusable piece of UI. Components accept props (inputs) and return JSX (what to render). They follow a hierarchy: pages contain components, which contain smaller components.
Component Organization
ui/ - Base UI Components (shadcn/ui)
Atomic, unstyled components from shadcn/ui. These are the building blocks:
| Component | Purpose | Radix Primitive |
|---|---|---|
button.tsx |
Clickable buttons | N/A |
input.tsx |
Text input fields | N/A |
select.tsx |
Dropdown selection | Radix Select |
dialog.tsx |
Modal dialogs | Radix Dialog |
dropdown-menu.tsx |
Context menus | Radix DropdownMenu |
tooltip.tsx |
Hover tooltips | Radix Tooltip |
slider.tsx |
Range input slider | Radix Slider |
checkbox.tsx |
Boolean checkbox | Radix Checkbox |
radio-group.tsx |
Single-select options | Radix RadioGroup |
card.tsx |
Content container | N/A |
badge.tsx |
Status indicators | N/A |
alert.tsx |
Notification messages | N/A |
skeleton.tsx |
Loading placeholders | N/A |
sheet.tsx |
Slide-out panels | Radix Dialog |
collapsible.tsx |
Expandable sections | Radix Collapsible |
separator.tsx |
Visual dividers | Radix Separator |
label.tsx |
Form field labels | Radix Label |
navigation-menu.tsx |
Site navigation | Radix NavigationMenu |
layout/ - Layout Components
Structural components that define page layouts (headers, footers, navigation, sidebars).
shared/ - Shared Components
Reusable components used across multiple pages (e.g., loading spinners, error boundaries).
stellar/ - Domain Components
Star/stellar-specific components like:
StarNameEditor- Edit star namesStarClassSelector- Select stellar classification (O, B, A, F, G, K, M)GradeControl- Adjust stellar grade (0-9)StellarPropertiesCard- Display star properties (mass, luminosity, temperature)
Business Logic (src/lib/)
What is the lib/ Directory?
The lib/ directory contains business logic—code that implements the application's rules and algorithms, separate from UI rendering. This separation follows the separation of concerns principle.
Generators (lib/generators/)
Generators implement the Mneme world generation rules using dice-based procedural generation.
| Generator | Purpose |
|---|---|
primaryStarGenerator.ts |
Generate primary star (class, grade, properties) |
companionStarGenerator.ts |
Generate companion/binary stars |
companionStarTables.ts |
Lookup tables for companion star generation |
brownDwarfGenerator.ts |
Generate brown dwarf objects |
brownDwarfTables.ts |
Brown dwarf lookup tables |
diskGenerator.ts |
Generate circumstellar disks (asteroid belts) |
diskTables.ts |
Disk generation tables |
planetGenerator.ts |
Generate planets |
moonGenerator.ts |
Generate moons |
worldGenerator.ts |
Generate world characteristics |
worldTables.ts |
World generation lookup tables |
starportGenerator.ts |
Generate starport class and facilities |
cultureGenerator.ts |
Generate cultural attributes |
How Generators Work
Generators use dice rolls mapped to lookup tables to produce results. Example from primaryStarGenerator.ts:
// 1. Define lookup table mapping dice rolls to results
const STELLAR_CLASS_TABLE = [
{ minRoll: 5, maxRoll: 7, class: 'O' }, // Hottest, rarest
{ minRoll: 8, maxRoll: 10, class: 'B' },
{ minRoll: 11, maxRoll: 13, class: 'A' },
{ minRoll: 14, maxRoll: 17, class: 'F' },
{ minRoll: 18, maxRoll: 22, class: 'G' }, // Sun-like
{ minRoll: 23, maxRoll: 26, class: 'K' },
{ minRoll: 27, maxRoll: 30, class: 'M' }, // Coolest
];
// 2. Roll dice (5D6 = five six-sided dice)
export function rollForStellarClass() {
const roll = roll5D6(); // Returns { total: number, dice: number[] }
// 3. Look up result in table
const entry = STELLAR_CLASS_TABLE.find(
(e) => roll.total >= e.minRoll && roll.total <= e.maxRoll
);
return { class: entry.class, roll };
}
Database (lib/db/)
Uses Dexie, a wrapper around IndexedDB, for client-side persistence. IndexedDB is a NoSQL database built into browsers, enabling offline storage.
queries/ - Database Query Functions
Functions to read/write data:
stellarQueries.ts- Query stellar properties by class/gradestarQueries.ts- CRUD operations for stars
Stellar Calculations (lib/stellar/)
Astronomical calculations:
zoneCalculations.ts- Calculate habitable zones, frost lines based on stellar luminosity
Export/Import (lib/export/, lib/import/)
Data interchange functionality:
- Export worlds to JSON for sharing/backup
- Import worlds from JSON files
Data Models (src/models/)
What are Models?
Models are TypeScript interfaces that define the shape of data. They ensure type safety—the compiler verifies that data matches expected structures.
Model Organization
common/ - Shared Types
// Example: Generation method enum
enum GenerationMethod {
PROCEDURAL = 'procedural', // Dice-based random generation
CUSTOM = 'custom', // User-specified values
}
stellar/types/ - Star Types
// Example: Star data interface
interface StarData {
id: string;
name: string;
stellarClass: StellarClass; // O, B, A, F, G, K, M
stellarGrade: StellarGrade; // 0-9
generationMethod: GenerationMethod;
diceRolls?: StarDiceRolls;
createdAt: string;
updatedAt: string;
}
// Stellar class enum
type StellarClass = 'O' | 'B' | 'A' | 'F' | 'G' | 'K' | 'M';
// Stellar grade (0 = brightest, 9 = dimmest)
type StellarGrade = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
stellar/data/ - Constants
Static data like spectral class properties, temperature ranges, mass/luminosity values.
world/ - World Types
// Example: Planet, moon, culture, starport interfaces
interface Planet { ... }
interface Moon { ... }
interface Culture { ... }
interface Starport { ... }
Data Flow
┌─────────────────────────────────────────────────────────────────┐
│ USER INTERACTION │
│ (click, type, press 'R') │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ PAGE COMPONENT │
│ (CreatePrimaryStar.tsx) │
│ │
│ • Captures user input via event handlers │
│ • Manages local state with useState │
│ • Calls generators for procedural creation │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ GENERATOR │
│ (lib/generators/primaryStarGenerator.ts) │
│ │
│ • Rolls dice (5D6) │
│ • Looks up results in tables │
│ • Returns typed data object │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ MODEL │
│ (models/stellar/types/interface.ts) │
│ │
│ • TypeScript validates data shape │
│ • Ensures type safety at compile time │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ DATABASE │
│ (lib/db/ via Dexie/IndexedDB) │
│ │
│ • Persists data to browser storage │
│ • Enables offline access │
│ • useLiveQuery provides reactive updates │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ UI UPDATE │
│ (React re-renders components) │
│ │
│ • State changes trigger re-render │
│ • useLiveQuery updates when DB changes │
│ • User sees updated UI │
└─────────────────────────────────────────────────────────────────┘
PWA Features
A Progressive Web App provides native app-like experiences on the web:
| Feature | Implementation | Benefit |
|---|---|---|
| Offline Support | Service Worker + IndexedDB | Works without internet |
| Installable | Web App Manifest | Add to home screen |
| Local Storage | IndexedDB via Dexie | Data persists across sessions |
| Export/Import | JSON file download/upload | Data portability and backup |
External References
Core Technologies
- React Documentation - Official React docs
- TypeScript Handbook - TypeScript language reference
- Vite Guide - Vite build tool documentation
- Tailwind CSS - Utility-first CSS framework
UI Components
Database
- IndexedDB API - Browser database API (MDN)
- Dexie.js - IndexedDB wrapper library
React Concepts
- React Hooks - useState, useEffect, etc.
- React Router - Routing library
General Web Development
- MDN Web Docs - Comprehensive web technology reference (the "Wikipedia" of web development)
- JavaScript Reference - JavaScript language reference