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 Family | Swatch | Hex Code | Usage |
---|---|---|---|
Brown | #181425 | Deepest background, near-black | |
#3F2832 | Primary UI panel background | ||
#743F39 | Accents, borders | ||
#B86F50 | Mid-tone accents | ||
#EAD4AA | Highlight text, secondary info | ||
#FFFFFF | Primary text color | ||
Clay | #3A4466 | Primary button background | |
#5A6988 | Button hover/active state | ||
#8B9BB4 | Disabled state accents | ||
#C0CBDC | Light accents, icons | ||
Gradient | #fec742 to #dd7c42 | Main 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.
- Hover: The background color slightly lightens (
-
Usage: Used for “Interact,” “Music,” “Help,” etc., in the main footer.
-
AI Reproduction Prompt:
PromptCreate 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:
PromptCreate 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:
PromptCreate 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 decorativeGameFrame
. Inside the frame, the two-column grid places thePixiGame
component on the left and thePlayerDetailsPanel
on the right. TheFooter
containing theButton
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 thePlayerDetailsPanel
is either empty or shows a default message. Clicking a character populates the panel. Clicking the “Interact” button in the footer initiates theParticipant's Journey
, triggering authentication and adding the player’sCharacter Sprite
to thePixiGame
.
3.2 Conversation Interface Flow
This flow details the dynamic state changes of the PlayerDetailsPanel
.
- Selection State: User clicks an AI agent. The panel populates with the agent’s info and a “Start Conversation” button.
- 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.
- 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. - 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.
- Conclusion State: User clicks “Leave Conversation”. The panel reverts to the “Selection State,” showing the now-archived final conversation.