You are an expert AI assistant tasked with generating the complete frontend code for a single-page application (SPA) called 'HexaGen: Yaratıcı Harita Üretici'. This application allows users to procedurally generate hexagonal maps using the Wave Function Collapse (WFC) algorithm. The goal is to provide game developers, TTRPG creators, and digital artists with a powerful yet user-friendly tool for creating unique, deterministic, and endlessly replayable game worlds or map assets.
**1. PROJECT OVERVIEW:**
HexaGen aims to democratize procedural content generation for hexagonal maps. The core problem it solves is the time-consuming and often repetitive nature of manual map creation for games or TTRPGs. The primary value proposition is offering a tool that leverages the Wave Function Collapse algorithm to generate complex, visually appealing, and rule-compliant hex maps quickly and efficiently, with a high degree of customization. Users can define their own tile sets and rules, ensuring unique outputs tailored to their specific needs. The application will be a responsive, single-page web application.
**2. TECH STACK:**
- **Frontend Framework:** React (using Vite for fast development server and build)
- **Styling:** Tailwind CSS (for rapid UI development and utility-first styling)
- **State Management:** Zustand (lightweight, efficient, and easy to use for global and local state)
- **UI Components:** Radix UI (for accessible and customizable primitive UI components like sliders, dropdowns, dialogs)
- **Icons:** Heroicons
- **Canvas Rendering (for preview):** Potentially react-konva or directly using the Canvas API for rendering the hex grid preview. For MVP, a simpler SVG or div-based representation might suffice, with Canvas/WebGL as a future enhancement.
- **Utilities:** Lodash (for utility functions), clsx (for conditional class names)
**3. CORE FEATURES & USER FLOW:**
* **A. Map Generation Core:**
* **User Flow:** The user lands on the main generation page. They see controls for map parameters: Map Size (e.g., slider or input for number of hex cells, visualized as radius or diameter), Seed (input field for a deterministic seed value, with a randomize button), and potentially presets for common map types (Island, Continent, Archipelago).
* **Details:** Upon clicking a 'Generate Map' button, the application will initiate the WFC algorithm using the provided parameters and the selected tile definition. A loading indicator will be shown. The generated map will be displayed in a preview area.
* **B. Tile Definition Editor:**
* **User Flow:** Users can navigate to a dedicated 'Tile Editor' section. Here, they can create new tile sets or modify existing ones. This involves defining individual hex tiles, specifying their possible edges (e.g., North, North-East, South-East, South, South-West, North-West) and the type of terrain/feature each edge represents (e.g., 'Grass', 'Water', 'Mountain', 'Forest', 'Road', 'Village'). They can also define adjacency rules: which edge types can connect to which other edge types.
* **Details:** The interface should allow users to visually select edges, choose types from a dropdown, and define connection rules (e.g., 'Water' can connect to 'Water' or 'Coast'; 'Road' must connect to 'Road'). Users should be able to save, name, and select these tile definitions for use in the map generator.
* **C. Map Preview & Interaction:**
* **User Flow:** The generated map is displayed in a central preview pane. Users can zoom and pan the map. Hovering over a hex cell could display its details (e.g., terrain type, seed value, coordinates). Basic interaction like selecting cells might be included in MVP.
* **Details:** The preview should be clear and readable. For MVP, a simple 2D representation is sufficient. Hexagonal coordinates should be handled correctly.
* **D. Export Functionality:**
* **User Flow:** After generating a map, users can click an 'Export' button. A modal or dropdown appears, offering export options: Image (PNG/JPG) and Data (JSON). The user selects the format and clicks 'Download'.
* **Details:** Image export should render the current preview. JSON export should provide the underlying grid structure, cell data, and possibly metadata about the generation process.
* **E. User Dashboard:**
* **User Flow:** Logged-in users can see a list of their previously generated maps and saved tile definitions. They can click to reload a map configuration or a tile set.
* **Details:** Basic list view with options to view, delete, or duplicate saved items.
**4. UI/UX DESIGN:**
- **Layout:** A clean, modern, and intuitive interface. A main navigation (sidebar or top bar) for switching between sections (Generate, Tile Editor, Dashboard, Settings). The central area will display the primary content (map generator controls, editor, or map preview).
- **Color Palette:** A balanced palette with a neutral base (e.g., light grays, off-whites) for backgrounds and containers, accented with a vibrant color (e.g., a teal, blue, or purple) for interactive elements, buttons, and highlights. Dark mode option is desirable for later stages.
- **Typography:** Use a clean, readable sans-serif font (e.g., Inter, Poppins) for all text. Clear hierarchy using font sizes and weights.
- **Responsiveness:** The application must be fully responsive, adapting gracefully to different screen sizes (desktop, tablet, mobile). Use Tailwind's responsive modifiers extensively. Mobile-first approach where applicable.
- **Interactivity:** Clear visual feedback for interactive elements (hover states, focus states, active states). Loading spinners/skeletons for asynchronous operations.
**5. DATA MODEL (State Management with Zustand):**
* **`useMapGeneratorStore`:**
* `mapSize`: number (e.g., radius)
* `seed`: string | number
* `selectedTileSetId`: string
* `generatedMapData`: Array<HexCell> | null
* `isLoading`: boolean
* `error`: string | null
* `actions`: {
`setMapSize`, `setSeed`, `setSelectedTileSetId`, `generateMap`, `exportMapImage`, `exportMapJson`
}
* **`useTileEditorStore`:**
* `tileSets`: Array<TileSet>
* `currentTileSetId`: string | null (for editing)
* `actions`: {
`addTileSet`, `updateTileSet`, `deleteTileSet`, `loadTileSet`, `saveTileSet`
}
* **`useAuthStore` (for Dashboard):**
* `user`: User | null
* `isAuthenticated`: boolean
* `savedMaps`: Array<MapConfig>
* `savedTileSets`: Array<TileSet>
* `actions`: {
`login`, `logout`, `saveMap`, `fetchUserData`
}
**Interfaces:**
```typescript
interface Edge {
type: string; // e.g., 'Grass', 'Water', 'Road'
// Optional: connection rules can be embedded here or managed globally
}
interface HexTile {
id: string;
name: string;
edges: {
north: Edge;
northEast: Edge;
southEast: Edge;
south: Edge;
southWest: Edge;
northWest: Edge;
};
// Optional: visual representation/icon for the tile
}
interface TileSet {
id: string;
name: string;
tiles: Array<HexTile>;
connectionRules: Record<string, string[]>; // e.g., {'Water': ['Water', 'Coast']}
}
interface HexCell {
id: string; // Unique ID for the cell
q: number; // Axial coordinate q
r: number; // Axial coordinate r
tileId: string; // ID of the HexTile used for this cell
// Additional data based on tile type if needed
}
interface MapConfig {
id: string;
name: string;
mapSize: number;
seed: string | number;
tileSetId: string;
createdAt: string;
// Optionally store the generated map data itself for quick reload
// mapData: Array<HexCell>;
}
interface User {
id: string;
username: string;
email: string;
}
```
**Mock Data:**
See **SAMPLE DATA** section.
**6. COMPONENT BREAKDOWN:**
* **`App.tsx`:** Root component, sets up routing (if using React Router, though for SPA might be minimal) and global context/stores.
* **`Layout.tsx`:** Main application layout, includes navigation (Sidebar/Navbar) and content area.
* **`Sidebar.tsx` / `Navbar.tsx`:** Navigation component for switching between main sections.
* **`MapGeneratorPage.tsx`:** Container for the map generation interface.
* **`ControlsPanel.tsx`:** Contains all input fields and buttons for map generation parameters.
* **`SliderInput.tsx`:** Reusable slider component (e.g., for `mapSize`). Uses Radix UI.
* **`SeedInput.tsx`:** Input field for seed, with a randomize button.
* **`TileSetSelector.tsx`:** Dropdown to select a TileSet (uses Radix UI Select).
* **`GenerateButton.tsx`:** Triggers the map generation process.
* **`MapPreview.tsx`:** Displays the generated hex map.
* **`HexGrid.tsx`:** Renders the grid of hex cells (initially using SVG or divs, later potentially Canvas).
* **`HexCell.tsx`:** Represents a single hex cell, displays its terrain/type. Handles hover effects.
* **`LoadingSpinner.tsx`:** Displays a visual indicator when the map is generating.
* **`ExportButtons.tsx`:** Contains buttons for exporting the map.
* **`TileEditorPage.tsx`:** Container for the tile set editor.
* **`TileSetList.tsx`:** Displays a list of saved TileSets, allows selection for editing.
* **`TileEditor.tsx`:** Main interface for creating/editing a TileSet.
* **`HexTileDesigner.tsx`:** Visual editor for a single `HexTile`, allowing edge type selection.
* **`EdgeTypeSelector.tsx`:** Component to select an edge type (dropdown/color picker).
* **`ConnectionRulesEditor.tsx`:** Interface to define which edge types can connect.
* **`SaveButtons.tsx`:** Buttons to save or update the current TileSet.
* **`DashboardPage.tsx`:** Container for the user dashboard.
* **`MapList.tsx`:** Displays saved map configurations.
* **`TileSetManager.tsx`:** Displays saved tile sets.
* **`Modal.tsx`:** Generic modal component (using Radix UI Dialog).
* **`Button.tsx`:** Reusable button component (using Radix UI Button or styled with Tailwind).
* **`Input.tsx`:** Reusable input field component.
**7. ANIMATIONS & INTERACTIONS:**
- **Hover Effects:** Subtle background color change or slight scaling effect on interactive elements like buttons, menu items, and hex cells in the preview.
- **Transitions:** Smooth transitions for UI element state changes (e.g., opening/closing modals, dropdown menus, sidebar collapse/expand). Tailwind's transition utilities will be used.
- **Loading States:** Use `LoadingSpinner.tsx` within the `MapPreview.tsx` or a dedicated overlay when `isLoading` is true. Skeleton loaders can be used for lists in the dashboard.
- **Micro-interactions:** Button press feedback, subtle animations on seed randomization.
- **WFC Generation:** A visual progress indicator or step-by-step rendering during generation could be a future enhancement, but for MVP, a simple loading spinner is sufficient.
**8. EDGE CASES:**
- **No Tile Sets:** If no tile sets are defined, prompt the user to create one before generation.
- **Generation Failure (WFC Stuck):** The WFC algorithm might get stuck if the constraints are too tight or contradictory. The application should catch this, display a user-friendly error message (e.g., "Could not generate map with current settings. Try adjusting size, seed, or tile rules."), and clear the map preview.
- **Empty States:** The dashboard and tile editor should display informative messages when there are no saved maps or tile sets (e.g., "You haven't created any maps yet. Click 'Generate Map' to start!").
- **Invalid Input:** Input validation for map size (must be positive integer), seed (handle different types gracefully).
- **Responsiveness:** Ensure all components reflow and resize correctly on smaller screens. Avoid horizontal scrolling where possible.
- **Accessibility (a11y):** Use semantic HTML, ensure proper ARIA attributes, keyboard navigation for all interactive elements, sufficient color contrast.
- **Data Persistence:** Gracefully handle scenarios where local storage might be full or unavailable.
**9. SAMPLE DATA:**
```json
// Example TileSet
{
"id": "basic_island_tileset_v1",
"name": "Basic Island",
"connectionRules": {
"Grass": ["Grass", "WaterEdge"],
"WaterEdge": ["Grass", "WaterEdge", "Coast"],
"Water": ["WaterEdge", "DeepWater"],
"Coast": ["WaterEdge", "Coast", "LandEdge"],
"LandEdge": ["Coast", "LandEdge", "Mountain"],
"Mountain": ["LandEdge", "Mountain"]
},
"tiles": [
{
"id": "grass_01",
"name": "Grassland",
"edges": {
"north": {"type": "Grass"},
"northEast": {"type": "Grass"},
"southEast": {"type": "Grass"},
"south": {"type": "Grass"},
"southWest": {"type": "Grass"},
"northWest": {"type": "Grass"}
}
},
{
"id": "water_edge_01",
"name": "Water Edge",
"edges": {
"north": {"type": "WaterEdge"},
"northEast": {"type": "WaterEdge"},
"southEast": {"type": "Grass"},
"south": {"type": "Grass"},
"southWest": {"type": "Grass"},
"northWest": {"type": "WaterEdge"}
}
},
{
"id": "coast_01",
"name": "Coast",
"edges": {
"north": {"type": "Coast"},
"northEast": {"type": "Grass"},
"southEast": {"type": "WaterEdge"},
"south": {"type": "WaterEdge"},
"southWest": {"type": "WaterEdge"},
"northWest": {"type": "Grass"}
}
},
{
"id": "deep_water_01",
"name": "Deep Water",
"edges": {
"north": {"type": "WaterEdge"},
"northEast": {"type": "WaterEdge"},
"southEast": {"type": "WaterEdge"},
"south": {"type": "WaterEdge"},
"southWest": {"type": "WaterEdge"},
"northWest": {"type": "WaterEdge"}
}
},
{
"id": "mountain_peak_01",
"name": "Mountain Peak",
"edges": {
"north": {"type": "Mountain"},
"northEast": {"type": "Mountain"},
"southEast": {"type": "LandEdge"},
"south": {"type": "LandEdge"},
"southWest": {"type": "LandEdge"},
"northWest": {"type": "Mountain"}
}
}
// ... more tiles
]
}
// Example HexCell data within generatedMapData
[
{
"id": "cell_0",
"q": 0,
"r": 0,
"tileId": "grass_01"
},
{
"id": "cell_1",
"q": 1,
"r": 0,
"tileId": "water_edge_01"
},
{
"id": "cell_2",
"q": 0,
"r": 1,
"tileId": "coast_01"
}
// ... more cells
]
// Example MapConfig for Dashboard
{
"id": "map_abc123",
"name": "My First Island",
"mapSize": 10,
"seed": "my_secret_seed_42",
"tileSetId": "basic_island_tileset_v1",
"createdAt": "2023-10-27T10:00:00Z"
}
```
**10. DEPLOYMENT NOTES:**
- **Build Tool:** Vite is recommended for its speed and ease of configuration.
- **Build Command:** `npm run build` (or `yarn build`). This will generate a production-ready static build in the `dist` folder.
- **Environment Variables:** Use `.env` files for managing environment variables (e.g., API endpoints if a backend is introduced later, feature flags). Vite supports loading environment variables prefixed with `VITE_`.
- **Hosting:** The static build can be hosted on platforms like Netlify, Vercel, GitHub Pages, or any static file server.
- **Performance Optimizations:**
- Code Splitting: Vite handles this automatically for different routes.
- Image Optimization: If using many image assets, consider formats like WebP and optimization tools.
- Memoization: Use `React.memo` and `useMemo`/`useCallback` judiciously to prevent unnecessary re-renders, especially in the `HexGrid` and `HexCell` components.
- WFC Algorithm Optimization: Ensure the WFC implementation itself is efficient, potentially exploring more optimized libraries or techniques if performance becomes an issue with very large maps.
- Lazy Loading: Load components like `TileEditorPage` only when needed.
- **State Persistence:** Utilize `localStorage` or `sessionStorage` for persisting user preferences, unsaved drafts, or the last used settings. Implement robust error handling for storage access.
- **Error Tracking:** Integrate a service like Sentry or LogRocket for monitoring runtime errors in production.
- **Dependencies:** Keep dependencies updated but be mindful of breaking changes, especially with major framework or library updates.
- **Testing:** Implement unit tests for utility functions and state management logic, and integration/e2e tests for core user flows using tools like Vitest or Jest and Playwright/Cypress.