Difference between revisions of "Getting Started with SKSE Plugin Development"

From the CreationKit Wiki
Jump to navigation Jump to search
imported>Scrivener07
m (Added categories.)
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
The Skyrim Script Extender (SKSE) is a tool that expands scriptings capabilities and adds additional functionality to the game, as well as allowing modders to create plugins to further extend Skyrim's scripting capacities. SKSE plugins take form as DLLs files that implement new functions into Papyrus, Creation Kit's scripting language. As you may guess, making an SKSE plugin is more difficult than a standard mod but the benefits of doing one are far greater. This guide focus on implementing new functions into Papyrus Scripting and debugging them.
[SKSE64 2.2.6 Revision]


This page is actually in progress and doesn't provide a complete tutorial on how to make an SKSE plugin project.  With any progression on our side will come further upgrade. Until then, be assured that everything that has already been laid out is correct and up-to-date.
The Skyrim Script Extender (SKSE) is a tool that enhances the capabilities of [[Papyrus]] scripts and adds additional functionality to the game, as well as allowing modders to create plugins to further extend Skyrim's scripting capacities. SKSE plugins take form as .DLL files that usually implement new functions into Papyrus, Creation Kit's scripting language. As you may guess, making an SKSE plugin is more difficult than using Papyrus, but you are free of many limitations that Papyrus has, and using C++ might improve performance dramatically where comparable.
 
== Sources ==
These are related sources that have inspired this guide. Please note that the instructions may differ from one source to another and that some might simply be completely wrong/outdated.
 
* [http://forums.bethsoft.com/topic/1496168-wipz-skyrim-script-extender-skse/page-4#entry23595441 Zartar's "noob tutorial" on Bethesda's old forum.]  The whole discussion may contain other helpful information too.
* [https://github.com/Ryan-rsm-McKenzie/CommonLibSSE/wiki Ryan-rsm-McKenzie's Tutorial on GitHub]. However, his tutorial doesn't include a solution for the C2039 errors when compiling with modern SDK.
* [https://www.reddit.com/r/skyrimmods/comments/bmg1z7/finally_aiming_for_my_first_skse_plugin_been/ This Reddit discussion]
* [https://github.com/xanderdunn Xanderdunn's GitHub], which includes material related to Skyrim32.
 
Credit goes to Bethesda, the SKSE Team, Ryan and every contributor of this page.


== Requirements ==
== Requirements ==
* Skyrim Special Edition
* Skyrim Special Edition
* [https://skse.silverlock.org/ SKSE for Skyrim SE] (Also referred as SKSE64), which you should already have installed.
* [https://skse.silverlock.org/ SKSE for Skyrim SE] (Also referred to as SKSE64), which you should already have installed.
* SKSE64 source code which is included in the SKSE64 distribution (In the '''src/''' folder)
* [https://visualstudio.microsoft.com/ Visual Studio 2022 Build Tools]. You don't need to install the entire IDE if you won't use it.
* A template SKSE Plugin.  [https://github.com/Ryan-rsm-McKenzie/CommonLibSSE/wiki Ryan's Tutorial] provide one.
*An IDE like Visual Studio, VS Code or CLion. [[User:Xieve|xieve]] recommends using CLion if you have not used Visual Studio before, as it will manage installation of vcpkg automatically, among other things.
* [https://visualstudio.microsoft.com/vs/ Visual Studio 2019], but you can use an earlier version if you wish.
* And most importantly, you need to know C/C++ programming and have a good understanding of memory management.


To eliminate any potential trouble, be sure to have Windows, SKSE and Skyrim Special Edition up-to-date. Please keep in mind that this guide does not guarantee backward/forward compatibility.
Ensure that your Windows and SKSE installations are up-to-date. If Skyrim Special Edition has not received an update in the previous week or so, you will want that up-to-date too. See the official SKSE page to see which version is currently supported. Please keep in mind that this guide does not guarantee backward/forward compatibility, and things keep breaking in unforeseen ways.


== C++ Toolset compatibility ==
== Setup ==
As you will notice in the following section, SKSE uses an earlier version of the 'Visual C++ platform toolset', the 2015 version. According to the SKSE team, using this version is safer because it's the same Bethesda used to build SSE, and compatibility cannot be ensured for every version. In other words, you can build SKSE with a later version of the toolset but the outcome might not work once loaded into SSE.
The easiest and recommended approach is to use a template plugin. [https://github.com/Monitor221hz/CommonLibSSE-NG-Template-Plugin This one] is currently (as of 2024-11-16) recommended for CommonLibSSE-NG. [https://commonlib.dev/ See here] for a comparison of the different CommonLibSSE versions.


While testing for such incompatibility, SKSE 2.0.15 re-targeted and built with VS2019 (and it's toolkits) successfully ran on the corresponding SSE runtime, 1.5.73. That alone doesn't fully guarantee cross-version-compatibility and builds made with newer SDK might break as SKSE implements new features. Also, remember that running ''DOES NOT'' equal stable and retargeted SKSE builds can bear unseen and niche compatibility problems.
Follow the documentation that the template plugin of your choice provides, it will be more up-to-date and applicable than any external resource.


This guide will try to use the latest version of all the mentioned programs. If you don't feel comfortable using the latest versions or want to use a different one, don't worry; each step can be performed in any version of Visual Studio.


Without further ado, let's set up the environment.
Should you want to, you can set environment variables inside <code>CMakeLists.txt</code> like so:
set(ENV{VARIABLE_NAME} "Variable value")
For example:
set(ENV{SKYRIM_MODS_FOLDER} "C:\\Games\\MO2\\mods")


== Setups ==
== Making a plugin ==
Before making a plugin, you need to set up the environment.
As of 2024-11-16, there is no definitive resource on SKSE plugin modding.  


=== Retargeting and building SKSE ===
These are related sources that have inspired this guide. Please note that the instructions may differ from one source to another and that some might simply be completely wrong/outdated.
To make a plugin we'll first need SKSE's source code. However, SKSE was made with an earlier version of Visual Studio and still use outdated toolsets that aren't available within VS2019. Therefore additional setups must be performed.
* [https://github.com/Ryan-rsm-McKenzie/CommonLibSSE/wiki Ryan-rsm-McKenzie's Tutorial on GitHub]. Most notably, includes documentation for debugging setup and CommonLibSSE's Papyrus API.
# Within the SKSE zip files obtained from [https://skse.silverlock.org/ the official website] locate and extract the '''src/''' directory.
*[https://github.com/ianpatt/skse64 The original SKSE64 source code on GitHub], which, in contrast to CommonLibSSE, '''has comments'''! You should definitely check this out as it is probably the best documentation you will find. I recommend cloning (downloading) this repository and checking it out in your IDE so you can search it more easily.
# Open the SKSE64 solution '''src/skse64/skse64.sln''' with Visual Studio 2019. VS2019 should already be associated with the .sln file type.
*[https://skyrim.dev/skse Skyrim.dev - SKSE]
# Upon loading, you'll be prompted with the option to "Permanently remove source control association bindings". The SKSE team uses what is called "Source control", which is a way to share, update and checkout codes coming from multiple users. We won't (and can't) use their source control so we can permanently remove any source control association. [https://imgur.com/95b5KXK (image)]
*[https://commonlib.dev/ Unofficial auto-generated documentation for CommonLibSSE, CommonLibVR and CommonLibSSE-NG]
# Just after that, a new window will appear and suggest to Retarget the Projects. The default options should be good enough and you can press '''"Ok"'''. [https://imgur.com/jnyPSWk (image)]
*[https://discord.gg/d96UKrKead MrowrPurr's Discord]. You can ask SKSE- or Papyrus-related questions here.
#; Why is that?
*[http://forums.bethsoft.com/topic/1496168-wipz-skyrim-script-extender-skse/page-4#entry23595441 Zartar's "noob tutorial" on Bethesda's old forum.]  The whole discussion may contain other helpful information too.
#: The SKSE project is made with an earlier version of the Visual C++ platform toolset. It's good development practice to keep your project's component up-to-date and, hopefully, Visual Studio can take care of that itself. However, some more configuration will be needed to successfully build the solution.
* [https://www.reddit.com/r/skyrimmods/comments/bmg1z7/finally_aiming_for_my_first_skse_plugin_been/ This Reddit discussion on weird errors while trying to set up a plugin template]
# Open the Property Pages for all projects.
#: We're gonna tweak some options within the Configuration Properties.
#: You can do so by selecting all projects within the solution explorer (Tip: select the first element and then the last one while holding '''SHIFT''' ) and press '''ALT'''+'''ENTER''' to open the Property Pages.
#: Also make sure that the '''Configuration''' field is set to '''All Configuration''', as we want them to apply for Debbuging as well as releasing.
## Disable post-build events
##: The project files include post-build events that we don't want (Such as automatically moving files into Skyrim's directory).
##: To disable post-build events, navigate to '''Build Events => Post-Build Event''' and change the '''Use in build''' field to '''No'''.
## Set the C++ Language Standard
##: Navigate to '''C/C++ => Language''' and set '''C++ Language Standard''' to '''ISO C++17 Standard (/std:c++17)'''.
## Force-include <string>
##: At this point, any attempt to build the solution will fail and there will be many errors [https://imgur.com/9jpNjtK (image)], with the most predominant one being <q>C2039: 'string' is not a member of 'std'</q>. In other words, many files are using the 'string' class without including the required header to do so.
##: You can fix this without manually adding #include directives by instead navigating to '''C/C++ => Advanced''' and adding "string" (without quotation) in the '''Force Include File''' field. This will automatically include the string header whenever it's required.
## Click "Apply" and then "Ok". [https://imgur.com/4DWpnzP (Image)]


SKSE should be ready to build. To test that, build the solution with the Release configuration. If no error occurs, congratulation! We can move on to the next section.
==== Testing the build ====
This section is optional and aims to further validate our home-built SKSE by testing it.
Assuming you already have SKSE installed, go ahead and replace the original files from the Skyrim SE directory with the new ones located in '''src/skse64/x64/Release'''. The files to replace are:
* '''skse_(version).dll''',
* '''skse_loader.exe''' and
* '''skse64_steam_loader.dll'''.
After replacing them, try to run '''skse_loader.exe'''. Skyrim should launch without any issues.
Note: Hypothetically, an SKSE built with updated configurations may give better performance than the default one provided by the SKSE team, but as explained in the "C++ Toolset compatibility" section, the opposite may also be true.
== Making a plugin ==
'''Be aware:''' SKSE Plugin cannot override or extends already existing script. In other words, consider an ''"ObjectReference"'' object and a ''"newMethod(<parameters>)"'' function you want to implement as an interaction of ''ObjectReference''. You won't be able to implement ''ObjectReference.newMethod(<parameters>)''. Instead, you can create a new ''"NewWrapperScript"'' object and implement ''NewWrapperScript.newMethod(ObjectReference, <parameters>)''.


At this point, we should start making the actual plugin. You can follow [https://github.com/Ryan-rsm-McKenzie/CommonLibSSE/wiki Ryan's Tutorial] while this page is being written.
Generally, SKSE plugin development heavily depends on a good IDE that allows you to browse the SKSE and CommonLibSSE sources, and on reading other people's source code on GitHub.  


If you chose to use CLion, navigate to <code><Project Directory>\build\debug-msvc\vcpkg_install\vcpkg\pkgs\commonlibsse-ng_x64-windows-skse</code>, right-click it and select <code>Mark directory as</code>→ <code>Library Files</code>. Now, when you hit shift twice to invoke Search Everywhere, all the CommonLibSSE symbols will show up in your search!


=== Implementing new methods ===
SKSE Plugin cannot override or extend already existing Form classes. In other words, consider an ''"ObjectReference"'' object and a ''"newMethod(<parameters>)"'' function you want to implement as an interaction of ''ObjectReference''. You won't be able to implement ''ObjectReference.newMethod(<parameters>)''. Instead, you can create a new ''"MyScript"'' object and implement ''MyScript.newMethod(ObjectReference, <parameters>)''.
[[Category:SKSE]]
[[Category:SKSE]]

Revision as of 13:47, 16 November 2024

[SKSE64 2.2.6 Revision]

The Skyrim Script Extender (SKSE) is a tool that enhances the capabilities of Papyrus scripts and adds additional functionality to the game, as well as allowing modders to create plugins to further extend Skyrim's scripting capacities. SKSE plugins take form as .DLL files that usually implement new functions into Papyrus, Creation Kit's scripting language. As you may guess, making an SKSE plugin is more difficult than using Papyrus, but you are free of many limitations that Papyrus has, and using C++ might improve performance dramatically where comparable.

Requirements

  • Skyrim Special Edition
  • SKSE for Skyrim SE (Also referred to as SKSE64), which you should already have installed.
  • Visual Studio 2022 Build Tools. You don't need to install the entire IDE if you won't use it.
  • An IDE like Visual Studio, VS Code or CLion. xieve recommends using CLion if you have not used Visual Studio before, as it will manage installation of vcpkg automatically, among other things.

Ensure that your Windows and SKSE installations are up-to-date. If Skyrim Special Edition has not received an update in the previous week or so, you will want that up-to-date too. See the official SKSE page to see which version is currently supported. Please keep in mind that this guide does not guarantee backward/forward compatibility, and things keep breaking in unforeseen ways.

Setup

The easiest and recommended approach is to use a template plugin. This one is currently (as of 2024-11-16) recommended for CommonLibSSE-NG. See here for a comparison of the different CommonLibSSE versions.

Follow the documentation that the template plugin of your choice provides, it will be more up-to-date and applicable than any external resource.


Should you want to, you can set environment variables inside CMakeLists.txt like so:

set(ENV{VARIABLE_NAME} "Variable value")

For example:

set(ENV{SKYRIM_MODS_FOLDER} "C:\\Games\\MO2\\mods")

Making a plugin

As of 2024-11-16, there is no definitive resource on SKSE plugin modding.

These are related sources that have inspired this guide. Please note that the instructions may differ from one source to another and that some might simply be completely wrong/outdated.


Generally, SKSE plugin development heavily depends on a good IDE that allows you to browse the SKSE and CommonLibSSE sources, and on reading other people's source code on GitHub.

If you chose to use CLion, navigate to <Project Directory>\build\debug-msvc\vcpkg_install\vcpkg\pkgs\commonlibsse-ng_x64-windows-skse, right-click it and select Mark directory asLibrary Files. Now, when you hit shift twice to invoke Search Everywhere, all the CommonLibSSE symbols will show up in your search!

Implementing new methods

SKSE Plugin cannot override or extend already existing Form classes. In other words, consider an "ObjectReference" object and a "newMethod(<parameters>)" function you want to implement as an interaction of ObjectReference. You won't be able to implement ObjectReference.newMethod(<parameters>). Instead, you can create a new "MyScript" object and implement MyScript.newMethod(ObjectReference, <parameters>).