-
Notifications
You must be signed in to change notification settings - Fork 31
Bad Modding Practices
This page describes practices modders should never use if they care about user experience, compatibility, and performance.
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.
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
CheckTextureOverridecalls 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
ibandvb0slots - WWMI
ibtriggers 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.
[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[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 = vb3Once 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
iborvb0hashes). - Perform limited
CheckTextureOverridecalls 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.