Skip to main content
The ui object provides APIs for controlling the user interface. These APIs are only available to servers and clients not running in headless mode.
Always check if ui is available: typeof ui !== 'undefined'

Properties

width
number
The width of the game window in pixels.
console.log(`Window width: ${ui.width}px`);
height
number
The height of the game window in pixels.
console.log(`Window height: ${ui.height}px`);
windows
number
The number of windows currently open.
console.log(`Open windows: ${ui.windows}`);
mainViewport
Viewport
The main viewport of the game.
const center = ui.mainViewport.getCentrePosition();
console.log(`Viewport center: (${center.x}, ${center.y})`);
tileSelection
TileSelection
The current tile selection.
if (ui.tileSelection.range) {
  console.log('Selection range:', ui.tileSelection.range);
}
console.log('Selected tiles:', ui.tileSelection.tiles.length);
tool
Tool | null
The currently active tool, or null if no tool is active.
if (ui.tool) {
  console.log(`Active tool: ${ui.tool.id}`);
}
imageManager
ImageManager
The image manager for custom image allocation and manipulation.
const range = ui.imageManager.allocate(10);
console.log(`Allocated images: ${range.start} to ${range.start + range.count}`);

Window Management

openWindow()

Opens a new custom window.
desc
WindowDesc
required
The window descriptor defining the window’s properties and widgets.
const window = ui.openWindow({
  classification: 'my-window',
  title: 'My Custom Window',
  width: 400,
  height: 300,
  widgets: [
    {
      type: 'label',
      x: 10,
      y: 20,
      width: 380,
      height: 14,
      text: 'Hello, OpenRCT2!'
    },
    {
      type: 'button',
      x: 150,
      y: 50,
      width: 100,
      height: 24,
      text: 'Click Me',
      onClick: () => {
        console.log('Button clicked!');
      }
    }
  ]
});
ui.openWindow({
  classification: 'info-window',
  title: 'Information',
  width: 300,
  height: 200,
  widgets: [
    {
      type: 'label',
      x: 10,
      y: 20,
      width: 280,
      height: 14,
      text: `Park Rating: ${park.rating}`
    }
  ]
});

getWindow()

Gets an existing window by ID or classification.
id
number
required
The window ID.
const window = ui.getWindow(0);
if (window) {
  console.log(`Window: ${window.title}`);
}

closeWindows()

Closes all windows with the specified classification.
classification
string
required
The window classification to close.
id
number
Optional specific window ID to close.
// Close all windows with classification
ui.closeWindows('my-window');

// Close specific window
ui.closeWindows('my-window', 5);

closeAllWindows()

Closes all open windows.
ui.closeAllWindows();
console.log('All windows closed');

Dialogs

showError()

Displays a red error box.
title
string
required
The title/first line of the box.
message
string
required
The message/second line of the box.
ui.showError('Invalid Input', 'Please enter a valid number.');
ui.showError('Action Failed', 'Not enough cash!');

showTextInput()

Shows a text input prompt.
desc
TextInputDesc
required
Parameters for the text input window.
ui.showTextInput({
  title: 'Enter Park Name',
  description: 'What would you like to name your park?',
  initialValue: park.name,
  maxLength: 32,
  callback: (value) => {
    park.name = value;
    console.log(`Park renamed to: ${value}`);
  }
});

showFileBrowse()

Shows a file browse window.
desc
FileBrowseDesc
required
Parameters for the file browse window.
ui.showFileBrowse({
  type: 'load',
  fileType: 'game',
  defaultPath: '/saves/mypark.sv6',
  callback: (path) => {
    console.log(`Selected file: ${path}`);
  }
});

showScenarioSelect()

Shows the scenario select window.
desc
ScenarioSelectDesc
required
Parameters for the scenario select window.
ui.showScenarioSelect({
  callback: (scenario) => {
    console.log(`Selected: ${scenario.name}`);
    console.log(`Path: ${scenario.path}`);
  }
});

Tools

activateTool()

Begins a new tool session with custom cursor and event handlers.
tool
ToolDesc
required
The properties and event handlers for the tool.
ui.activateTool({
  id: 'my-tool',
  cursor: 'cross_hair',
  filter: ['terrain', 'entity'],
  
  onStart: () => {
    console.log('Tool started');
  },
  
  onDown: (e) => {
    if (e.mapCoords) {
      console.log(`Clicked at: (${e.mapCoords.x}, ${e.mapCoords.y})`);
    }
  },
  
  onMove: (e) => {
    if (e.mapCoords) {
      // Update preview or highlight
    }
  },
  
  onUp: (e) => {
    console.log('Mouse released');
  },
  
  onFinish: () => {
    console.log('Tool finished');
  }
});
ui.activateTool({
  id: 'tile-selector',
  cursor: 'cross_hair',
  filter: ['terrain'],
  
  onDown: (e) => {
    if (e.mapCoords) {
      const tileX = Math.floor(e.mapCoords.x / 32);
      const tileY = Math.floor(e.mapCoords.y / 32);
      const tile = map.getTile(tileX, tileY);
      
      console.log(`Selected tile: (${tileX}, ${tileY})`);
      console.log(`Elements: ${tile.numElements}`);
    }
  }
});

registerMenuItem()

Registers a new item in the game’s main menu.
text
string
required
The menu item text.
callback
Function
required
The function to call when clicked.
ui.registerMenuItem('My Plugin', () => {
  console.log('Menu item clicked');
  ui.openWindow({
    classification: 'plugin-window',
    title: 'My Plugin',
    width: 400,
    height: 300,
    widgets: []
  });
});

registerToolboxMenuItem()

Registers a new item in the toolbox menu on the title screen.
Only available to intransient plugins.
text
string
required
The menu item text.
callback
Function
required
The function to call when clicked.
ui.registerToolboxMenuItem('Launch Custom Scenario', () => {
  console.log('Toolbox item clicked');
});

Shortcuts

registerShortcut()

Registers a keyboard shortcut.
desc
ShortcutDesc
required
The shortcut descriptor.
ui.registerShortcut({
  id: 'myplugin.togglewindow',
  text: 'Toggle My Window',
  bindings: ['CTRL+SHIFT+M'],
  callback: () => {
    const window = ui.getWindow('my-window');
    if (window) {
      window.close();
    } else {
      ui.openWindow({
        classification: 'my-window',
        title: 'My Window',
        width: 300,
        height: 200,
        widgets: []
      });
    }
  }
});

Usage Examples

Park Statistics Window

function openStatsWindow() {
  ui.openWindow({
    classification: 'park-stats',
    title: 'Park Statistics',
    width: 400,
    height: 350,
    widgets: [
      {
        type: 'label',
        x: 10,
        y: 20,
        width: 380,
        height: 14,
        text: `Park Name: ${park.name}`
      },
      {
        type: 'label',
        x: 10,
        y: 40,
        width: 380,
        height: 14,
        text: `Rating: ${park.rating}`
      },
      {
        type: 'label',
        x: 10,
        y: 60,
        width: 380,
        height: 14,
        text: `Guests: ${park.guests}`
      },
      {
        type: 'label',
        x: 10,
        y: 80,
        width: 380,
        height: 14,
        text: `Cash: £${(park.cash / 10).toFixed(2)}`
      },
      {
        type: 'button',
        x: 150,
        y: 120,
        width: 100,
        height: 24,
        text: 'Refresh',
        onClick: () => {
          ui.closeWindows('park-stats');
          openStatsWindow();
        }
      }
    ],
    onUpdate: function() {
      // Update window contents periodically
    }
  });
}

ui.registerMenuItem('Park Stats', openStatsWindow);

Guest Finder Tool

ui.registerMenuItem('Find Guest', () => {
  ui.showTextInput({
    title: 'Find Guest',
    description: 'Enter guest name:',
    maxLength: 32,
    callback: (name) => {
      const guests = map.getAllEntities('guest');
      const found = guests.find(g => g.name === name);
      
      if (found) {
        ui.mainViewport.scrollTo({ x: found.x, y: found.y, z: found.z });
        console.log(`Found ${name} at (${found.x}, ${found.y})`);
      } else {
        ui.showError('Not Found', `Guest "${name}" not found.`);
      }
    }
  });
});

Custom Paint Tool

ui.registerMenuItem('Paint Tool', () => {
  ui.activateTool({
    id: 'paint-tool',
    cursor: 'paintbrush',
    filter: ['terrain'],
    
    onDown: (e) => {
      if (e.mapCoords) {
        const tileX = Math.floor(e.mapCoords.x / 32);
        const tileY = Math.floor(e.mapCoords.y / 32);
        
        // Modify tile appearance
        console.log(`Painting tile: (${tileX}, ${tileY})`);
      }
    }
  });
});

Window Object

Windows returned by openWindow() and getWindow() have these properties and methods:
classification
number
The window classification.
number
number
The window number.
x
number
The x position of the window.
y
number
The y position of the window.
width
number
The width of the window.
height
number
The height of the window.
title
string
The window title.
widgets
Widget[]
The widgets in the window.
colours
number[]
The window colour palette.
tabIndex
number
The currently selected tab index.

close()

Closes the window.
const window = ui.getWindow('my-window');
if (window) {
  window.close();
}

bringToFront()

Brings the window to the front.
window.bringToFront();

findWidget()

Finds a widget by name.
name
string
required
The widget name.
const button = window.findWidget('myButton');
button.text = 'New Text';