Add F4SE plugin template
Create a minimal Fallout 4 F4SE/CommonLibF4 starter repo with build, packaging, install, and rename scripts, plus initial plugin source, headers, and xmake configuration.
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = crlf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.{cpp,h,hpp}]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[*.lua]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
# IDE / editor
|
||||||
|
.cache/
|
||||||
|
.idea/
|
||||||
|
.vs/
|
||||||
|
.vscode/.cache/
|
||||||
|
|
||||||
|
# xmake
|
||||||
|
.xmake/
|
||||||
|
build*/
|
||||||
|
vs*/
|
||||||
|
compile_commands.json
|
||||||
|
|
||||||
|
# Visual Studio generated files
|
||||||
|
*.sln
|
||||||
|
*.vcxproj
|
||||||
|
*.vcxproj.filters
|
||||||
|
*.vcxproj.user
|
||||||
|
|
||||||
|
# Build output
|
||||||
|
*.obj
|
||||||
|
*.pdb
|
||||||
|
*.ilk
|
||||||
|
*.dll
|
||||||
|
*.lib
|
||||||
|
*.exp
|
||||||
|
*.exe
|
||||||
|
*.zip
|
||||||
|
|
||||||
|
# Local config
|
||||||
|
local.json
|
||||||
|
dev-config.json
|
||||||
|
|
||||||
|
# OS junk
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "ThirdParty/CommonLibF4"]
|
||||||
|
path = ThirdParty/CommonLibF4
|
||||||
|
url = https://github.com/libxse/commonlibf4.git
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 YourName
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -0,0 +1,199 @@
|
|||||||
|
# F4SEPluginTemplate
|
||||||
|
|
||||||
|
Minimal reusable Fallout 4 F4SE plugin template using CommonLibF4.
|
||||||
|
|
||||||
|
This template is intentionally lightweight. Add project-specific dependencies such as Ultralight, GameNetworkingSockets, ImGui, or custom SDKs inside each actual mod repo instead of adding them here.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Windows
|
||||||
|
- Visual Studio 2022 with C++ tools, or another MSVC/Clang-CL C++23 toolchain
|
||||||
|
- xmake 3.0.0 or newer
|
||||||
|
- Git
|
||||||
|
- Fallout 4 Script Extender installed for testing
|
||||||
|
|
||||||
|
## Create a new mod repo from this template
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git clone <your-template-repo-url> MyNewF4SEMod
|
||||||
|
cd MyNewF4SEMod
|
||||||
|
git submodule update --init --recursive
|
||||||
|
.\scripts\rename-template.ps1 -NewName "MyNewF4SEMod" -Author "YourName"
|
||||||
|
```
|
||||||
|
|
||||||
|
Then commit the renamed version as the starting point for the new mod.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
xmake build
|
||||||
|
```
|
||||||
|
|
||||||
|
The built plugin is copied to:
|
||||||
|
|
||||||
|
```text
|
||||||
|
package/F4SE/Plugins/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Generate Visual Studio project
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
xmake project -k vsxmake
|
||||||
|
```
|
||||||
|
|
||||||
|
## Package for mod managers
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\scripts\package.ps1 -OutputName "MyNewF4SEMod"
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates a zip with the expected layout:
|
||||||
|
|
||||||
|
```text
|
||||||
|
F4SE/Plugins/MyNewF4SEMod.dll
|
||||||
|
F4SE/Plugins/MyNewF4SEMod.pdb
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dev install to Fallout 4
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\scripts\install-dev.ps1 -Fallout4Path "C:\Program Files (x86)\Steam\steamapps\common\Fallout 4"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Repo layout
|
||||||
|
|
||||||
|
```text
|
||||||
|
src/ C++ plugin source
|
||||||
|
include/ Public/internal headers
|
||||||
|
ThirdParty/CommonLibF4/ CommonLibF4 submodule
|
||||||
|
package/ Staged mod-manager package output
|
||||||
|
scripts/ Helper scripts
|
||||||
|
```
|
||||||
|
## Optional Modules
|
||||||
|
|
||||||
|
This template intentionally keeps the base plugin minimal. Only add extra third-party modules when a specific mod needs them.
|
||||||
|
|
||||||
|
The recommended convention is to place optional dependencies in `ThirdParty/`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ThirdParty/
|
||||||
|
├─ CommonLibF4/
|
||||||
|
├─ xbyak/
|
||||||
|
├─ Ultralight-SDK/
|
||||||
|
├─ framework-F4-Conversion/
|
||||||
|
├─ spdlog/
|
||||||
|
└─ tomlplusplus/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Xbyak
|
||||||
|
|
||||||
|
Use Xbyak when the plugin needs low-level hook helpers, runtime assembly generation, trampoline work, or custom patching logic. Xbyak is a header-only x86/x64 JIT assembler library.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git submodule add https://github.com/herumi/xbyak.git ThirdParty/xbyak
|
||||||
|
git submodule update --init --recursive
|
||||||
|
```
|
||||||
|
|
||||||
|
Example `xmake.lua` include:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
add_includedirs("ThirdParty/xbyak", { public = true })
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ultralight SDK
|
||||||
|
|
||||||
|
Use Ultralight when the mod needs HTML/CSS/JavaScript-driven UI, such as a custom browser, server browser, launcher-like interface, or rich overlay. Ultralight is a GPU-accelerated HTML renderer with C and C++ support.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git submodule add <your-ultralight-sdk-repo-url> ThirdParty/Ultralight-SDK
|
||||||
|
git submodule update --init --recursive
|
||||||
|
```
|
||||||
|
|
||||||
|
Example `xmake.lua` include:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
add_includedirs("ThirdParty/Ultralight-SDK/include", { public = true })
|
||||||
|
```
|
||||||
|
|
||||||
|
Linking Ultralight usually requires additional `.lib` files and runtime `.dll` files. Keep those project-specific rather than adding them to the base template.
|
||||||
|
|
||||||
|
### framework-F4-Conversion
|
||||||
|
|
||||||
|
Use `framework-F4-Conversion` only for mods that depend on NomadsReach's Fallout 4 conversion/UI framework. This should not be required for normal F4SE plugins.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git submodule add https://github.com/NomadsReach/framework-F4-Conversion.git ThirdParty/framework-F4-Conversion
|
||||||
|
git submodule update --init --recursive
|
||||||
|
```
|
||||||
|
|
||||||
|
Example `xmake.lua` include:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
add_includedirs("ThirdParty/framework-F4-Conversion/include", { public = true })
|
||||||
|
```
|
||||||
|
|
||||||
|
Only wire this into the build once the mod actually uses it.
|
||||||
|
|
||||||
|
### spdlog
|
||||||
|
|
||||||
|
Use `spdlog` if the plugin needs more advanced logging than the default template logging setup, such as rotating logs, multiple sinks, custom formatting, or async logging.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git submodule add https://github.com/gabime/spdlog.git ThirdParty/spdlog
|
||||||
|
git submodule update --init --recursive
|
||||||
|
```
|
||||||
|
|
||||||
|
Example `xmake.lua` include:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
add_includedirs("ThirdParty/spdlog/include", { public = true })
|
||||||
|
```
|
||||||
|
|
||||||
|
### toml++
|
||||||
|
|
||||||
|
Use `toml++` if the plugin needs structured configuration files, for example:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Data/F4SE/Plugins/MyPlugin.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git submodule add https://github.com/marzer/tomlplusplus.git ThirdParty/tomlplusplus
|
||||||
|
git submodule update --init --recursive
|
||||||
|
```
|
||||||
|
|
||||||
|
Example `xmake.lua` include:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
add_includedirs("ThirdParty/tomlplusplus/include", { public = true })
|
||||||
|
```
|
||||||
|
|
||||||
|
### SimpleIni
|
||||||
|
|
||||||
|
Use SimpleIni for very small `.ini` configuration files. This is useful when the plugin only needs a few basic settings and a TOML parser would be overkill.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git submodule add https://github.com/brofield/simpleini.git ThirdParty/SimpleIni
|
||||||
|
git submodule update --init --recursive
|
||||||
|
```
|
||||||
|
|
||||||
|
Example `xmake.lua` include:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
add_includedirs("ThirdParty/SimpleIni", { public = true })
|
||||||
|
```
|
||||||
|
|
||||||
|
### fmt
|
||||||
|
|
||||||
|
Use `fmt` if the plugin needs standalone formatting utilities. Some logging libraries already include or depend on `fmt`, so avoid adding it separately unless the project directly needs it.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git submodule add https://github.com/fmtlib/fmt.git ThirdParty/fmt
|
||||||
|
git submodule update --init --recursive
|
||||||
|
```
|
||||||
|
|
||||||
|
Example `xmake.lua` include:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
add_includedirs("ThirdParty/fmt/include", { public = true })
|
||||||
|
```
|
||||||
Vendored
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace PluginName
|
||||||
|
{
|
||||||
|
inline constexpr auto NAME = "F4SEPluginTemplate";
|
||||||
|
inline constexpr auto VERSION = "0.1.0";
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]$Fallout4Path
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$root = Split-Path -Parent $PSScriptRoot
|
||||||
|
$plugins = Join-Path $root "package\F4SE\Plugins"
|
||||||
|
$target = Join-Path $Fallout4Path "Data\F4SE\Plugins"
|
||||||
|
|
||||||
|
New-Item -ItemType Directory -Force -Path $target | Out-Null
|
||||||
|
Copy-Item -Path (Join-Path $plugins "*") -Destination $target -Force
|
||||||
|
|
||||||
|
Write-Host "Installed plugin files to $target"
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
param(
|
||||||
|
[string]$OutputName = "F4SEPluginTemplate"
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$root = Split-Path -Parent $PSScriptRoot
|
||||||
|
$packageDir = Join-Path $root "package"
|
||||||
|
$outFile = Join-Path $root "$OutputName.zip"
|
||||||
|
|
||||||
|
if (Test-Path $outFile) {
|
||||||
|
Remove-Item $outFile -Force
|
||||||
|
}
|
||||||
|
|
||||||
|
Compress-Archive -Path (Join-Path $packageDir "*") -DestinationPath $outFile
|
||||||
|
Write-Host "Created $outFile"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]$NewName,
|
||||||
|
|
||||||
|
[string]$Author = "YourName"
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$root = Split-Path -Parent $PSScriptRoot
|
||||||
|
$files = Get-ChildItem -Path $root -Recurse -File | Where-Object {
|
||||||
|
$_.FullName -notmatch "\\\.git\\" -and
|
||||||
|
$_.FullName -notmatch "\\lib\\commonlibf4\\"
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($file in $files) {
|
||||||
|
$content = Get-Content $file.FullName -Raw
|
||||||
|
$content = $content.Replace("F4SEPluginTemplate", $NewName)
|
||||||
|
$content = $content.Replace("YourName", $Author)
|
||||||
|
Set-Content -Path $file.FullName -Value $content -NoNewline
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Renamed template references to $NewName"
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void MessageHandler(F4SE::MessagingInterface::Message* a_message)
|
||||||
|
{
|
||||||
|
if (!a_message) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (a_message->type) {
|
||||||
|
case F4SE::MessagingInterface::kGameLoaded:
|
||||||
|
REX::INFO("Game loaded");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
F4SE_PLUGIN_LOAD(const F4SE::LoadInterface* a_f4se)
|
||||||
|
{
|
||||||
|
F4SE::Init(a_f4se);
|
||||||
|
|
||||||
|
REX::INFO("F4SEPluginTemplate loaded");
|
||||||
|
|
||||||
|
const auto messaging = F4SE::GetMessagingInterface();
|
||||||
|
if (messaging) {
|
||||||
|
messaging->RegisterListener(MessageHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <RE/Fallout.h>
|
||||||
|
#include <F4SE/F4SE.h>
|
||||||
|
#include <REX/REX.h>
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
using namespace std::literals;
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
-- F4SEPluginTemplate
|
||||||
|
-- Minimal reusable Fallout 4 F4SE plugin template using CommonLibF4.
|
||||||
|
|
||||||
|
includes("ThirdParty/CommonLibF4")
|
||||||
|
|
||||||
|
set_project("F4SEPluginTemplate")
|
||||||
|
set_version("0.1.0")
|
||||||
|
set_license("MIT")
|
||||||
|
set_languages("c++23")
|
||||||
|
set_warnings("allextra")
|
||||||
|
|
||||||
|
add_rules("mode.debug", "mode.releasedbg")
|
||||||
|
add_rules("plugin.vsxmake.autoupdate")
|
||||||
|
|
||||||
|
target("F4SEPluginTemplate")
|
||||||
|
add_rules("commonlibf4.plugin", {
|
||||||
|
name = "F4SEPluginTemplate",
|
||||||
|
author = "YourName",
|
||||||
|
description = "Fallout 4 F4SE plugin template using CommonLibF4"
|
||||||
|
})
|
||||||
|
|
||||||
|
add_files("src/**.cpp")
|
||||||
|
add_headerfiles("src/**.h")
|
||||||
|
add_headerfiles("include/**.h")
|
||||||
|
add_includedirs("src", "include")
|
||||||
|
set_pcxxheader("src/pch.h")
|
||||||
|
|
||||||
|
after_build(function (target)
|
||||||
|
local outdir = path.join(os.projectdir(), "package", "F4SE", "Plugins")
|
||||||
|
os.mkdir(outdir)
|
||||||
|
os.cp(target:targetfile(), outdir)
|
||||||
|
|
||||||
|
local pdb = path.join(target:targetdir(), target:basename() .. ".pdb")
|
||||||
|
if os.isfile(pdb) then
|
||||||
|
os.cp(pdb, outdir)
|
||||||
|
end
|
||||||
|
end)
|
||||||
Reference in New Issue
Block a user