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
The width of the game window in pixels.console.log(`Window width: ${ui.width}px`);
The height of the game window in pixels.console.log(`Window height: ${ui.height}px`);
The number of windows currently open.console.log(`Open windows: ${ui.windows}`);
The main viewport of the game.const center = ui.mainViewport.getCentrePosition();
console.log(`Viewport center: (${center.x}, ${center.y})`);
The current tile selection.if (ui.tileSelection.range) {
console.log('Selection range:', ui.tileSelection.range);
}
console.log('Selected tiles:', ui.tileSelection.tiles.length);
The currently active tool, or null if no tool is active.if (ui.tool) {
console.log(`Active tool: ${ui.tool.id}`);
}
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.
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!');
}
}
]
});
Simple Window
Interactive Window
Tabbed Window
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}`
}
]
});
ui.openWindow({
classification: 'control-panel',
title: 'Control Panel',
width: 400,
height: 250,
widgets: [
{
type: 'checkbox',
name: 'pauseGame',
x: 10,
y: 20,
width: 200,
height: 14,
text: 'Pause Game',
isChecked: context.paused,
onChange: (checked) => {
context.paused = checked;
}
},
{
type: 'spinner',
name: 'cashSpinner',
x: 10,
y: 50,
width: 150,
height: 24,
text: `Cash: ${park.cash}`,
onIncrement: () => {
park.cash += 1000;
},
onDecrement: () => {
park.cash -= 1000;
}
}
]
});
ui.openWindow({
classification: 'tabbed-window',
title: 'Statistics',
width: 500,
height: 400,
tabs: [
{
image: 'guests',
widgets: [
{
type: 'label',
x: 10,
y: 20,
width: 480,
height: 14,
text: `Total Guests: ${park.guests}`
}
]
},
{
image: 'finance',
widgets: [
{
type: 'label',
x: 10,
y: 20,
width: 480,
height: 14,
text: `Cash: £${(park.cash / 10).toFixed(2)}`
}
]
}
]
});
getWindow()
Gets an existing window by ID or classification.
const window = ui.getWindow(0);
if (window) {
console.log(`Window: ${window.title}`);
}
The window classification.
const window = ui.getWindow('my-window');
if (window) {
window.title = 'Updated Title';
}
closeWindows()
Closes all windows with the specified classification.
The window classification to close.
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.
The title/first line of the box.
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.
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.
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}`);
}
});
Begins a new tool session with custom cursor and event handlers.
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');
}
});
Tile Selector
Entity Inspector
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}`);
}
}
});
ui.activateTool({
id: 'entity-inspector',
cursor: 'picker',
filter: ['entity'],
onDown: (e) => {
if (e.entityId !== undefined) {
const entity = map.getEntity(e.entityId);
if (entity) {
console.log(`Entity: ${entity.type}`);
if (entity.type === 'guest') {
console.log(`Name: ${entity.name}`);
console.log(`Happiness: ${entity.happiness}`);
}
}
}
}
});
Registers a new item in the game’s main menu.
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: []
});
});
Registers a new item in the toolbox menu on the title screen.
Only available to intransient plugins.
The function to call when clicked.
ui.registerToolboxMenuItem('Launch Custom Scenario', () => {
console.log('Toolbox item clicked');
});
Shortcuts
registerShortcut()
Registers a keyboard shortcut.
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);
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.`);
}
}
});
});
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:
The window classification.
The x position of the window.
The y position of the window.
The height of the window.
The widgets in the window.
The window colour palette.
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.
Finds a widget by name.
const button = window.findWidget('myButton');
button.text = 'New Text';