Documentation

Casting

Cast a laptop window to a screen in the world, and place the screens players cast to.

A window can be cast to a screen in the world, such as a TV in a briefing room or a projector wall in an office. The screen shows the window's content, not a copy of the laptop's pixels, so it stays sharp at any distance. Everyone nearby sees the cast on the screen, while the laptop keeps showing its own window.

Disable casting with cast.enabled = false. The Cast button is then gone and nothing of it runs.

#Cast a Window

Press Cast to a Screen in the window's title bar. It lists up to 20 screens the laptop reaches, nearest first, with how it reaches each one, HDMI or Wireless, and its distance. A screen someone else casts to shows as In use.

Pick a screen to cast the window, and pick Stop Casting in the same menu to end it. The laptop must be on, and the player must be at it.

  • One player casts one window at a time. Casting another window, or to another screen, ends the first cast.
  • A screen shows one cast at a time.
  • The cast ends when the window closes, the laptop turns off, its OS closes, the screen is removed, or the player leaves the server.

#Apps That Cast

Three apps cast, under each OS's own name for them.

AppWhat the screen shows
Image viewerThe image on show. Stepping to the next or previous image changes the screen too.
PaintThe drawing, drawn sharp at the screen's own size. Each stroke shows while it is drawn. A drawing too busy for that goes as a picture instead.
SlidesThe slide on show, the one being edited or the one the slideshow is on. Never the rest of the deck or the speaker notes, so the presenter view keeps its notes on the laptop.

Paint and Slides are downloaded from the app store; see Operating Systems.

In a running slideshow:

ActionKey
Laser pointer on or off. A red dot follows on the screen and fades a moment after it stops.Ctrl+L or its button
Pen on or off. The ink shows on the screen as it is drawn and is saved on the slide.Ctrl+P or its button
Erase the slide's inkE or its button

#HDMI & Wireless

Each screen takes an HDMI cable, wireless casts, or both.

  • HDMI: plug an hdmi_cable into the HDMI port of a laptop that is put down, through Ports like any other device; see Ports & Devices. Screens within the cable's reach of the laptop are listed as HDMI. Casting to one connects the cable, and every player nearby sees it run from the laptop's port to the screen. One cable connects one screen, and a screen takes one cable: a screen another laptop's cable is in can't be used.
  • Wireless: any laptop, held or put down, casts to a wireless screen within the screen's wireless range.

A screen that takes both is reached by HDMI when the cable reaches it, and wirelessly otherwise. A laptop only reaches screens in its own routing bucket.

The server checks the cable, the distances, and the laptop's power once a second. An HDMI cast ends when the cable is pulled out, the laptop is picked up, or the screen ends up out of the cable's reach. A wireless cast ends once the laptop leaves the screen's range.

Set cast.hdmi = false to leave only wireless screens.

#Placing Screens

The resource doesn't place screens on its own, since a TV prop doesn't say which screens a server wants players to use. Admins place them in game with /laptopscreens.

The command outlines every screen within 60 metres, with its name, and opens a menu with Place a New Screen and the screens nearby, nearest first. Placing one shows a see-through picture where you aim:

  • Aim at a wall to place the screen flat on it. Scroll to resize it, and press X to cycle its shape between 16:9, 16:10, 4:3, 21:9, and 1:1.
  • Aim at a TV, monitor, or other prop and the screen snaps to the front of the prop, along its top, at its width.
  • Press G to set the corners instead: click the top left corner, then the bottom right one, on the same wall.
ActionKey
Place, or set a cornerEnter or left mouse button
Resize on a wallScroll wheel
Cycle the shapeX
Switch between size and cornersG
Undo a corner, or cancelBackspace or right mouse button

Then give the screen a Name, an Input (HDMI and wireless, HDMI cable only, or Wireless only), a Cable reach, and a Wireless range, in metres.

Pick a placed screen in the menu to Edit details, Move it, Teleport to it, or Delete it. Deleting a screen ends a cast on it. A cast on a screen that is moved or edited goes on while the laptop still reaches it. Screens from the config show in the menu but are only changed in the config.

Placed screens are kept in the zyke_laptop_cast_screens table, created on start, and load for every player when the resource starts. Each screen is in the routing bucket of the admin who placed it. Up to 200 screens can be placed. Placing, changing, and deleting a screen is logged as an admin action.

The command and its ace permission are cast.creator. The CanCreateScreen hook decides who may use it; see Hooks.

#Config Screens

Fixed screens go in cast.screens. Give each a unique id, a label, and an input of "hdmi", "wireless", or "both". reach and range are optional and fall back to cableReach and wirelessRange. bucket is the routing bucket, 0 when left out.

Give either three corners as seen from in front, or the centre of the picture with the heading it faces and its size in metres:

lua
screens = {
    -- Michael's living room, on the projector screen above the fireplace, by its corners
    {id = "michael_projector", label = "Living room projector", corners = {topLeft = vec3(-800.667, 174.880, 75.145), topRight = vec3(-800.165, 173.573, 75.145), bottomLeft = vec3(-800.667, 174.880, 74.355)}, input = "both", reach = 6.0},
    -- The same screen by its centre, the heading it faces and its size
    -- {id = "michael_projector", label = "Living room projector", coords = vec4(-800.416, 174.227, 74.75, 111.0), width = 1.4, height = 0.79, input = "wireless", range = 10.0},
},

Screens are 0.2 to 12 metres wide and tall. Reach is at most 30 metres and range at most 60. A screen the config gets wrong is skipped with a warning in the server console.

#Settings

All under cast in the Config.

KeyDefaultDescription
enabledtrueTurns casting on or off.
liveScreens2Casts one player sees at once, the nearest screens in front of them. Between 1 and 4.
viewRange25.0Metres from a screen its cast is seen.
cableReach5.0Metres of HDMI cable, for screens without their own reach.
wirelessRange8.0Metres a wireless screen takes casts from, for screens without their own range.
hdmi.item"hdmi_cable"The cable item. hdmi = false leaves only wireless screens.
resolution1280Pixels across a cast's picture. Its height follows the screen's shape.
limitsHow much one player may send while casting; see Limits.
imageHosts{}Hosts whose images a cast may show, such as "r2.fivemanage.com".
creator{command = "laptopscreens", permission = "command"}The screen creator's command and ace permission.
screens{}Fixed screens; see Config Screens.

By default a cast only shows images that are in the cast itself or come from a resource, such as the laptop's own pictures. Every viewer's game loads an image from imageHosts, which tells that host who looked at the screen.

#Limits

The laptop sends a cast as a snapshot (the window's whole content), then deltas (changes to it, such as a pen stroke) and signals (passing things, such as the laser pointer). The server keeps the latest snapshot and the deltas since, so a player who walks up later sees the cast as it is.

KeyDefaultDescription
snapshotBytes32768Most a snapshot may take as JSON.
deltaBytes2048Most a delta may take as JSON.
signalBytes256Most a signal may take as JSON.
snapshot{count = 3, rate = 1}A burst of count snapshots, then rate a second.
delta{count = 30, rate = 15}A burst of count deltas, then rate a second.
signal{count = 10, rate = 8}A burst of count signals, then rate a second.

The laptop paces its sends within these limits, and the server drops what goes over them. A window too large to cast says so in the Cast menu.

The server checks every cast before relaying it. The app must be one that casts, its content is cleaned by the app's own check, and an image must be in the cast itself, a resource's file, or from imageHosts. A cast only goes to players near the screen, in its routing bucket, who can see it.

#Hooks

Both are in server/unlocked/hooks.lua; see Can-Check Hooks.

HookDescription
CanCastToScreen(plyId, screenId)Return false and an optional locale key to refuse a cast, such as a briefing screen only the police may use. Asked when a cast starts, after the cable and range checks. screenId is config:<id> for config screens and placed:<number> for placed ones. Allows every cast by default.
CanCreateScreen(plyId)Whether a player may place, change, and delete screens. Asked on every change. By default, players with cast.creator.permission.

#Performance

Each cast a player sees costs a browser page in their game, so keep liveScreens low. Screens further away than viewRange, behind the player, or out of sight show nothing and cost nothing. With no cast screen near a player, nothing of casting runs for them.