client runtime · Lua API
Open77.remoteCamera
Runs inside the game process. Reads and presentation are local; anything that changes shared state has to go through the server.
On this page15 sections
bindHud
Open77.remoteCamera.bindHud(cameraId, rect)Shows one source in a native HUD rectangle and returns the binding id.
Client-only; requires camera.capture. rect is {x, y, width, height} in viewport pixels -- a screen-space viewport, not a DOM element, so it does not track page layout. The returned binding id is opaque and allocated by the host for this resource generation. Multiple bindings may share one source, and capture is demanded only while at least one binding is visible; hiding the last visible binding stops the rendering without destroying the source. The id ends at unbind() or when the source is destroyed.
Parameters 2
| Name | Type | Use | Default |
|---|---|---|---|
cameraId | string | required | — |
rect | table | required | — |
Returns
- binding id (opaque string), or nil, reason
Example
local hud, reason = Open77.remoteCamera.bindHud(cam, {
x = 80, y = 100, width = 640, height = 360,
})
if hud then
-- The source keeps existing; only this presentation goes away
Open77.remoteCamera.updateBinding(hud, { visible = false })
endRemote cameras & world screens guide · Registered in ResourceHost.cpp as LuaRemoteCameraBindHud (line 25314).
bindings
Open77.remoteCamera.bindings([cameraId])This resource's bindings, optionally only those of one source.
Client-only; requires camera.capture. With no argument every binding this resource owns is listed; passing a camera id filters to that source. Owner-scoped like the rest of the namespace, so it cannot be used to read another resource's presentations. Rows are the same snapshots getBinding() returns.
Parameters 1
| Name | Type | Use | Default |
|---|---|---|---|
cameraId | string | optional | — |
Returns
- array of binding snapshots
Example
-- One source's presentations
for _, binding in ipairs(Open77.remoteCamera.bindings(cam) or {}) do
print(binding.id, binding.kind, binding.state)
endRemote cameras & world screens guide · Registered in ResourceHost.cpp as LuaRemoteCameraBindings (line 25319).
bindWebUI
Open77.remoteCamera.bindWebUI(cameraId, page, rect)Shows one source under a resource-owned transparent page and returns the binding id.
Client-only; requires camera.capture, and the WebUI layer keeps its own permission. page must belong to the calling resource; another resource's page is refused and the provider never accepts one on a caller's behalf. rect is {x, y, width, height} in viewport pixels -- the image is drawn by a native underlay behind that transparent region, and the resource still owns the page's layout. The engine's dynamic texture stays behind an Ink image: this is not an HTML video element, an image URL, a JavaScript-readable pixel stream or a transferable GPU texture, and no raw graphics pointer or unsynchronized resource lifetime crosses into Lua or JavaScript.
Parameters 3
| Name | Type | Use | Default |
|---|---|---|---|
cameraId | string | required | — |
page | userdata | required | — |
rect | table | required | — |
Returns
- binding id (opaque string), or nil, reason
Example
local page = WebUI.create({
entry = "web/monitor.html",
layer = "hud",
transparent = true,
visible = true,
})
if page then
local underlay = Open77.remoteCamera.bindWebUI(cam, page, {
x = 80, y = 100, width = 640, height = 360,
})
print(underlay)
endRemote cameras & world screens guide · Registered in ResourceHost.cpp as LuaRemoteCameraBindWebUI (line 25316).
bindWorld
Open77.remoteCamera.bindWorld(cameraId, placement)Shows one source on a depth-tested world panel and returns the binding id.
Client-only; requires camera.capture. placement is {position, rotation, width, height, model, parent} with physical dimensions in metres. model defaults to surface, a frameless display placed just in front of an existing prop; panel uses the stock authored housing. worldModels() describes the supported profiles, not installed slot availability. Unsupported models are refused rather than substituted. parent is {type=..., id=...} and makes position/rotation local to a prop, localProp, player, vehicle or entity; only canonical prop, player and vehicle parents are accepted over the network. Foreground geometry occludes the display. This is not material substitution, UV reuse or a texture painted onto an arbitrary mesh.
Parameters 2
| Name | Type | Use | Default |
|---|---|---|---|
cameraId | string | required | — |
placement | table | required | — |
Returns
- binding id (opaque string), or nil, reason
Example
-- Frameless display standing three metres in front of the player
local view = Open77.camera.view()
if view then
local panel = Open77.remoteCamera.bindWorld(cam, {
position = { x = view.position.x + 3.0, y = view.position.y, z = view.position.z },
rotation = { yaw = 90, pitch = 0, roll = 0 },
width = 2.4,
height = 1.35,
})
print(panel)
endRemote cameras & world screens guide · Registered in ResourceHost.cpp as LuaRemoteCameraBindWorld (line 25315).
budget
Open77.remoteCamera.budget()The effective admission limits and current usage, read-only.
Client-only; requires camera.capture. Reports the global and caller-scoped limits and usage, including allocations that are still retiring, so a caller can decide whether to request another source before it is refused with camera_slots_exhausted. There is no public setter: the budget is host/operator policy, and the provider service must not change it either.
Returns
- budget table
Example
-- Read-only: the operator owns the ceiling, the caller only reads it
print(Open77.json.encode(Open77.remoteCamera.budget()))Remote cameras & world screens guide · Registered in ResourceHost.cpp as LuaRemoteCameraBudget (line 25312).
capabilities
Open77.remoteCamera.capabilities()Reports output, presentation support, admission limits and asset requirements.
Client-only; requires camera.capture. Reports the fixed output, supported presentation kinds, source and binding limits, expected slot templates, TweakDB availability and world readiness. Storage capacity is not the number of installed slot graphs; asset availability is resolved when a source or presentation is created. Read-only: admission limits are host/operator policy.
Returns
- capabilities table
Example
local capabilities = Open77.remoteCamera.capabilities()
print(Open77.json.encode(capabilities))Remote cameras & world screens guide · Registered in ResourceHost.cpp as LuaRemoteCameraCapabilities (line 25311).
create
Open77.remoteCamera.create(view)Queues one independent capture source and returns its opaque id.
Client-only; requires camera.capture. view is {position={x,y,z}, rotation={yaw,pitch,roll}, fov, range} in world metres and degrees: position is required, rotation defaults to zero, FOV to 60 (1..120) and range to 100 (1..500). The id belongs to the calling resource generation; it is neither an engine id nor a server camera id. Admission is asynchronous: pending does not mean active capture. Follow open77:remoteCamera:stateChanged or read get(). Failure is nil, reason; camera_slots_exhausted means the shared budget is full and camera_record_unavailable means the source record could not be prepared. Missing or incompatible packed assets can also fail later component configuration. Nothing renders until a visible binding demands it, and acceptance is not proof of a fresh frame.
Parameters 1
| Name | Type | Use | Default |
|---|---|---|---|
view | table | required | — |
Returns
- camera id (opaque string), or nil, reason
Example
-- One source in the loading bay, rendered without taking the player's view
local cam, reason = Open77.remoteCamera.create({
position = { x = -699.094, y = 2164.29, z = 54.7051 },
rotation = { yaw = 135, pitch = 0, roll = 0 },
fov = 60,
range = 100,
})
if not cam then
Open77.log.warn("no source: " .. tostring(reason))
else
Open77.log.info("source " .. cam .. " queued")
endRemote cameras & world screens guide · Registered in ResourceHost.cpp as LuaRemoteCameraCreate (line 25306).
destroy
Open77.remoteCamera.destroy(cameraId)Retires a source and its bindings.
Client-only; requires camera.capture. Retirement is asynchronous: the id goes through destroying and ends with a terminal removed event, and the slot is not reusable until the native resources and bindings finish cleanup. After the terminal event the id is stale -- get() answers nil, "stale_id" -- and a caller never held the engine id, so it cannot reach the native object by mistake. Bindings are removed with the source; unbind() is how a caller retires one presentation and keeps the source.
Parameters 1
| Name | Type | Use | Default |
|---|---|---|---|
cameraId | string | required | — |
Returns
- true, or false, reason
Example
-- Bindings go with the source
local ok, reason = Open77.remoteCamera.destroy(cam)
if not ok then
Open77.log.warn("destroy refused: " .. tostring(reason))
endRemote cameras & world screens guide · Registered in ResourceHost.cpp as LuaRemoteCameraDestroy (line 25310).
get
Open77.remoteCamera.get(cameraId)Snapshot of one owned source: requested pose, asynchronous state and demand.
Client-only; requires camera.capture. The snapshot carries the requested pose as direct fields (position keyed x/y/z, rotation keyed yaw/pitch/roll, fov, range) plus id, state, reason, width, height and captureEnabled. States are pending, active, failed and destroying; active means the native object is established, not that a GPU frame is fresh and not that the remote world around the camera is complete. A terminal removed event invalidates the id, after which this returns nil, "stale_id". Ids are opaque: no raw engine handle is exposed.
Parameters 1
| Name | Type | Use | Default |
|---|---|---|---|
cameraId | string | required | — |
Returns
- source snapshot, or nil, reason
Example
-- `pending` is queued, `active` is established -- neither is a fresh frame
local source = Open77.remoteCamera.get(cam)
if source then
print(source.state, source.width, source.height, source.captureEnabled)
endRemote cameras & world screens guide · Registered in ResourceHost.cpp as LuaRemoteCameraGet (line 25308).
getBinding
Open77.remoteCamera.getBinding(bindingId)Snapshot of one binding: source, kind, requested options, state and reason.
Client-only; requires camera.capture. The snapshot carries id, cameraId, kind, state, reason and visible, with the kind's requested options flattened onto the same row. Binding states are the source states plus hidden and unavailable; unavailable is not proof that the source is gone, only that this presentation cannot be materialised right now. removed is terminal and invalidates the id: a later call answers nil, "stale_binding_id".
Parameters 1
| Name | Type | Use | Default |
|---|---|---|---|
bindingId | string | required | — |
Returns
- binding snapshot, or nil, reason
Example
local binding = Open77.remoteCamera.getBinding(panel)
if binding then
print(binding.kind, binding.state, binding.visible)
endRemote cameras & world screens guide · Registered in ResourceHost.cpp as LuaRemoteCameraGetBinding (line 25318).
list
Open77.remoteCamera.list()Every capture source this resource owns.
Client-only; requires camera.capture. Owner-scoped: another resource's sources are never listed, and neither are native objects the host holds for internal reasons. Rows are the same snapshots get() returns, including sources that are still retiring -- a retirement that has not completed keeps counting against the budget until it does.
Returns
- array of source snapshots
Example
-- Including sources still retiring
for _, source in ipairs(Open77.remoteCamera.list() or {}) do
print(source.id, source.state)
endRemote cameras & world screens guide · Registered in ResourceHost.cpp as LuaRemoteCameraList (line 25309).
unbind
Open77.remoteCamera.unbind(bindingId)Retires one presentation and keeps its source alive.
Client-only; requires camera.capture. Retirement is asynchronous: the binding enters destroying, then a terminal removed event invalidates its id. Its source and other bindings remain; rendering continues only while another binding demands it. Use destroy() to retire the source and all its presentations.
Parameters 1
| Name | Type | Use | Default |
|---|---|---|---|
bindingId | string | required | — |
Returns
- true, or false, reason
Example
-- Remove just this monitor; the camera keeps running
local ok, reason = Open77.remoteCamera.unbind(panel)
if not ok then
Open77.log.warn("unbind refused: " .. tostring(reason))
endRemote cameras & world screens guide · Registered in ResourceHost.cpp as LuaRemoteCameraUnbind (line 25320).
update
Open77.remoteCamera.update(cameraId, patch)Applies a sparse pose, FOV or range patch to one owned source.
Client-only; requires camera.capture. Only the fields the caller names change, and position, rotation, fov and range are the same values and limits create accepts. The patch is sparse per field but not per axis: a named position or rotation replaces that value as a whole, so { rotation = { yaw = 90 } } lands with pitch and roll at zero rather than keeping the previous pitch. Pass the full table whenever only one axis should differ. The logical id survives the patch, and so do its bindings. A native source may be rebuilt to apply a patch, and that happens asynchronously, so acceptance is not a smooth per-frame update and not a guarantee of a fresh GPU frame. Mutations return true or false, reason; a destroyed source answers with a stale-id refusal.
Parameters 2
| Name | Type | Use | Default |
|---|---|---|---|
cameraId | string | required | — |
patch | table | required | — |
Returns
- true, or false, reason
Example
-- Sparse: the id and every binding survive the patch
local ok, reason = Open77.remoteCamera.update(cam, { fov = 40, range = 60 })
if not ok then
Open77.log.warn("update refused: " .. tostring(reason))
endRemote cameras & world screens guide · Registered in ResourceHost.cpp as LuaRemoteCameraUpdate (line 25307).
updateBinding
Open77.remoteCamera.updateBinding(bindingId, patch)Changes what a binding shows or where, without changing its identity.
Client-only; requires camera.capture. The patch is sparse and kind-appropriate: cameraId selects a source, visible sets requested visibility, rectangle fields move/size HUD and WebUI presentations, and position/rotation/width/height/model/parent update world panels. parent = false detaches. Position and rotation replace whole vectors: position requires all axes; omitted rotation axes become zero. Kind and WebUI page cannot change. Native changes may be asynchronous. Current limitations: switching an established HUD/WebUI source can leave the previous image mounted; world visibility gates capture demand but does not suppress the mesh's last or shared-source image.
Parameters 2
| Name | Type | Use | Default |
|---|---|---|---|
bindingId | string | required | — |
patch | table | required | — |
Returns
- true, or false, reason
Example
-- Same panel, same id, new place
local ok, reason = Open77.remoteCamera.updateBinding(panel, {
position = { x = 12.5, y = -4.0, z = 1.2 },
visible = true,
})
if not ok then
Open77.log.warn("binding refused: " .. tostring(reason))
endRemote cameras & world screens guide · Registered in ResourceHost.cpp as LuaRemoteCameraUpdateBinding (line 25317).
worldModels
Open77.remoteCamera.worldModels()Lists supported world-display profiles, dimensions and placement bases.
Client-only; requires camera.capture. Rows carry id, defaultWidth, defaultHeight, frameless, sizing and basis. Both built-in profiles default to 1.6 by 0.9 metres. surface is a frameless display with sizing = "display_plane" and entity-local basis right +X, up +Z, normal -Y, yawOffset = 0. panel uses the stock housing, sizing = "mesh_bounds" and authored mesh-face basis with yawOffset = 90; its in-plane axes are not advertised as known. Apply the selected profile's correction once. This catalogue does not scan packed assets: a supported profile may still fail creation if its slot graph is missing or incompatible.
Returns
- array of {id, defaultWidth, defaultHeight, frameless, sizing, basis={space, right, up, normal, yawOffset}}
Example
-- `surface` is the frameless default; `panel` keeps the authored housing
for _, model in ipairs(Open77.remoteCamera.worldModels() or {}) do
print(model.id, model.defaultWidth, model.defaultHeight, model.frameless)
endRemote cameras & world screens guide · Registered in ResourceHost.cpp as LuaRemoteCameraWorldModels (line 25313).
// For agents & LLMsthis page as Markdownllms.txtllms-full.txt
