Talk:Modifying an existing level: Difference between revisions

From OniGalore
mNo edit summary
mNo edit summary
 
(19 intermediate revisions by the same user not shown)
Line 117: Line 117:


===Asset panel?===
===Asset panel?===
If this is also possible, there is no more reason left why Blender should not become the community’s editor.
If this is also possible, there is no more reason left why Blender should not become community’s main editor.


==Reviving demo level Alpha Helix?==
==Reviving demo level Alpha Helix?==
Line 144: Line 144:


====Scaling====
====Scaling====
Round-tripping the old helix through Blender caused an upscaling.
Roundtripping the old helix through Blender caused an upscaling.


Old code:
Old code:
Line 208: Line 208:
* A complete dev env should contain files to test every possible conversion including options.
* A complete dev env should contain files to test every possible conversion including options.
* Keep test data out of original AE directory. When debugging multiple codebases, you don't want them to crash into one another.
* Keep test data out of original AE directory. When debugging multiple codebases, you don't want them to crash into one another.
* To set up advanced agents - that might even include (interesting but tricky) self-improvement - look at the web for [examples https://david.coffee/vibe-coding-part-1/].


=====Custom bot=====
=====Roundtripping=====
* On a general note: Roundtripping data is a very effective method to detect observable differences and actual bugs.
* More specifically: Descriptor IDs, such as in <code><TRAC id="6787"></code>, are not preserved because ONI files use ''local'' IDs and are later repacked during DAT creation. Therefore, IDs in XML/ONI are typically reset to 0.
** Therefore, you can define hash parity of output files as a general goal, with the exception that differences can be ignored if they are caused only by non-semantic ID changes. In other words: you may consider semantic equivalence under normalized comparison as sufficient.
** By the way, DAE files - which are internally XML - contain a tag for the authoring tool and version. Therefore, these files may also differ at the byte level.
 
=====Agent.md example=====
* Add notes about resources there. Like a downloaded Onisplit wiki page and what to expect from it. Commands and args. Be consistent using known terms, like "export" and "extract", in their proper use cases.
* Add notes about resources there. Like a downloaded Onisplit wiki page and what to expect from it. Commands and args. Be consistent using known terms, like "export" and "extract", in their proper use cases.
* Add general working instructions like for reading and writing test data.
* Add general working instructions like for reading and writing test data.


Example of an Agent.md; for "..." use your own start path.
Example of an Agent.md; for "..." use your own start path.
The display name is not determined by the filename but by the internal name. Either add manually or tell the IDE chatbot to add your agent directory to the '''project file'''. After that agents can be picked. For roundtripping and autoimproving new C# via old C# agent 1 is picked. For roundtripping and autoimproving VB via new C# agent 2 is picked.
This way, agents also can have a global directory.
<pre>
  <ItemGroup>
    <None Include="$(UserProfile)\.github\agents\*.md" />
  </ItemGroup>
</pre>
The bigger idea is to write '''universal information into agent md''' so the actual '''prompts can be shortened'''.
Agent md
<pre>
<pre>
---
---
name: Oni-Ni-Kanabo
name: Oni-Ni-Kanabo-2
description: Agent helps in creating Oni (Bungie, 2001) game related tools and data.
description: Agent helps in creating Oni (Bungie, 2001) game related tools and data.
---
---


# Oni-Ni-Kanabo
# Oni-Ni-Kanabo (c# .NET 10 vs VB)


When working with Onisplit (Onisplit.exe) then you can lookup commands and arguments from locally saved html webpage at %USERPROFILE%/.github/agents/
When working with Onisplit (Onisplit.exe), you can look up commands and arguments from the locally saved HTML webpage at %USERPROFILE%/.github/agents/
Read that helpful html when you start.
Read that helpful HTML when you start.


c#-based Onisplit.exe is located at ...\OniSplit-src-net10\bin\Debug\net10.0-windows\Onisplit.exe
C#-based Onisplit.exe is located at ...\OniSplit-src-net10\bin\Debug\net10.0-windows\Onisplit.exe
c#-based Onisplit sorce code is located at ...\OniSplit-src-net10
C#-based Onisplit source code is located at ...\OniSplit-src-net10


Read test data from ...\Oni\AE\GameDataFolder if needed, but write outputs to github-ignoreable subfolders of the individual's local OniSplit codebase to avoid conflicts with the source code and to keep test outputs organized and separate from source files.
Read test data from ...\Oni\AE\GameDataFolder if needed, but write outputs to github-ignoreable subfolders of the individual's local OniSplit codebase to avoid conflicts with the source code and to keep test outputs organized and separate from source files.
Use .test-output for outputs and comparisons to reach hash-based conclusions about parity between c# and vb builds.
Use .test-output for outputs and comparisons to reach hash-based conclusions about parity between C# and VB builds.


When conversions with this vb-based application fail, test same command with the c#-based Onisplit.exe to check if the issue is vb-specific or shared.
If you compare over 100 files at once, do it sequentially in steps of 100 so the consoles do not overflow or hang. If using powershell or other terminals, don't lose connection and report every time a batch finished, so you can continue with your remaining work after all batches finished.
If shared, then it's not a parity issue and should be fixed in both builds together. Skip (but document) shared issues for now and focus on vb-only issues.
 
If vb-specific, then it's a parity issue and should be fixed in the vb codebase to match the c# behavior.
If roundtripping is requested, get specified files (or naming pattern) from active user prompt, export oni files from dat if necessary, then extract oni files to xml and create oni again. Analyze diff in xml and hash-diffs of old and new oni files. Patch VB codebase to make roundtripping work and reach oni-hash-parity: Ignore-exception: Descriptors IDs like in TRAC id="6787" are not preserved because irrelevant and will be reset to 0. Log example of probably unimportant mismatches though. And show values of one mismatch example in console output: What do they represent.
 
When conversions with this VB-based application fail, test same command with the C#-based Onisplit.exe to check if the issue is VB-specific or shared.
If shared, then it's not a parity issue and should be fixed in both builds together. Skip (but document) shared issues for now and focus on VB-only issues.
If vb-specific, then it's a parity issue and should be fixed in the VB codebase to match the c# behavior.
</pre>
</pre>


=====Session instruction example=====
=====Prompt example=====
Followup session example. The subtypes (selection) was copied from from terminal.
  test roundtripping of TxtC*.oni files
<pre>Test sequential (100) stop-at-first-mismatch roundtrips with following XML subtypes (file prefixes)
 
Prefix Count Status  Stage File                    Reason
Prompt engineering for agentic coding is also known as vibecoding.
------ ----- ------  ----- ----                    ------
* You basically write pseudocode, which the agent then translates into real code and additional means to make everything work. The pseudocode should strike the right balance between formulating your app’s features and how these should be implemented, without going into every detail.
SNDD    2392 MISMATCH ONI  SNDDac1lp1.aif.oni      create exit cs=1 vb=1
* Besides considering your information and the rules defined in the md files, the agent will also make its own assumptions. These might be incorrect at some point or go ''off track''. Therefore, one prompt usually never achieves what you want. Further details - including broad or more specific bug-fix instructions - will need to be written by you at a later time anyway.
TRAC      32 MISMATCH ONI  TRAMTANCOMkick_low.oni create exit cs=0 vb=1
* For more complex apps, think of a structure (components/modules, data flow, responsibilities) that the agent should build.
TRAM    2618 MISMATCH ONI  TRAMCOMCOMcomb_k.oni   create exit cs=0 vb=1
TURR      24 MISMATCH ONI  TURRmbo_turret_ciel.oni create exit cs=1 vb=1
TXCA      7 MISMATCH ONI  TXMPCOVCRATE_3.oni      create exit cs=0 vb=1
TXMP    3309 MISMATCH ONI  TXMP%3Cnone%3E.oni      create exit cs=0 vb=1
TxtC      56 MISMATCH ONI  TxtClevel_11a.oni      create exit cs=1 vb=1
See if c#-based onisplit exe/project also fails. If c# fails, skip that type. If c# pass, then analyze codebase differences, patch vb until oni-hash-parrity is reached, coninue with next subtype.
</pre>


====Notes on C# (.NET Framework 4) (Onisplit 0.9.99.0)====
====Notes on C# (.NET Framework 4) (Onisplit 0.9.99.0)====
Looks like the current OniSplit srouce on svn has a bug in XML/ParticleXmlImporter.cs
Looks like the current OniSplit source on svn has a bug in XML/ParticleXmlImporter.cs
             // broken: string text = xml.ReadElementContentAsString();
             // broken: string text = xml.ReadElementContentAsString();
             string text = xml.ReadContentAsString();
             string text = xml.ReadContentAsString();
Line 268: Line 285:
New fixes for 0.9.99:
New fixes for 0.9.99:
* XML was first exported with slightly less accuracy: Floats are rounded to 6 instead of 7 digits after the decimal separator. The desired behavior was reimplemented by adding methods that mimic this quasi-legacy float-parsing.
* XML was first exported with slightly less accuracy: Floats are rounded to 6 instead of 7 digits after the decimal separator. The desired behavior was reimplemented by adding methods that mimic this quasi-legacy float-parsing.
* TRAM needs double checking.
* TRAM needs double checking:
** oni-roundtripping TRAMBARABeast fails with both: 0.9.95 and 0.9.99
** added fix for rare particle array bug to 0.9.99


====Notes on VB (.NET 10)====
====Notes on VB (.NET 10)====
Line 275: Line 294:
Things that already work:
Things that already work:
* DAT export for oni files
* DAT export for oni files
* XML extraction
* XML extraction double checking later
** Tested: DAE co-extraction for objects
** Tested: DAE co-extraction for objects
** Not tested: DAE co-extraction characters / anims
** Not tested: DAE co-extraction characters / anims
Line 284: Line 303:
* SUBT creation
* SUBT creation
* Explicitly tested XML roundtripping and fixed:
* Explicitly tested XML roundtripping and fixed:
** M3GM (not created from OBJ)
** M3GM double checked, not created from OBJ
** BINA
** BINA dc
** TRAM dc, fixed a rare particle array bug and minor rounding diff
** TRAC dc
** TRSC dc
** TRAS dc
** ONGS dc
** ONCC dc
** TRBS dc
** TxtC dc
** TXMB dc
** OBAN dc
** FILM dc
** ONSK dc
** ONWC dc
** TXMP dc (a few files with special sign like TXMP%45YE.oni still needs individual checking)
** TURR dc (potential particle fix needs ingame testing, if this fails, wiki/source research is needed)


XML imports needs a better test setup because of all the subformats.
Especially non-XML imports need separate test setups.


==(Another tool placeholder)==
==(Another tool placeholder)==

Latest revision as of 21:12, 18 April 2026

This community is the manifested pain of Herodotus...

Idea

To convert an extracted ONLV into a new project file you need even more in-depth knowledge about the file structure than for simply building a level project file from scratch.

Therefore, it would be nice if we could provide a tool to automate necessary work as much as possible.

One-click operation:

  1. Level extraction.
  2. Create means to seamlessly handle Onisplit's dae files:
    1. Either post-edit dae files to make them compatible with Blender. (The onisplit arg -blender seems to work for character import/export only.)
    2. Or write an Blender addon that can directly read Onisplits dae files. Ideally, that addon should also be able to output Onisplit compatible dae files so an additional fbx roundtrip can be avoided.
  3. Conversion of ONLV into an actual project file.
  4. Recycling of physics and locklights.
  5. Preserving as much vertex shading as possible by preferring DAE over CJBO linked meshes.
  6. BSL analysis to create FILM and cut scene sections?

AE package

mods.oni2.net
 |
 +-- 08030LevelRecycler#.zip (# = Upload version)
      |
      +-- 08030LevelRecycler_Win
           |
           +-- Mod_Info.cfg
           +-- plain
                |
                +--win_only
                    |
                    +--Tools
                        |
                        +-- LevelRecycler
                             |
                             +-- icon.png (32 x 32 px)
                             +-- LevelRecycler.exe

Mod_Info.cfg

AEInstallVersion -> 2.0
NameOfMod -> Level Recycler
Creator -> 
ModVersion -> 
Readme -> 
ExeName -> Tools/LevelRecycler/LevelRecycler.exe
WorkingDir -> Exe
IconName -> Tools/LevelRecycler/icon.png

Distribution notes

Experimenting with a new workflow:

  • LevelRecycler.vbproj contains a switch <SkipToolPublish>false</SkipToolPublish> to build a standalone executable that gets zipped together with a release package structure (as seen above) via post-build command running a bat. No additional installations of NET libraries necessary. The file size increases by 50 MB but as advantage it is usable out of the box.
  • Paths are adaptable for other environments through a BuildPaths.xml. See BuildPaths[Dummy].xml in project folder.

Blender detection / management

...

Startup

Oni
 |
 +-- AE
     |
     +-- Tools
     |    |
     |    +-- OniSplit.exe
     |    +-- LevelRecycler
     |         |
     |         +-- icon.png
     |         +-- LevelRecycler.exe
     |
     +-- GameDataFolder
          |
          +-- level0_Final.dat
          +-- level0_Final.raw
          +-- level1_Final.dat
          +-- level1_Final.raw
          +-- ...
          +-- IGMD
               |
               +-- BSL script folders

The "on load" event of the LevelRecycler should automatically update an overview of existing levels:

  • Level0_Final.dat stores all ONLD with more meaningful level names. Map them with help of DAT file names. With those extracted files, a list for modders can be built to easily identify the level they want to recycle.
// shortened paths
OniSplit -export:ONLD* ONLD level0_Final.dat
OniSplit -extract:xml ONLD ONLD/*.oni
for each valid ONLD DAT pair
    OniSplit -export:ONLV* ONLV ....dat
OniSplit -extract:xml ONLV ONLV/*.oni
dat file name, BSL script folder, natural level name
----------------------------------------------
level1_Final.dat, ONLV<Name>, ONLD<DisplayName>

As soon as the modder has selected the preferred level, it should be a one-click operation to carry out the recycling.

Less write operations

With each onload event the ONLV and ONLD would get extracted. To reduce somewhat the amount of write operations an xml cache file could be used to feed the program's overview table. If the DAT files are older then no new extractions are done.

Blender add-ons

Import

  • Blender-v5-DAE-Importer-Add-on (broken but fixable)
    • At first glance, positions of individual objects from collective files like lab_furn.dae are all set to 0, 0, 0. So, until that is fixed too, we should only support Blender 4.x. As for April 2026, the latest LTS blender version is 4.5.8 which also supports drag and drop of dae. DnD was for long time an unsupported feature.
  • BetterCollada (untested)

Export

GenAI wrote dae addons to import and export dae. Unexpectedly, the problem with technique tag and missing attributes seems to be go by now. The addon needs more testing to see how transparency and other features are handled.

CLI support?

To establish full modding support, blender needs to be able to load dae when called from CLI. Untested. This probably requires source code changes as we don’t simply want to call new blender instances with each import. In order to keep up full modding support one would need to always fork and update the new blender versions. For convenience, the question is whether an automatic patcher can be made.

XSI addon replacement?

The general mechanisms - for floating menus and direct value rendering on objects - must be researched first, before this can be considered.

Are attachable strings possible? According to documentation, it is possible for regular objects and strings will be added to Geometry nodes in Blender 5.2.

Asset panel?

If this is also possible, there is no more reason left why Blender should not become community’s main editor.

Reviving demo level Alpha Helix?

History

When you work on a level, you need to constantly test it ingame so possible errors are caught as early as possible. For that reason the tool around Helix had a plugin-based workflow. An AE package takes much longer to install and the AEI doesn't start Oni automatically.

To not confuse novice modders with two different workflows, the new Helix should be package-based. The advantage would be that the package structure is ready from first second and interdependencies can better be dealt with during level development.

Dev notes

Checklist

Done for addon

Blender_5.1_experimental_dae_import_export_tn.jpg
[x] changed initial addon so that individual objects inside dae won't be placed at 0, 0, 0 in Blender
[x] import dae via drag and drop
[x] exports onisplit compatible dae (<technique sid="common">)
[x] exports with adjusted world scaling and orientation (Z_UP rotates the map as Blender uses a different orientation in general)
<unit name="meter" meter="0.1"/>
<up_axis>Z_UP</up_axis>
[ ] version control, review, more testing
[ ] support dnd import of multiple files
[ ] add option to group objects during import
[ ] add dae quick save option (as floating menu or hotkey?)
[ ] add option to replace COLLISION with _marker_barrier during export and/or "on demand" (floating menu?)
[ ] import special dae on specific layer (Blender collection)
[ ] MOAR (maybe)

Scaling

Roundtripping the old helix through Blender caused an upscaling.

Old code:

<unit meter="0.1" name="decimetre"></unit>
<up_axis>Y_UP</up_axis>

New code:

<unit name="meter" meter="1"/>
<up_axis>Z_UP</up_axis>

The scaling can be reverted to normal by setting meter value.

New code:

<unit name="meter" meter="0.1"/>

World orientation and up axis

From perspective of spawned player, character looks forward if map is:

  • XSI: +Z = forward, +Y = up, +X = left.
  • Blender: -Y = forward, +Z = up, +X = left (set Z_up during export)

Gunk flag textures

Collision

COLLISION versus _marker_barrier

COLLISION is a material found in the shared resource collection. Based on previous tests, collision boxes seem to need an exception rule in the master file.

Onisplit's level export will output the material _marker_barrier. Its purpose is pretty much the same. But while COLLISION won't automatically gunk flag its geometry, _marker_barrier will automatically flag geometry with Transparent TwoSided Invisible NoObjectCollision NoOcclusion.

So, at some point, we could replace instances of COLLISION with _marker_barrier as a workaround: By that we avoid the necessity to write an exception rules into the level master xml for assigning gunk flags to collision.

Usage of OFGA

OFGA imports should result in uneditable proxies (changes in position and rotation allowed only) and then add exception rules so the non-collision object textures will assign NoCharacterCollision NoOcclusion.

To derive editable OFGA variants, we could create a new object class as shared resource or incorporate the new object into the AKEV core geometry. For special texture treatment, we would still need an exception rule.

The bigger idea is that every object with custom data gets treated appropriately automatically: Their features get added the the master xml or are optionally also used to build new OFGA resources.

Onisplit

Tests with original and alternative codebases

Due to former contact with Onisplit, I was curious whether the codebase could be upgraded.

As a secondary goal I might (re)implement the FILM fix described on Onisplit's talkpage.

Based on snv revision 1211, level0_Final.dat was used for export. 10 tests in a row for each version, averaged values. On 5.0 PCI-E nvme SSD.

Performance

Program Onisplit C# (.NET Framework 4) Onisplit C# (.NET 10) Onisplit VB (.NET 10)
Speed 5.571 ms 5.406 ms 5.748 ms
Peak RAM usage 1.155,81 MB 150,51 MB 63,64 MB

Who would have thought that VB performes so well against C#. (At least for the export.) On second thought, it makes sense that both .NET 10 builds are more memory-efficient overall, as they share a more modern - and therefore more efficient - foundation.

Dev notes

On a general note:

  • Do simpler fixes first, so the more complex bug might get easier to fix if a few other interdependencies are already fixed.
  • In case of big pools of files with same subtype, use a limited amount of test files at once first.
  • A complete dev env should contain files to test every possible conversion including options.
  • Keep test data out of original AE directory. When debugging multiple codebases, you don't want them to crash into one another.
  • To set up advanced agents - that might even include (interesting but tricky) self-improvement - look at the web for [examples https://david.coffee/vibe-coding-part-1/].
Roundtripping
  • On a general note: Roundtripping data is a very effective method to detect observable differences and actual bugs.
  • More specifically: Descriptor IDs, such as in <TRAC id="6787">, are not preserved because ONI files use local IDs and are later repacked during DAT creation. Therefore, IDs in XML/ONI are typically reset to 0.
    • Therefore, you can define hash parity of output files as a general goal, with the exception that differences can be ignored if they are caused only by non-semantic ID changes. In other words: you may consider semantic equivalence under normalized comparison as sufficient.
    • By the way, DAE files - which are internally XML - contain a tag for the authoring tool and version. Therefore, these files may also differ at the byte level.
Agent.md example
  • Add notes about resources there. Like a downloaded Onisplit wiki page and what to expect from it. Commands and args. Be consistent using known terms, like "export" and "extract", in their proper use cases.
  • Add general working instructions like for reading and writing test data.

Example of an Agent.md; for "..." use your own start path.

The display name is not determined by the filename but by the internal name. Either add manually or tell the IDE chatbot to add your agent directory to the project file. After that agents can be picked. For roundtripping and autoimproving new C# via old C# agent 1 is picked. For roundtripping and autoimproving VB via new C# agent 2 is picked.

This way, agents also can have a global directory.

  <ItemGroup>
    <None Include="$(UserProfile)\.github\agents\*.md" />
  </ItemGroup>

The bigger idea is to write universal information into agent md so the actual prompts can be shortened.

Agent md

---
name: Oni-Ni-Kanabo-2
description: Agent helps in creating Oni (Bungie, 2001) game related tools and data.
---

# Oni-Ni-Kanabo (c# .NET 10 vs VB)

When working with Onisplit (Onisplit.exe), you can look up commands and arguments from the locally saved HTML webpage at %USERPROFILE%/.github/agents/
Read that helpful HTML when you start.

C#-based Onisplit.exe is located at ...\OniSplit-src-net10\bin\Debug\net10.0-windows\Onisplit.exe
C#-based Onisplit source code is located at ...\OniSplit-src-net10

Read test data from ...\Oni\AE\GameDataFolder if needed, but write outputs to github-ignoreable subfolders of the individual's local OniSplit codebase to avoid conflicts with the source code and to keep test outputs organized and separate from source files.
Use .test-output for outputs and comparisons to reach hash-based conclusions about parity between C# and VB builds.

If you compare over 100 files at once, do it sequentially in steps of 100 so the consoles do not overflow or hang. If using powershell or other terminals, don't lose connection and report every time a batch finished, so you can continue with your remaining work after all batches finished.

If roundtripping is requested, get specified files (or naming pattern) from active user prompt, export oni files from dat if necessary, then extract oni files to xml and create oni again. Analyze diff in xml and hash-diffs of old and new oni files. Patch VB codebase to make roundtripping work and reach oni-hash-parity: Ignore-exception: Descriptors IDs like in TRAC id="6787" are not preserved because irrelevant and will be reset to 0. Log example of probably unimportant mismatches though. And show values of one mismatch example in console output: What do they represent.

When conversions with this VB-based application fail, test same command with the C#-based Onisplit.exe to check if the issue is VB-specific or shared.
If shared, then it's not a parity issue and should be fixed in both builds together. Skip (but document) shared issues for now and focus on VB-only issues.
If vb-specific, then it's a parity issue and should be fixed in the VB codebase to match the c# behavior.
Prompt example
test roundtripping of TxtC*.oni files

Prompt engineering for agentic coding is also known as vibecoding.

  • You basically write pseudocode, which the agent then translates into real code and additional means to make everything work. The pseudocode should strike the right balance between formulating your app’s features and how these should be implemented, without going into every detail.
  • Besides considering your information and the rules defined in the md files, the agent will also make its own assumptions. These might be incorrect at some point or go off track. Therefore, one prompt usually never achieves what you want. Further details - including broad or more specific bug-fix instructions - will need to be written by you at a later time anyway.
  • For more complex apps, think of a structure (components/modules, data flow, responsibilities) that the agent should build.

Notes on C# (.NET Framework 4) (Onisplit 0.9.99.0)

Looks like the current OniSplit source on svn has a bug in XML/ParticleXmlImporter.cs

           // broken: string text = xml.ReadElementContentAsString();
           string text = xml.ReadContentAsString();

Double checked: Testing roundtrip with shipped 0.9.95.0 and local build of 0.9.99.0

95: pass
99: fail

Applied fix in C# .NET 10 build:

99+: pass

Notes on C# (.NET 10)

The idea was (and is) to translate the v0.9.99-codebase from C# to vb, but as minior bugs linger in v0.9.99 that route builds also mental load, permanent doubts that there could be something wrong which then affects the vb codebase as well. As for traslating the v0.9.95-codebase, you are permanently concerned that it will miss new features introduced in v0.9.99.

New fixes for 0.9.99:

  • XML was first exported with slightly less accuracy: Floats are rounded to 6 instead of 7 digits after the decimal separator. The desired behavior was reimplemented by adding methods that mimic this quasi-legacy float-parsing.
  • TRAM needs double checking:
    • oni-roundtripping TRAMBARABeast fails with both: 0.9.95 and 0.9.99
    • added fix for rare particle array bug to 0.9.99

Notes on VB (.NET 10)

Fixing the vb codebase in its entireness might take two weeks and one addional week for heavy testing.

Things that already work:

  • DAT export for oni files
  • XML extraction double checking later
    • Tested: DAE co-extraction for objects
    • Not tested: DAE co-extraction characters / anims
  • Image extraction: DDS, PNG, TGA
  • Object extraction: DAE and OBJ
  • WAV extraction
  • TXT extraction
  • SUBT creation
  • Explicitly tested XML roundtripping and fixed:
    • M3GM double checked, not created from OBJ
    • BINA dc
    • TRAM dc, fixed a rare particle array bug and minor rounding diff
    • TRAC dc
    • TRSC dc
    • TRAS dc
    • ONGS dc
    • ONCC dc
    • TRBS dc
    • TxtC dc
    • TXMB dc
    • OBAN dc
    • FILM dc
    • ONSK dc
    • ONWC dc
    • TXMP dc (a few files with special sign like TXMP%45YE.oni still needs individual checking)
    • TURR dc (potential particle fix needs ingame testing, if this fails, wiki/source research is needed)

Especially non-XML imports need separate test setups.

(Another tool placeholder)