vr_setup(3)

πŸ“¦
version 0.7.1 Β· 2 versions
, in nixos 26.05

πŸ’… vr_setup β€” Arcan Lua API, bestie

Okay so this is vr_setup(3) from the Arcan Lua API, and it's literally the launch button for VR device support. Buckle up πŸŽ€


✨ NAME ✨

vr_setup β€” launch the VR bridge so your VR devices can, like, actually exist 🌈


πŸ¦‹ SYNOPSIS πŸ¦‹

nil
vr_setup( string:args, func:callback )
vr_setup( func:callback )

πŸ’– DESCRIPTION πŸ’–

So here's the tea β˜•: VR support is managed through an external service that you launch with this function. In principle it works just like a normal frameserver, except it's got some special semantics and a whole different engine code path for interpreting events and stuff. iykyk.

"VR" here is a big umbrella β€” like, a huge assortment of devices. These include but are absolutely not limited to:

  • Haptic Gloves 🧀
  • Haptic Suites
  • Eye/Gaze Trackers πŸ‘€
  • Positional Devices
  • Inside/Out trackers
  • Motion Capture Systems

And they may expose separate video/audio devices too (hi, front-facing camera πŸ“Έ).

The framework gets launched and controlled with this function, and other system changes come through the status table. For any of this to work though, the auxiliary vrbridge tool needs to be built β€” and ngl, it's not in the default engine compilation path β€” and then the binary has to be explicitly added to the arcan appl namespace of the active database. Like so:

arcan_db add_appl_kv arcan ext_vr /path/to/vrbridge

The optargs is a normal arcan_arg packed string (key=value:key2) with bridge-specific arguments (for now, anyway). The test argument gives you a virtual object and a test limb to play with. Oh, and heads up πŸ™ˆ β€” the user arcan is running as will need to be able to access USB devices for most real hardware backends to work. No USB access, no vibes.

The whole system is built around limbs appearing and disappearing, where a limb is a mapped and tracked 3d model bound to a vid β€” and that vid can be used like literally any normal vid. The only caveat? Updating position and orientation happens automatically behind the scenes, which is the whole point: it keeps latency and CPU load down πŸ”₯.

The possible status.kind field values are:

  • limb_added β€” a new limb was discovered ✨
  • limb_removed β€” a previously added limb was lost (device failure) πŸ’€

For both limb_added and limb_removed, these subfields are present:

  • id β€” a value to use with vr_map_limb
  • name β€” a textual representation of the limb slot that was consumed

The possible values for name are, and I'm quoting the whole squad here:

(person, neck, eye-[left,right], shoulder-[left,right], elbow-[left,right], wrist-[left,right], [thumb,pointer,middle,ring,pinky]-[proximal,middle,distal]-[left,right], hip-[left,right], knee-[left,right], ankle-[left,right], tool-[left,right]

The limb for the neck actually represents the head mounted device itself. Once this limb has appeared, it's safe to query display properties via hmd_metadata. And in contrast to the other limbs, this slot can be mapped twice β€” that's how you account for both viewpoints you need when setting up the pipe. Unmapping the limb by setting it to BADID will drop both slots at once 🫢.

The limb for the abstract person defines the coordinate system that all the others reference, and it's typically important when there's a positional tracking system in play. The reason it isn't bound to the limb-skeleton as such? Cost. Keeping it separate keeps the cost down for resolving hierarchies πŸ’Έ.

Lowkey important: this system does not actually control the displays themselves. They're expected to appear and be managed with the same system as normal dynamic display hotplugging β€” so the display_enabled event should act as your trigger to rescan for new monitors πŸ‘‘

🌸 EXAMPLE 🌸

function vr_setup0()
      vr_setup("test", function(source, status)
            print(status.kind)
      end);
end

πŸŽ€ SEE ALSO πŸŽ€

iodev


Alright bestie, that's the whole page πŸ’œ Go forth and track those limbs. This iconic little doc is from vr_setup(3) in the Arcan Lua API, dated October 2026, and it's sourcing from iodev β€” slay, periodt πŸ’…βœ¨

πŸ“¦ where this page comes from