Skip to content
S3ctor’s S3cret St4sh

Mod Morrowind active

FlexTag

A community tagging standard for Morrowind records and cells. Tags dungeons, items, NPCs, ingredients, civic spaces, and more. Built as a dependency for mods like Static Switching System.

Stable
not released
Development
1.0.2-dev.3
Runs on
OpenMW any version
Package
Single directory

Overview

FlexTag is a lightweight, zero-overhead tagging framework for Morrowind on OpenMW. It lets mods ask questions like "is this cell a dungeon?" or "does this NPC belong to the Camonna Tong?" — without hardcoding IDs or guessing.

Nothing happens in-game just by installing FlexTag. It's a dependency. Other mods use it.

Built-In Tags

FlexTag ships with six tag datasets covering the vanilla game and its DLCs:

ModuleTagsWhat It Covers
dungeon_tags.yaml12576 dungeon cells plus subcategories (mine, cave, daedric, dwemer, tomb, shipwreck, sewer, stronghold)
item_tags.yaml42Weapon and armor materials, clothing tiers, enchanted items, unique gear
civic_tags.yaml5Taverns, merchants, Tribunal Temples, Imperial Cult shrines
npc_tags.yaml22Bandits, Sixth House, vampires, necromancers, assassins, faction enemies — with vanilla-specific variants
ingr_tags.yaml9Edible vs. inedible ingredients, plants, fungi, minerals, animal parts, magical, quest
item_origins.yaml5Item origins: Morrowind, Skyrim, Cyrodiil, Orsinium, Elsweyr

All tags use the record IDs from Morrowind.esm, Tribunal.esm, and Bloodmoon.esm. Case-insensitive.

YAML Format

Tag data files live in a ModTags/ directory under any data= path in openmw.cfg. The format is simple — each top-level key is a tag name, and its value is a list of record IDs:

CellDungeon:
  - "addamasartus"
  - "ald daedroth, inner shrine"
  - "arkngthand, cells of hollow hand"

NPCBandit:
  - "adraria nilor"
  - "agrob gro-bolmog"

That's it. No wrapper keys, no tags list, no applied_tags map. Create as many files as you want. FlexTag loads them all.

API

FlexTag exposes two interfaces: I.FlexTagG (global scripts) and I.FlexTagL (all other contexts). Both have the same functions. Every function that accepts an object also accepts a raw string record ID — case doesn't matter.

Querying Tags

objectHasTag(object, tag) — returns true if the object has the tag. tag can be a single string or an array of strings (returns true on the first match).

if I.FlexTagL.objectHasTag(self.cell, "CellDungeonDaedric") then
    -- do something in daedric ruins
end

if I.FlexTagL.objectHasTag(self, {"NPCBandit", "NPCSixthHouse"}) then
    -- target is either a bandit or a Sixth House cultist
end

objectTags(object) — returns a table of all tags on an object (read-only).

local tags = I.FlexTagL.objectTags(self)
if tags.NPCBandit then
    -- ...
end

getRecordsWithTag(tag) — returns an array of all record IDs that have a given tag.

local dungeons = I.FlexTagG.getRecordsWithTag("CellDungeonMorrowind")
log(#dungeons .. " dungeon cells found")

tagList() — returns the set of all registered tag names.

appliedTags() — returns the full {recordId: {tagName: true}} map (read-only).

Modifying Tags

addTag(object, tag) — adds one or more tags to an object. tag can be a single string or an array.

I.FlexTagG.addTag(someNPC, "QuestActive")
I.FlexTagG.addTag(someCell, {"CellExplored", "CellCleared"})

removeTag(object, tag) — removes one or more tags from an object.

I.FlexTagG.removeTag(someNPC, "QuestActive")

Tags added or removed at runtime are visible immediately and persist for the session.

Type Reference

TypeMeaning
FlexTag.TaggableA string record ID, or any OpenMW game object (GObject, LObject, SelfObject), or a cell (GCell, LCell)
FlexTag.ObjectTagA tag name string
FlexTag.TagArgA single tag string or an array of tag strings
FlexTag.ObjectTagListA set of tag names ({[tag] = true})
FlexTag.AppliedTagsThe full record-to-tag map ({[recordId] = ObjectTagList})

For Mod Authors: Adding Tags

Drop a .yaml file into any ModTags/ directory. Use the format above: top-level keys are tag names, values are arrays of record IDs. FlexTag loads all files at startup, one key per frame, so even large files won't cause a hitch.

# MyMod_tags.yaml
QuestActive:
  - "caldera_mine_slave_key"
  - "dwemer_boots_auriels"

CellCleared:
  - "addamasartus"
  - "gnisis, eggmine"

Technical Notes

  • Tags are loaded via a coroutine that yields between YAML keys — zero frame hitches.
  • All storage writes are deferred until loading completes. Runtime tag mutations are atomic.
  • The TagList catalogue prunes automatically when the last instance of a tag is removed.
  • Storage lifetime is Temporary — nothing persists in your save file. Tags rebuild fresh each session.

Install

Single directory · 1.0.2-dev.3

OpenMW, by handextract, then add these lines to openmw.cfg
  1. Extract the archive to a folder of its own, for example C:/Games/OpenMW-Mods/FlexTag.
  2. Add the lines below to openmw.cfg. Keep them after the data= lines of anything this mod depends on.
  3. Open the launcher and check the load order. Content files load in the order listed here.
data="C:/Games/OpenMW-Mods/FlexTag"
content=FlexTag.esp

Replace the folder with wherever you extracted the archive.

DreamWeave clientsCHIMERA and other tools that read the manifest

Give the tool this page's address, or the manifest directly. It finds the release for its channel, checks compatibility and dependencies, downloads from any listed source and refuses bytes whose SHA-256 does not match.

Project id
ed77443e-a232-4eee-839d-427c515a358b
Manifest
https://dreamweave-mp.github.io/S3ctors-S3cret-St4sh/dreamweave/projects/ed77443e-a232-4eee-839d-427c515a358b.json

What is in the archive

  • flextag.zip
    • FlexTag.espand the rest of the data directory
    • flextag-Documentation/this page and its docs, readable offline
    • flextag-dwmod.tomlthe project's mod.toml
    • dreamweave.release.jsonwhat this archive is, for tools

Compatibility

Anything not listed here is untested.

Runs on

  • OpenMWany version
  1. 1.0.1 stable unverified 2026-09-09

  2. 1.0 stable unverified 2026-07-01

  3. 0.6 stable unverified 2025-06-26

Discussion

GitHub Discussions · sign in with GitHub to join in