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.
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 |
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 |
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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'.
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.
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.