Skip to content

Feature request/proposal: Tileset configuration & reskin pack system

LaputianBirdLaputianBird Member Posts: 107
edited March 2018 in General Discussions NWN:EE

TLDR:



I'm proposing/requesting a system that would allow:
- tileset authors to greatly reduce the need for terrain/crosser duplication and for creation/distribution of whole alternative versions of their tilesets
- tileset reskinners to create their retextured version of a specific tileset without any need to touch the model files themselves
- area builders to assign in the toolset a specific texture pack to a specific area, based on the texturepacks available for the specific tileset used to build the area

The system would be 100% backward compatible, no changes would be required for existing tilesets. At the same time, if anybody wanted to apply and take advantage of the system with an existing tileset, it could be done by simply creating and editing a text file.

LONG VERSION:



As a CC author I've been following the development and implementation of the new attributes and systems to extend the modeling and texturing options offered by the game, and I find that at the moment the approach seems to be based on considering each model individually, rather than as part of a set. In particular, I find there is much room for improvement for what concerns tileSETs.

The problem:

Tileset reskins are a popular thing in the CC scene, and up to the current scenario they imply extracting, decompiling and renaming the models, updating the internal name references, changing the texture referenced in the ASCII "code", and then recompiling the models and packaging them as part of a separate tileset.
Aside for the long process, this workflow has at least one critical flaw, which is that since for the engine the reskinned tileset is actually a separate entity, any extending, updating and debugging of the original tileset doesn't automatically propagate to the reskinned version. In other words, each reskin work creates a parallel fork in the development, which introduces the need to manually keep up with any change in the source tileset, or generates the chaotic situation of many different incarnations of the same set of models and hak versions all around the place, each with a different degree of completeness and, uhm, bug-free’ness, if that is a legally usable expression.

A possible solution:

I’m proposing a configuration system for tilesets that includes:
- multiple texture/materials packs assigned to each tileset, with the ability for the area builder to specify which alternative set to load in place of the default one (with a fallback system)
- a companion system that synchronizes any associated placeables pack to use the same texture/material replacements as the area tileset
- local overrides of the default global shaders, to better accommodate for the peculiarities of the textures used in the tileset, and to allow the builder an additional degree of granularity in the area design and in its final result client-side (it refers and integrates my previous request, more details can be found there)

The steps required would be at least:
- a modification/extension of the .are GFF structure to include a “MaterialPack” or “TexturePack” field
- the addition in the area properties tab in the toolset of a dropdown list of available texture/material packs specified in the tileset config
- a config file associated with the tileset by naming convention (using its resref as prefix, like it happens for the edge tile 2da), which provides the data for toolset and game. It’s be preferable for the config file to be a 2da, but it isn’t strictly necessary (more about this below)
- a modification of the engine lookup for textures, with the inclusion of a step in which the engine resolves the texture references using a cached table of contents loaded from the associated config file and the area-specific settings stored in the .are file. Once each texture/material reference is resolved, the engine should be able to proceed with the lookup for resources

As mentioned, the config file would preferably be a 2da file, for several reasons:
- 2das provide arrays which can include as many fields as needed
- 2das are widely used and understood by existing utilities and tools, and by text editors
- 2das are widely understood even by the casual NWN modder, and would provide a familiar environment
- 2das are already used for tileset configuration (specifically for the edge tile settings)

The 2da would be named something like (using the Castle Exterior tileset as an example) tno01_config.2da, and would include the following content:



The “Type” column defines what sort of resource to override, the “Subtype” specifies the name of the global resource if relevant (it’s the case of global shaders), the MaterialSet_Default defines our, uh.. default resources, and each new column defines an alternative texture/material pack. If the column has any value aside for the blank “****”, its header should populate the toolset dropdown menu as an available option. Blank values in such partially populate columns would fallback to the default column.

The walkmesh_material type is necessary in case the texture pack replaces a ground texture with something that expect different vfxs and sfxs (from grass and leaves to snow, in my example). Upon loading each tile model the engine would have to replace the material assigned to each face accordingly.

The “texture/material” type would interpret the strings as .mtr files, and would default back to texture names (.dds, .tga) if such a .mtr file isn’t found - for backward compatibility. Each .mtr file would then specify a whole set of textures, from diffuse to normal, specular, reflective etc.

As a companion feature, the engine would need to use the same cached lookup/alias table loaded from the config 2da and the area properties, and apply any valid substitution upon loading any relevant placeable included in the area it is rendering.
This step is required in order to maintain area consistency in case there is a placeable pack that complements the tileset, as it is common for tileset authors to provide. That way, switching the tileset’s tree foliage to an autumnal flavor by enabling an alternative texturepack would automatically apply to any foliage used by companion placeables, based on texture/material names in the models. Or, using a different example, if the wall and floor textures were changed from a stone material to a wooden material, all placeables elements like columns, balconies etc would follow.

Post edited by LaputianBird on

Comments

  • JuliusBorisovJuliusBorisov Member, Administrator, Moderator, Developer Posts: 22,754
    Moved to General Discussions NWN:EE as there was no request about it.

    Anyway, here's a Trello card for this idea: https://trello.com/c/3zZv2rKL/163-a-configuration-system-for-tilesets
  • InflatableFriendInflatableFriend Member Posts: 57
    Now that there's a board for it are you going to move it back for discussion? :tongue:
  • JuliusBorisovJuliusBorisov Member, Administrator, Moderator, Developer Posts: 22,754
    Maybe if it gets more than 1 page?
  • SherincallSherincall Member Posts: 387

    Maybe if it gets more than 1 page?

    Guess we should paste the discord discussions that led to this? :)


    Anyway, I do have something constructive to add for a change. Last week, we also discussed adding per-client texture overrides, such as:
    
    SetTextureOverrideForClient(object oObject, string sOldTexture, string sNewTexture="", object oPC=OBJECT_INVALID);
    Which would replace sOldTexture with sNewTexture, for oPC when rendering oObject. if oPC is OBJECT_INVALID, it would replace it globally for all players. If oObject is an area, it would replace it for all the tiles of that area. if sNewTexture is "", it will restore the original.

    With a bit of scripting, that can achieve everything @LaputianBird brought up, as far as the players are concerned. However, it would only work in game, and when painting the area in the toolset, the builders would see the original textures, so they'd probably need to use a temporary override/builder hak.

    That said, I think the scripting approach is far more flexible and should be given priority, and the additional stuff posted here can probably be built on top of that.
  • LaputianBirdLaputianBird Member Posts: 107


    With a bit of scripting, that can achieve everything @LaputianBird brought up, as far as the players are concerned.

    I'm not sure I agree that the script approach would get anywhere close to the config system proposed, or maybe I should say that it's opportune to add more to what you're hinting at, which is the "as far as players are concerned"

    It is true that the ability to handle the textures in game can be achieved in various ways, but the main benefit of this approach is for tileset authors, reskinners and builders, as it creates a simple and powerful system that abstracts the modeling step from the texturing step well enough that the resulting workflow will potentially generate a blossoming of tileset variations, which is what would ultimately enrich the experience for players.
    A script based system has a main flaw in my opinion, which is that the textures need to be already present in the hakpack, and that authors/reskinners would have to provide such texture packs without a configuration file, that would have to be built by the scripter in the toolset by manually reconstructing a set of co-ordinated changes, while the purpose of the system is that of having one global config location where textures can be organized in set once and for all.
    At some point there'd be the need to have some sort of scripted library with pre-configured sets of coordinated textures, which ironically would end up being the sort of config file that I'm proposing as a 2da.

    Furthermore, a tileset author isn't necessarily familiar with scripts or be willing to provide such pre-configured scripted database of texture/material replacements.

    Not to say that the scripted tools wouldn't have their use and usefulness of course, but I tend to see them as a fine-tuning step of the system, with the ability to adjust the material overriding on a per-object basis and/or per-client basis


  • SherincallSherincall Member Posts: 387

    A script based system has a main flaw in my opinion, which is that the textures need to be already present in the hakpack, and that authors/reskinners would have to provide such texture packs without a configuration file, that would have to be built by the scripter in the toolset by manually reconstructing a set of co-ordinated changes, while the purpose of the system is that of having one global config location where textures can be organized in set once and for all.
    At some point there'd be the need to have some sort of scripted library with pre-configured sets of coordinated textures, which ironically would end up being the sort of config file that I'm proposing as a 2da.

    Actually, that is what I meant when I said doable by scripting. I meant that we could implement the same system using the 2DA files, standardize it among the CC authors and work from there. It wouldn't get a special dropdown in the toolset, but you have the GUI to edit local variables, and that's good enough, really.
    I don't see that as a flaw - instead of relying on BD to maintain the system, we'd have full control over it.


    The scripting approach does have a fatal flaw of only working in the game, not the toolset. Normally, this would be enough to shoot it dead in the crib, but since the same thing would have many other uses, I was just saying it seems pragmatic to do that first. And the toolset!=game problem will need to be solved somehow for the NSS/shader API. It'd be very good to keep this (the original post) proposal in mind when it comes to that.
  • LaputianBirdLaputianBird Member Posts: 107
    edited March 2018


    Actually, that is what I meant when I said doable by scripting. I meant that we could implement the same system using the 2DA files, standardize it among the CC authors and work from there. It wouldn't get a special dropdown in the toolset, but you have the GUI to edit local variables, and that's good enough, really.
    I don't see that as a flaw - instead of relying on BD to maintain the system, we'd have full control over it.

    The scripting approach does have a fatal flaw of only working in the game, not the toolset. Normally, this would be enough to shoot it dead in the crib, but since the same thing would have many other uses, I was just saying it seems pragmatic to do that first. And the toolset!=game problem will need to be solved somehow for the NSS/shader API. It'd be very good to keep this (the original post) proposal in mind when it comes to that.


    So if I'm getting this right, you're proposing that while we wait for BD to have the time and/resources to implement it on an engine level, with proper toolset support and even (heavens forbid) a new dropdown element in the UI, we could use the same config/2da file approach, load the 2da data with a script call, and use local variables to set the texturepack on the area.

    All this as long as BD at least implements the shaders API and the TextureOverride scripting function?
    I could settle for such a temporary solution, even if I guess it'd be less perfomant, beside the issue of not being visible in the toolset (which is a real annoyance since the point of the toolset nowadays is mainly that of being able to compose the visual aspect of areas, everything else can be done with external tools)


  • virusmanvirusman Member, Developer Posts: 173
    This approach wouldn't enable drop-in texturepacks, right? Since it's a single 2da, all texturepacks will have to be specified there (and since they're based on columns, merging them won't be straightforward.
    Is there a way around this?
  • LaputianBirdLaputianBird Member Posts: 107
    edited April 2018
    virusman said:

    This approach wouldn't enable drop-in texturepacks, right? Since it's a single 2da, all texturepacks will have to be specified there (and since they're based on columns, merging them won't be straightforward.
    Is there a way around this?

    That could be easily achieved by splitting the 2da and extending the naming convention:

    [tileset_prefix]_config_[pack_suffix].2da would then contain only the first 4 columns (type, subtype, default value, texturepack value).
    Any texturepack would be an independent drop-in, assumed it contains a config 2da.

    However, that would also increase the risk of outdated or incomplete texturepacks floating around, as the further development of the tileset might extend or even replace a subset of textures.
    Using one global 2da has the drawback of not allowing completely independent texturepacks, but the benefit of forcing a consistency check because additional texturepacks must be merged in manually.

    Furthermore, some config features would be independent from the texturepack approach, like the ability to override global shaders for the specific tileset, so if the texturepacks are split into their own separate files, a tileset global config file would still be necessary.

    In short, the approach could become:

    [tileset_prefix]_config.2da <---- global tileset settings

    [tileset_prefix]_config_[pack_suffix].2da <---- texturepack specific. Might include global settings too (shader overrides etc). Has higher priority on the global tileset settings file

    I'm not sure it's worth though, I kind of like the simpler setup with only one centralized tileset config file, it's easier to have everything under control even visually. All rows would be the same for all texturepacks etc.
    Also, I don't think that nowadays it'd be a problem to create a texturepack merger, if necessary. In fact, I'm going to create a new .set editor, and such a functionality can be easily added to it

Sign In or Register to comment.