Skip to content

Bad Modding Practices

SpectrumQT edited this page Feb 13, 2026 · 2 revisions

This page describes practices modders should never use if they care about user experience, compatibility, and performance.


Shipping a Mod with d3dx.ini Included

Don’t do it. Period.

d3dx.ini is a global configuration file for the entire DLL. It affects all mods and should never be distributed with individual mods.

There is no option in this file that is strictly required for a mod to function. If you believe otherwise, open an issue on the Model Importer page instead of bundling it with your release.

This file is provided by Model Importer and is designed to create a shared, consistent modding environment for a given game.

Including a “rogue” d3dx.ini can cause serious problems, such as:

  • Redefined system keybindings that override documented controls and break manuals or guides.
  • Modified rendering, device, or system settings that can crash the game or break other mods on certain hardware.
  • Altered Shader Hunting Mode configuration, which creates major confusion for beginner modders because it deviates from standard guides and tutorials.

In short: never ship d3dx.ini with your mod.


Improper Usage of Global CheckTextureOverride

This is a hidden performance trap when used incorrectly.

By design, the CheckTextureOverride command asks the DLL to compute a hash for the resource in a given slot, compare it against every [TextureOverride] section from all ini files and then execute commands from ones with matching hash.

Running this command for every shader call (for example, from a [ShaderRegex] section without an accompanying [ShaderRegex.Pattern]) is extremely expensive. Running it for multiple slots is even worse.

Consider this worst-case example:

  • 2000 shader calls per frame
  • 10 global CheckTextureOverride calls for different slots
  • 1000 [TextureOverride] sections across all INI files

This results in:

  • 2000 × 10 = 20,000 resource hashes per frame
  • 20,000 × 1000 = 20,000,000 hash comparisons per frame

While real scenarios are usually less extreme (resources are often reused and the DLL performs internal optimizations), having multiple files globally triggering TextureOverride for many slots will severely degrade performance regardless.

That is why unconditional global CheckTextureOverride should be handled by only one INI file: the Model Importer core.

For modern games with complex shaders and many draw calls, Model Importers limit this behavior to only a few carefully chosen slots:

  • WWMI and EFMI trigger only ib and vb0 slots
  • WWMI ib triggers must be explicitly enabled via API
  • Older titles may still use broader triggers (“GIMI style”), but this is no longer recommended

These global triggers act as entry points, strictly limiting how many additional CheckTextureOverride calls are made later.

Old approach (“GIMI style”)

[ShaderRegex_GlobalTriggerTextureOverrides]
shader_model = vs_4_0 vs_4_1 vs_5_0 vs_5_1
; Calculate 6 hashes per call per frame
; Trigger 6 passes over all TextureOverride sections comparing their `hash` with slot hash
CheckTextureOverride = ps-t0
CheckTextureOverride = vb0
CheckTextureOverride = vb1
CheckTextureOverride = vb2
CheckTextureOverride = vb3
CheckTextureOverride = ib

Preferred approach

[ShaderRegex_GlobalTriggerTextureOverrides]
shader_model = vs_4_0 vs_4_1 vs_5_0 vs_5_1
; Calculate 1 hash per call per frame
; Trigger 1 pass over all TextureOverride sections comparing their `hash` with slot hash
CheckTextureOverride = ib

[TextureOverride_HandleGlobalTrigger_IB]
hash = f34a83e9 ; IB hash
; Calculate 5 hashes only for shader calls with matching IB
; Trigger 5 passes only for shader calls with matching IB over all TextureOverride sections comparing their `hash` with slot hash
CheckTextureOverride = ps-t0 
CheckTextureOverride = vb0
CheckTextureOverride = vb1
CheckTextureOverride = vb2
CheckTextureOverride = vb3

Once again, this is the responsibility of the Model Importer.

Unless absolutely necessary (for example, certain UI mods), mods must not define global CheckTextureOverride commands.

Instead, mods should:

  • Use the provided entry points (such as ib or vb0 hashes).
  • Perform limited CheckTextureOverride calls only inside triggered sections.

For example, in the snippet above, [TextureOverride_HandleGlobalTrigger_IB] uses the ib hash as its entry point and only then performs additional checks.

This approach keeps performance under control and preserves compatibility across mods.

Clone this wiki locally