That is an absolutely unfair characterization of the development process. In fact, probably the most common complaint we get is that we spend way too much effort on maintaining compatibility. We had abandoned numerous enhancements because there was no reasonable way to make them without breaking hypothetical existing SP modules. While not officially documented (something I keep putting off, sorry), our compatibility guarantees are based on those of the Linux kernel which is the golden industry standard.
Our compatibility guarantees are orders of magnitude stronger than what Bioware had for the original patches, and stronger than 99+% of the games with modding support (I’m sure there’s some that have us beat, I’m just not aware of any).
All that said, there are things that simply can’t be supported while continuing the development of the game. The most obvious extreme case is that we don’t support “nwncx” and similar exe hacks, because that would mean that we couldn’t ever recompile the game at all. I doubt this is contentious.
Here are some other things that we don’t support:
-
Scripts compiled with a modified nwscript.nss
or 3rd party compilers. I have actually seen in the wild NCS files that try to call a non-existent nwscript function and expect to be terminated when that happens. Since functions are identified by their ordinal number, simply adding new nwscript functions has broken those scripts and any modules that use them. However, we are not going to stop adding new functions just because of them, what they are doing is unsupported.
-
Adding new columns to engine 2DA files. We reserve the right to add new columns to any 2DA and assign certain engine behavior to those. We go well out of our way to make sure that if a module has modified those 2DAs somehow and the new columns are missing that existing-behavior-preserving defaults are used (this results in a lot of table hardcoding in the engine). However, if a module just added random columns of the same name but with different semantic meaning, it can have unintended consequences. We cannot detect this, so this is unsupported.
-
Similarly, we sometimes add new data files that the engine expects. This follows the established naming conventions, so for some of them, such as scripts and blueprints we use nw_
prefix, but 2DA, MDL, SHD and other file format don’t have a naming format. It is possible that one of those additions conflicts with what is in a module’s custom content and cause undefined behavior.
-
File formats are only forwards compatible - Newer game version can always read files produced by older game/toolset version. Going in the other direction is not supported. e.g. MDLs have been extended in ways that makes them not work on 1.69 and older EEs. This includes GFF file schemas. The game is only guaranteed to work with formats that were produced by official tools of version less-or-equal to the current one. If you were to manually build a GFF file with letoscript/nwn_gff/etc and produce an output that does not match output produced by any official tool at any point in time, then the behavior of parsing that output is not defined.
-
Shader includes are not stable. This one is an unfortunate side effect of exposing customizable shaders before all renderer work has finished, since shaders are tightly coupled to the renderer. We try to keep them compatible in various ways (including rewriting shaders on load), however sufficiently beneficial graphics improvements might result in breakage. If you want to avoid that, best to never #include
any stock .shd
files and just manually copy the bits you want to use.
-
The game’s internal resman order and layout is not stable. We could shuffle files around in the .bifs. Modules should not depend on a certain resource being at a specific location; instead they should just assume that it is somewhere that is available. This includes the behavior of ovr/, override/, development/ and similar global folders too - these are not for a module to use.
-
Various toggles in settings.tml are not stable. These are not part of the module API, and a module should not require a certain value for some setting to be playable (e.g. “auto fail on 1” may theoretically be removed).
-
Everything in ruleset.2da is not stable and can be removed or change meaning. This is documented plainly at the top of that file.
-
EDIT2: Anything performance-sensitive can change. For example, we don’t consider it a regression that loading screens now finish too fast for a player to see the image/text.
The above is a non-exhaustive list, but it should cover 90% of it. If there is a specific bit anywhere above that you consider unreasonable, I would like to hear why.
EDIT:
The above is about compatibility being broken on purpose. Bugs do unfortunately happen, but if it’s not one of the above, we will strive to fix them when reported. Unfortunately, what sometimes happens is that a regression stays unreported for a few years and new modules are made with the new behavior in mind, and then even reverting to the old one means breakage. Then, it’s a judgement call to pick the lesser of two evils.
Also, there may come a time when a specific thing will get broken on purpose, because the benefit of doing so is just too good to pass. In these cases, we will try to communicate it as clearly as possible, well in advance, and offer assistance in migrating the code to an equivalent solution that is supported.