{"id":13780327,"url":"https://github.com/DeviantdVeloper/ButtplugUE","last_synced_at":"2025-05-11T13:31:56.610Z","repository":{"id":205611080,"uuid":"705513562","full_name":"DeviantdVeloper/ButtplugUE","owner":"DeviantdVeloper","description":"Buttplug UE is a plugin for the Unreal Engine that implements the Buttplug.io framework for controlling a wide range of external devices and other peripherals directly from your game.","archived":false,"fork":false,"pushed_at":"2024-11-15T13:40:55.000Z","size":1065,"stargazers_count":9,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-11-15T14:32:23.623Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DeviantdVeloper.png","metadata":{"files":{"readme":"README.MD","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-16T06:54:42.000Z","updated_at":"2024-11-03T00:15:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"bc6e5efe-c25b-4ba1-83a2-adb513e1b8be","html_url":"https://github.com/DeviantdVeloper/ButtplugUE","commit_stats":null,"previous_names":["deviantdveloper/buttplugue"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeviantdVeloper%2FButtplugUE","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeviantdVeloper%2FButtplugUE/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeviantdVeloper%2FButtplugUE/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeviantdVeloper%2FButtplugUE/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DeviantdVeloper","download_url":"https://codeload.github.com/DeviantdVeloper/ButtplugUE/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225056802,"owners_count":17414212,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T18:01:14.559Z","updated_at":"2024-11-17T15:31:07.107Z","avatar_url":"https://github.com/DeviantdVeloper.png","language":"C++","readme":"# Buttplug UE\n\n![ButtplugUE Icon](./Resources/Icon128.png)\n\nAn Unreal Engine integration for the [Buttplug.io](https://buttplug.io/) framework.\n\nIf you use this in your project(s), please consider supporting its continued development on my [Patreon](https://www.patreon.com/DeviantdVeloper) or [SubscribeStar](https://subscribestar.adult/deviant-dveloper).\n\n---\n\n## Projects Using this Plugin\n\nLet me know if you want your project featured here!\n\n## Overview\n\nButtplug UE is a plugin for the Unreal Engine that implements the [Buttplug.io](https://buttplug.io/) framework for controlling a wide range of *external devices* and other peripherals directly from your game.\n\nIt provides both a Blueprint and a C++ interface (via a [Game Instance Subsystem](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Engine/Subsystems/UGameInstanceSubsystem?application_version=5.3)) which allows you to directly manage individual devices, as well as providing basic support for \"fire-and-forget\" device commands.\n\nTested with Intiface Central v2.6.4+30\n\n### Supported Engine Versions\n\n| Engine | Supported        | Notes                               |\n| ------ | ---------------- | ----------------------------------- |\n| \u003c= 5.0 | No               |                                     |\n| 5.1    | Deprecated       | Check Releases, No Example Content  |\n| 5.2    | Deprecated       | Check Releases                      |\n| 5.3    | Yes              | No Example Content (check releases) |\n| 5.4    | Yes              |                                     |\n| 5.5    | Yes              |                                     |\n\n### Supported Platforms\n\n| Platform | Supported | Notes       |\n| -------- | --------- | ----------- |\n| Windows  | Yes       | 64bit Only  |\n| Android  | Yes       |             |\n| Linux    | Probably  | Let me know |\n| OSX      | Probably  | Let me know |\n| iOS      | Probably  | Let me know |\n\n### Architecture\n\nButtplug.io and this plugin work through the [Intiface Central](https://intiface.com/central/) application, like so:\n\n```mermaid\nflowchart LR;\n\nDevice-1\u003c--\u003eIntiface-Central;\nDevice-2\u003c--\u003eIntiface-Central;\nDevice-3\u003c--\u003eIntiface-Central;\nIntiface-Central\u003c--\u003eButtplugUE;\n\n```\n\nThis way Intiface handles all the troublesome work of identifying, querying, and controling the devices, and ButtplugUE simply requests information about the devices, which tells it how to pass along commands. All communication between Unreal and Intiface is through a [Websocket](https://docs.unrealengine.com/5.0/en-US/API/Runtime/WebSockets/) via JSON formatted messages.\n\nOn the Unreal end, we handle this through a [Game Instance Subsystem](https://docs.unrealengine.com/5.0/en-US/programming-subsystems-in-unreal-engine/), which means a connection to the Intiface server is persistent throughout the gameplay session, between map changes and more.\n\nInformation about Devices is handled in the form of Structs; this plugin makes heavy use of the [Struct Utils](https://docs.unrealengine.com/5.1/en-US/API/Plugins/StructUtils/) plugin to simplify the serialization and deserialization of information coming in and out of Intiface.\n\nThe storing and handling of persistent device information is not included in this plugin at this time; this functionality is left to you, the developer, to implement as-needed for your specific use-case.\n\nIt is highly recommended to familiarize yourself with the [Buttplug.io specs](https://buttplug-developer-guide.docs.buttplug.io/docs/spec) to have a better understanding of how the different messages and commands work.\n\n### Basics\n\nFirst you will want to initialize the connection to Intiface\n\n![Calling the Connect node on the BPDeviceSubsystem](./Docs/Images/ConnDisconnIsConn.png)\n\nAfter this you should check if the connection was successful. And of course remember to Disconnect upon closing your game.\n\nOnce you are connected you can tell the server to start, then stop scanning for devices, and then request a list of devices:\n\n![Requesting devices from the server](./Docs/Images/ScanningAndDeviceList.png)\n\nNote that the response is an Instanced Struct, and you have to manually tell it what struct type you are looking for, much like casting.\n\nThis can be circumvented by binding to the appropriate delegate/callback on the subsystem *prior* to making the request. This way you will recieve a correctly typed struct every time.\n\n![Binding to the response to requesting devices from the server](./Docs/Images/BoundDeviceList.png)\n\nFinally, you can now send commands to  the devices in question. Each device struct outlines what commands they are compatible with, and as such you can use this information to know what type of command to send.\n\n![Sending commands to devices](./Docs/Images/SendCommands.png)\n\nThis is a single command, and as such you will also need to tell it when to stop; sending a strength of 0 or using one of the Stop commands will achieve this.\n\n![Sending stop commands to devices](./Docs/Images/StopCommands.png)\n\nThese functions behave as you would expect: stopping a given device, or stopping all devices (wise to do on quit, close, exit, etc). They optionally also can either ignore or include currently ongoing Pattern Commands, as these are handled locally in the plugin.\n\nA simpler approach is to use the \"Pattern Command\"\n\n![Sending pattern commands to devices](./Docs/Images/SendPatternCommands.png)\n\nThese pattern commands take a Duration and a Float Curve as arguments. The Curve dictates the strength and will loop for the duration, self-ending. These essentially sample the given curve at the set rate, sending updates to the device per-update.\n\n### Example Procedure\n\nThe basic flow of interacting with a device, from start to end, is:\n\n```mermaid\nsequenceDiagram\n\n    participant Device-1\n    participant Intiface-Central\n    participant ButtplugUE\n\n    Intiface-Central-\u003e\u003eIntiface-Central:Starts Server\n    ButtplugUE-\u003e\u003eButtplugUE:Launches\n    ButtplugUE-\u003e\u003eIntiface-Central:Connects\n    ButtplugUE-\u003e\u003eIntiface-Central:Request Start Scanning\n    Intiface-Central-\u003e\u003eIntiface-Central:Starts Scanning\n    Intiface-Central-\u003e\u003eDevice-1:Finds Device 1\n    Device-1-\u003e\u003eIntiface-Central:Sends Information\n    Intiface-Central-\u003e\u003eButtplugUE:Device 1 Added\n    ButtplugUE-\u003e\u003eIntiface-Central:Request Stop Scanning\n    Intiface-Central-\u003e\u003eIntiface-Central:Stops Scanning\n    ButtplugUE-\u003e\u003eIntiface-Central:Sends Command for Device 1\n    Intiface-Central-\u003e\u003eDevice-1: Sends Command\n    Device-1-\u003e\u003eDevice-1:Executes Command\n    \n```\n\nAs you can see, this means that all communication to and from ButtplugUE is with Intiface Central, whether it is looking for devices, getting information about them, or sending commands.\n\n## Quick Start\n\nFor the fastest start simply open the `Debug_P` map in the ButtplugUE content folder and play it. This will bring up an on-screen UI that will allow you to connect to and manipulate connected devices through Intiface. The UI itself can be found in the UI folder of the plugin's content where you can see how it, and its sub-components, do the things it does.\n\nBy default, the ButtplugUE plugin will automatically attempt to connect to a locally running Intiface instance at the default address and port (`127.0.0.1:12345`) so launch Intiface and start it with the defaults and on launch your Unreal instance should connect. Check the log (category `LogButtplugUE`) for messages confirming as such.\n\nYou can change these settings in `Project Settings \u003e Plugins \u003e ButtplugUE Settings`. You can also connect to Intiface instances running on the local network, assuming you have a basic network environment; you are not limited to the same machine it is running on.\n\nNext you will want to get a list of devices. This can be achieved either by telling Intiface to start (and stop) scanning via the normal Intiface GUI or by sending the appropriate commands via the `BPDeviceSubsystem`. You can send either `Start Scanning` or `Get Device List`.\n\nThe former will start Intiface scanning for devices, where as the latter will return a list of previously found devices. To receive the responses you will need to either bind to the `Response` delegate from the `RequestDeviceList` function, or bind to the `OnDeviceAddedResponse` delegate in `BPDeviceSubsystem`, as after you start scanning you will get a `DeviceAdded` message after each new device is found and registered with Intiface, and you will need to send the `StopScanning` command afterwards.\n\nNow that you have a list of devices to choose from, you can send an appropriate command. Each device will have a list of `Scalar`, `Linear`, and `Rotate` commands based on what kind of action the device supports. Simply send the appropriate type of command and your device should respond appropriately.\n\nButtplugUE closes it's connection with Intiface when play ends, but you can also manually disconnect (and reconnect) through the Subsystem if desired.\n\n## Planned Features\n\nThe following are features that are not yet implemented, but will be at a later date.\n\nIn no particular order:\n\n- Sensor Support.\n- Pre-programmed device commands, eg pulsing, ramping, fire-and-forget durations. `Intial Implementation Done`\n    - Custom curve support. `Somewhat Implemented`\n- Further abstraction from command types, simplified developer front-end.\n- Double check if there are any replication implications from using `UGameInstanceSubsystem` (spoiler, there are).\n    - This might mean moving (or duplicating) the behaviour to a `UObject`, thereby making replication the responsibility of you, the developer.\n\n## Further Reading\n\n- [Buttplug.io Specs](https://buttplug-developer-guide.docs.buttplug.io/docs/spec)\n- [Unreal Engine Subsystems](https://docs.unrealengine.com/5.0/en-US/programming-subsystems-in-unreal-engine/)\n- [Unreal Engine Struct Utils](https://docs.unrealengine.com/5.1/en-US/API/Plugins/StructUtils/)\n\n## Support \u0026 Supporting\n\nIf you use this in your project(s), please consider supporting its continued development on my [Patreon](https://www.patreon.com/DeviantdVeloper) or [SubscribeStar](https://subscribestar.adult/deviant-dveloper), as well as that of the official [Buttplug.io](https://www.patreon.com/qdot) development.\n\nYou can contact me here, on [Bluesky](https://bsky.app/profile/ddev.games), or Discord (\\_ddev\\_).\n","funding_links":["https://www.patreon.com/DeviantdVeloper","https://www.patreon.com/qdot"],"categories":["Development and Libraries"],"sub_categories":["Game Development"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDeviantdVeloper%2FButtplugUE","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FDeviantdVeloper%2FButtplugUE","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDeviantdVeloper%2FButtplugUE/lists"}