diff --git a/examples/crossed-cloak/.gitignore b/examples/crossed-cloak/.gitignore new file mode 100644 index 0000000..704c612 --- /dev/null +++ b/examples/crossed-cloak/.gitignore @@ -0,0 +1,2 @@ +# Built zips are attached to GitHub Releases, not committed. +dist/ diff --git a/examples/crossed-cloak/README.md b/examples/crossed-cloak/README.md new file mode 100644 index 0000000..d7be42c --- /dev/null +++ b/examples/crossed-cloak/README.md @@ -0,0 +1,92 @@ +# Crossed Cloak — FSMP Pattern Example + +**Version 0.1.0** · an FSMP (Faster HDT-SMP) **pattern** demonstration mod. + +This is a worked example for the [FSMP modder guide](https://github.com/DaymareOn/FSMP-Validator/wiki): it rebuilds the +physics of one Cloaks of Skyrim cloak as a **crossed 2-D tissue** using the FSMP *pattern* +macro feature, instead of hand-writing every bone and constraint. It is meant to be read +alongside the two source files, which are heavily commented. + +> ⚠️ **Requires an FSMP build with pattern support, which is not yet released.** Until then +> this mod only works with the test DLL handed to testers. It is published here as a +> versioned reference, not yet as a public Nexus release. + +--- + +## What it demonstrates + +The required Cloaks of Skyrim cloak NIF is a 3×6 grid of `CB` cloth bones (`CB 01 1` … +`CB 03 6`) wired as three independent vertical chains. This example keeps the **same real NIF +bones** but reorganises the physics: + +- **`patterns/DaydreamingDay.xml`** — a shared pattern library. It defines one reusable + pattern, `DaydreamingDay.cloak`, that emits the whole cloth structure: + - the CB grid (parameterised by `cols`/`rows`), + - **warp** constraints chaining each column top-to-bottom (locked near the neck, lightly + limited lower down), + - **weft** constraints tying adjacent columns at the same row — a deliberately loose, + non-Hookean spring so the cloak drapes as a sheet without going rigid. + - The weft tuning is exposed as parameters (`weftStiffness`, `weftLinearLimit`, …) with + sensible defaults. +- **`cloak.xml`** — the consumer. It declares only what is specific to *this* NIF (the + collision shapes, the body skeleton bones those shapes skin to) and invokes the pattern + with one line, overriding two weft knobs: + + ```xml + + ``` + +At load time FSMP expands that single tag into 18 bones and 25 constraints. Dropping +`DaydreamingDay.xml` into the global `patterns/` folder makes the pattern available to every +physics file, so other cloaks can reuse the same structure with their own tuning. + +The expanded document passes the FSMP `smp report` validator with **0 errors, 0 warnings**. + +--- + +## Requirements + +Install **all** of these first, in this order. This mod ships **only XML config** — no +meshes or textures — so the cloak itself comes entirely from the mods below. + +1. **[SKSE64](http://skse.silverlock.org/)** +2. **Faster HDT-SMP (FSMP) with pattern support** — the test build (pattern support is + unreleased as of this version). A stock HDT-SMP/FSMP without pattern support will fail to + load this file. +3. **[Cloaks of Skyrim](https://www.nexusmods.com/skyrimspecialedition/mods/6369)** (Nikinoodles + & Nazenn) — the base cloak items, meshes and textures. +4. **[Artesian Cloaks of Skyrim](https://www.nexusmods.com/skyrimspecialedition/mods/17416)** — + the SMP-enabled cloak NIFs (`Meshes\Clothes\cloaksofskyrim\`) whose `CB` bones this config + binds to. + +## Installation + +Install with a mod manager (MO2/Vortex) **after** the cloak mods above, and let it +**overwrite**. This mod replaces the SMP cloak patch's `cloak.xml` with the pattern-based +version and adds the shared `patterns/DaydreamingDay.xml`: + +``` +SKSE/Plugins/hdtSkinnedMeshConfigs/cloak.xml (replaces the patch's) +SKSE/Plugins/hdtSkinnedMeshConfigs/patterns/DaydreamingDay.xml (new, shared library) +``` + +It only changes the **cloak** physics. The patch's `cape.xml` is left untouched. + +--- + +## Credits + +- **Cloaks of Skyrim** — Nikinoodles & Nazenn. Base cloak meshes, textures and items. +- **Artesian Cloaks of Skyrim** — Zeridian and Rosent. The SMP-enabled cloak NIFs and the + original `cloak.xml` this example is derived from. +- **HDT-SMP / Faster HDT-SMP** — HydrogensaysHDT and the FSMP maintainers. The physics engine + and the pattern feature. +- **DaydreamingDay** — the pattern, this reimplementation, and the example. + +## Permissions + +This mod contains only original XML configuration authored by DaydreamingDay, derived from +Artesian Cloaks of Skyrim's `cloak.xml`. It **redistributes no art assets** (no meshes, no +textures) — those remain with their original authors and are obtained by installing the +required mods above. Artesian Cloaks of Skyrim's permissions explicitly forbid redistributing +its art assets, which this example respects by depending on it rather than bundling it. diff --git a/examples/crossed-cloak/SKSE/Plugins/hdtSkinnedMeshConfigs/cloak.xml b/examples/crossed-cloak/SKSE/Plugins/hdtSkinnedMeshConfigs/cloak.xml new file mode 100644 index 0000000..92d1527 --- /dev/null +++ b/examples/crossed-cloak/SKSE/Plugins/hdtSkinnedMeshConfigs/cloak.xml @@ -0,0 +1,98 @@ + + + + + + + + 5 + ground + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + body2 + body + + + + 0 + 0 + Feet + body + + + + 0 + cloth + + + diff --git a/examples/crossed-cloak/SKSE/Plugins/hdtSkinnedMeshConfigs/patterns/DaydreamingDay.xml b/examples/crossed-cloak/SKSE/Plugins/hdtSkinnedMeshConfigs/patterns/DaydreamingDay.xml new file mode 100644 index 0000000..aabe6c3 --- /dev/null +++ b/examples/crossed-cloak/SKSE/Plugins/hdtSkinnedMeshConfigs/patterns/DaydreamingDay.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + 1 + + + 0.02 + + 0.8 + 0.8 + 0.9 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/crossed-cloak/package.ps1 b/examples/crossed-cloak/package.ps1 new file mode 100644 index 0000000..ba86181 --- /dev/null +++ b/examples/crossed-cloak/package.ps1 @@ -0,0 +1,29 @@ +# Builds the installable, versioned zip for the "Crossed Cloak - FSMP Pattern Example" mod. +# +# The zip root mirrors a Skyrim Data install (SKSE/Plugins/...), so a mod manager can install +# it directly, plus the README at the root. Output goes to dist/ (git-ignored); attach the +# resulting zip to a GitHub Release as the versioned asset, then upload that same file to Nexus. +# +# Usage: pwsh ./package.ps1 [-Version 0.1.0] +param([string]$Version = "0.1.0") + +$ErrorActionPreference = "Stop" +$here = Split-Path -Parent $MyInvocation.MyCommand.Path +$dist = Join-Path $here "dist" +New-Item -ItemType Directory -Force -Path $dist | Out-Null + +$zip = Join-Path $dist ("FSMP-Crossed-Cloak-Pattern-Example-{0}.zip" -f $Version) +if (Test-Path $zip) { Remove-Item $zip -Force } + +# Contents: the installable data tree + the readme. Nothing else (no art assets). +$items = @( + (Join-Path $here "SKSE"), + (Join-Path $here "README.md") +) +Compress-Archive -Path $items -DestinationPath $zip -CompressionLevel Optimal + +$size = [math]::Round((Get-Item $zip).Length / 1KB, 1) +Write-Output ("Built {0} ({1} KB)" -f $zip, $size) +Write-Output "Contents:" +Add-Type -AssemblyName System.IO.Compression.FileSystem +[System.IO.Compression.ZipFile]::OpenRead($zip).Entries | ForEach-Object { Write-Output (" " + $_.FullName) } diff --git a/skse/plugins/hdtSkinnedMeshConfigs/hdtSMP64.sch b/skse/plugins/hdtSkinnedMeshConfigs/hdtSMP64.sch index 7980aa8..fe91495 100644 --- a/skse/plugins/hdtSkinnedMeshConfigs/hdtSMP64.sch +++ b/skse/plugins/hdtSkinnedMeshConfigs/hdtSMP64.sch @@ -23,6 +23,37 @@ + + Pattern macro authoring rules + + + + + + repeat count must be a non-negative integer or a ${...} placeholder. + + + + + repeat from must be an integer or a ${...} placeholder. + + + + + repeat count is 0; this repeat emits nothing. + + + + + param name must not contain spaces. + + + pattern-default name must not contain spaces. + + + Static rigid body constraints (mass=0) diff --git a/skse/plugins/hdtSkinnedMeshConfigs/hdtSMP64.xsd b/skse/plugins/hdtSkinnedMeshConfigs/hdtSMP64.xsd index c87ef44..e63c7db 100644 --- a/skse/plugins/hdtSkinnedMeshConfigs/hdtSMP64.xsd +++ b/skse/plugins/hdtSkinnedMeshConfigs/hdtSMP64.xsd @@ -6,7 +6,7 @@ targetNamespace="FSMP-Validator" elementFormDefault="qualified" attributeFormDefault="unqualified" - version="2.1.0" + version="2.2.0" > @@ -118,6 +118,9 @@ element. + + + @@ -206,6 +209,104 @@ element. + + + + + + + Defines a reusable pattern macro: a parameterized cluster of bones and +constraints. name is required; author (optional) namespaces it so its full name is author.name; +version (optional) lets several versions of one pattern coexist. Holds zero or more param +declarations followed by one body template. FSMP expands every pattern (and removes every +pattern-default) before the document is validated against the rest of this schema, so a body may +contain ${placeholders} that the strict element types would otherwise reject -- the body content is +therefore left unvalidated here. + + + + + + + + + + + + + + + + Declares a pattern parameter. name is required; default (optional) is the +value used when a use site omits the parameter -- a parameter without a default is required. + + + + + + + + + + + The template a pattern expands to: ordinary system-level elements plus +nested repeat and pattern uses, with ${param}/${loopVar}/${loopVar+/-N} placeholders. Left +unvalidated (lax) because of the placeholders; FSMP validates the expanded result strictly. + + + + + + + + + + + + Emits its content once per index, binding var to from .. from+count-1 +(from defaults to 0). count and from are strings because they may be ${placeholders}. Nest two for a +2-D grid. Content is left unvalidated (lax) for the same reason as body. + + + + + + + + + + + + + + + Instantiates a pattern. name is required and is the pattern's full name +(author.name when namespaced); version (optional) pins a version. Every other attribute supplies a +parameter value, so arbitrary attributes are permitted here. + + + + + + + + + + + + Root element of a shared pattern-library file, the kind that lives in +data/skse/plugins/hdtSkinnedMeshConfigs/patterns/. FSMP loads every such file once at startup and +makes its pattern-default definitions available to every physics XML. A library holds only pattern +definitions (no bones, constraints, or shapes); those live in the consuming system file. + + + + + + + + +