The RoadVr headset, seen from the front left on a bright ground.Product render

Spatial AR interface for FiveMoff

Panels that staywhere you put them.

Fourteen apps and seven wall widgets in glass windows anchored to the world, not to the camera. Put one down, walk around it, come back tomorrow — it is still there.

Version 0.1.0 · betaSee the apps

The headsetbooting

An item, not a menu.

A player sits in a lounge at sunset wearing the headset; the city is still visible through the window.

Passthroughpassthrough

The room is still there.

Everything past this point is what he sees.

Product render
It sits in the inventory. Use it and it goes on; use it again and it comes off. Everything below happens while it is on your face — and the moment it comes off, the world is exactly as you left it.
  • ItemPut the headset on or take it off
  • F7Open the home screen
  • F6Open the control centre
  • EFocus the window you are looking at
  • GEdit the widgets on the walls
  • EscDrop focus, back to passthrough

Defaults. F6, F7 and G are real key mappings — players rebind them in GTA's own settings. The focus key is the server owner's choice.

RoadVr only works in first-person view.

RoadVr ships no headset model. It uses the glasses your server already streams, so the visor on your server is the one you chose.

The first time it goes on, it sets you up.

Six short steps — language, look, how windows behave — and every answer can be changed again later in Settings.

  1. 1welcome
  2. 2beta
  3. 3language
  4. 4look
  5. 5windows
  6. 6ready

The in-game setup, from welcome to ready.

Windows float in the room around you and stay there. Six short steps and it is set up the way you want it.

The windowspassthrough

Four windows in the room.Not on a screen.

Push one out to arm's length, or hang it across the room six metres away. Then walk around it. It does not follow you, it does not turn to face you, it does not drift. It is a thing standing in a place, and you are the one moving.

That is the whole difference between an interface drawn on a monitor and one standing in the world.

Radius is per window. The player stands at the centre.

  • Move all

    Grab the arrangement instead of a window. Spacing and distance hold; the whole set swings to where you are looking.

  • Take all along

    Pin the arrangement to yourself. Walk, drive, get shot at — it comes with you and keeps its shape.

  • Arrange windows

    One control puts everything back on an even arc, for when an evening of dragging has left the shell a mess.

One grab moves the arrangement. The next moves a single window.

The home screenpassthrough

Fourteen apps.Right where you look.

While this is on, the grabber, the wheel and the tilt control of any window act on all of them.

The appspassthrough

Fourteen apps. All of them finished.

Not mockups and not screenshots. Every one of them opens, works, keeps what you did, and is still there tomorrow. And fourteen is the floor, not the ceiling — your server's own apps register alongside them.

  • Settings

    Language, light or dark, which icon set, the accent colour, and how new windows behave.

    1.5 × 1 m

  • Media

    A YouTube link in a window. The sound stays with the wearer and falls off between 1.5 and 8 metres.

    2 × 1.28 m

  • Vehicles

    Your garage with plates and parking state, and a valet who drives a car out to you.

    1.6 × 1 m

  • Basketball

    A real hoop and ball put down in the room. Flick the mouse to shoot; it counts points and streaks.

    0.95 × 0.66 m

  • Map

    A slice of the world map lying on the floor. Take hold of it, drag it around, the wheel zooms.

    0.72 × 0.5 m

  • Environments

    Swaps the world around you for a 360° panorama, with how far it takes over on a slider.

    1 × 0.78 m

  • Weather

    Temperature from the server so everyone reads the same number; sky and time from the client.

    0.62 × 0.92 m

  • Clock

    In-game time, a stopwatch and a timer. No alarms — a headset is not where you set one.

    0.8 × 0.6 m

  • Calculator

    A calculator, kept plain. No history and no scientific mode; this is the one you reach for mid-conversation.

    0.58 × 0.86 m

  • Notes

    Notes in their own table, list on the left and the editor on the right.

    1.5 × 0.95 m

  • Messages

    A second screen for the phone's texts: read, reply, start a thread without taking the phone out. Needs RoadPhone — classic or Pro, it works out which.

    1.5 × 0.95 m

  • Photos

    The camera roll as a grid. Open a shot and it gets its own window, which grows to wall size.

    1.35 × 0.9 m

  • Drone

    Put down a real drone prop and fly it. Assisted, or full FPV acro with analog throttle.

    1 × 0.72 m

  • Control Centre

    One key, one sheet: the four switches, the environments, see-through, and whatever the phone is playing. The button that takes the headset off is red.

    1.9 × 1.15 m

Environmentspassthrough

Or replace Los Santos entirely.

Pull one slider and Los Santos fades out behind somewhere else.

Immersion85 %

How far around your head the picture reaches.

At the bottom only what is behind you is covered; at the top the picture closes in front of you as well. Set it beforehand and the next place comes up at that level.

Start walking and it pulls back on its own, so the street you actually have to cross is never hidden by the one you would rather be on.

Environments are 360° panoramas the server owner supplies. Two steps, and they show up here. Equirectangular JPG, PNG or WebP; polyhaven.com has plenty under CC0.

  1. 1Put the panoramas herepublic/environments/
  2. 2List them hereConfig.Environments.list in config.lua

One slider between Los Santos and somewhere else.

The widgetswidgets

Seven things for the walls.

Windows float. Widgets belong to the building. Hang a clock in the hallway of your apartment and it is still hanging there next week — only you can see it, and only through the headset. Twelve of them per character.

Pick a widget, or grab one off the wall.

Watchwidgets

The widgets, in motion.

Wheel resizes · Left click places · Right click cancels

A villa wall in daylight through the headset: a framed pool photo, the weather circle, the wall clock, a green sticky note, and the aquarium sunk into the plaster.

The wallwidgets

Five of the seven,on one wall.

In game. The two above are renders.

Two modesfocus

Scenery, or something you can click.

In passthrough the windows are scenery: the player runs, drives and shoots while the glass floats along. Press E and the window takes the mouse — the character stands still and the interface becomes clickable. Esc hands control back.

Movement
Free
Mouse
Camera
Windows
Scenery

Every state that can be entered can be left. Focus releases on death, on taking the headset off, and on resource stop.

Behind the wheelfocus

Behind the wheel it gets out of the way.

Get in a car and the windows step back by themselves. What stays is on the windscreen: your speed, the next turn, how far is left. Underneath it, the controls for doors, windows, lights, engine and locks — any of which you can switch off if your server already handles them somewhere else.

DoorsWindowsLightsVehicle
  • Headlights
  • High beam
  • Hazards
  • Interior
  • Engine
  • Central locking

Bolted to the windscreen — nothing to arrange, nothing in the way, and it fits the shape of the car it is in.

Only the engine and the locks ask the server first.You do not have the keys to this vehicle.

Speed, next turn, distance left.km/h or mph

On your serverpassthrough

Works with every framework.

Drop it in and it finds its own footing: it works out what you are running and adapts to it. No fork to pick, no version to match, nothing to wire up by hand.

  • ESXdetected on start
  • QBCoredetected on start
  • Qboxdetected on start
  • Anything elseruns standalone

Dependencies are ox_lib, oxmysql and OneSync. The database tables are created on first start.

Three lines and it runs.

  1. 1ox_lib and oxmysql must be running.
  2. 2Register an item roadvr_headset in the inventory (the name is Config.Item). An empty Config.Item means no item is needed — that is how it runs standalone.
  3. 3ensure roadvr in the server.cfg.

That is all. The database does not have to be set up by hand — the four tables are created on first start, and an older installation has missing columns added.

> roadvr diagBridgeokqboxox_libokoxmysqlokInventoryokox_inventoryLocaleokenDatabaseokroadvr_profilesxsound--optional, not runningRoadPhone--optional, not running

Restart the resource. Nothing moves.

Stop it in the middle of a busy evening and start it again. Every window comes back exactly where it hung, and the widgets are still in the walls.

Stopped, started, unchanged.

Not in it.

  • FaceTime and voice
  • Poker and other multiplayer apps
  • Shared panels
  • Persona / avatar
  • Free website embedding
  • Battery system
  • Panoramas for the environments

The core is built so that these extensions require no rebuild.

For developerspassthrough

Ship your own app to the headset.

Your resource registers an app and its icon is on the home screen. Opening it loads your page into a window. Inside the frame you use whatever you like — plain HTML or a framework — and a crash in your app cannot take the headset down with it.

  1. 1

    Serve two files

    A page and an icon, in your own resource's files {} block. No ui_page: the window belongs to RoadVr.

  2. 2

    Register once at start

    One export call with an id, the page and a size in metres. It survives the headset coming off and going back on.

  3. 3

    Talk to your own Lua

    A plain fetch reaches your own RegisterNUICallback. Inbound goes through sendToRoadVrApp.

client.lua
local ok, err = exports.roadvr:registerRoadVrApp({
    id     = 'myserver_dispatch',   -- unique, prefix it with your resource
    name   = 'Dispatch',            -- shown under the icon
    page   = 'ui/index.html',       -- a file in YOUR resource
    icon   = 'ui/icon.png',         -- a file in YOUR resource
    size   = { w = 1.1, h = 0.7 },  -- metres
    anchor = 'body',                -- 'body' follows you, 'world' stays put
})

if not ok then
    print(('registration failed: %s'):format(err))
end

Returns ok, err. Registration fails when the id already belongs to another resource — nobody gets to replace someone else’s window. There is no need to unregister on stop: RoadVr notices your resource going away and closes the window itself.

See it move.shutdown

Still in beta

RoadVr is still being worked on. Most of it stands, some of it can still stumble — and how smooth it feels comes down to your frame rate.

Beta buildBugs and odd behaviour are possible. Report what you run into — right now that is worth more than anything else you could do.
90 to 100+ FPSThe windows are redrawn with the game, so their steadiness is your frame rate. Below that they trail behind noticeably when you turn your head.

{{TODO: one line above the Discord button — what the visitor gets by joining}}

{{TODO: Discord button label, e.g. "Join the Discord"}}

{{TODO: optional line under the button — release timing, or what beta access means}}

Look at a window and press E to work with it. Everything here can be changed again in Settings.