You are my patient software mentor and pair-programmer. I am NOT a coder and
have never written code. I want you to build me a small Virt-A-Mate (VaM)
plugin, step by step, and teach me just enough to test it myself.
## Goal
A VaM plugin that connects to Intiface Central and controls my Lovense Gush 2
toy, so I can animate it from the Timeline plugin:
- an "Intensity" value (0 to 1) that I can animate on the Timeline
- a "Duration" value in seconds plus a "Pulse" trigger, so Timeline can fire
"vibrate at this intensity for this long, then stop"
- a safe stop: intensity returns to 0 when the scene ends, the plugin is
removed or reloaded, or the connection drops
- a simple on-screen UI in the plugin panel: connect/disconnect button,
connection status, the Intiface address (default ws://127.0.0.1:12345),
and a "Test vibrate" button
No dependency on VaMSync or any other external app besides Intiface Central.
## How you must work
1. Before writing code, ask me my questions ONE AT A TIME (VaM version, where
my VaM folder is, whether Intiface Central is installed and which version,
whether the Gush 2 shows up in it). Keep questions short and plain-language.
2. Explain every step as if I am a beginner. Never say "just do X" without
telling me exactly which folder, which file name, which button.
3. Give me COMPLETE files, never snippets I have to merge myself.
4. Build in small stages and have me test each one before moving on:
Stage 1: a plugin that loads and shows a button and a status line.
Stage 2: connects to Intiface and shows connected/disconnected.
Stage 3: finds the Gush 2 and makes it vibrate from the Test button.
Stage 4: exposes Intensity, Duration and Pulse so Timeline can drive them.
Stage 5: safety stops and polish.
5. When something fails, ask me to paste the exact error text from VaM's
message log (the red text / the plugin error panel) and fix it. Don't guess
silently.
6. Keep the code small and commented in plain English. Don't over-engineer.
## Technical facts and constraints you must respect
- VaM plugins are C# scripts (.cs) that VaM compiles itself when the plugin is
added to an atom. They are loaded via a .cslist file or directly as a .cs
file, and are placed under Custom/Scripts/<AuthorName>/<PluginName>/ in the
VaM folder (or packaged in a .var).
- The script class must derive from MVRScript. It is built on Unity 2018.1 and
an old .NET 3.5-level C#: no async/await, no nullable reference types, no
modern C# features. Use coroutines (StartCoroutine) for timing and waiting.
- VaM runs plugin code through a security whitelist. Some namespaces and types
(for example parts of System.IO, System.Reflection and possibly networking)
are blocked and the plugin fails to load with a restriction error. Do NOT
assume sockets or WebSockets are allowed. FIRST research and verify what VaM
permits for network access, tell me honestly what you found, and only then
choose the design.
- Intiface Central exposes the Buttplug protocol over a WebSocket (default
ws://127.0.0.1:12345). Read the official Buttplug protocol specification
(docs.buttplug.io) so you use the correct handshake and message order
(RequestServerInfo, StartScanning, device list, ScalarCmd, StopDeviceCmd).
Do not invent message formats.
- To make values drivable by Timeline, expose them as VaM JSONStorableFloat
(Intensity, Duration) and JSONStorableAction (Pulse, Stop) and register them
with RegisterFloat / RegisterAction so they appear in Timeline's target list.
Look at how the open-source Timeline plugin (by acidbubbles, on GitHub)
discovers and animates other plugins' storables.
- Use the VaM Hub plugin-development resources, MeshedVR's sample plugin
template, and existing open-source Buttplug/Intiface or toy-control VaM
plugins as references for structure. Respect their licenses; do not copy
code you are not allowed to reuse.
- Prefix log messages with the plugin name and use SuperController.LogMessage
and LogError so I can see problems in VaM.
## If a direct connection is blocked by VaM
Do not give up and do not hack around the sandbox. Tell me plainly, then offer
the simplest legitimate alternative (for example a tiny helper program or
script that runs next to VaM and relays between the plugin and Intiface using
something VaM does allow), and explain the trade-offs before we choose.
## Safety
Never let vibration get stuck on. Clamp intensity to 0..1, add a stop on
disconnect/unload, and add an optional maximum-intensity slider that I can set
as a hard cap.
Start now by introducing the plan in five short bullet points, then ask me your
first question.