To get started, use the Starter Kit.
By default, a log file is created for your plugin, based on its plugin name.
My Games\Skyrim Special Edition\SKSE\<your plugin name>.log
To write to the log file, use:
logger::trace()
logger::debug()
logger::info()
logger::warn()
logger::error()
logger::critical()
You can pass fmt
formatted strings:
logger::info(
"{}'s form ID in hexadecimal is {:x}",
baseObject->GetName(),
baseObject->GetFormID()
);
If you want to customize the filename of the log without changing the name of your SKSE mod:
#include <SkyrimScripting/Plugin.h>
PluginLogFileName("Butts.log");
// Or customize the full system path:
PluginLogFullPath("C:\\logs\\butts.log");
// By default, we do NOT support logging to the Debug Console
// whenever a debugger is attached. To enable that feature:
PluginLogToDebugConsole;
// Or totally disable lots, entirely.
PluginLogDisable;
OnInit { ... }
Want to log to the ~
game console?
ConsoleLog("Hello, world!");
It supports fmt
formatting, just like logger
:
ConsoleLog(
"{}'s form ID in hexadecimal is {:x}",
baseObject->GetName(),
baseObject->GetFormID()
);
Note: the console is not available for logging until
OnDataLoaded
or after.
Specify code that should run on certain SKSE event:
#include <SkyrimScripting/Plugin.h>
OnInit {
logger::info("I run immediately, as soon as the plugin is loaded");
}
OnDataLoaded {
logger::info("Data loaded! Now I have access to all of the forms in the game");
}
OnNewGame {
logger::info("Oh, hey! A new game was created!");
}
The following callback macros are available:
Timing | SKSE Event | |
---|---|---|
OnPluginLoad OnInit |
Runs immediately, as soon as the SKSE plugin is loaded. | n/a |
OnPluginsLoaded |
Runs as soon as all SKSE plugins have been loaded. It can be preferable to run code here, as any code run in OnInit may run before other SKSE plugins have loaded. |
kPostLoad |
AfterPluginsLoaded |
Runs immediately after OnPluginsLoaded . Infrequently used, but can be useful for coordinating messaging with other plugins. |
kPostPostLoad |
OnLoadingGame |
Runs before the savegame is loaded by Skyrim.TODO: provide a way to get the size/path of the .ess save game |
kPreLoadGame |
OnLoadedGame |
Runs after the savegame has been loaded by Skyrim.TODO: provide a way to get whether load was successful |
kPostLoadGame |
OnSaveGame |
Runs when saving a game | kSaveGame |
OnDeleteGame |
Runs when deleting a game | kDeleteGame |
OnNewGame |
Runs after a new game has been created, but before the game has loaded | kNewGame |
OnInputLoaded |
Runs after the game's input initializes, right before the Main Menu initializes | kInputLoaded |
OnDataLoaded OnFormsLoaded |
Runs after all of the game mods have been loaded (all Forms are loaded) | kDataLoaded |
If you really want to provide your own SKSEPluginLoad
, just make sure to call SkyrimScripting::Plugin::Initialize()
.
SKSEPluginLoad(const SKSE::LoadInterface *skse) {
SKSE::Init(skse);
// Your code
// Note: this is where OnInit { ... } code runs
SkyrimScripting::Plugin::Initialize();
// Your code
return true;
}
This will:
- Initialize the log
- Run the
OnInit
handlers
⚠️ Note: CallingPlugin::Initialize()
will register a SKSE message listener.
You will no be able to *also*SKSE::GetMessagingInterface()->RegisterListener()
.
Game events are events like RE::TESActivateEvent
and RE::TESHitEvent
and more.
If you want to find out whenever one of these events happens in the game:
#include <SkyrimScripting/Plugin.h>
EventHandlers {
On<RE::TESActivateEvent>([](const RE::TESActivateEvent* event) {
auto activator = event->actionRef->GetBaseObject()->GetName();
auto activated = event->objectActivated->GetBaseObject()->GetName();
logger::info("{} activated {}", activator, activated);
});
// Basically:
On<TheEventType>([](const TheEventType* event) {
// Then, in here, you can do things with the event.
// The `event` will store fields about the event.
});
}
To find events, I recommend searching CommonLibSSE for files with
TES*Event
in their names.
- Visit this link: https://github.com/CharmedBaryon/CommonLibSSE-NG
- Press the
T
key to open the fuzzy find file search- Type
TESEvent
- Choose any of the files that show up! They're probably events that you can get via an event sink 😸
Note: not all events have defined structures. You want to find ones which have their own files defined.
That's all... for now!