AI Town: UI/UX Framework

Part One: Global Design System

This section defines the foundational visual and interactive principles that give AI Town its unique identity. It is the single source of truth for all aesthetic and behavioral standards.

1.1 Overall Visual Identity

The product’s aesthetic is a carefully crafted homage to classic 16-bit console RPGs. This “retro-tech” feel is not just decorative; it evokes a sense of nostalgia, whimsy, and immersion into a self-contained digital world. Every design element, from color to typography, must serve this core identity.

1.2 Color Palette

The palette is intentionally limited and thematic, creating a cohesive and warm environment. It is divided into two families: a dominant warm “brown” set for backgrounds and text, and a cooler “clay” set for interactive elements.

Palette FamilySwatchHex CodeUsage
Brown
#181425Deepest background, near-black
#3F2832Primary UI panel background
#743F39Accents, borders
#B86F50Mid-tone accents
#EAD4AAHighlight text, secondary info
#FFFFFFPrimary text color
Clay
#3A4466Primary button background
#5A6988Button hover/active state
#8B9BB4Disabled state accents
#C0CBDCLight accents, icons
Gradient
#fec742 to #dd7c42Main title text gradient
1.3 Typography

The typography is a critical component of the retro aesthetic, using two distinct pixelated fonts.

  • Display Font: Upheaval Pro

    • Usage: Exclusively for the main “AI Town” title.
    • Style: Bold, uppercase, with a prominent text gradient (see palette) and a hard drop-shadow to create impact and depth. It sets the game-like tone immediately.
  • Body Font: VCR OSD Mono

    • Usage: For all other UI text, including buttons, descriptions, chat messages, and labels.
    • Style: Monospaced, highly readable even at small sizes. It provides a clean, thematic, and slightly technical feel, reminiscent of old computer terminal text.
1.4 Layout & Spacing

The layout is built on a responsive grid system. The core principle is to frame the experience, making the user feel like they are looking through a window into another world.

  • Main Frame: The entire application is contained within a thick, decorative pixel-art border. This is not just a container but a key design element that separates the “world” from the browser.
  • Two-Column Structure: On desktop screens, the layout is a responsive two-column grid: a flexible main column for the Game World and a fixed-width (24rem / 384px) right column for the Details & Chat Panel. On smaller screens, the layout stacks to a single column to prioritize the game view.
  • Spacing: A consistent spacing scale (based on multiples of 4px) should be used for padding and margins to maintain visual rhythm.
1.5 Iconography & Effects
  • Icons: Icons are simple, pixel-art style SVGs, typically monochromatic, to fit seamlessly with the aesthetic.
  • Shadows: The UI avoids modern, soft drop-shadows. Instead, it uses a “solid shadow” effect—a hard, offset, darker background layer—to give buttons and panels a tactile, pseudo-3D, 8-bit feel.

Part Two: Core Component Library

This section breaks down the most critical UI components. Each entry includes a description, behavior, and a ready-to-use prompt for AI-assisted development.

2.1 Component: Base Button

This is the standard button for all primary actions in the footer.

  • UI Description: A rectangular button with a dark blue-gray (clay-700) background and a hard-edged “solid shadow”. It contains a small pixel-art icon on the left and white, uppercase, monospaced text on the right.

  • UX Behavior:

    • Hover: The background color slightly lightens (clay-500). A tooltip with the button’s title appears.
    • Click: The button has a subtle “press down” effect.
    • Disabled: The button is visually muted and does not respond to hover or click events.
  • Usage: Used for “Interact,” “Music,” “Help,” etc., in the main footer.

  • AI Reproduction Prompt:

    Prompt
    Create a reusable React button component in TypeScript named `Button`, styled with Tailwind CSS.
    - The root element should be an `<a>` tag to handle both `onClick` events and `href` links.
    - It must accept `onClick`, `title`, `imgUrl`, and `children` as props.
    - Style it as an `inline-flex` container with a dark background (`#3A4466`), white text, and padding of `px-4 py-2`. The font should be 'VCR OSD Mono', uppercase, and `text-xl`.
    - Implement a "solid shadow" effect by using a pseudo-element or a wrapper div with a slightly offset, darker background color.
    - On hover, the main background should lighten to `#5A6988`.
    - Inside the flex container, render an `<img>` tag for the icon (source from `imgUrl` prop) with a size of `w-8 h-8` and a margin to the right of the text.
2.2 Component: Character Sprite

The visual representation of all characters within the game world.

  • UI Description: A 16-bit style animated sprite. It must support animation cycles for walking in 4 directions (up, down, left, right). It can display a 💭 (thinking) or 💬 (speaking) bubble directly above it. A unique emoji can also be displayed. The user’s own character is differentiated by a persistent glowing indicator beneath it.

  • UX Behavior: The walking animation only plays when the character is moving. The thought/speech bubbles appear and disappear instantly to provide real-time feedback on the character’s internal state. The entire sprite is a clickable target.

  • Usage: Rendered inside the Pixi.js canvas for every player and AI agent.

  • AI Reproduction Prompt:

    Prompt
    Create a game character component named `Character` using `@pixi/react` for a 2D pixel-art game.
    - The component should render an `AnimatedSprite` from a spritesheet texture. The texture scaling mode must be set to `NEAREST` to preserve the pixelated look.
    - It must accept an `isMoving` boolean prop. The animation should only play if this is true.
    - It must accept an `orientation` prop (a number from 0-360) and select the correct animation ('up', 'down', 'left', 'right') from the spritesheet data based on this value.
    - Conditionally render a '💭' text bubble above the sprite if an `isThinking` prop is true.
    - Conditionally render a '💬' text bubble above the sprite if an `isSpeaking` prop is true.
    - The component must be interactive (`eventMode = 'static'`) and trigger an `onClick` prop when clicked.
2.3 Component: Details & Chat Panel

The primary information and interaction hub on the right side of the screen.

  • UI Description: A tall, vertical, scrollable panel with a dark (brown-800) background. It’s divided into three sections: a header with the character’s name and status, a main body for conversation history, and a footer for contextual action buttons and the message input field.

  • UX Behavior: The panel’s content is dynamic, changing based on the selected character and conversation state. The conversation history is scrollable, with the most recent messages at the bottom.

  • Usage: Permanently visible on the right side of the desktop layout.

  • AI Reproduction Prompt:

    Prompt
    Create a React component named `PlayerDetailsPanel`. Style it with Tailwind CSS.
    - The root container should have a fixed width of `24rem`, a height of `100%`, a dark background (`#3F2832`), and white text (`#FFFFFF`). Use flexbox to arrange its children in a column.
    - The top section should display a character's name (`h2`, font 'VCR OSD Mono') and their current status (`p`, smaller text).
    - The middle section should be a scrollable `div` that takes up the remaining vertical space. This div will contain the `Messages` component.
    - The bottom section should conditionally render action buttons (like "Start Conversation") or a `MessageInput` component based on the current conversation state, passed in via props.

Part Three: Key Screen Flows

This section analyzes how the core components are assembled into key user interfaces.

3.1 Main Screen & Layout

The Main Screen is the single, persistent view of the application.

  • Composition: It’s orchestrated by the root App.tsx component. The screen is wrapped in the decorative GameFrame. Inside the frame, the two-column grid places the PixiGame component on the left and the PlayerDetailsPanel on the right. The Footer containing the Button components is positioned below this grid.
  • Flow: On initial load, the screen is in Spectator mode. The PixiGame renders the live state of the world, and the PlayerDetailsPanel is either empty or shows a default message. Clicking a character populates the panel. Clicking the “Interact” button in the footer initiates the Participant's Journey, triggering authentication and adding the player’s Character Sprite to the PixiGame.
3.2 Conversation Interface Flow

This flow details the dynamic state changes of the PlayerDetailsPanel.

  1. Selection State: User clicks an AI agent. The panel populates with the agent’s info and a “Start Conversation” button.
  2. Initiating State: User clicks “Start Conversation”. The button becomes disabled and changes text to “Walking over…”. The user’s character begins moving towards the agent.
  3. Active State: Once the characters are in proximity, the backend updates the state. The panel’s footer swaps the button for the MessageInput component. The conversation history area is now live. A “Leave Conversation” button appears.
  4. Typing State: When the user types, a “typing…” status is sent to the backend. When the AI is generating a response, the panel displays an “AI is typing…” indicator in the message list.
  5. Conclusion State: User clicks “Leave Conversation”. The panel reverts to the “Selection State,” showing the now-archived final conversation.