-
Notifications
You must be signed in to change notification settings - Fork 0
Timeline Web Remote
Remote control for the Action Timeline via a built-in HTTP server and browser UI.
- Open Action Timeline in Studio.
- Click Web in the toolbar to start the server (default port 5077).
- Click Open or visit the shown URL from any device on your LAN (e.g.
http://192.168.1.42:5077/).
The server stops when you click Web Stop or close Studio. With "autoStart": true in config, it also starts automatically when Studio loads.
Configuration Manager (BepInEx): section Timeline · Web Remote
| Setting | Meaning |
|---|---|
| Auto-start server | Start the web server when Studio loads |
| Port | HTTP port (default 5077) |
| Bind address |
+ = all interfaces / LAN; 127.0.0.1 = localhost only |
| TLS enabled | HTTPS with auto self-signed cert (for playit.gg etc.) |
| TLS port | HTTPS listen port (default 5443) |
| TLS public host | Domain shown in Open URL (e.g. yourname.playit.plus) |
| TLS certificate hostnames | Comma-separated SANs for the cert |
| TLS only (disable HTTP) | Skip plain HTTP when TLS is on |
| Auth disabled | No access token required |
| Access token | Shared secret for ?token=; empty = auto-generate on first start |
Changes are mirrored to timeline_web.json. Studio Live presets stay JSON-only.
File: BepInEx/config/com.hs2.sandbox/timeline_web.json
{
"port": 5077,
"bind": "0.0.0.0",
"token": "your-secret-here",
"autoStart": false,
"studio": {
"defaultMode": "live",
"preset": "medium",
"presets": {
"low": { "width": 640, "height": 360, "fps": 2, "jpegQuality": 55 },
"medium": { "width": 854, "height": 480, "fps": 5, "jpegQuality": 65 },
"high": { "width": 1280, "height": 720, "fps": 8, "jpegQuality": 75 }
}
}
}| Field | Meaning |
|---|---|
bind |
0.0.0.0 = LAN; 127.0.0.1 = localhost only |
token |
When empty, a random token is auto-generated on first Web start and saved to this file |
authDisabled |
Set true for open LAN access without a token (no auto-generation) |
autoStart |
Set true to start the web server when Studio loads (no Web click needed) |
On first Web click with no config / empty token, the plugin generates a URL-safe token, saves it here, and logs it to the BepInEx console. Use the Open button — it opens the URL with ?token= already appended.
To use a custom token, set "token": "your-secret" before starting the server. To disable auth entirely:
{ "authDisabled": true, "token": "" }| Tab | Purpose |
|---|---|
| Dashboard | Live display-window cards (same values as in-game Display commands) |
| Studio Live | MJPEG preview, Screenshot-Follow, or on-demand snapshot |
| Timeline | Full run control + command list editing |
| Variables | Timeline and global variables |
| Log | Live BepInEx/LogOutput.log (auto-refresh while tab is open) |
- Live (MJPEG) — low-FPS viewport capture while the tab is open (no capture when tab is hidden).
-
Screenshot-Follow — shows the last file written by a Timeline
screenshotcommand (zero GPU cost between shots). - Snapshot — one high-res frame on demand.
Requires ScreenshotManager for Screenshot-Follow.
When token is set in config, pass it as:
- Header:
X-Timeline-Token: your-secret - Header:
Authorization: Bearer your-secret - Query:
?token=your-secret
The web UI stores the token from the URL in localStorage when you open http://host:5077/?token=....
The plugin can serve HTTPS directly (no Caddy/nginx) using an auto-generated self-signed certificate. Browsers show a one-time security warning unless you trust the cert; this is fine for personal remote use (e.g. playit.gg HTTPS tunnels).
File: BepInEx/config/com.hs2.sandbox/timeline_web.json
{
"port": 5077,
"bind": "127.0.0.1",
"token": "your-secret-here",
"tls": {
"enabled": true,
"port": 5443,
"bind": "127.0.0.1",
"httpDisabled": true,
"plainHttpOnly": true,
"publicHost": "yourname.playit.plus",
"hostnames": ["yourname.playit.plus", "localhost"]
}
}| Field | Meaning |
|---|---|
tls.enabled |
Start HTTPS listener |
tls.port |
HTTPS port (point playit tunnel here, e.g. 5443) |
tls.bind |
Usually 127.0.0.1 when playit agent runs on the same PC |
tls.httpDisabled |
When true, plain HTTP on port is not started |
tls.plainHttpOnly |
Keep true for playit — Unity cannot run a local TLS server (SSPI errors). playit terminates HTTPS; this port receives plain HTTP only |
tls.publicHost |
Shown in Open URL and logs (your playit domain) |
tls.hostnames |
DNS names in the certificate; changing this regenerates the cert |
Certificate files: timeline_web_tls.pfx and timeline_web_tls.meta.json in the same config folder.
Configuration Manager (BepInEx): section Timeline · Web Remote — TLS enabled, TLS port, public host, hostnames.
Restart the web server after changing TLS settings.
playit terminates HTTPS at the edge and must forward plain HTTP to tls.port. Unity/Mono cannot terminate TLS locally (UNITYTLS_INTERNAL_ERROR / SSPI). The plugin listens on plain HTTP only (plainHttpOnly: true, default).
- Config:
tls.enabled: true,tls.plainHttpOnly: true,tls.httpDisabled: true, setpublicHostto your.playit.plusdomain. - Start Timeline Web server — log should say
tunnel listening on http://127.0.0.1:5443/ (plain HTTP for playit.gg). - playit HTTPS tunnel → local port 5443, origin HTTP (not TLS passthrough to local).
- Open
https://yourname.playit.plus/?token=….
If you see "received TLS bytes on plain-HTTP port", playit is forwarding encrypted TLS instead of HTTP — change the tunnel's local/origin protocol to HTTP in the playit dashboard.
Alternatively, keep HTTP on port 5077 and terminate TLS with Caddy or nginx on another machine or the same PC.
timeline.example.com {
reverse_proxy 192.168.1.42:5077
}
server {
listen 443 ssl;
server_name timeline.example.com;
# ssl_certificate ...;
location / {
proxy_pass http://127.0.0.1:5077;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Timeline-Token "your-secret";
proxy_buffering off; # important for MJPEG / SSE
}
}Set proxy_buffering off for /api/studio/mjpeg and /api/events so streams are not delayed.
First run with bind: 0.0.0.0 may prompt to allow StudioNEOV2.exe on private networks.
| Endpoint | Method | Description |
|---|---|---|
/api/status |
GET | Server info |
/api/dashboard |
GET | Display cards |
/api/events |
GET | SSE live updates |
/api/studio/mjpeg |
GET | MJPEG stream |
/api/studio/screenshot-latest |
GET | Last screenshot file |
/api/timeline |
GET | Commands + validation |
/api/timeline/run |
GET/POST | Run state / start stop pause |
/api/variables |
GET/PUT | Timeline variables |
/api/globals |
GET/PUT | Persistent globals |
/api/log |
GET | Full log (text/plain); ?offset=N for append tail; headers X-Log-Offset, X-Log-Truncated
|
- Record Keys/Mouse commands cannot be recorded from the browser.
- Mouse cross overlay is IMGUI-only; web toggles the flag.
- Studio Live shows the game viewport; plugin IMGUI windows appear in the image.
- Overview
- Folders & library
- Search, filters & sort
- Grid & selection
- Pose groups
- Multi-character apply
- Pose stash
- Pose items
- Import/export ZIP
- Thumbnails
- Options & data