Commit Graph

8 Commits

Author SHA1 Message Date
Axel Meyer
9a61647b4a Fix coastline water side flipping on rotation
Root cause: pairEdges returned edges sorted numerically, but
getVerticesOnSide interprets "CW walk from edge2 to edge1" —
when the pair order flipped (e.g., [NE,NW] vs [E,SE]), the
CW walk went the long way vs short way, swapping water/land.

Fix: normalize edge pair so CW distance from e1→e2 is always
≤3 steps (the short arc). This makes waterSide=1 consistently
mean the same geometric side at every rotation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 11:22:52 +00:00
Axel Meyer
ce95930b87 Fix coastline: 2-edge only, explicit waterSide, flip control
Coastline analysis and fix:
- Coastlines now only show 2-edge patterns (straight, wide curve,
  sharp bend) — Y-junctions and crossroads removed since a coast
  always divides exactly two sides
- Added waterSide property to HexFeature (1=CW, -1=CCW) — stored
  explicitly instead of computed by broken center-distance heuristic
  that flipped water/land at rotation midpoint
- F key or "Flip water side" button in palette to toggle which side
  is water before placing
- Inspector shows flip button (swap arrows) for placed coastlines
- Rotation preserves waterSide — no more land/water swaps
- Separate pattern lists: GENERAL_PATTERNS for road/river,
  COASTLINE_PATTERNS for coastline (core/tile-patterns.ts)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 11:17:56 +00:00
Axel Meyer
b6bd66cd9e Tile palette with previews, click-to-place, independent rotation
Completely reworked feature placement UX:
- Tile palette in sidebar shows 7 pattern types (dead-end, straight,
  wide curve, sharp bend, Y-split, Y-wide, crossroads) for each
  linear terrain (road, river, coastline) with small hex previews
- Click pattern to select, click hex to place — no more edge-clicking
- Q/E keys or scroll wheel to rotate selected pattern before placing
- Each placed feature has independent rotation controls (arrows) and
  remove button in the hex inspector panel
- Edge constraint enforcement still runs automatically on placement

Also added: core/tile-patterns.ts with canonical pattern definitions
and rotation math (accounting for symmetry).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 11:09:28 +00:00
Axel Meyer
f144063db9 Fix sidebar init, client-side first, coastline rework
- Fix: move terrainPickerUI declaration before createToolbar to avoid
  "can't access lexical declaration before initialization" error
- Hex size is now fixed per map (not adjustable at runtime)
- Client-side first: localStorage for persistence, no server needed
  for editing. Added Export/Import JSON buttons in sidebar.
- Removed server dependency from main.ts init flow
- Coastline rework: routes edge-to-edge like road/river (bezier),
  fills one side with water color (the side away from hex center).
  No longer draws along hex edges — it's a proper dividing curve.
- Simplified map-settings to just grid toggle + opacity slider

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 10:59:29 +00:00
Axel Meyer
367ba8af07 Phase 3: Express backend, SQLite persistence, auto-save
- server/db.ts: sql.js with migration system (hex_maps, hexes, hex_features)
- server/routes/maps.ts: CRUD for hex maps
- server/routes/hexes.ts: Bulk hex upsert, region load, sparse storage
- server/index.ts: Express 5, CORS, tile serving, SPA fallback
- src/data/api-client.ts: Frontend HTTP client for all API endpoints
- src/main.ts: Auto-save with 1s debounce, load map state on startup
- Port 3002 (Kiepenkerl uses 3001)
- Graceful fallback when API unavailable (works without server too)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 10:45:37 +00:00
Axel Meyer
0e2903b789 Phase 2: Terrain textures, bezier routing, drag-paint, HTTPS
- svg/renderer.ts: Full Canvas rendering engine with terrain textures
  (trees for forest, waves for water, peaks for mountains, contour
  lines for hills, hatch for farmland, buildings for settlements)
- Linear features: paired-edge bezier routing (straight-through,
  curves, dead-ends), river wobble, proper coastline along hex edges
- Drag-paint: click-and-drag in Paint mode paints multiple hexes,
  disables map panning during paint gesture
- NGINX reverse proxy + Let's Encrypt cert for hexifyer.davoryn.de
- Refactored hex-layer.ts to delegate rendering to renderer module

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 10:41:24 +00:00
Axel Meyer
f302932ea8 Phase 1: Core hex engine, Leaflet overlay, terrain painting UI
- core/: Pure TS hex engine (axial coords, hex grid, terrain types,
  edge connectivity with constraint solver, HexMap state model)
- src/map/: Leaflet L.CRS.Simple map init, Canvas-based hex overlay
  layer (L.GridLayer), click/edge interaction detection
- src/ui/: Sidebar with toolbar (Select/Paint/Feature modes),
  terrain picker, hex inspector, map settings (hex size, grid, opacity)
- pipeline/: Tile pyramid generator (sharp, from source image)
- tests/: 32 passing tests for coords, hex-grid, edge-connectivity
- Uses Kiepenkerl tiles (symlinked) for development

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 10:32:52 +00:00
Axel Meyer
5a19864fb5 Initial project scaffolding 2026-04-07 10:09:51 +00:00