YAVAPF/docs/gettingstarted.md
alterNERDtive 5b6db94bce documentation
plus some refactoring / added code on the way …
2022-07-11 01:46:42 +02:00

8.1 KiB
Raw Blame History

Getting Started

First off, you can see the Example plugin project on Github for reference.

Second off, this documentation assumes that you have at least cross read the section about plugins in the VoiceAttack manual. If any terminology is new to you, it is probably introduced there. Unlike said manual though this will provide step by step instructions to get your plugin set up.

Creating a Visual Studio Project

I am going to assume for this part of the documentation that you are using Visual Studio 2022 or later (not Visual Studio Code!) as your development environment. The Community Edition is free for unlimited time personal use.

VoiceAttack is a .Net Framework 4.8 application. Plugins targeting .Net 5+ or .Net Core will not work. I still recommend creating a .Net project instead of a .Net Framework project, then changing the “Target Framework” to .Net Framework 4.8. This allows you to use the full dotnet tool chain, which makes e.g. using Github Actions to build / release your project much less painful. Trust me, Ive done it both ways.

So, create a new “Class Library” project, then use a text editor to change the “TargetFrameworks” property to net48. While youre there you might also want to change the “LanguageVerison” to 10. Most new features are backwards compatible with .Net Framework. The compiler will assist you with errors for those that are not.

Adding YAVAPF as a Dependency

This one is the simple part, just install alterNERDtive.YAVAPF through NuGet. Done.

Alternatively you can add it manually by cloning github.com/alterNERDtive/YAVAPF.git as a git submodule and referencing VoiceAttack-Framework\VoiceAttack-Framework.csproj as a project reference.

But seriously, use NuGet. I havent taught myself how to release NuGet packages just for you to ignore it!

Adding VoiceAttack as a Dependency

This is a little more involved. In order to use the actual proxy classes from VoiceAttack instead of the “official” crutch of dynamic types, you will need to add an assembly reference to VoiceAttack.exe.

Right click → “Add” → “Assembly Reference…” → “Browse” → browse to the VoiceAttack installation folder → select VoiceAttack.exe → hit “Add” → make sure it is ticked in the list → hit “OK”.

Now, we want to reference VoiceAttack.exe, but we dont want to include it when compiling the plugin. So select “VoiceAttack” in “Dependencies” → “Assemblies” and make sure that both “Copy Local” and “Embed Interop Types” are set to “No”.

Distributing VoiceAttack.exe with your plugin would technically be a copyright violation. Do make sure to take the steps outlined in the last paragraph to prevent accidentally doing that! Using it as a reference assembly is generally OK and I have received confirmation from Gary, the author of VoiceAttack.

Setting Up Debugging Through VoiceAttack

In order to be able to run VoiceAttack when debugging and actually debug your plugin, you will need to open “Debug” → “<your project> Debug Properties”.

There you will need to “Create a new profile” → “Executable”. Set the path to your VoiceAttack executable and any command line options you might prefer. Personally I like to set a custom -datadir in order to not mess with my regular profile database accidentally.

The example plugin project has a Properties\launchSettings.sample.json file that you can copy to Properties\launchSettings.json and edit accordingly to accomplish the same thing.

The last thing youll need to do is make your plugin available to VoiceAttack in a place where it can find it. I have requested an equivalent -appdir parameter, but as long as that is not available you will need to have your plugin present inside the regular Apps folder of VoiceAttack. I recommend creating a directory junction (mklink /j, or New-Item -ItemType Junction in PowerShell) between an Apps subfolder and your projects debug output directory (usually <project name>\bin\Debug\net48 inside your solution folder).

Building Through Github Actions

If you, like me, want to automate building/testing/releasing through Github Actions, youll need to have VoiceAttack available while building on the worker. Obviously that will only work on a Windows worker.

I have created the alterNERDtive/setup-voiceattack-action to facilitate that. Usage example:

- name: Install VoiceAttack
  uses: alterNERDtive/setup-voiceattack-action
  with:
    version: "1.10"

Make sure that the path to VoiceAttack on your machine (which is the path referenced in the project file) matches the path where you install VoiceAttack on the worker! Alternatively, if you have installed VoiceAttack in a custom folder locally, you can create a symlink (mklink, or New-Item -ItemType SymbolicLink in PowerShell) to your VoiceAttack.exe location at C:\Program Files\VoiceAttack\VoiceAttack.exe and include that as the assembly reference.

Creating a Minimum Viable Plugin

A valid VoiceAttack plugin must implement a selection of public, static methods:

  • VA_DisplayName(): Must return the name of the plugin.
  • VA_DisplayInfo(): Must return the description of the plugin.
  • VA_Id(): Must return the GUID of the plugin.
  • VA_Init1(dynamic): Is executed when the plugin is loaded into VoiceAttack.
  • VA_Invoke1(dynamic): Is executed whenever a plugin context is run from a command.
  • VA_Exit1(dynamic): Is executed when VoiceAttack shuts down.
  • VA_StopCommand(): Is executed when VoiceAttack stops all commands, e.g. through the command action or main interface button.

When using YAVAPF these methods are to be passed straight to the corresponding methods of a VoiceAttackPlugin object that handles most things for you. It has a few required properties:

  • Name: The name of the plugin.
  • Version: The version of the plugin.
  • Info: The description of the plugin.
  • Guid: The GUID of the plugin.

All of those are strings for ease of use, though the Guid obviously has to be a valid string representation of a GUID. You can generate one using “Tools” → “Create GUID”. Make sure to select “Registry Format”.

For a YAVAPF plugin you will have to derive your plugin class from alterNERDtive.Yavapf.VoiceAttackPlugin. Since VoiceAttacks plugin API relies entirely on static methods, youll need to instantiate your plugin object in its static constructor and hold it in a static variable for future reference (no pun intended).

So a minimum viable plugin using YAVAPF looks kind of like this:

using System;

using alterNERDtive.Yavapf;

namespace YourNamespace
{
    public class YourPlugin : VoiceAttackPlugin
    {
        private static readonly YourPlugin Plugin;

        static YourPlugin()
        {
            Plugin = new ()
            {
                Name = "Your Plugin",
                Version = "0.0.1",
                Info = "This is a description",
                Guid = "{5E93F293-B2CB-4B3F-AFC5-AE500A7EEBA9}",
            };
        }

        public static string VA_DisplayName() => Plugin.VaDisplayName();

        public static string VA_DisplayInfo() => Plugin.VaDisplayInfo();

        public static Guid VA_Id() => Plugin.VaId();

        public static void VA_Init1(dynamic vaProxy) => Plugin.VaInit1(vaProxy);

        public static void VA_Invoke1(dynamic vaProxy) => Plugin.VaInvoke1(vaProxy);

        public static void VA_Exit1(dynamic vaProxy) => Plugin.VaExit1(vaProxy);

        public static void VA_StopCommand() => Plugin.VaStopCommand();
    }
}

Thats it! Technically youre done. Hit the debug button, and VoiceAttack should find your plugin on startup, report loading it in the event log, and list it under “Options” → “General” → “Plugin Manager”.

Of course you are only just getting started if you want your plugin to actually do something!