Skip to content

Suggestion/Feature Request - Making custom part appearances available cross-module

Has a method to make 2da-dependent parts like clothes or creature appearances available to players as module-independent standalones been discussed yet?

I've set up console command scripts for switching bodyparts by number which can be called from any module someone is playing, allowing players to (for instance) switch their head models out for any specific one by number. For heads, this works because heads don't have a linked 2da file at the moment - players can just place heads, and the head-changing scripts, in their override folder. At that point, the remaining issue is that same-numbered heads in module haks would override the head model and/or texture.

I'm tempted to suggest an expanded or additional SetCreatureBodyPart function (SetCreaturePartModel?) that looks for the model by string rather than 2da number, not in the least because the mental image of replacing the hands and feet with heads amuses me more than it ought. Or hands with axe heads, or longsword blades. Robe models would have the problem that their 2da information on which bodyparts to turn invisible would be missing, but that could be worked around via scripting, setting up a spawn script for each robe-based clothing item that creates an armour with invisible model appearances in the slots needing to be hidden for that particular robe. Or maybe SetHiddenWhenEquipped could be expanded to be able to target individual parts in armours.

For heads, as things are working right now, greatly expanding the number slots available to use would do the trick, too. If I could put the override-installed heads on, say, numbers 8001 and upwards, they wouldn't clash with any module-hak-heads we've currently got. There'd still be the potential for custom-content compatibility issues going forward, if other people use the same numbers for their stuff, but it'd be a quick fix for the current problem.

::headscratch::

Throwing the thought out there, anyway. Other solutions would be most welcome.

Comments

  • LaputianBirdLaputianBird Member Posts: 107
    edited May 2018

    I'm tempted to suggest an expanded or additional SetCreatureBodyPart function (SetCreaturePartModel?) that looks for the model by string rather than 2da number

    Wouldn't work. The engine could look up a model by string, true, but what happens when it needs to save the gff file related to the object? The current GFF structures for body/clothing-part objects (.bic and .uti) use integers, not strings. To implement such an alternative logic, the GFF format would need to be extended, and moreover implementing additional logic to match strings and IDs (which is currently covered by the pertinent 2da) would be required.

    Furthermore, the model "string" follows a naming convention that locks the model name to the numeric ID in the 2da (necessary for things like gender/racial/pheno variations of the ID stored in the GFF), so if models were given a string/name independent from their numeric ID, the whole variations system would require to be redesigned, I believe

    [edit]
    There is also the issue of the lookup for plts done on the basis of the model name, which should be taken into account for the gender/racial/pheno variations


  • TheBarbarianTheBarbarian Member Posts: 58
    edited May 2018
    Hmm. Good point. >_< What other options could there be for making creature and body/armourpart appearances available cross-module?

    Additional 2das? What if the .bics and .utis could store the name of the 2da to use for a part in addition to the row number in that 2da, defaulting to the standard 2da for the slot if no custom one is specified? Appearance-adding packs could maintain their own custom parts 2das that don't conflict with one another.

    If custom 2das follow a set naming scheme to group them, maybe they could even all be used to automatically load their contents into one big list - parts_robe.2da, parts_robe_dinocostumes.2da, parts_robe_sparklydresses.2da and so on. Making manual 2da merging unnecessary going forward would be pretty neat, if it's doable somehow.

    That'd still have the problem of same-numbered model/texture files in different packs overriding one another, though. :frowning: I hmm at this.

    Edit: Could they be made to look for custom parts matching the 2da name - as in, if parts_robe.2da looks for pfh0_robe###.mdl and so on, then parts_robeaaa.2da looks for pfh0_robeaaa###.mdl, and it's other race/gender/pheno variations?
  • LaputianBirdLaputianBird Member Posts: 107
    edited May 2018

    That'd still have the problem of same-numbered model/texture files in different packs overriding one another, though.

    Yup. The problem is not the 2das, they are part of the solution.
    It's the model naming that needs a pattern (prefixes, type) and a unique ID (the numeric suffix).
    Even that body part that doesn't use a 2da suffers from this, as you pointed out. Heads are overridden by hakpack content, as any other asset. You can move the GFFs from one module to the other freely, the engine doesn't prevent it. But the meaning of the IDs changes depending on the context.

    Most body/clothing part 2das have the only purpose of telling the engine what models exist, if they were removed and the engine did a lookup based only on the IDs stored in the GFF files, the benefit would be minimal. You'd be able to add some models through the override, but like for heads, no guarantee that they wouldn't be overridden

    Edit: Could they be made to look for custom parts matching the 2da name - as in, if parts_robe.2da looks for pfh0_robe###.mdl and so on, then parts_robeaaa.2da looks for pfh0_robeaaa###.mdl, and it's other race/gender/pheno variations?

    Using custom 2da names (or embedding a referenced 2da in the GFF) doesn't solve the issue either, that would again pose the issue of potential different versions of the same 2da scattered in overrides or hakpacks, just like it does for models.




  • TheBarbarianTheBarbarian Member Posts: 58
    What're you thinking for the 2das? Automated merging on gamestart (adding prefixes/suffixes to found models/textures to have unique instances of them, generating a single 2da using the matching unique rows in all found 2das) and then doing the same again on module load? With ridiculous amount of buffer space in between default game/override/patch hak/module hak content sections? ::chinscratch:: Or something different entirely?

    Concern: When setting up content, the models tend to glitch if the internal naming/numbering doesn't match the file name. Would each found .mdl need to be altered to have the prefix/suffix added to it internally as well as to the file name? Would that be a problem? Some of those existing haks have a lot of files in them. A good bit of existing custom content has been uploaded compiled, too.

    Using custom 2da names (or embedding a referenced 2da in the GFF) doesn't solve the issue either, that would again pose the issue of potential different versions of the same 2da scattered in overrides or hakpacks, just like it does for models.

    Isn't that the same problem as if somebody tried to put two different "thisisanexample.hak" files into the hak folder and had to decide which to override, though? Two content creators giving their content packages the same name isn't a horribly hard-to-solve issue. Unless both parties get stubborn about the other person being the one to change the name a little, anyway. ^^

    A scheme where custom parts_*.2das are set up separately and have a custom pre- or suffix that automatically looks for models of the current naming scheme but with the same pre-/suffix as the 2da seems like it would allow for continuing to use the system as it currently works as well as have separate model files unique to a package. ::headscratch:: It couldn't break any existing 2das or modules either, since it doesn't touch them at all. Custom parts could be installed in standalone packages, and be made usable via scripts provided by the package creator - like armour-appearance-changing self-conversations swapping through nothing but the parts in the specified 2da. True, it doesn't automate making different custom content packages compatible with eachother at the end user's PC, but we already have utilities for renaming models and textures, so making new packs using this method wouldn't take long. It seems like a fairly quick, easy, and safe way to bring module-independent custom appearance packs to players. Hm. Except for heads... since... heads don't... have a 2da. :frowning: Ugh. There's always something.

    But then, heads could work well enough with just having the available numbers expanded greatly, since lack of a 2da means the override installation method works fine. Plenty of games have the problem that custom content is set up on specific, conflicting numbers, and you can only install one or the other pack. There doesn't seem to be a great deal of outrage over it.

    Not saying it's an ideal solution, and not saying it's the best solution we're going to come up with, but it mightn't be the absolute worst way to go about it either. May be worth considering some, unless automated merging of some sort is already underway or better ideas come up.
  • LaputianBirdLaputianBird Member Posts: 107
    edited May 2018

    What're you thinking for the 2das? Automated merging on gamestart (adding prefixes/suffixes to found models/textures to have unique instances of them, generating a single 2da using the matching unique rows in all found 2das) and then doing the same again on module load? With ridiculous amount of buffer space in between default game/override/patch hak/module hak content sections? ::chinscratch:: Or something different entirely?

    Concern: When setting up content, the models tend to glitch if the internal naming/numbering doesn't match the file name. Would each found .mdl need to be altered to have the prefix/suffix added to it internally as well as to the file name? Would that be a problem? Some of those existing haks have a lot of files in them. A good bit of existing custom content has been uploaded compiled, too.

    You're underestimating the amount of resources that it'd take to traverse the whole range of possible sources, and the number of relevant files. The resman routine does the lookup per-asset, if and when the engine requires it. Even assuming that browsing the whole game and custom resources was feasible, the game then needs to analyze the 2das and the file names, which is a huge and slow task. Let's assume again that it's feasible: the next step would be renaming on the fly all those resources that conflict, which is a complex task, as models reference other models and reference textures, all internally - so you'd have to traverse the whole game and custom content to update all references to the renamed models.
    What happens to those files that need to be renamed and that reside inside hakpacks? You'd need to save them somewhere with their new name, ready to be loaded if the engine requires them. Should the engine decompile them and save them as ASCII files in the override? And then there is the even worse part: since each module has a different set of haks, you'd need to do this gargantuan merging on a per-module basis, and what happens of those files that were already renamed?
    And what happens when you join a server? You'd likely need to revert some of those changes again.

    In other words, you'd be adding to the game a never-seen-before custom content manager that can merge/harmonize on the fly the whole game and the whole custom content present on the client. Every time you start the game and load a module.

    There is already a way to do that, and much simpler: create a global set of haks and setup all your modules to use it

    Isn't that the same problem as if somebody tried to put two different "thisisanexample.hak" files into the hak folder and had to decide which to override, though? Two content creators giving their content packages the same name isn't a horribly hard-to-solve issue. Unless both parties get stubborn about the other person being the one to change the name a little, anyway. ^^

    It requires user input, hence defeating the purpose of an automated system.

    A scheme where custom parts_*.2das are set up separately and have a custom pre- or suffix that automatically looks for models of the current naming scheme but with the same pre-/suffix as the 2da seems like it would allow for continuing to use the system as it currently works as well as have separate model files unique to a package. ::headscratch:: It couldn't break any existing 2das or modules either, since it doesn't touch them at all. Custom parts could be installed in standalone packages, and be made usable via scripts provided by the package creator - like armour-appearance-changing self-conversations swapping through nothing but the parts in the specified 2da. True, it doesn't automate making different custom content packages compatible with eachother at the end user's PC, but we already have utilities for renaming models and textures, so making new packs using this method wouldn't take long. It seems like a fairly quick, easy, and safe way to bring module-independent custom appearance packs to players. Hm. Except for heads... since... heads don't... have a 2da. :frowning: Ugh. There's always something.

    But then, heads could work well enough with just having the available numbers expanded greatly, since lack of a 2da means the override installation method works fine. Plenty of games have the problem that custom content is set up on specific, conflicting numbers, and you can only install one or the other pack. There doesn't seem to be a great deal of outrage over it.

    Not saying it's an ideal solution, and not saying it's the best solution we're going to come up with, but it mightn't be the absolute worst way to go about it either. May be worth considering some, unless automated merging of some sort is already underway or better ideas come up.

    Using partial matches in theory could work on the 2da side, but I think there is a misunderstanding. The engine logic isn't 2da-centric, it's GFF-centric. It's the GFF format what dictates how to use the resources. The 2das are just a tool to link the game objects to a visible model.
    In the end the problem is again how the relevant GFF stores the data. NWN as a whole uses numeric IDs, which are reliable because they are unique, relatively to the context (the module, primarily). If the engine could read 2das with a partial naming match, how would it prioritize them, how would it generate the unique IDs, and how could translate between the local/specific context of a module and the whole game context?
    The GFFs would need to use the model name as their string ID, which is a complex change and would affect existing systems

  • TheBarbarianTheBarbarian Member Posts: 58
    Not underestimating. I'd kinda meant to point the complexity of it out. :-) I'd been trying to figure out where your thinking is going with it, if the potential for custom 2da naming conflicts between content creators disqualifies a method. So, tried to picture methods that avoid the potential for naming conflicts entirely. You'd say "Have the builders decide the content on a per-module basis" then, yeah? Fair enough. ^^ That is the situation we've got, and it works. Don't try to fix things that're not broken, yeah.

    I've been looking at it from a singleplayer-player-oriented perspective. Yes - builders can put together hak packages to use in modules. But using custom appearances within different modules is difficult as heck to do for players. Even appearance override packs get overridden by module content in turn (necessary, not questioning that). So far, to get custom appearances for 2da based parts into a module (that has it's own version of that 2da), players would have to open the module haks and merge the lines for their files into the module 2das one module at a time. Installing extra visual content is ridiculously difficult for players to do right now. And 2da merging isn't a whole lot of fun on the builders' end, either.

    The starting point is already clunky and user-involved as heck, and the possibility for compatibility issues between content creators (potential of hak naming conflicts, certainty of 2da conflicts, and .mdl naming/numbering conflicts are already common to the extreme) already exists anyway. It'd be good not to have the potential for naming conflicts at all, but keeping it wouldn't exactly be a loss from where we're standing right now. It seems odd for retaining an already existing limitation to disqualify opening up new possibilities unless the existing limitation is meant to be removed going forward.

    Maybe there could be an alternative to trying to save model appearance changes at all, too. Commandline scripts to change the appearance that have to be used again on reload? Maybe if reapplying the appearance change when necessary could be automated in some way? Even a non-persistent method changing the visual appearance to any model by string could make for a pretty fun gimmick (Axe! hands!) to be used in scripting by builders.

    Depends on whether it can actually work in practice, though, yeah. I can't judge that. :-/ Far as the custom parts 2das thing goes, the method of storing the by number doesn't need to be changed; you'd just need to add a field for the name of the 2da to use for that part, and then look for models following the usual naming scheme but with the custom 2da's suffix. With a noob-y glance at the documentation and cracking up a .bic with a GFF editor, GFFs look to be able to store strings just fine - see stored character name/description/etc. But this is lack of knowledge talking, yeah.

    Far as the prioritizing and differences between specific-module- and entire-game-contexts go - 2das are already being changed in between modules, aren't they? Module-attached 2das override the default game 2das just fine - like how the available appearances in the toolset change when you attach a custom 2da. Wouldn't it be just the same thing, only looking for more than one 2da while reading 2da contents? Go through them one at a time, alphabetically, until no parts_whatever*.2das are found anymore. Entering a module with a .bic that's referring to a row number in a nonexistent custom 2da from a previous module would show a missing model for the part, but custom 2das could be accessible from all modules, like via the override folder. Or chuck all the custom parts 2das into a new NWN\2da\ folder, and look for custom 2das to load in addition to the module-level one in that folder only.

    It'd be pretty cool if that actually worked. No more 2da merging for builders when installing new packs set up with this method, plus standalone content packs available to singleplayer players cross-module. Food for thought for the people doing the backstage wizardry, I suppose.

    hmm.

    In case scripting to switch to models by name isn't an option, and modularizing 2das isn't an option, does anyone have more ideas for ways to give players access to appearance packs cross-module? Leaving it entirely up to the builder what appearances they want to make available to players in their module is supportive of the builder's artistic vision, but character customization options are in pretty dang high demand in RPGs. I think it might be good for NWN to look into a player-empowering means of doing this, even if it does prove to be more work than it's worth when examined closely and has to go into the bin. And I'd really like to get to upload some robes as plug-and-play standalone additions to the game for Steam Workshop players.

    Time to get a bucket of caffeine and read that GFF documentation in detail. :pensive:
  • LaputianBirdLaputianBird Member Posts: 107
    edited May 2018
    I don't think there is any way to make such a system available to players as an engine feature. Even assuming that a partial match approach for 2da files worked (it wouldn't, as you'd need a logic to prioritize duplicates - and if you used the current game logic it would be the resman hierarchy, with hakpacks at the top), it would only work from now on, any existing content (GFFs, 2DAs and .mdls) wouldn't benefit from it. Defeating the original purpose.

    However, since either way such a system would need a NEW beginning, then the option is already there without any need to alter the system: create a community policy of never including module-specific body/clothing parts in SP modules, and offer a community-wide package of such assets.
    In other words, a CEP-like package, but done the right way.
    Updating old modules to the new standard would also be possible, but the result would need to be manually evaluated per-module.

    The issue is always the same, all module content was created in the context of a specific, module-scoped context. Changing the context, by overriding the original builder's choices with a new set of hakpacks, or by adding a fancy global 2da-based approach, both yield the same result: it can work or it can trash the module, based on the use the builder made of the context. Even if you imagine a programmatic way to update the GFF files to the new context, such tool would be blind to the visual/gameplay result (changing a chest model can turn a full plate into simple clothes for example) - and you'd need again a qualified evaluator to approve the "upgrade". Or you'd need to teach the tool some very advanced analysis AI, and how to apply it to the specific context of each single module (would need to be able to compare the visual content of different stand-alone resource packs, and decide filtering/overriding criteria on its own)

    It's the bane, but also the blessing of NWN: the context is always the module. Creating a module-agnostic system is against its nature. It can be done, but only with the explicit "permission" of the module, which needs to give up its prerogatives, by not including a certain class of assets or by adopting one that is shared with other modules.
  • TheBarbarianTheBarbarian Member Posts: 58
    edited May 2018
    I'd've thought the fact that the existing content packages wouldn't be affected by this kind of system change to be a plus, as it's in line with the overarching goal of preserving full backwards compatibility. I'm not asking about a means to merge or affect existing content, here, but about one to make new 2da-dependent content accessible from modules that it hasn't been manually attached to.

    Reminder:


    Has a method to make 2da-dependent parts like clothes or creature appearances available to players as module-independent standalones been discussed yet?

    ^- The original purpose put forth here. :-)

    Avoiding automatically overriding existing content, thereby mucking with the modulebuilders' choices or risking optical (or, in case of placeables, walkmesh-breaking) compatibility issues, is at the root of this concept. If a module was built without a specific custom additional 2da, then no objects in it would be referencing lines in that 2da. Hence, no parts in the module can be affected by the addition of or changes to an additional 2da. The content would simply be available for the player to manually and deliberately create and use, such as via commandline scripts. Same as with the first idea of a scripting function that makes models targetable by string name; it's not meant to override existing module content, it's supposed to make 2da-dependent content accessible for players in modules that have their own 2das attached.

    I think the current hierarchy would work just fine for that. If a module has a custom additional 2da of a specific suffix attached that's overriding an override folder or patch hak level version of that 2da, why not just let it? It'd give the modulebuilder the ability to block specific appearance packs from their module at very low effort, just by adding an empty 2da under that name to their module hak. But if that's deemed undesirable, I'd think it entirely possible to add a new folder just for 'partial' 2das and load it after the contents of the module haks.

    The first (in order of importance) qualified evaluator to approve the upgrade in this scenario is the player who is choosing to download and install the pack. I'd say it's for each individual player to decide whether they want to play the game wearing lolita dresses, or spiky armour, or riding around on a giant chicken mount. Or, heck, if a player decides that they want to play ADWR while using the creature appearance of a triceratops for their character, more power to them. Go team Chaotic! :-)

    The second (actually first in order of appearance ::confused headscratch::) qualified evaluator is the content creator, who may reasonably be expected to test their content before uploading it to make sure it's working as intended.


    create a community policy of never including module-specific body/clothing parts in SP modules, and offer a community-wide package of such assets.
    In other words, a CEP-like package, but done the right way.
    Updating old modules to the new standard would also be possible, but the result would need to be manually evaluated per-module.

    Do we have people willing to implement and maintain this new package? The idea of a new, 'done right' CEP has been brought up every now and then across the years, yet nobody stepped up to actually do it. If we don't have people who would start and maintain such a package, then this is not going to be happening in practice. Note how existence of a functional system, even if unsatisfactory in some way, tends to make people view changing the current system or setting up a new one with a great deal less enthusiasm.

    Also, establishing an one-size-fits-all community policy for anything is practically impossible to pull off (see real world politics). We'll never manage to get all module creators to agree to use a particular package by default, or to refrain from using other packages entirely. The more a system depends on getting people to work together, cooperate, and (most importantly) agree on a single set of rules, the more troublesome it'll be to maintain. There are ongoing module projects whose creators may not look favourably on the notion of having to rework their module and all it's haks for compatibility with an unproven new system. Or, imagine if a large amount of modulebuilders are cooperative towards the community hak package and start lodging requests for content to be integrated into the package so they can use and work with it. You'd have to handle constant requests for the new content to be integrated into the community hak 2das, and the builders would have to wait on that happening or risk having to redo parts if they simultaneously hand in content different builders inadvertently handed in to community pack maintenance that they integrated into the same row numbers, unaware that somebody else was doing the same. I suppose we could make everyone push and pull the 2das, but that also means we'll need people who're spending time teaching every new builder to use Git.

    And, unlike an engine change, it wouldn't work for existing modules without people having to manually edit, test, and reupload each and every single one of them. If the proposal includes "Adjust every single existing Neverwinter Nights module to use a new set of haks", it's going to fail to ever be completed in entirety on grounds of module licensing issues. Not all modules were uploaded with permission to edit and redistribute. The existing module 2das also aren't identical, and in the case of 2das with models following a default naming scheme (armourparts), we can't even retrieve the row number using the model name (placeables) to even start trying to batch adjust the row numbers the objects are referring to; it'd have to be done manually. With enough volunteers, we might be able to add the haks to some modules that don't already use haks - but we're never ever going to manage to complete adjusting all of them, we're not going to be crafting new content in the time we're spending doing that, and the content is still not going to be available to players in any of the modules we haven't finished manually adjusting yet.

    Realistically, what'd happen is that the new package would be available for builders to use, and some builders would use it, some would stick with the CEP or Project Q, some would stick with their own module haks. We can't force builders to use a particular hak package, community policy or no. There are always going to be people who'll flip you the bird and go "You're not the boss of me! I'll do what I darn well want to!" just for the attempt to impose some kind of community standard on them - and they've got a point. What're we going to do about it if they don't adhere to the policy? Stone them? Tar and feather? :-/ Peer pressure only goes so far, and it's not very pleasant for anyone involved. I wouldn't be comfortable being involved in any system that even attempts it.

    While I'm not meaning to discourage anyone who wants to tackle the "Let's make a new CEP done right"-project, and anyone who would like to do so is quite welcome to integrate the stuff I've crafted if they like - far as fulfilling this particular feature request goes, we'd be adding one more package that's incompatible with the other ones we've already got, and the objective of making 2da based content available to players cross-module still wouldn't be met. The benefits and detriments of these design decisions really aren't identical. It's not quite a matter of 'This can be done already with the means we've got'.

    A technical solution of some sort that allows each content creator to maintain their own package independently would be much easier to handle diplomacy-wise alone, in addition to bringing new content to players cross-module affecting all existing modules immediately and making 2da merging unnecessary for builders when using content packages set up in this style going forward. And, for BD, it'd be a matter of implementing the system change once - they wouldn't be in charge of maintaining the content packs themselves. From that point on, the content creators could work and upload independently, and no existing modules would need reworking in any way; not by us on the content creation or modulebuilding end, not by the players.

    ::chinscratch::

    So, yep. What I'm saying here really is "Yay! Consider looking into giving the engine some capability for module agnosticism (this term is amazing and I love it ^^), if it's technically doable!". I think it'd be a good idea and could very quickly spruce up playing through old modules from the players' perspective, and the point of development isn't normally to only add features that already exist anyway. This isn't Neverwinter Nights: As It's Always Been, it's Neverwinter Nights: Enhanced Edition. It not being identical to 1.69 and earlier in every way is the selling point.

    If something like this could be pulled off, it'd be a major argument in favor of developing for the EE version of NWN, specifically, for asset pack creators and modulebuilders both. It'd essentially be that CEP-done-right people've been wanting, without the need for user coordination and centralized maintenance, able to be added on top of the existing packs, and able to be accessed by players from within existing modules without a need for manual alteration of the module.

    ::waves "Go Module Agnosticism!" sign about:: ::gets out the megaphone:: ::builds tent::


    also, increase maximum numbers usable for heads, pls >_>
Sign In or Register to comment.