Skip to content

Query and Load

Ryan edited this page May 7, 2019 · 8 revisions

Plugin Entry Point

SKSE calls your plugin via two exported functions - SKSEPlugin_Query and SKSEPlugin_Load. These are the entry points for your plugin and you can consider them equivalent to int main().

  • Query

The query passes two arguments:

  1. SKSEInterface: This is the SKSE interface which gives you access to the functionality that SKSE provides.
  2. PluginInfo: This is a plugin info structure which contains fields relating to info about your plugin, and it is your responsibility to fill these fields out. These fields are as follows:
    • infoVersion: Fill this out with the version of PluginInfo your plugin was compiled with (i.e. PluginInfo::kInfoVersion).
    • name: Fill this out with the name of your plugin (i.e. "MyFirstPlugin"). Note that this is a pointer, and is non-owning. Be sure that the data it points to is always valid.
    • version: Fill this out with the version of your plugin (i.e. 42). It can be anything you want, so long as you understand how to interpret it.

The main purpose of the query is to determine if your plugin can safely load. During the query, you should fill out the plugin info structure, check if your plugin is compatible with the current executable, and return a boolean indicating if your plugin can be safely loaded. You should do nothing else during this phase.

  • Load

The load passes one argument:

  1. SKSEInterface: This is the SKSE interface which gives you access to the functionality that SKSE provides.

The load is when your plugin is free to do whatever it wants: query the interface, apply hooks, register callbacks, etc. Finish by returning a boolean indicating if your plugin loaded successfully. Note that because of the nature of code injection, you aren't driving the executable. Your code must act in response to events. This also means that you can't rely on stack allocated memory if you wish to store persistent data. When your functions are done executing, they'll pop off the stack, and your local variables will be lost. If you want data to persist beyond the scope it's allocated in, you'll need to allocate it on the heap, and access it via statically declared variables. You can read other sections to learn how to leverage assembly hooks and callbacks to inject your code into the executable, and perform the tasks you want.

CommonLib Extensions

CommonLib wraps the SKSE API in an easy to use interface that enables the use of modern C++ features, such as lambdas. The SKSE::Init function, accessed using #include "SKSE/API.h", acquires and stores all SKSE interfaces for the user, eliminating the need for awkward extern juggling between files. A basic template plugin written for CommonLib demonstrates how to handle the basic query and load functions. Note that SKSEInterface has been split into two classes, SKSE::QueryInterface and SKSE::LoadInterface, so as to prevent authors from doing more than they should during the query function. Member access has also been wrapped into member functions, which prevents authors from accidentally corrupting SKSE's exported types.

Clone this wiki locally