An unofficial BepInEx mod that adds head tracking to PEAK via OpenTrack. Look around naturally with your head while your aim stays independent.
- Decoupled look + aim: Look around freely with your head while your crosshair stays where you're aiming
- 6DOF head tracking: Full rotation (yaw, pitch, roll) and positional tracking via OpenTrack UDP protocol
- PEAK (Steam)
- OpenTrack or a compatible head tracking app (smartphone, webcam, or dedicated hardware)
- Windows 10/11 (x64)
- Download the latest release from the Releases page
- Extract the ZIP anywhere
- Double-click
install.cmd - Configure OpenTrack to output UDP to
127.0.0.1:4242 - Launch the game
The installer automatically finds your game via Steam registry lookup. If it can't find the game:
- Set the
PEAK_PATHenvironment variable to your game folder, or - Run from command prompt:
install.cmd "D:\Games\PEAK"
If you prefer to install manually or the installer doesn't work for you:
- Install BepInExPack_PEAK into your game folder:
- Download and extract the archive
- Copy the contents of the
BepInExPack_PEAKfolder to your game root (wherePeak.exelives) — this includeswinhttp.dll,doorstop_config.ini, and theBepInExfolder
- Download the Nexus release ZIP (the one ending in
-nexus.zip) - Extract it into your game folder — the DLLs will land in
BepInEx/plugins/:PeakHeadTracking.dllCameraUnlock.Core.dllCameraUnlock.Core.Unity.dll
- Configure your tracker to output UDP to
127.0.0.1:4242 - Launch the game
- Download and install OpenTrack
- Configure your tracker as input
- Set output to UDP over network
- Host:
127.0.0.1, Port:4242 - Start tracking before launching the game
No special hardware needed — OpenTrack's built-in neuralnet tracker uses any webcam for 6DOF face tracking.
- In OpenTrack, set the input to neuralnet tracker
- Select your webcam in the tracker settings
- Set output to UDP over network (
127.0.0.1:4242) - Start tracking before launching the game
- Recenter in OpenTrack via its hotkey, and press Home in-game to recenter the mod as needed
This mod includes built-in smoothing for network jitter on positional tracking (Remote Smoothing, default 0.15), so you can send directly from your phone on port 4242 without needing OpenTrack on PC. Rotation is not smoothed by that setting; it is interpolated between tracker samples by the PoseInterpolator, which also absorbs uneven packet timing.
- Install an OpenTrack-compatible head tracking app
- Configure it to send to your PC's IP on port 4242 (run
ipconfigto find it) - Set the protocol to OpenTrack/UDP
With OpenTrack (optional): If you want curve mapping or visual preview, route through OpenTrack. Set OpenTrack's input to "UDP over network" on a different port (e.g. 5252), output to 127.0.0.1:4242, and point your phone at port 5252. Make sure your firewall allows incoming UDP on the input port.
Two equivalent binding sets - use whichever your keyboard has:
| Action | Nav-cluster | Chord |
|---|---|---|
| Recenter | Home |
Ctrl+Shift+T |
| Toggle tracking | End |
Ctrl+Shift+Y |
| Cycle tracking mode | Page Up |
Ctrl+Shift+G |
| Toggle yaw mode | Page Down |
Ctrl+Shift+H |
Page Up / Ctrl+Shift+G cycles tracking mode:
- Normal head-tracked gameplay
- Positional tracking disabled, rotational tracking enabled
- Rotational tracking disabled, positional tracking enabled
- Back to normal
The mod creates a config file at BepInEx/config/com.cameraunlock.peak.headtracking.cfg on first run.
The section headers are numbered ([01. Connection], [02. General], and so
on) so they sort in a sensible order. The numbers are part of the section name:
a setting written under [Connection] instead of [01. Connection] is in a
section the mod never looks at, and it silently keeps its default.
A comment has to sit on its own line. BepInEx splits each line at the first =
and takes everything after it as the value, so a trailing # note becomes part
of the value, the conversion fails, and the entry silently keeps its default -
the only trace is a line in BepInEx/LogOutput.log. Put explanations above the
key, never after it.
[01. Connection]
# Must match OpenTrack output port (1024-65535)
UDP Port = 4242
# Seconds before reconnection attempt (1-60)
Reconnect Timeout = 5
# Max packets to buffer (10-500)
Packet Buffer Size = 100
[02. General]
# Start with tracking enabled
Tracking Enabled = true
# Enable lean/positional tracking (6DOF)
Position Enabled = true
# Play sounds for tracking state changes
Enable Audio Feedback = true
# Move the crosshair to the real aim point while head tracking is active
Show Reticle = true
# true = horizon-locked yaw (default), false = camera-local yaw
World Space Yaw = true
[03. Sensitivity]
# Horizontal rotation (0.1-5.0)
Yaw Sensitivity = 1.0
# Vertical rotation (0.1-5.0)
Pitch Sensitivity = 1.0
# Head tilt (0.1-5.0)
Roll Sensitivity = 1.0
Invert Yaw = false
Invert Pitch = false
Invert Roll = true
# Lateral sensitivity (0.0-5.0)
Position Sensitivity X = 2.0
# Vertical sensitivity (0.0-5.0)
Position Sensitivity Y = 2.0
# Depth sensitivity (0.0-5.0)
Position Sensitivity Z = 2.0
# Max lateral offset in meters (0.01-0.5)
Position Limit X = 0.30
# Max vertical offset in meters (0.01-0.5)
Position Limit Y = 0.20
# Max forward offset in meters (0.01-0.5)
Position Limit Z = 0.40
# Max backward offset in meters (0.01-0.5)
Position Limit Z Back = 0.10
[04. Rotation Limits]
# Clamp pitch rotation
Enable Pitch Limits = true
# Max look-down angle (-90 to 0)
Minimum Pitch = -85
# Max look-up angle (0 to 90)
Maximum Pitch = 85
# Enable head tilt
Enable Roll = true
# Clamp roll rotation
Enable Roll Limits = true
# Max tilt angle (0-90)
Maximum Roll = 30
[05. Smoothing]
# Both values apply to positional tracking only. Rotation is not smoothed by them:
# the rotation path skips the smoothing stage and relies on the PoseInterpolator,
# which interpolates between tracker samples to fill in frames.
# Tracker on this machine (loopback), 0 = none, 1 = heavy
Local Smoothing = 0.0
# Tracker on a remote network device, 0 = none, 1 = heavy
Remote Smoothing = 0.15
[06. Deadzone]
# Ignore small movements near center
Enable Deadzone = false
# Yaw deadzone in degrees (0-10)
Yaw Deadzone = 0
# Pitch deadzone in degrees (0-10)
Pitch Deadzone = 0
# Roll deadzone in degrees (0-10)
Roll Deadzone = 0
[07. Hotkeys]
Toggle Tracking = End
Recenter View = Home
Toggle Position = PageUp
Yaw Mode Key = PageDown
# Re-read the config file and restart the UDP listener. Only UDP Port takes
# effect this way; sensitivity, limits, deadzones and smoothing are read once at
# startup and need a game restart
Reload Config = F12
# Present in the file but not wired up in this version; changing it does nothing
Toggle Reticle = Insert
[08. Advanced]
# Enable detailed debug logging
Debug Logging = false
# Target update rate in Hz (30-120)
Update Rate = 60
Maintain Relative Position = true
# Prevents seeing through player model during head bob (0.01-0.5)
Near Clip Override = 0.15Game crashes on startup after installing BepInEx:
- PEAK requires the BepInExPack_PEAK build (ships with a PEAK-specific doorstop). Our
install.cmddownloads this automatically. - If the game crashes on startup, add
-force-vulkanto your Steam launch options (game Properties > General > Launch Options) to bypass DX12
Mod not loading:
- Check
BepInEx/LogOutput.logfor errors - Ensure all three DLLs are in
BepInEx/plugins/:PeakHeadTracking.dll,CameraUnlock.Core.dll,CameraUnlock.Core.Unity.dll - Verify
winhttp.dllis in the game folder
No tracking response:
- Verify OpenTrack is running and outputting data
- Check UDP port matches (default 4242)
- Press End to enable tracking, Home to recenter
- Check firewall isn't blocking UDP port 4242
A config edit had no effect:
- Make sure nothing follows the value on the line. A trailing
# commentis read as part of the value, the entry falls back to its default, and the game gives no sign of it.BepInEx/LogOutput.logrecords the failed conversion.
Jittery movement:
- For jittery leaning (positional tracking), increase
Remote Smoothingfor a phone or other network device, orLocal Smoothingfor a tracker running on this PC, with nothing after the value on the line. These two values do not affect rotation jitter - Enable deadzones in the
[06. Deadzone]section - Improve lighting for webcam-based tracking
Yaw feels wrong when looking up or down at extreme angles:
- Try toggling between world-locked and camera-local yaw with
Page Down. World-locked (default) is horizon-stable; camera-local follows the camera's current up-axis.
Download the new release and run install.cmd again.
Run uninstall.cmd from the release folder. This removes the mod DLLs. BepInEx is only removed if it was originally installed by this mod. To force-remove BepInEx:
uninstall.cmd /force
git clone --recurse-submodules https://github.com/itsloopyo/peak-headtracking.git
cd peak-headtracking
# Build and install to game
pixi run install
# Build only
pixi run build
# Package for release
pixi run package| Task | Description |
|---|---|
pixi run build |
Build the mod (Release configuration) |
pixi run install |
Build and install to game directory |
pixi run uninstall |
Remove the mod from the game |
pixi run uninstall -- --force |
Remove the mod and BepInEx |
pixi run package |
Create release ZIPs |
pixi run clean |
Clean build artifacts |
pixi run release |
Version bump, build, tag, and push |
- Discord: Loop's Head Tracking Hangout - setup help, bug reports, and new-release announcements
- Lopari - free Windows launcher with one-click install and launch for the released head-tracking mods
- Headcam - free app that turns your iPhone or Android phone into the head tracker
MIT License - see LICENSE for details.
- Aggro Crab / Landfall - PEAK
- BepInEx - Unity modding framework
- OpenTrack - Head tracking software
- Harmony - Runtime patching library
This mod is not affiliated with, endorsed by, or supported by Aggro Crab Games or Landfall. Use at your own risk.