shire Docs
Docs/Plugin API/Getting started

Getting Started

Requirements

  • Shire 1.14 or newer (the build that contains Plugin API 1.0).
  • The interpreter for your language:
    • Python 3.10+ for language: "python";
    • Node.js 18+ for language: "node"/"typescript";
    • .NET 8 runtime/SDK for language: "dotnet";
    • Rust or MSVC for language: "executable" compiled plugins.
  • Python is also used by the shire-plugin developer CLI.

Five-minute Python plugin

From the Shire repository:

python tools\shire-plugin\shire_plugin.py init `
  --lang python `
  --name "My First Plugin" `
  --id com.example.myplugin `
  --dir C:\dev\my-plugin

The generated project contains:

my-plugin/
  manifest.json
  main.py
  shire_sdk.py

main.py creates a plugin, logs a line, shows a notification, adds a text and a button to the Plugin Manager, and runs the event loop.

Edit main.py, then test it against the standalone mock Host. No Genshin session is needed:

cd C:\dev\my-plugin
python C:\path\to\Shire-main\tools\shire-plugin\shire_plugin.py test .

The CLI starts shire_mock_host.exe, reads the pipe/token it prints, launches your plugin as a child process with the SHIRE_PLUGIN_* variables, and reports whether it stayed connected.

Pack the plugin:

python C:\path\to\Shire\tools\shire-plugin\shire_plugin.py pack .

That writes my-plugin.shiremod, a stored ZIP with manifest.json at the root and the Python SDK bundled.

Install in Shire

  1. Open Shire's menu.
  2. Open Config and click Plugins → Open Plugin Manager, or press F9.
  3. Click Install .shiremod and choose the package.
  4. Select the plugin. Its declared permissions are listed. Approve the ones it needs with the checkboxes or Approve all.
  5. Tick Enabled. The Host launches the plugin process and waits for its handshake.

The plugin's UI appears in the same manager window. The plugin can show notifications, read storage and subscribe to events.

Manifest

{
  "id": "com.example.myplugin",
  "name": "My First Plugin",
  "version": "1.0.0",
  "author": "Developer",
  "description": "Example Shire plugin",
  "apiVersion": "1.0",
  "language": "python",
  "entrypoint": "main.py",
  "permissions": ["player.read", "ui.create", "notifications.show"]
}

The id must be unique and stable. The Host stores the plugin under %LOCALAPPDATA%\Shire\plugins\<id> and keeps its settings in data/storage.json.

First useful plugin: player position

from shire_sdk import Plugin

plugin = Plugin()
position = plugin.player_position()
plugin.set_ui([
    plugin.text("Player", "title"),
    plugin.text(f"X {position['x']:.1f}", "x"),
    plugin.text(f"Y {position['y']:.1f}", "y"),
    plugin.text(f"Z {position['z']:.1f}", "z"),
    plugin.button("refresh", "Refresh"),
])


def on_ui(component, kind, value):
    if component == "refresh":
        p = plugin.player_position()
        plugin.set_ui([
            plugin.text("Player", "title"),
            plugin.text(f"X {p['x']:.1f}", "x"),
            plugin.text(f"Y {p['y']:.1f}", "y"),
            plugin.text(f"Z {p['z']:.1f}", "z"),
            plugin.button("refresh", "Refresh"),
        ])


plugin.on_ui_event(on_ui)
plugin.run()

Set "permissions": ["player.read", "ui.create"] and approve both in the manager. The Host returns copies of numbers; the plugin never receives a game pointer.

Development loop

  • shire-plugin test <dir> runs one launch against the mock Host.
  • shire-plugin dev <dir> keeps the mock Host alive; use it while iterating.
  • shire-plugin validate <dir> checks the manifest and entrypoint.
  • shire-plugin build <dir> builds TypeScript, Rust, C++ or C# projects.
  • shire-plugin pack <dir> creates .shiremod.
  • shire-plugin init --lang ... generates a new project.

The production Plugin Manager shows plugin logs. The mock Host writes a local debug log at %TEMP%\shire_host_debug.log (mock builds only).

Shire Plugin API 1.0 · Written in English. Documentation home · API status · Changelog

Independent project. Not affiliated with HoYoverse. Never put secrets in a plugin, manifest or package.