Description
Adding category information to types can help with organization of code gen, docs gen, or filtering/categorizing types inside of a UI. Without this info in nif.xml it has to be associated manually by the library or program.
The vanilla Gamebryo engine is split up into libs/modules such as:
NiAnimation
NiCollision
NiMain
NiMesh (20.5+)
NiParticle
NiPhysX (20.2+)
NiPortal
While I do not believe we need to perfectly replicate their organization, I think it is a good basis. NiMain
could probably be split up into a few smaller logical sections.
Historically, there are actually two different NiParticle
modules. In 20.5 everything NiParticleSystem/NiPSys related was deprecated and replaced by NiPSParticleSystem/NiPS. So NiParticle
needs to organizationally become two modules e.g. NiParticle
and NiParticle 20.5+
. Making all new particle classes was actually due to the replacement of NiGeometry with NiMesh, because NiParticles' parent is NiGeometry and NiParticles is the top level of the particle system.
Given this history and since there is an NiMesh
module, there can probably be an NiGeometry
module too. Other potential sub-categories of NiMain are NiProperty
and NiExtraData
.
There is also the question of custom blocks. Either each game should get a category or it should be Bethesda and "Other". In addition, Bethesda's custom blocks are extensive enough that it could probably be split up into its own categories. The most egregious example of their custom blocks being bhk
.
Proposed Categories
# Vanilla
NiAnimation
NiMain
NiGeometry
NiExtraData
NiProperty
NiMesh
NiParticle
NiParticle (20.5+)
NiPhysX
# Custom (Bethesda)
BSMain
BSHavok
BSShader
BSAnimation
# Custom (Other)
NiCustom
# NetImmerse (pre-10.1)
NiLegacy
Example
<module name="NiMain" priority="0" />
<!-- ... -->
<module name="BSMain" custom="true" priority="5000" />
<module name="NiCustom" custom="true" priority="9000" />
<module name="NiLegacy" deprecated="true" priority="10000" />
<niobject name="NiAVObject" abstract="1" inherit="NiObjectNET" module="NiMain">
<niobject name="NiRawImageData" inherit="NiObject" module="NiLegacy">
<niobject name="NiBezierMesh" inherit="NiAVObject" module="NiLegacy">
<niobject name="NiClod" inherit="NiTriBasedGeom" module="NiCustom">
<niobject name="NiFurSpringController" inherit="NiTimeController" module="NiCustom">
<niobject name="BSFadeNode" inherit="NiNode" module="BSMain">
With the module attribute you can immediately tell if something is old or custom, etc. Non-Bethesda custom blocks have a tendency to use the Ni
terminology and so they blend in well with vanilla types.
Also for NiAnimation and NiParticle, there are major organizational benefits as there are so many blocks and yet none are innately defined as being animation or particle related. In NifSkope, I resorted to complicated rules on the names and predefined maps of top-most parents.
Module Tag
Deprecated status: deprecated = <boolean>
There are a lot of NetImmerse blocks that are hardly functioning at the moment. This mostly applies to versions before 4.0.0.0
, and at least Morrowind (4.0.0.2
) is exempt, but everything else before 10.1 is a crapshoot.. Anything that is old and still not decoded should go into NiLegacy
and the module should be marked as deprecated.
This allows a lib/program to discard these old and likely non-functioning blocks without resorting to discarding everything before a certain version.
Custom flag: custom = <boolean>
This is a no-brainer; it allows entire groups of blocks to be marked as non-standard without having to know each and every one by heart or having to keep a list manually. Like deprecated
, it can also be leveraged during code or docs generation to various effect.
Implicit or Explicit ordering: priority | order = <integer>
At first I figured that the order in which it's listed in the XML should be the implicit priority of the modules. The ordering would be useful for the main page of the docs, or for actually reading and re-writing the XML for various reasons and keeping the organization the same (for version control reasons).
However, if say the XML were to be deserialized in order to be updated/sanitized/formatted/etc then at least the modules should have their order explicitly defined. The only real way to order them automatically would be alphabetically, which would put Bethesda stuff at the top of the file.
Opinion: Go ahead and explicitly order the modules so that their declaration order is not important.
For Discussion
Ultimately, the end goal is to have a tool which will reorganize the XML, initially having one horrendous reorganization commit, and then after that the tool will keep the XML consistently formatted for us. No blocks strewn about the file that belong together.
However the module organization will benefit code and docs generation as well. The main page of the XML docs is currently alphabetical in both hierarchy and list, which puts important blocks much further down, and the list view is nigh unusable with no categorization.
For interpreters of the XML, like NifSkope and PyFFI, the categorization still has uses for filtering and UI.