### Configure and Interact with Owlbear Rodeo Scene Grid
Source: https://context7.com/zjhsteven/owlbear-doc/llms.txt
This snippet demonstrates how to configure and interact with the scene's grid system. It covers getting grid properties like DPI, scale, type, and measurement, as well as setting grid appearance (color, opacity, line type). It also shows how to set the grid type and scale, snap positions to the grid with optional sensitivity and corner/center snapping, and calculate distances between points. Finally, it includes examples of reacting to grid changes using useEffect and setting up different grid configurations (square, hex, isometric).
```javascript
import OBR from "@owlbear-rodeo/sdk";
// Get grid properties
const dpi = await OBR.scene.grid.getDpi(); // e.g., 150
const scale = await OBR.scene.grid.getScale(); // e.g., "5ft"
const gridType = await OBR.scene.grid.getType(); // "SQUARE", "HEX_VERTICAL", etc.
const measurementType = await OBR.scene.grid.getMeasurement(); // "CHEBYSHEV", etc.
console.log(`Grid: ${gridType} at ${scale} (${dpi} DPI)`);
// Configure grid appearance
await OBR.scene.grid.setColor("DARK");
await OBR.scene.grid.setOpacity(0.3);
await OBR.scene.grid.setLineType("DASHED");
// Set grid type and scale
await OBR.scene.grid.setType("HEX_VERTICAL");
await OBR.scene.grid.setScale("10ft");
await OBR.scene.grid.setMeasurement("EUCLIDEAN");
// Snap position to grid
const mousePos = { x: 523, y: 478 };
const snappedPos = await OBR.scene.grid.snapPosition(mousePos);
console.log(`Snapped ${mousePos.x},${mousePos.y} to ${snappedPos.x},${snappedPos.y}`);
// Snap with custom sensitivity (0-1, higher = more sensitive)
const cornerSnap = await OBR.scene.grid.snapPosition(
mousePos,
0.5, // sensitivity
true, // useCorners
false // useCenter
);
// Calculate distance between points
const start = { x: 0, y: 0 };
const end = { x: 500, y: 500 };
const distance = await OBR.scene.grid.getDistance(start, end);
console.log(`Distance: ${distance} ${scale}`);
// React to grid changes
// Assuming useEffect and setGridScale/setGridType are defined elsewhere in the component context
// useEffect(() => {
// return OBR.scene.grid.onChange((grid) => {
// console.log(`Grid changed: ${grid.type} at ${grid.scale}`);
// setGridScale(grid.scale);
// setGridType(grid.type);
// });
// }, []);
// Complete grid configuration tool
async function setupSquareGrid() {
await OBR.scene.grid.setType("SQUARE");
await OBR.scene.grid.setScale("5ft");
await OBR.scene.grid.setMeasurement("CHEBYSHEV"); // D&D 5e style
await OBR.scene.grid.setColor("DARK");
await OBR.scene.grid.setOpacity(0.2);
}
async function setupHexGrid() {
await OBR.scene.grid.setType("HEX_HORIZONTAL");
await OBR.scene.grid.setScale("5ft");
await OBR.scene.grid.setMeasurement("EUCLIDEAN");
}
async function setupIsometricGrid() {
await OBR.scene.grid.setType("ISOMETRIC");
await OBR.scene.grid.setScale("5ft");
await OBR.scene.grid.setMeasurement("MANHATTAN");
}
// Measurement tool with grid snapping (Example Component)
// Assuming useState is imported from React
// function MeasurementTool() {
// const [start, setStart] = useState(null);
// const [end, setEnd] = useState(null);
// const [distance, setDistance] = useState(0);
// const handleClick = async (e) => {
// const pos = { x: e.clientX, y: e.clientY };
// const snapped = await OBR.scene.grid.snapPosition(pos);
// if (!start) {
// setStart(snapped);
// } else {
// setEnd(snapped);
// const dist = await OBR.scene.grid.getDistance(start, snapped);
// setDistance(dist);
// }
// };
// return (
//
// {distance > 0 &&
Distance: {distance}
}
//
// );
// }
```
--------------------------------
### Dynamic Lighting with OBR.scene.items
Source: https://context7.com/zjhsteven/owlbear-doc/llms.txt
Examples of creating and adding various types of lights and walls to the scene to create dynamic lighting effects.
```APIDOC
## Dynamic Lighting with OBR.scene.items
### Description
Implement dynamic lighting by creating and adding light sources and blocking elements (walls) to the scene. Supports various light types and configurations.
### Methods
- `OBR.scene.items.addItems(items: Item[])`: Adds one or more items (lights, images) to the scene.
- `OBR.scene.items.getItems(filter?: (item: Item) => boolean)`: Retrieves items from the scene, optionally filtered.
### Light Configuration Examples
#### 1. Torch Light (360° with falloff)
```javascript
const torch = buildLight()
.position({ x: 500, y: 500 })
.attenuationRadius(300) // Light reach
.sourceRadius(20) // Soft shadow size (0 = hard shadows)
.falloff(0.5) // Edge softness (0 = hard, 1 = soft)
.innerAngle(360) // Full circle
.name("Torch")
.build();
await OBR.scene.items.addItems([torch]);
```
#### 2. Directional Light (Spotlight/Cone)
```javascript
const spotlight = buildLight()
.position({ x: 1000, y: 500 })
.attenuationRadius(500)
.sourceRadius(30)
.falloff(0.7)
.innerAngle(60) // Cone angle in degrees
.outerAngle(90) // Outer cone for falloff
.rotation(45) // Direction in degrees
.name("Spotlight")
.build();
await OBR.scene.items.addItems([spotlight]);
```
#### 3. Vision Light for Token
```javascript
const visionLight = buildLight()
.position({ x: 500, y: 500 })
.attenuationRadius(400)
.sourceRadius(0) // Hard shadows for performance
.innerAngle(360)
.attachedTo("token-id-123") // Attach to token
.name("Player Vision")
.build();
await OBR.scene.items.addItems([visionLight]);
```
#### 4. Walls to Block Light
```javascript
const wall = buildImage()
.url("/wall-texture.png")
.position({ x: 700, y: 500 })
.width(400)
.height(50)
.layer("MOUNT")
.locked(true)
.disableHit(true) // Not selectable
.name("Wall")
.build();
await OBR.scene.items.addItems([wall]);
```
#### 5. Multi-level Dungeon with Elevation
```javascript
const lowerLight = buildLight()
.position({ x: 500, y: 500 })
.attenuationRadius(300)
.zIndex(0) // Lower level
.build();
const upperLight = buildLight()
.position({ x: 500, y: 500 })
.attenuationRadius(300)
.zIndex(1) // Upper level
.build();
const lowerWall = buildImage()
.url("/wall.png")
.position({ x: 700, y: 500 })
.layer("MOUNT")
.zIndex(0) // Blocks lower lights only
.build();
```
#### 6. Secondary Lighting (Conditional)
```javascript
const conditionalLight = buildLight()
.position({ x: 800, y: 500 })
.attenuationRadius(200)
.sourceRadius(0)
.visionOnly(true) // Only active when another light hits it
.name("Reflective Surface")
.build();
```
#### 7. Performance Optimization (Hard Shadows)
```javascript
const performantLight = buildLight()
.position({ x: 300, y: 300 })
.attenuationRadius(250)
.sourceRadius(0) // Hard shadows = better performance
.innerAngle(360)
.build();
```
#### 8. Complete Dungeon Lighting Setup Function
```javascript
async function setupDungeonLighting() {
const lights = [];
// Player vision lights
const tokens = await OBR.scene.items.getItems(
item => item.layer === "CHARACTER" && isImage(item)
);
for (const token of tokens) {
const visionLight = buildLight()
.position(token.position)
.attenuationRadius(400)
.sourceRadius(0)
.attachedTo(token.id)
.name(`Vision: ${token.name}`)
.build();
lights.push(visionLight);
}
// Ambient torches
const torchPositions = [
{ x: 200, y: 200 },
{ x: 800, y: 200 },
{ x: 200, y: 800 },
{ x: 800, y: 800 }
];
for (const pos of torchPositions) {
const torch = buildLight()
.position(pos)
.attenuationRadius(250)
.sourceRadius(15)
.falloff(0.6)
.innerAngle(360)
.name("Torch")
.build();
lights.push(torch);
}
await OBR.scene.items.addItems(lights);
}
```
```
--------------------------------
### OBR Core API - SDK Initialization
Source: https://context7.com/zjhsteven/owlbear-doc/llms.txt
Provides core functionality for initializing extensions and checking SDK availability. It includes examples for checking SDK readiness and accessing player information.
```APIDOC
## OBR Core API - SDK Initialization
### Description
This section covers the initialization of the Owlbear Rodeo SDK and checking for its availability. It demonstrates how to listen for the SDK's ready state and access basic player and scene information.
### Method
Initialization and event listening
### Endpoint
N/A (Client-side SDK)
### Parameters
N/A
### Request Example
```javascript
import OBR from "@owlbear-rodeo/sdk";
// Check if embedded in Owlbear Rodeo
if (OBR.isAvailable) {
// Initialize extension when SDK is ready
OBR.onReady(() => {
console.log("SDK is ready");
// Get current player info
OBR.player.getName().then(name => {
console.log(`Player name: ${name}`);
});
// Check if scene is loaded
OBR.scene.isReady().then(ready => {
if (ready) {
console.log("Scene is ready for manipulation");
}
});
});
}
// React integration pattern
import { useEffect, useState } from "react";
function MyExtension() {
const [isReady, setIsReady] = useState(false);
useEffect(() => {
return OBR.onReady(() => {
setIsReady(true);
});
}, []);
if (!isReady) return
Loading...
;
return
Extension ready!
;
}
```
### Response
N/A (Client-side SDK behavior)
```
--------------------------------
### KeyFilter Examples for Conditional Logic
Source: https://github.com/zjhsteven/owlbear-doc/blob/master/docs/markdown/reference/filters.md
Provides examples of KeyFilter configurations used to define conditional logic for filters. These filters check key-value pairs on objects, allowing for various comparison operators and logical coordinators (AND/OR) for complex filtering scenarios.
```javascript
// The visible property must be `true`
const a = [{ key: "visible", value: true }];
// The visible property must be `true` and the type must not equal `DRAWING`
const b = [
{ key: "visible", value: true },
{ key: "type", value: "DRAWING", operator: "!=" },
];
// The visible property must be `true` or the type must not equal `DRAWING`
const c = [
{ key: "visible", value: true, coordinator: "||" },
{ key: "type", value: "DRAWING", operator: "!=" },
];
```
--------------------------------
### Build Image Upload with File
Source: https://github.com/zjhsteven/owlbear-doc/blob/master/docs/markdown/reference/image-upload.md
Initializes an ImageUploadBuilder with a specified file. This is the starting point for configuring an image upload. It takes a File or Blob object as input.
```javascript
buildImageUpload(file);
```
--------------------------------
### Example Metadata Structure
Source: https://github.com/zjhsteven/owlbear-doc/blob/master/docs/markdown/reference/metadata.md
This JSON snippet illustrates the recommended structure for metadata, using a reverse domain name notation prefix ('com.tutorial.initiative-tracker/metadata') to prevent key collisions with other extensions. It shows how to store custom data, such as 'initiative' for an initiative tracker.
```json
{
"com.tutorial.initiative-tracker/metadata": {
initiative: number
}
}
```
--------------------------------
### Manage Tool Configuration Metadata with OWLBear SDK
Source: https://context7.com/zjhsteven/owlbear-doc/llms.txt
This snippet demonstrates how to store configuration metadata for specific tools within the OWLBear SDK. It provides an example of setting custom properties like stroke and fill colors for a drawing tool.
```javascript
await OBR.tool.setMetadata("com.example.drawing/circle", {
"com.example.drawing/strokeColor": "#FF0000",
"com.example.drawing/fillColor": "#FFCCCC",
"com.example.drawing/strokeWidth": 3
});
```
--------------------------------
### Manage Scene Metadata with OWLBear SDK
Source: https://context7.com/zjhsteven/owlbear-doc/llms.txt
This code example shows how to set and manage metadata for the entire scene using the OWLBear SDK. It covers storing scene-specific attributes such as difficulty, environment type, and level.
```javascript
await OBR.scene.setMetadata({
"com.example.scene/difficulty": "hard",
"com.example.scene/environment": "dungeon",
"com.example.scene/level": 5
});
```
--------------------------------
### Grid API
Source: https://github.com/zjhsteven/owlbear-doc/blob/master/docs/markdown/apis/grid.md
This section covers the API endpoints for interacting with the scene's grid. You can get and set various properties like DPI, scale, color, opacity, type, line type, measurement, and line width.
```APIDOC
## `OBR.scene.grid.getDpi`
### Description
Get the dots per inch (DPI) of the grid. Determines the resolution of one grid cell. For square grids this represents both the width and height of the grid cell. For vertically oriented hex grids this is the width of the grid cell. For horizontally oriented hex grids this is the height of the grid cell. For isometric and dimetric grids this is the post-transform height of the grid cell.
### Method
GET
### Endpoint
/scene/grid/dpi
### Parameters
None
### Request Example
```javascript
OBR.scene.grid.getDpi()
```
### Response
#### Success Response (200)
- **dpi** (number) - The dots per inch of the grid.
#### Response Example
```json
{
"dpi": 100
}
```
```
```APIDOC
## `OBR.scene.grid.getScale`
### Description
Get the current scale of the grid.
### Method
GET
### Endpoint
/scene/grid/scale
### Parameters
None
### Request Example
```javascript
OBR.scene.grid.getScale()
```
### Response
#### Success Response (200)
- **scale** (GridScale) - The current scale of the grid. See [GridScale](#gridscale) for possible values.
#### Response Example
```json
{
"scale": "5ft"
}
```
```
```APIDOC
## `OBR.scene.grid.setScale`
### Description
Set the scale of the grid as a raw string.
### Method
POST
### Endpoint
/scene/grid/scale
### Parameters
#### Request Body
- **scale** (string) - Required - The new raw scale of the grid.
### Request Example
```json
{
"scale": "5ft"
}
```
### Response
#### Success Response (204)
No content is returned on successful update.
#### Response Example
(No content)
```
```APIDOC
## `OBR.scene.grid.getColor`
### Description
Get the current color of the grid.
### Method
GET
### Endpoint
/scene/grid/color
### Parameters
None
### Request Example
```javascript
OBR.scene.grid.getColor()
```
### Response
#### Success Response (200)
- **color** (GridColor) - The current color of the grid. See [GridColor](#gridcolor) for possible values.
#### Response Example
```json
{
"color": "DARK"
}
```
```
```APIDOC
## `OBR.scene.grid.setColor`
### Description
Set the color of the grid.
### Method
POST
### Endpoint
/scene/grid/color
### Parameters
#### Request Body
- **color** (GridColor) - Required - The new color of the grid. See [GridColor](#gridcolor) for possible values.
### Request Example
```json
{
"color": "DARK"
}
```
### Response
#### Success Response (204)
No content is returned on successful update.
#### Response Example
(No content)
```
```APIDOC
## `OBR.scene.grid.getOpacity`
### Description
Get the current opacity of the grid between 0 and 1.
### Method
GET
### Endpoint
/scene/grid/opacity
### Parameters
None
### Request Example
```javascript
OBR.scene.grid.getOpacity()
```
### Response
#### Success Response (200)
- **opacity** (number) - The current opacity of the grid.
#### Response Example
```json
{
"opacity": 0.5
}
```
```
```APIDOC
## `OBR.scene.grid.setOpacity`
### Description
Set the opacity of the grid.
### Method
POST
### Endpoint
/scene/grid/opacity
### Parameters
#### Request Body
- **opacity** (number) - Required - The new opacity of the grid between 0 and 1.
### Request Example
```json
{
"opacity": 0.5
}
```
### Response
#### Success Response (204)
No content is returned on successful update.
#### Response Example
(No content)
```
```APIDOC
## `OBR.scene.grid.getType`
### Description
Get the current grid type.
### Method
GET
### Endpoint
/scene/grid/type
### Parameters
None
### Request Example
```javascript
OBR.scene.grid.getType()
```
### Response
#### Success Response (200)
- **type** (GridType) - The current grid type. See [GridType](#gridtype) for possible values.
#### Response Example
```json
{
"type": "HEX_VERTICAL"
}
```
```
```APIDOC
## `OBR.scene.grid.setType`
### Description
Set the type of the grid.
### Method
POST
### Endpoint
/scene/grid/type
### Parameters
#### Request Body
- **type** (GridType) - Required - The new type of the grid. See [GridType](#gridtype) for possible values.
### Request Example
```json
{
"type": "HEX_VERTICAL"
}
```
### Response
#### Success Response (204)
No content is returned on successful update.
#### Response Example
(No content)
```
```APIDOC
## `OBR.scene.grid.getLineType`
### Description
Get the current grid line type.
### Method
GET
### Endpoint
/scene/grid/lineType
### Parameters
None
### Request Example
```javascript
OBR.scene.grid.getLineType()
```
### Response
#### Success Response (200)
- **lineType** (GridLineType) - The current grid line type. See [GridLineType](#gridlinetype) for possible values.
#### Response Example
```json
{
"lineType": "DASHED"
}
```
```
```APIDOC
## `OBR.scene.grid.setLineType`
### Description
Set the type of the grid line.
### Method
POST
### Endpoint
/scene/grid/lineType
### Parameters
#### Request Body
- **lineType** (GridLineType) - Required - The new type of the grid line. See [GridLineType](#gridlinetype) for possible values.
### Request Example
```json
{
"lineType": "DASHED"
}
```
### Response
#### Success Response (204)
No content is returned on successful update.
#### Response Example
(No content)
```
```APIDOC
## `OBR.scene.grid.getMeasurement`
### Description
Get the current grid measurement type.
### Method
GET
### Endpoint
/scene/grid/measurement
### Parameters
None
### Request Example
```javascript
OBR.scene.grid.getMeasurement()
```
### Response
#### Success Response (200)
- **measurement** (GridMeasurement) - The current grid measurement type. See [GridMeasurement](#gridmeasurement) for possible values.
#### Response Example
```json
{
"measurement": "EUCLIDEAN"
}
```
```
```APIDOC
## `OBR.scene.grid.setMeasurement`
### Description
Set the measurement type of the grid.
### Method
POST
### Endpoint
/scene/grid/measurement
### Parameters
#### Request Body
- **measurement** (GridMeasurement) - Required - The new measurement type of the grid. See [GridMeasurement](#gridmeasurement) for possible values.
### Request Example
```json
{
"measurement": "EUCLIDEAN"
}
```
### Response
#### Success Response (204)
No content is returned on successful update.
#### Response Example
(No content)
```
```APIDOC
## `OBR.scene.grid.getLineWidth`
### Description
Get the current line width of the grid in pixels.
### Method
GET
### Endpoint
/scene/grid/lineWidth
### Parameters
None
### Request Example
```javascript
OBR.scene.grid.getLineWidth()
```
### Response
#### Success Response (200)
- **lineWidth** (number) - The current line width of the grid in pixels.
#### Response Example
```json
{
"lineWidth": 1
}
```
```
--------------------------------
### Room State and Metadata Management
Source: https://context7.com/zjhsteven/owlbear-doc/llms.txt
This section covers how to interact with room-level data, including getting the current room ID, checking and reacting to player permissions, and managing room-wide metadata.
```APIDOC
## Room State and Metadata Management
This API provides functionalities to manage room-level data and permissions shared across all players.
### Get Room ID
Retrieves the unique identifier for the current room.
- **Method**: GET
- **Endpoint**: `OBR.room.id`
- **Description**: Returns the ID of the current room.
### Get Player Permissions
Retrieves the current permissions for the player within the room.
- **Method**: GET
- **Endpoint**: `OBR.room.getPermissions()`
- **Description**: Fetches the player's permissions in the room.
- **Returns**: A Promise that resolves to an object containing permission details.
### Subscribe to Permission Changes
Allows you to register a listener that will be called whenever player permissions change.
- **Method**: SUBSCRIBE
- **Endpoint**: `OBR.room.onPermissionsChange(callback)`
- **Description**: Attaches a callback function to be executed when permissions are updated.
- **Parameters**:
- `callback` (function) - The function to execute with the new permissions data.
- **Returns**: A function to unsubscribe from the event.
### Set Room Metadata
Stores or updates room-wide metadata. The metadata is stored as a key-value object and has a maximum size limit of 16KB per namespace.
- **Method**: POST
- **Endpoint**: `OBR.room.setMetadata(metadata)`
- **Description**: Sets or updates metadata for the room. Can accept an object of key-value pairs or a function to update existing values.
- **Parameters**:
- `metadata` (object | function) - An object where keys are namespaces and values are the data to store, or a function that receives the previous value and returns the new value.
- Example object: `{ "com.example.combat/state": { ... } }`
- Example function: `(prev) => { ... return updated; }`
### Get Room Metadata
Retrieves all room-wide metadata.
- **Method**: GET
- **Endpoint**: `OBR.room.getMetadata()`
- **Description**: Fetches all metadata associated with the room.
- **Returns**: A Promise that resolves to an object containing all room metadata.
### Subscribe to Metadata Changes
Allows you to register a listener that will be called whenever room metadata changes.
- **Method**: SUBSCRIBE
- **Endpoint**: `OBR.room.onMetadataChange(callback)`
- **Description**: Attaches a callback function to be executed when metadata is updated.
- **Parameters**:
- `callback` (function) - The function to execute with the new metadata object.
- **Returns**: A function to unsubscribe from the event.
### Request Example: Setting Combat State Metadata
```json
{
"com.example.combat/state": {
"active": true,
"round": 3,
"currentTurn": "player-id-123",
"initiative": [
{ "id": "player-id-123", "name": "Fighter", "initiative": 18 },
{ "id": "player-id-456", "name": "Wizard", "initiative": 15 },
{ "id": "npc-id-789", "name": "Goblin", "initiative": 12 }
]
},
"com.example.session/info": {
"sessionNumber": 5,
"campaignName": "Lost Mines of Phandelver",
"startTime": 1678886400000
}
}
```
### Response Example: Getting Room Metadata
```json
{
"com.example.combat/state": {
"active": true,
"round": 3,
"currentTurn": "player-id-123",
"initiative": [
{ "id": "player-id-123", "name": "Fighter", "initiative": 18 },
{ "id": "player-id-456", "name": "Wizard", "initiative": 15 },
{ "id": "npc-id-789", "name": "Goblin", "initiative": 12 }
]
},
"com.example.session/info": {
"sessionNumber": 5,
"campaignName": "Lost Mines of Phandelver",
"startTime": 1678886400000
}
}
```
```
--------------------------------
### Scene Fog API
Source: https://github.com/zjhsteven/owlbear-doc/blob/master/docs/markdown/apis/fog.md
Provides methods to interact with the base fog settings for a scene, including getting and setting its color, stroke width, and fill state. It also allows for subscribing to changes in fog settings.
```APIDOC
## GET /api/scene/fog/color
### Description
Gets the current color of the scene's fog.
### Method
GET
### Endpoint
/api/scene/fog/color
### Parameters
None
### Request Example
None
### Response
#### Success Response (200)
- **color** (string) - The current color of the fog.
#### Response Example
```json
{
"color": "#FFFFFF"
}
```
```
```APIDOC
## PUT /api/scene/fog/color
### Description
Sets the color of the scene's fog.
### Method
PUT
### Endpoint
/api/scene/fog/color
### Parameters
#### Request Body
- **color** (string) - Required - The new color for the fog.
### Request Example
```json
{
"color": "#FF0000"
}
```
### Response
#### Success Response (200)
- **message** (string) - Confirmation message.
#### Response Example
```json
{
"message": "Fog color updated successfully."
}
```
```
```APIDOC
## GET /api/scene/fog/strokeWidth
### Description
Gets the current stroke width of the scene's fog.
### Method
GET
### Endpoint
/api/scene/fog/strokeWidth
### Parameters
None
### Request Example
None
### Response
#### Success Response (200)
- **strokeWidth** (number) - The current stroke width of the fog.
#### Response Example
```json
{
"strokeWidth": 5
}
```
```
```APIDOC
## PUT /api/scene/fog/strokeWidth
### Description
Sets the stroke width of the scene's fog.
### Method
PUT
### Endpoint
/api/scene/fog/strokeWidth
### Parameters
#### Request Body
- **width** (number) - Required - The new stroke width for the fog.
### Request Example
```json
{
"width": 10
}
```
### Response
#### Success Response (200)
- **message** (string) - Confirmation message.
#### Response Example
```json
{
"message": "Fog stroke width updated successfully."
}
```
```
```APIDOC
## GET /api/scene/fog/filled
### Description
Gets the current filled state of the scene's fog.
### Method
GET
### Endpoint
/api/scene/fog/filled
### Parameters
None
### Request Example
None
### Response
#### Success Response (200)
- **filled** (boolean) - True if the fog is filling the scene, false otherwise.
#### Response Example
```json
{
"filled": true
}
```
```
```APIDOC
## PUT /api/scene/fog/filled
### Description
Sets the filled state of the scene's fog.
### Method
PUT
### Endpoint
/api/scene/fog/filled
### Parameters
#### Request Body
- **filled** (boolean) - Required - The new filled state for the fog (true/false).
### Request Example
```json
{
"filled": false
}
```
### Response
#### Success Response (200)
- **message** (string) - Confirmation message.
#### Response Example
```json
{
"message": "Fog filled state updated successfully."
}
```
```
```APIDOC
## POST /api/scene/fog/onChange
### Description
Subscribes to changes in the scene's fog settings. A callback function is executed whenever fog properties are updated.
### Method
POST
### Endpoint
/api/scene/fog/onChange
### Parameters
#### Request Body
- **callback** (function) - Required - A function that accepts a `Fog` object as an argument and returns void. This function will be called when fog changes.
### Request Example
```javascript
OBR.scene.fog.onChange((fog) => {
console.log('Fog has changed:', fog);
});
```
### Response
#### Success Response (200)
- **unsubscribe** (function) - A function that, when called, will unsubscribe the callback from fog change events.
#### Response Example
```javascript
const unsubscribe = OBR.scene.fog.onChange(...);
// To unsubscribe later:
unsubscribe();
```
```
--------------------------------
### React to Theme Changes with useEffect
Source: https://github.com/zjhsteven/owlbear-doc/blob/master/docs/markdown/apis/theme.md
An example demonstrating how to use the `onChange` theme event with React's `useEffect` hook. The `useEffect` hook manages the subscription and unsubscription to theme changes automatically.
```javascript
/**
* Use an `onChange` event with a React `useEffect`.
* `onChange` returns an unsubscribe event to make this easy.
*/
useEffect(
() =>
OBR.theme.onChange((theme) => {
// React to theme changes
}),
[]
);
```
--------------------------------
### Send and Receive Messages with OBR.broadcast (JavaScript)
Source: https://context7.com/zjhsteven/owlbear-doc/llms.txt
Demonstrates sending ephemeral messages to players using different destinations (REMOTE, LOCAL, ALL) and receiving messages via an event listener. Messages are limited to 16KB. It requires the '@owlbear-rodeo/sdk' and 'react' for the example.
```javascript
import OBR from "@owlbear-rodeo/sdk";
import { useEffect, useState } from "react";
// Define message channel (use your extension namespace)
const CHANNEL = "com.example.combat/events";
// Send message to other players (REMOTE is default)
await OBR.broadcast.sendMessage(CHANNEL, {
type: "ROLL_DICE",
playerId: await OBR.player.getId(),
playerName: await OBR.player.getName(),
roll: {
dice: "1d20",
result: 18,
modifier: 3,
total: 21
},
timestamp: Date.now()
});
// Send to specific destinations
await OBR.broadcast.sendMessage(
CHANNEL,
{ type: "PING", position: { x: 500, y: 500 } },
{ destination: "REMOTE" } // Only other players
);
await OBR.broadcast.sendMessage(
CHANNEL,
{ type: "LOCAL_UPDATE", data: "test" },
{ destination: "LOCAL" } // Only current player (for multi-window sync)
);
await OBR.broadcast.sendMessage(
CHANNEL,
{ type: "GLOBAL_EVENT", message: "Session starting" },
{ destination: "ALL" } // All players including sender
);
// Receive messages
useEffect(() => {
return OBR.broadcast.onMessage(CHANNEL, (event) => {
const { data, connectionId } = event;
console.log(`Message from ${connectionId}:`, data);
switch (data.type) {
case "ROLL_DICE":
// showDiceRoll(data.playerName, data.roll);
break;
case "PING":
// showPing(data.position);
break;
case "DAMAGE":
// applyDamage(data.targetId, data.amount);
break;
case "TURN_END":
// advanceInitiative();
break;
}
});
}, []);
// Complete dice roller example
function DiceRoller() {
const [rolls, setRolls] = useState([]);
useEffect(() => {
return OBR.broadcast.onMessage("com.example.dice/rolls", (event) => {
setRolls(prev => [...prev, event.data]);
});
}, []);
const rollDice = async (dice) => {
const result = Math.floor(Math.random() * 20) + 1;
const playerName = await OBR.player.getName();
await OBR.broadcast.sendMessage("com.example.dice/rolls", {
player: playerName,
dice,
result,
timestamp: Date.now()
});
};
return (
{rolls.map((roll, i) => (
{roll.player} rolled {roll.result}
))}
);
}
// Note: Messages limited to 16KB
```
--------------------------------
### Manage Room State and Permissions with OBR.room SDK
Source: https://context7.com/zjhsteven/owlbear-doc/llms.txt
This snippet demonstrates how to get the current room ID, check player permissions, and subscribe to permission changes using the OBR.room module. It showcases asynchronous operations and event handling for real-time updates.
```javascript
import OBR from "@owlbear-rodeo/sdk";
// Get room ID
const roomId = OBR.room.id;
console.log(`Current room: ${roomId}`);
// Check player permissions
const permissions = await OBR.room.getPermissions();
console.log("Room permissions:", permissions);
// React to permission changes
useEffect(() => {
return OBR.room.onPermissionsChange((permissions) => {
console.log("Permissions updated:", permissions);
});
}, []);
```
--------------------------------
### Find World Position of Line Start
Source: https://github.com/zjhsteven/owlbear-doc/blob/master/docs/markdown/reference/math-m.md
This example shows how to calculate the world position of a line's start point. It involves creating transformation matrices from the line and its start position, multiplying them, and then decomposing the resulting matrix to extract the world position.
```javascript
const line = buildLine().build();
const lineTransform = MathM.fromItem(line);
const startTransform = MathM.fromPosition(line.startPosition);
const worldTransform = MathM.multiply(lineTransform, startTransform);
const worldPosition = MathM.decompose(worldTransform).position;
```
--------------------------------
### Delete Items and Attachments using Context Menu
Source: https://github.com/zjhsteven/owlbear-doc/blob/master/docs/markdown/apis/items.md
An example demonstrating how to delete selected items and their attachments when a context menu item is clicked. It uses `getItemAttachments` to get all related items and then `deleteItems` to remove them from the scene. This requires access to the context menu and scene items API.
```javascript
OBR.contextMenu.create({
id: "rodeo.owlbear.example",
icons: [
{
icon: "icon.svg",
label: "Example",
},
],
async onClick(context) {
const ids = context.items.map((item) => item.id);
const allItems = await OBR.scene.items.getItemAttachments(ids);
const allIds = allItems.map((item) => item.id);
OBR.scene.items.deleteItems(allIds);
},
});
```
--------------------------------
### Complete Dungeon Lighting Setup Function - JavaScript
Source: https://context7.com/zjhsteven/owlbear-doc/llms.txt
Provides a complete function to set up dungeon lighting dynamically. It creates player vision lights attached to tokens and adds ambient torch lights. Dependencies include OBR SDK and helper functions like isImage. Inputs are existing scene tokens. Outputs are a scene populated with lights.
```javascript
// Complete dungeon lighting setup
async function setupDungeonLighting() {
const lights = [];
// Player vision lights
const tokens = await OBR.scene.items.getItems(
item => item.layer === "CHARACTER" && isImage(item)
);
for (const token of tokens) {
const visionLight = buildLight()
.position(token.position)
.attenuationRadius(400)
.sourceRadius(0)
.attachedTo(token.id)
.name(`Vision: ${token.name}`)
.build();
lights.push(visionLight);
}
// Ambient torches
const torchPositions = [
{ x: 200, y: 200 },
{ x: 800, y: 200 },
{ x: 200, y: 800 },
{ x: 800, y: 800 }
];
for (const pos of torchPositions) {
const torch = buildLight()
.position(pos)
.attenuationRadius(250)
.sourceRadius(15)
.falloff(0.6)
.innerAngle(360)
.name("Torch")
.build();
lights.push(torch);
}
await OBR.scene.items.addItems(lights);
}
```
--------------------------------
### Get and Set Grid Color - OBR.scene.grid
Source: https://github.com/zjhsteven/owlbear-doc/blob/master/docs/markdown/apis/grid.md
Enables getting the current grid color and setting a new color. The color can be set using predefined string values.
```javascript
async getColor()
```
```javascript
async setColor(color)
```
```javascript
OBR.scene.grid.setColor("DARK");
```
--------------------------------
### Initialize Owlbear Rodeo SDK and Check Availability (JavaScript)
Source: https://context7.com/zjhsteven/owlbear-doc/llms.txt
Initializes the Owlbear Rodeo SDK and checks for its availability within the Owlbear Rodeo environment. It demonstrates how to react to the SDK being ready and retrieve basic player and scene information. Requires the @owlbear-rodeo/sdk package.
```javascript
import OBR from "@owlbear-rodeo/sdk";
// Check if embedded in Owlbear Rodeo
if (OBR.isAvailable) {
// Initialize extension when SDK is ready
OBR.onReady(() => {
console.log("SDK is ready");
// Get current player info
OBR.player.getName().then(name => {
console.log(`Player name: ${name}`);
});
// Check if scene is loaded
OBR.scene.isReady().then(ready => {
if (ready) {
console.log("Scene is ready for manipulation");
}
});
});
}
// React integration pattern
import { useEffect, useState } from "react";
function MyExtension() {
const [isReady, setIsReady] = useState(false);
useEffect(() => {
return OBR.onReady(() => {
setIsReady(true);
});
}, []);
if (!isReady) return
Loading...
;
return
Extension ready!
;
}
```
--------------------------------
### Create Dynamic Lights (Torch, Spotlight, Vision) and Walls - JavaScript
Source: https://context7.com/zjhsteven/owlbear-doc/llms.txt
Demonstrates creating and adding various dynamic lighting elements and walls to the scene using the OBR SDK. This includes a 360° torch light, a directional spotlight, a token-attached vision light, and a wall image to block light. Dependencies include OBR SDK's buildLight and buildImage. Inputs are light properties (position, radius, angle) and image properties (URL, position, dimensions). Outputs are the added items to the scene.
```javascript
// Create torch light (360° with falloff)
const torch = buildLight()
.position({ x: 500, y: 500 })
.attenuationRadius(300) // Light reach
.sourceRadius(20) // Soft shadow size (0 = hard shadows)
.falloff(0.5) // Edge softness (0 = hard, 1 = soft)
.innerAngle(360) // Full circle
.name("Torch")
.build();
await OBR.scene.items.addItems([torch]);
// Create directional light (spotlight/cone)
const spotlight = buildLight()
.position({ x: 1000, y: 500 })
.attenuationRadius(500)
.sourceRadius(30)
.falloff(0.7)
.innerAngle(60) // Cone angle in degrees
.outerAngle(90) // Outer cone for falloff
.rotation(45) // Direction in degrees
.name("Spotlight")
.build();
await OBR.scene.items.addItems([spotlight]);
// Create vision light for token
const visionLight = buildLight()
.position({ x: 500, y: 500 })
.attenuationRadius(400)
.sourceRadius(0) // Hard shadows for performance
.innerAngle(360)
.attachedTo("token-id-123") // Attach to token
.name("Player Vision")
.build();
await OBR.scene.items.addItems([visionLight]);
// Create walls to block light
const wall = buildImage()
.url("/wall-texture.png")
.position({ x: 700, y: 500 })
.width(400)
.height(50)
.layer("MOUNT")
.locked(true)
.disableHit(true) // Not selectable
.name("Wall")
.build();
await OBR.scene.items.addItems([wall]);
```
--------------------------------
### Get and Set Grid Line Type - OBR.scene.grid
Source: https://github.com/zjhsteven/owlbear-doc/blob/master/docs/markdown/apis/grid.md
Enables getting the current grid line type and setting a new line type. Available line types include DASHED and others defined by GridLineType.
```javascript
async getLineType()
```
```javascript
async setLineType(lineType)
```
```javascript
OBR.scene.grid.setLineType("DASHED");
```