-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcodex.txt
More file actions
119 lines (95 loc) · 8.26 KB
/
codex.txt
File metadata and controls
119 lines (95 loc) · 8.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# Codex Instructions
## Project Overview
**fantasymap** is a front-end web application for generating fantasy-novel-like maps.
## Tech Stack
- **Language:** TypeScript in strict mode
- **Platform:** Web (browser-based, front-end only)
- **UI:** React
- **Rendering:** Canvas 2D by default
- **Testing:** Vitest and React Testing Library
## Coding Conventions
- Use TypeScript.
- Enable and preserve strict TypeScript settings.
- Prefer `const` over `let`; avoid `var`.
- Use named exports over default exports.
- Use descriptive variable and function names.
- Keep functions small and focused on a single responsibility.
- Use async/await over raw Promises where applicable.
- Prefer explicit types for public APIs and core domain models.
## File & Folder Structure
- Keep source code in `src/`.
- Keep tests in a `__tests__/` directory.
- Use kebab-case for file names (e.g., `map-generator.tsx`).
- Keep core domain types in a shared location so generation, rendering, tests, and UI use the same source of truth.
## Testing
- Use Vitest for unit and integration tests.
- Use React Testing Library for React UI tests.
- Write tests in TypeScript.
- Write unit tests for utility functions and core logic.
- Test files should be named `*.test.ts`, `*.spec.ts`, `*.test.tsx`, or `*.spec.tsx` as appropriate.
- Keep core procedural-generation logic covered with deterministic, seed-based tests and graph or terrain invariants.
- Write test-first when adding new features or fixing bugs.
- Use Test-Driven Development (TDD) principles: write a failing test, implement the feature, then refactor.
- Keep tests in the centralized `__tests__/` directory unless there is a strong reason to do otherwise.
## Git
- Write clear, concise commit messages in imperative mood (e.g., "Add room linking feature").
- Keep commits focused on a single change.
## Agent Guidance
- When creating new features, start by understanding the existing code structure before making changes.
- Prefer small, incremental changes over large rewrites.
- Always check for and fix TypeScript, test, and React errors after making changes.
- When making architecture decisions, prefer the simplest choice that preserves determinism, testability, and separation between generation and rendering.
- When unsure about a design choice with non-obvious consequences, ask before proceeding.
## Architectural Decisions
- Build the app around a clear separation between `generation`, `rendering`, and `ui` layers.
- Keep the procedural generation engine framework-agnostic and free of React dependencies.
- Treat map generation as a deterministic engine driven by an explicit seed and a serializable parameter object.
- Preserve seeded reproducibility as a first-class requirement: the same seed and parameters should produce the same map shape and major features.
- Prefer pure functions for generation passes where practical, but allow well-scoped mutation inside graph and world state when it keeps the port simpler and closer to the original Java code.
- Represent the generated world with a small number of well-defined core types such as map parameters, locations, edges, graphs, regions, and render metadata.
- Use React for application UI, controls, and canvas lifecycle management, not for the procedural generation engine itself.
- Use Canvas 2D as the default rendering target for the map. Add SVG only for overlays or labels when it clearly improves the result.
- Recreate the Java rendering in web-native code rather than trying to preserve Java2D abstractions verbatim.
- Keep geometry, Voronoi, noise, and pathfinding concerns modular so individual libraries can be swapped if needed.
- Prefer lightweight web-native libraries over compatibility layers intended to emulate Java behavior.
- Favor incremental delivery: first achieve correct world generation and a debug render, then improve style and visual fidelity.
- Avoid premature optimization, but structure generation and rendering so expensive work can move to Web Workers later if needed.
- Treat the original Java project as a reference for behavior and output, not as a requirement for line-by-line parity.
## Implementation Priorities
- Start by porting the core data model and generation pipeline before attempting to match the final visual style.
- Get a deterministic seeded map generator working with a simple debug render as early as possible.
- Prefer correctness and inspectability first: make it easy to visualize cells, edges, rivers, roads, cities, and towns while the port is in progress.
- Add stylized terrain, coastlines, textures, and decorative details only after the underlying graph and world data are stable.
- Prefer small, verifiable milestones over large speculative rewrites.
- When porting logic from Java, preserve behavior first and refactor only after tests and visual checks confirm parity.
- If performance becomes an issue, optimize after measuring; do not make the first implementation more complex than necessary.
## Module Boundaries
- Keep generation code under modules focused on domain concepts such as `graph`, `terrain`, `hydrology`, `settlements`, and `roads`.
- Keep rendering code separate from simulation code, with renderers consuming generated map data rather than mutating it.
- Keep React components thin: they should orchestrate controls, user input, and drawing surfaces, not contain map-generation algorithms.
- Isolate browser-specific APIs such as Canvas, DOM events, and workers from the core generation engine.
- Prefer explicit parameter objects and return values over hidden global state.
- Keep random number generation injectable so tests and seeded generation stay reproducible.
- Design the system so a generated map can be serialized, inspected, and re-rendered without recomputing the entire world.
## Library Guidance
- Prefer small, well-supported TypeScript-friendly libraries that fit naturally into a browser-based architecture.
- Use a dedicated Voronoi or Delaunay library for graph construction rather than implementing computational geometry from scratch.
- Use a dedicated seeded noise library for terrain and moisture generation rather than hand-rolling Perlin or Simplex implementations unless there is a clear need.
- Use lightweight geometry helpers for polygon clipping, intersections, and related operations when needed, but avoid large geometry stacks unless the simpler approach is clearly insufficient.
- Prefer small utility libraries for data structures such as priority queues only when they materially simplify the implementation.
- Avoid libraries whose main purpose is emulating Java, Java2D, Swing, or other JVM-era abstractions in the browser.
- Avoid introducing state-management libraries unless the application state becomes complex enough to justify them.
- Avoid introducing rendering engines such as WebGL frameworks unless Canvas 2D has been tried first and shown to be insufficient.
- Choose libraries that work cleanly with ESM, Vitest, and strict TypeScript settings.
- When selecting a library, prefer one that keeps generated map data in plain serializable objects rather than opaque framework-owned structures.
## Porting Strategy
- Treat the Java `FlatWorld` project as the behavioral reference implementation for map generation rules and feature ordering.
- Identify the smallest end-to-end slice that can produce a seeded map in the browser, and implement that first.
- Port in stages: core types, graph construction, elevation and water logic, rivers, settlements and roads, then stylized rendering.
- Build a simple debug renderer early so generated structures can be inspected visually during the port.
- Preserve the original generation sequence when possible so intermediate results remain comparable to the Java version.
- Keep each ported subsystem testable in isolation before composing it into the full pipeline.
- When behavior differs from the Java version, document the difference and move forward rather than forcing awkward browser code to match every incidental detail.
- Use saved seeds and visual snapshots to compare browser output against the Java reference during the migration.
- Prefer shipping a simpler but correct browser version first, then iterating toward higher visual fidelity.
- If an original Java implementation detail is tightly coupled to Java2D or another JVM-specific API, re-express the intent in web-native terms instead of preserving the exact mechanism.