Skip to content

PenguinToast/DynamicArmorVariants-Extended

 
 

Repository files navigation

Framework for mods to define armor variants by swapping armor addons dynamically at runtime.

Dynamic Armor Variants Extended

Dynamic Armor Variants Extended is a fork of the original Dynamic Armor Variants by Parapets, extended with new features/native API.

Runtime compatibility intentionally stays close to the original project:

  • plugin name remains DynamicArmorVariants.dll
  • save data code remains compatible with the original DAV plugin
  • config loading still uses Data/SKSE/Plugins/DynamicArmorVariants

Changes 100% vibecoded with Codex

Updates From Original DAV

  • Added a public SKSE messaging API for native integrations.
  • Added support for registration/deletion of new variants at runtime.
  • Added support for replacement identifiers that specify both owning armor and armor addon.
    • This lets variants render in completely disjoint slots from the original armor, so long as the actor doesn't have a conflict
  • Added caching around variant resolution for minor performance improvements.

Config Format

Variant replacement maps support two replacement identifier forms:

  • Plugin.esp|AddonLocalID
    • Replaces with that ARMA and keeps the source armor as the default owner.
  • Plugin.esp|ArmorLocalID|Plugin.esp|AddonLocalID
    • Replaces with that ARMA and explicitly supplies the owning ARMO to use while visiting the addon.

This applies to values in both replaceByForm and replaceBySlot, and to arrays of those values.

Variants may also define an optional integer priority in the range -1000000 to 1000000.

  • Higher priority wins when multiple condition-active variants compete.
  • Manually applied variant overrides still always take precedence over condition-based resolution.

Example:

{
  "priority": 10,
  "replaceByForm": {
    "Skyrim.esm|0010D6A1": [
      "Dragonborn.esm|0001C655|Skyrim.esm|00027DE4",
      "Skyrim.esm|00027DE5"
    ]
  }
}

Requirements

  • xmake
  • Visual Studio 2022 with Desktop development with C++

Setup

git submodule update --init --recursive

Build

From Windows:

xmake f -y -m release
xmake build -y

From WSL:

./scripts/build.sh

The plugin DLL is produced under build/windows/x64/<mode>/DynamicArmorVariants.dll.

Build And Deploy

To build from WSL and deploy into the pt_test MO2 modlist:

./scripts/build-deploy.sh
./scripts/build-deploy.sh --clean
./scripts/build-deploy.sh debug

By default this deploys to /mnt/f/games/skyrim/modlists/pt_test/mods/Dynamic Armor Variants Extended. Set MOD_DIR to override the destination. The default deploy mode is releasedbg, so the script also deploys DynamicArmorVariants.pdb when available. Use ./scripts/build-deploy.sh release for a stripped release build.

The deploy step copies the built DLL, the repository data/ tree, and compiled Papyrus output.

Build And Package

To build a release archive:

./scripts/build-package.sh

For the full WSL build, deploy, packaging, tag, and GitHub release workflow, see docs/Build-Deploy-Release.md.

This writes a zip under dist/ named like: Dynamic Armor Variants Extended v1.1.0.zip

For a real release package, keep the worktree clean and put a semver tag like v1.7.1 on HEAD. Otherwise scripts/version.sh will emit a dev version string and the archive name will include the -dev+<sha> suffix.

The release package includes:

  • a FOMOD installer layout compatible with the original DAV package structure
  • DynamicArmorVariants.dll
  • DynamicArmorVariants.pdb
  • compiled Papyrus .pex
  • Papyrus source .psc

Lint And Format

./scripts/format.sh
./scripts/format.sh --check
./scripts/lint.sh
./scripts/lint.sh src/main/DynamicArmorManager.cpp

From WSL, format.sh prefers Linux clang-format when available. lint.sh prefers the Visual Studio LLVM x64 clang-tidy.exe because the generic Visual Studio Llvm/bin binary is a 32-bit build that crashes in this environment.

lint.sh also passes /Y- to disable MSVC PCH use during linting. xmake's generated compile_commands.json points clang-tidy at a PCH path that does not exist, so disabling PCH is the reliable way to lint these translation units.

Public API

Dynamic Armor Variants Extended exposes a versioned SKSE messaging API for native integrations.

Public consumer files:

  • include/DynamicArmorVariantsExtendedAPI.h
  • include/DynamicArmorVariantsExtendedAPI.cpp

Fetch the interface after SKSE::MessagingInterface::kPostLoad:

auto* dav = DynamicArmorVariantsExtendedAPI::GetDynamicArmorVariantsExtendedInterface001();

Interface 001 exposes:

  • RegisterVariantJson(name, variantJson)
  • DeleteVariant(name)
  • SetVariantConditionsJson(name, conditionsJson)
  • RefreshActor(actor)
  • ApplyVariantOverride(actor, variantName, keepExistingOverrides = false)
  • RemoveVariantOverride(actor, variantName)

RegisterVariantJson expects the same JSON object shape as a single entry in the variants array from the config files. If the variant already exists, it is fully overwritten.

SetVariantConditionsJson accepts either:

  • a raw JSON array of condition strings
  • a JSON object with conditions and optional refs

Example conditions payload:

{
  "refs": {
    "target": "Skyrim.esm|00000007"
  },
  "conditions": [
    "GetDistance TARGET <= 256",
    "IsSneaking == 1"
  ]
}

About

Framework for mods to define variants of armors by swapping armor addons dynamically at runtime.

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages

  • C++ 83.2%
  • Shell 8.9%
  • Papyrus 7.2%
  • Xmake 0.7%