Skip to content

Latest commit

 

History

History
372 lines (288 loc) · 10.8 KB

File metadata and controls

372 lines (288 loc) · 10.8 KB

UI Components

pixel-ops ships 16 UI overlay components. All are React components that render as absolutely-positioned HTML on top of the Pixi canvas. They are exported individually so you can use them in custom compositions.

Auto-wired components

These components are mounted and managed automatically inside <PixelOps />. You do not need to render them yourself when using the standard component.

Component Position Description
FurnitureEditor Top right Toggle button and editor panel for furniture edit mode
AssetLibrary Left panel (modal) Browseable asset picker for adding furniture
CommsTerminal Bottom right Collapsible notification log
ReputationHUD Top left Reputation score bar and tier badge
BudgetBar Top right area Compute credits balance, income, and expenses
TimeControls Top centre Time speed buttons, clock display, day/season
BubbleOverlay Canvas overlay Speech bubbles that track agent positions

Individually exported components

These components are exported but not automatically mounted by <PixelOps />. They are available for custom HUD compositions.

Component Description
MinimapOverlay Canvas-based minimap showing rooms and agents
DynamicInfoBar Bottom status bar showing hovered agent or building info
AgentDetailSidebar Right-side slide-in panel with full agent stats
FaxMachine Simulation events panel with decision buttons
AwardsModal Full-screen awards ceremony overlay
PolicyPanel Slider panel for adjusting simulation policy settings
NotificationPanel Toast notification stack
HeatmapToggle Buttons to switch heatmap overlay mode
TaskQueueOverlay Dot indicators over rooms showing queue depth

Component props reference

FurnitureEditor

interface FurnitureEditorProps {
  editMode: boolean;
  onToggleEditMode: () => void;
  onExportLayout: () => void;
  onResetLayout: () => void;
  onSaveLayout: () => void;
  onRotateCW: () => void;
  onRotateCCW: () => void;
  onScaleUp: () => void;
  onScaleDown: () => void;
  onOpenAssetLibrary: () => void;
  onFlip?: () => void;
  selectedFurniture: string | null;
}

Shows a toggle button. When editMode is true, expands to a panel with orientation controls (floor, left wall, top wall), scale buttons, and layout management (save, export as JSON, reset to default). When a piece of furniture is selected in the canvas, its key is passed as selectedFurniture.


AssetLibrary

interface AssetLibraryProps {
  open: boolean;
  onClose: () => void;
  onAddAsset: (key: string, url: string) => void;
  onRemoveSelected: () => void;
  selectedFurniture: string | null;
}

Full-height side panel with search, category filters, and a grid of asset thumbnails. Assets can be clicked to add them to the currently selected room, or dragged directly onto the canvas. When selectedFurniture is set, shows a "Remove selected item" button.


CommsTerminal

interface CommsTerminalProps {
  notifications: Array<{
    id: string;
    type: string;
    title: string;
    message: string;
    createdAt: number;
  }>;
  unreadCount: number;
  onMarkAllRead: () => void;
}

A circular button (bottom right) that pulses when there are unread notifications. Clicking opens a scrollable log panel listing all messages with type-coloured indicators.


ReputationHUD

interface ReputationHUDProps {
  reputation: number;       // 0–1000
  eventBus?: GameEventBus;
}

Displays the campus reputation score with a colour-coded progress bar and tier badge. When eventBus is provided, floating delta numbers animate up from the panel whenever reputation changes.


BudgetBar

interface BudgetBarProps {
  credits: number;
  income: number;
  expenses: number;
}

Compact widget showing current credit balance (colour-coded green/yellow/red by threshold) and cumulative income and expense totals. Requires EconomySystem.


TimeControls

interface TimeControlsProps {
  timeOfDay: number;     // 0–24
  dayCount: number;
  season: string;        // 'spring' | 'summer' | 'autumn' | 'winter'
  timeSpeed: number;     // 0 | 1 | 2 | 4
  onSpeedChange: (speed: 0 | 1 | 2 | 4) => void;
}

Row of speed buttons (pause, 1x, 2x, 4x), a 24-hour clock display, and the current day and season. Requires TimeSystem.


BubbleOverlay

interface BubbleData {
  id: string;
  agentId: string;
  agentName: string;
  type: 'alert' | 'task-complete' | 'error' | 'working' | 'info';
  message: string;
  screenX: number;
  screenY: number;
  expiresAt: number;
  route?: string;
}

interface BubbleOverlayProps {
  bubbles: BubbleData[];
  onDismiss: (id: string) => void;
}

Renders speech bubbles at absolute screen positions above each agent. Bubbles automatically track agent movement every frame. Click to dismiss.


MinimapOverlay

interface MinimapAgent {
  id: string;
  agentType: string;
  status: string;
  gridX: number;
  gridY: number;
}

interface MinimapProps {
  agents: MinimapAgent[];
  gridWidth: number;
  gridHeight: number;
  rooms: Array<{ id: string; gx: number; gy: number; w: number; h: number; color: number }>;
  corridors: Array<{ x1: number; y1: number; x2: number; y2: number }>;
  onClickTile?: (gx: number, gy: number) => void;
  viewport?: { gx: number; gy: number; gw: number; gh: number };
}

Canvas-based minimap (180x200px). Running agents pulse, error agents flash red. Pass viewport to overlay a gold rectangle showing the current camera view. Pass onClickTile to handle click navigation.


DynamicInfoBar

interface InfoBarProps {
  hoveredAgent: {
    id: string;
    name: string;
    agentType: string;
    status: string;
    stats: { totalRuns: number; successRate: number };
  } | null;
  hoveredBuilding: {
    id: string;
    label: string;
    occupantCount: number;
  } | null;
  totalAgents: number;
  activeAgents: number;
  errorAgents: number;
}

A full-width bar fixed to the bottom of the container. When nothing is hovered, shows aggregate counts. When an agent is hovered, shows that agent's stats. When a building is hovered, shows its occupant count.


AgentDetailSidebar

interface SidebarProps {
  agent: AgentInfo | null;
  onClose: () => void;
  onNavigate: (agentType: string) => void;
}

Slides in from the right edge when agent is non-null. Shows agent type, status, version, enabled state, and a statistics grid (total runs, successes, failures, success rate, average duration). The footer button calls onNavigate with the agent type so you can route to a detail page in your app.


FaxMachine

interface FaxMachineProps {
  events: SimulationEvent[];
  onChoice: (eventId: string, choice: string) => void;
  onDismiss: (eventId: string) => void;
}

Renders a toggle button with an unread badge (bottom right). When open, shows a list of simulation events with colour-coded severity borders, countdown timers for events with deadlines, and choice buttons. Requires EventSystem.


AwardsModal

interface AwardsModalProps {
  trophies: Trophy[] | null;
  onDismiss: () => void;
}

Full-screen overlay with a gold shimmer header. Displays one card per trophy with category icon, agent name, and stat summary. Clicking outside the modal or the Close button calls onDismiss. Requires AwardsSystem.


PolicyPanel

interface PolicyPanelProps {
  open: boolean;
  onClose: () => void;
  policies: PolicySettings;
  onPolicyChange: (key: keyof PolicySettings, value: number) => void;
}

interface PolicySettings {
  autoRetryThreshold: number;     // 1–10
  restThreshold: number;          // 0.1–0.8
  loadBalanceSensitivity: number; // 0.1–1
  escalationThreshold: number;    // 0.1–1
  confidenceMinimum: number;      // 0.3–1
}

Dropdown panel with five sliders. Each slider updates a policy value immediately. Wire onPolicyChange to update SimulationEngine.getState().policies.


NotificationPanel

interface NotificationData {
  id: string;
  type: 'error' | 'warning' | 'success' | 'info';
  title: string;
  message: string;
  agentId?: string;
  agentType?: string;
  createdAt: number;
  expiresAt: number;
}

interface NotificationPanelProps {
  notifications: NotificationData[];
  onDismiss: (id: string) => void;
}

Toast-style notification stack anchored to the top right. Notifications auto-expire when expiresAt passes (checked every second). Click or the dismiss button removes immediately. This is a separate display component from CommsTerminal — it is intended for transient toasts rather than a persistent log.


HeatmapToggle

type HeatmapMode = 'none' | 'load' | 'errors' | 'traffic' | 'density';

interface HeatmapToggleProps {
  mode: HeatmapMode;
  onModeChange: (mode: HeatmapMode) => void;
  llmEnabled: boolean;
  onLlmToggle: () => void;
}

A compact button row (bottom left) for switching heatmap overlay modes (Load, Errors, Traffic, Density) and toggling LLM speech generation. Clicking an active mode toggles it back to 'none'.


TaskQueueOverlay

interface TaskQueueOverlayProps {
  queues: Array<{
    roomId: string;
    count: number;
    screenX: number;
    screenY: number;
  }>;
}

Renders rows of 6px coloured dots at screen positions over rooms. Colour indicates urgency: green (1–3), yellow (4–5), red (6+). Dots cap at 8 regardless of count to keep the display readable. Pass screenX/screenY in canvas pixel coordinates.


Custom HUD composition

If you want to build your own HUD instead of using the default layout inside <PixelOps />, you can compose individual components yourself. Use SimulationEngine directly and subscribe to GameEventBus for state changes.

import {
  PixelOps,
  ReputationHUD,
  DynamicInfoBar,
  NotificationPanel,
  GameEventBus,
} from 'pixel-ops';

// This is a conceptual sketch — wiring the engine directly
// requires using the advanced SimulationEngine API.
export function CustomLayout({ adapter, config }) {
  const [reputation, setReputation] = useState(500);
  const [notifications, setNotifications] = useState([]);

  return (
    <div style={{ position: 'relative', width: '100%', height: '100%' }}>
      <PixelOps adapter={adapter} config={config} />

      {/* Overlay your own components */}
      <ReputationHUD reputation={reputation} />
      <NotificationPanel
        notifications={notifications}
        onDismiss={(id) => setNotifications(prev => prev.filter(n => n.id !== id))}
      />
    </div>
  );
}

Note: when using <PixelOps />, the built-in auto-wired components (listed above) are always rendered. For a fully custom layout, you would need to build your own canvas wrapper using SimulationEngine directly, which is an advanced use case not covered in this version of the docs.