Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle template NPCs #90

Closed
focustense opened this issue Aug 13, 2021 · 5 comments
Closed

Handle template NPCs #90

focustense opened this issue Aug 13, 2021 · 5 comments
Labels
easynpc Issues/requests relating the EasyNPC app enhancement New feature or request
Milestone

Comments

@focustense
Copy link
Owner

First observed in #61 by commenter llyarc:

If one npc template has another npc, using a different face in this case may cause problems

This is referring to NPCs with a TPLT reference. I have to admit to being a little confounded over how this is supposed to work, and it probably needs some testing in game.

Inspection of existing records, such as the ones based on EncSoldierImperialTemplate, show that the templated NPCs don't use the same head parts, and might not even be the same race.

Looking at the wiki page, I believe the magic ingredient is the template flag "Use Traits". This is described, partially as:

Traits tab, including race, gender, height, weight, voice type, death item; Sounds tab; Animation tab; Character Gen tabs

My initial hypothesis is that even though such NPCs may specify their own race, head parts, and so on, these are supposed to be ignored by the game in favor of the template.

Most templated NPCs do not specify Traits, such as the one above, but there are those that do, such as the EncThalmor based templates.

If the hypothesis is correct, then these NPCs should be hidden from view in EasyNPC, and ignored in any saved profiles. However, when generating the actual merge, their records, facegens and facetints do still need to be copied, but there are no choices for them, they must be exact copies of the template.

Emphasis on hypothesis, I won't implement any of this until I can determine if that's the actual mechanic.

@focustense focustense added enhancement New feature or request easynpc Issues/requests relating the EasyNPC app labels Aug 13, 2021
@focustense
Copy link
Owner Author

Looking back at some existing mods and some of the few remaining false positive warnings in the dev branch actually give more of a clue.

Two examples that have come up are the Gormlaith offshoots (SummonGormlaith and MQ206Gormlaith) in Kalilies NPCs, and MQ304Rikke in Bijin NPCs. All of these point to the original NPC (GormlaithGoldenHilt and Rikke), and in each of the mods in question, where these characters are known to work, the templated NPC - which does not have a facegen - uses the same headparts as the original NPC, and has the Traits flag.

I believe this confirms the hypothesis: a templated NPCs head parts, and facegen file, should be identical to the template. They should be excluded from view, and be given a copy of the template's face attributes and facegen in the patch/res-merge process.

focustense added a commit that referenced this issue Aug 16, 2021
Each build check is now independent, and implements an interface so that an IoC container can inject them all into a build checker as a list/enumerable.

Checks have also been rewritten to use the new analysis system, and not have any generic parameters. The facegen check in particular now compares head parts and produces virtually no false positives - the only ones remaining are template NPCs, to be handled in #90.

A few minor features may be missing and labeled as todos.

#26 #37 #50 #64
@focustense
Copy link
Owner Author

This has a simple solution in concept, but is actually turning out to be rather more nuanced in practice, because it is possible for plugins to change where a template points, and some plugins actually do (OBIS for one, and I wouldn't be surprised if USSEP or other mega-patches did as well). It's not common, but it happens.

From a usability point of view, it would be best to hide templated, trait-inheriting NPCs. Face choices aren't really meaningful for them, and they clutter up the list. On the other hand, it's not possible to predict with any certainty who the conflict winner will be after the "source mods" used in EasyNPC are disabled, if the default selection for these template NPCs is hidden from the app itself. Just because OBIS is in the load order now, doesn't mean it will be (or that something else won't override it) when the mod is activated. On the other other hand, it's stupid to include override records in the EasyNPC mod at all when they won't do anything useful, it would be preferable to leave this up to the modder and his load order... but then we run the risk of an inconsistent facegen.

I'm not exactly sure what the right answer is yet. Really want to remove useless choices and clutter from the UI, but not sure if it's possible to deterministically resolve the facegen without requiring users to choose at least the default plugin. And this isn't even considering the scenario of plugins "de-templatifying" an NPC and turning it standalone, which is probably game-breaking in itself, but I'm not surprised by anything anymore.

Maybe it's possible to use an heuristic method to determine the proper, implied default plugin for a templated NPC, using some or all of the following:

  • The default plugin selected for the template target, as determined by the original record
  • The list of masters already specified for the merge, and their load order
  • The overhaul plugins that are not masters, which can be assumed to be pending deactivation... probably

Doesn't feel exactly right, but the only alternative that springs to mind including all of these in the UI, and I guess trying to provide some visual cues. But even in the UI, any visual cues are actually dependent on whichever plugin is currently selected as the default, so this may end up making things even more confusing.

Time to sleep on it.

@focustense
Copy link
Owner Author

To add insult to injury, I thought of another corner case, which is a face plugin changing a non-templated NPC (or non-trait-inheriting NPC) to use a trait-inheriting template, and depending on that behavior i.e. by not providing a facegen.

I think that is sort of handled by simply producing a warning and treating it as a missing facegen, since the merge won't take the template setting from the overhaul. But if any mods actually do this, it could result in confusing behavior.

@focustense
Copy link
Owner Author

Here's what I'm thinking after a short break:

  • If all overrides for an NPC in the current load order point to a LVLN or invalid template, exclude it completely from the profile. These don't have a specific appearance, don't support facegen and there's nothing useful we can do with them.

  • If all overrides for an NPC point to the same template target NPC and all inherit traits, then keep it in the profile but hide it from all UI, since it makes no difference (for face attributes) which one is used as default. Don't generate any record for this NPC (let the load order handle it). Ideally we wouldn't copy facegen either, but because there is a possibility that some other plugin is trying to provide a conflicting facegen, we should still copy the facegen from the template target as the templated output.

  • If some overrides either change the target NPC or change the traits flag, then we have to show the NPC in the UI. However, whenever the currently-selected default plugin specifies trait inheritance, disable all of the face customization UI and render an informational message instead. Then, at build time, copy the default record normally, and for face:

    • First see if the templated NPC has a face option with the same plugin as the template target; if so, copy face attributes from that.
    • Otherwise, copy face attributes from the actual target record.
    • Always copy the target record's facegen as the templated facegen (see above, this may not require a facegen but I'm worried about other mods conflicting.)

Not nearly as simple as I'd hoped, but I think the behavior should not be too confusing, and will considerably cut down on the bloat.

@focustense
Copy link
Owner Author

I've also just noted that templates can be recursive, i.e. NPC template referencing another NPC with a template pointing to... etc.

I'm not sure how the actual game is supposed to behave with multiple layers of trait inheritance and don't want to spend the whole day testing it, so for now I'm just going to assume that it only applies to the specific NPC that inherits traits. If its target also inherits traits and doesn't have a facegen... then the lowest-level one simply won't end up with a facegen, no difference between EasyNPC output and original input.

focustense added a commit that referenced this issue Aug 19, 2021
The important information right now is the target key (obviously), the target type (if it's not an NPC, then the templated NPC shouldn't have any facegens), and whether or not it inherits traits (i.e. facegens).

#90
focustense added a commit that referenced this issue Aug 19, 2021
This prevents editing any face attributes in the UI, and shows prominent messaging that they are templated.

Also ignores these in most build checks and build tasks. A few tweaks are still needed for edge cases.

#90
@focustense focustense added this to the v0.9-beta2 milestone Aug 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
easynpc Issues/requests relating the EasyNPC app enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant