The Civilisation DApp frontend is a single-page application built with React and Vite. It prioritises fast load times, offline readiness, and seamless integration with the World App WebView.
- Entry point:
src/main.tsxsets up the React root, mounts the app, and wires global providers (routing, theme, stores). - Routing: Vite's file-based router is not used; navigation relies on in-app state machines and modals because the WebView runs in a single-page environment.
- Styling: Tailwind CSS (configured via
postcss.config.cjs) defines utility-first styling, with component-specific overrides where necessary.
- Zustand stores (located under
src/store/andsrc/features/**/store.ts) hold gameplay and UI state. - Persistence: The
persistmiddleware writes selected slices to IndexedDB so that tutorial progress, preferences, and settlement state survive reloads. - Selectors: Components consume minimal state through selectors to avoid unnecessary re-renders. Follow the pattern used in
src/hooks/useStoreSelector.ts.
- Configurations: Static JSON files in
configs/define the canonical list of buildings, resources, and units. They are imported at build time. - Worldchain:
wagmiandviemprovide contract reads. Transactions are executed through the World App MiniKit integration, which exposessendTransactionAPIs inside the WebView. - Audio: Preloaded via dynamic imports to keep the initial bundle slim.
- Components: Shared UI primitives live in
src/components/. Feature-specific UIs sit undersrc/features/<feature-name>/. - Hooks: Reusable logic is centralised under
src/hooks/(e.g., for timers, resource production, battle resolution). - Assets: Images and sprites are stored in
assets/and referenced through Vite's asset handling.
- Network and contract errors propagate through custom hooks that translate RPC failures into player-friendly messaging.
- Global error boundaries in
src/components/ErrorBoundary.tsxcapture unexpected runtime issues and surface retry options.
- Unit tests: Implemented with Vitest (Bun-compatible). Place tests alongside components using the
.test.tsxsuffix. - Interaction tests: Use React Testing Library to verify complex UI flows.
- Storybook: Stories double as documentation and manual test beds. Keep them synchronised with component props.
- Lazy-load heavyweight screens and modals using
React.lazy. - Memoise expensive calculations (e.g., resource production) with
useMemoor dedicated selectors. - Monitor bundle size via
bun run build -- --analyzebefore major releases.
- Provide keyboard navigation for all interactive components.
- Use
aria-attributes on modals and forms. - Prefer semantic HTML for lists, tables, and headings.
- Co-locate state and UI with the feature to keep modules cohesive.
- Document any new configuration schema fields inside
configs/README.md(create if missing). - Update this page when adding new cross-cutting libraries or changing the store architecture.