Skip to content

SARDONYX-sard/fnis_aa

Repository files navigation

FNIS Alternate Animation — SKSE Plugin

The goal of implementing the script for FNIS Alternate Animation (hereinafter referred to as FNIS AA) in C++ is to achieve the following:

  • Enable FNIS and Nemesis-compatible patching tools, such as d_merge and Pandora, to easily support FNIS AA simply by outputting the specified JSON format.
  • Improve performance (by constructing the data required by FNIS scripts when reading JSON and caching it in memory).

This will be useful for users who are using the Patching Tool and FNIS AA mods such as XPMSE or FNIS Sexy Move SE.

Requirements

Installation

  1. Enable the FNIS AA mod and this mod in MO2 or similar software

  2. Apply the patch as usual using a patching tool compatible with this plugin

  3. Launch the game. No further setup needed.

How It Works

FNIS generates the following script each time it runs to define the valid ranges for the variables used by all FNIS AA mods that you have enabled.

  • FNIS_aa2.pex

  • FNISVersionGenerated.pex

Instead of compiling the script every time, this plugin defines functions based on JSON using SKSE Plugin.

Also, overwrite the following script to speed up execution

  • FNIS_aa.pex

Data Flow & State Transition

[Patching Tool(e.g., d_merge, Pandora)]
 ├──> FNIS AA to OAR
`SKSE/Plugins/
    ├──> Injects FNISaa_* variables. Using BehaviorDataInjector is another option.
    └──> Generated [fnis_aa/config.json] --------> [C++ Plugin] (Native memory allocation)

                                     |
[Existing Mod Scripts] --------------|
    |                                |
    | (Call SetAnimGroupEX)          |
    v                                v
[Native Interceptor] ---------> [Dynamic Vector] (mod_id 0 ~ Unlimited)
    |                                |
    | (Calculate: Base + Index)      |
    v                                v
[Actor Variable] -------------> Sets "FNISaa_<group>" to behavior graph

config.json

Generated by patching tool. Located at SKSE/Plugins/fnis_aa/config.json.

{
  "crc": 1520082533,
  "fnis_version": "V07.06.00.0",
  "fnis_creature_version": "V07.06.00.0",
  "mods": [
    {
      "prefix": "fsm",
      "name": "fsm",
      "mod_id": 0,
      "groups": [
        {
          "name": "_mt",
          "base": 1
        }
      ]
    },
    {
      "prefix": "fs3",
      "name": "fs3",
      "mod_id": 1,
      "groups": [
        {
          "name": "_mt",
          "base": 10
        },
        {
          "name": "_mtx",
          "base": 1
        }
      ]
    },
    {
      "prefix": "xpe",
      "name": "xpe",
      "mod_id": 2,
      "groups": [
        {
          "name": "_1hmeqp",
          "base": 1
        },
        {
          "name": "_2hmeqp",
          "base": 1
        }
      ]
    }
  ]
}
Field Description
crc Fingerprint of the slot layout. Invalidates saved values on load order change.
fnis_version FNIS version string returned by FNISVersionGenerated.get().
prefix 3-character mod prefix used by FNIS (e.g. xpe for XPMSE).
mod_id FNIS AA id. (start from 0)
base First slot index occupied by this mod for this group. (start from 1. 0 is default)
  • FNIS version string format:

    format: "V<major:2>.{minor:2}.{patch:2}{flags(Option):1}"
    
    [1..2] = Major
    [4..5] = Minor1
    [7..8] = Minor2
    [10] = Flags (0=Release, 1=Alpha, 2=Beta): <- Option
    
    Example: "V07.06.00", "V07.06.002"

Slot Layout & Base calculation

slot 0..N     mod A  (base=1, slot_count=N)
slot N..M   mod B  (base=N+1, slot_count=M-N)

GetAAprefixList returns a string encoded as {mod_id:2}{group_id:2}{base:2}.

Since each digit is two characters long, the total cannot exceed 99.

These were primarily used in the original FNIS_aa.pex, which serves as a wrapper, but since heap allocation is wasteful, this plugin does not use them.

In other words, if you are only using mods that do not depend on the behavior of GetAAprefixList, I believe it should be fine to register more than 99 entries.

CRC and Save Compatibility

The crc field is a fingerprint of the current slot layout. On each game load, the plugin writes the current CRC to FNISaa_crc on the actor. If the value differs from what was saved, the calling Papyrus script should re-apply all animation variables to reflect the updated layout.

Uninstallation

This SKSE plugin simply registers a function and does nothing else.

Therefore, you can uninstall it at any time.

Developer

See developer.md

About

An SKSE Plugin that replaces specific FNIS scripts with a C++ implementation, dynamically generating functions at runtime based on JSON configuration

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks