Jump to content

Apotheosis - Mod Editor for Deadfire


Recommended Posts

On 10/16/2023 at 10:36 AM, HurukHai said:

Hi Noqn awesome job with this!

Thanks, your tool looks awesome too ❤️ I'll take a more in depth look at it tomorrow

Quote

One question, did you know if there is posible reset companion stats without start a new game? my changes only take efect on new games.

Maybe using the RemoveFromParty / RemoveFromPartyAndLeave scripts could reset the stats? You could try running them as console commands to test:

https://eternity.obsidian.net/game-data-formats/scripts#RemoveFromParty

I have a gut feeling it won't work, but it's the only thing I can come up with and is worth testing at least

Edited by Noqn
  • Like 1
Link to comment
Share on other sites

I've made some test this week, and it seems that the stats can be overridden until the companion is instantiated. For example:

 - Eder appears to be instantiated in a new game, so you should mod him before starting a new game.

 - However, all other companions (Pallegina and Maia have not been tested yet) seem to be instantiated once you start the dialogue that allows you to recruit them.

It's pending to test what happens if you load a previous save with other companions (Eder is not working).

  • Like 1
Link to comment
Share on other sites

On 10/19/2023 at 4:58 PM, HurukHai said:

I've made some test this week, and it seems that the stats can be overridden until the companion is instantiated. For example:

 - Eder appears to be instantiated in a new game, so you should mod him before starting a new game.

 - However, all other companions (Pallegina and Maia have not been tested yet) seem to be instantiated once you start the dialogue that allows you to recruit them.

It's pending to test what happens if you load a previous save with other companions (Eder is not working).

I've always worked under the assumption that once a companion is added to the party, an instance of the character's data at that point is added to the save game. This is then used by the game to load the data it needs and if something is changed with the character in game (changes to their current equipment and gaining of new abilities, for example) it then saves these to the instance of that character that is stored in the game save. This would explain why the game never updates the companions to reflect any changes made to the character data in a .gamedatabundle.

I can't test it myself at the moment, but the method suggested by noqn of using a script to remove and then add the companion back into the party is a good bet. As this brings up the class selection dialogue again and seems to set the character back to level 1, it might also update their stats.
The mod Reclassify Companions uses this method and would work for testing.

Edited by Kvellen
  • Like 1
Link to comment
Share on other sites

 

I have been using Apotheosis for the past months and although I have familiarised myself, there some things I need help or clarification with:

  1. Is there a way to add components to abilities or attacks such as AuraAbilityComponent or AOEComponent without duplicating and modifying existing files that already have them?
  2. New attacks always use AttackBaseGameData, is there a way on creation to specify which GameData to use instead? 
  3. Is there a way to highlight or list modified files when opening mods in the editor and include value changes?
  4. Is there a way to find out where status effects are referenced?
  5. I am trying to write a user script that goes through all conversations and replace conditions containing a specific subclass and replace them with a specific ability. How can I achieve this?
  6. Rangers, Chanters and Druids uses custom1 category for animal companions, phrases and spirtshifts. I tried adding custom2 and custom3 categories to ClassProgressionTableComponent, but for some reason they do not appear ingame. Is this a game limitation or is this something I am missing?
  7. I am currently extracting gamedatas in text files and comparing them in visual code. Is there a built-in compare select in the editor? 
  8. Can BaseProgressionTables include modified abilities or new abilities only?
  9. Can you provide a search query example for searching status effects that trigger once on the next spell attack?
  10. Can status effects trigger on targets with specific status effects or is it limited to keywords?
  • Like 2
Link to comment
Share on other sites

Hi, thanks for your questions, I'll do my best to answer 😄

On 10/27/2023 at 11:41 PM, Cmushi said:

1. Is there a way to add components to abilities or attacks such as AuraAbilityComponent or AOEComponent without duplicating and modifying existing files that already have them?

If you right-click the topmost row in the tree view, you can select "Add Component..." and add any valid components.

Vs83ris.png

nqNrO90.png

Quote

2. New attacks always use AttackBaseGameData, is there a way on creation to specify which GameData to use instead? 

If you expand AttackBase row and right-click e.g. AttackBeam, you get to create a gamedata of that type instead.

Quote

3. Is there a way to highlight or list modified files when opening mods in the editor and include value changes?

No, but that sounds like a good feature!

Quote

4. Is there a way to find out where status effects are referenced?

Like getting a full list of other objects that reference a specific StatusEffect, or just which data types that can reference StatusEffects?
If it's the latter, try searching the official documentation pages for Components and Structures, then manually Ctrl+F for "StatusEffectGameData".

If it's the former, it's a feature that would be very useful but isn't available. For now, the closest thing is querying for a specific data type that may refer to a specific StatusEffect and see if that matches, for example:
#GenericAbility.StatusEffects[*]=LAX02_Food_Ekkevit_SE_Hangover
^ will display abilities that contain your status effect

Quote

5. I am trying to write a user script that goes through all conversations and replace conditions containing a specific subclass and replace them with a specific ability. How can I achieve this?

Ooooh, it makes me very happy that someone is getting use of the use script functions!

This script should do the trick, just replace the contents of the SubclassPairs: https://gitlab.com/noqn/apotheosis-user-scripts/-/blob/main/swap_subclass_checks.cs
(Note that IsPaladinOrder or IsDeity are used in some conversations instead of the HasSubclass conditional. In case you specifically want to replace Paladin/Priest subclass checks, you would have to edit this script to properly replace those checks too.)

Quote

5. Rangers, Chanters and Druids uses custom1 category for animal companions, phrases and spirtshifts. I tried adding custom2 and custom3 categories to ClassProgressionTableComponent, but for some reason they do not appear ingame. Is this a game limitation or is this something I am missing?

Yeah I saw your thread, I briefly checked the decompiled code with dnSpy to see how it's implemented, but didn't get any answers from what I looked at. Anyhow, my guess is that it's hardcoded so that only Custom1 shows up.

Quote

6. I am currently extracting gamedatas in text files and comparing them in visual code. Is there a built-in compare select in the editor? 

No, but that would be a good feature.
I've considered a data view where you get to visualize all mod files of the current mod, get to see exactly which changes those files make, compare the changes with vanilla/dependent mod values, etc.

Some kind of JSON preview would be a good thing on top of that (and really nice as a separate feature regardless).

Quote

7. Can BaseProgressionTables include modified abilities or new abilities only?

If you create a BaseProgressionTableAppend object, you'll only have the option to add new abilities to the referenced table, not edit ones that already exist in it.
The advantage is that it will be fully compatible with other mods that edit the same table, so I highly recommend it if you only need to add new stuff.

Editing the CharacterProgressionTable or ClassProgressionTable objects directly will however allow you to edit the existing abilities, at the cost of overriding/getting overriden by all other mods that edit the same table. 

(I might've misunderstood this question, let me know if that's the case.)

Quote

Can you provide a search query example for searching status effects that trigger once on the next spell attack?

Hm, this might be tricky, don't know if there're any vanilla spells that only trigger once like that.
Something like this for finding StatusEffects which trigger on a spell attack at least:

#StatusEffect{AttackFilter.Source=Spell && EventValue=OnLaunchesAttack}

On 10/27/2023 at 11:41 PM, Cmushi said:

Can status effects trigger on targets with specific status effects or is it limited to keywords?

I think if you edit the ApplicationPrerequisites of the StatusEffect you might be able to achieve that (though testing may be required):

HasStatusEffect(Target, Your_SE_here)

  • Like 1
Link to comment
Share on other sites

 

@Noqn thank you for answering my questions.

Quote

If you right-click the topmost row in the tree view, you can select "Add Component..." and add any valid components.

Right-Clicking top most row of Abilities and Attacks displays only DataScriptEventComponent.

Quote

If you expand AttackBase row and right-click e.g. AttackBeam, you get to create a gamedata of that type instead.

Yes that was what I was looking for and it also add components which answers the first question.

Quote

If it's the former, it's a feature that would be very useful but isn't available. For now, the closest thing is querying for a specific data type that may refer to a specific StatusEffect and see if that matches, for example:
#GenericAbility.StatusEffects[*]=LAX02_Food_Ekkevit_SE_Hangover
^ will display abilities that contain your status effect

Exactly what I needed.

Quote

Yeah I saw your thread, I briefly checked the decompiled code with dnSpy to see how it's implemented, but didn't get any answers from what I looked at. Anyhow, my guess is that it's hardcoded so that only Custom1 shows up.

I turned Wizard base subclasses into a selectable ability and this is the result:

CDN media

Base subclasses have 1 specialized and 2 opposed schools. You can mix and match specialized and opposed schools with this new system.

First 5 greyed iconed ability are added as unlike attributes, you cannot spend less than the available points. The system functions using a single category, only if you do not pick 3 of the same school such as Conjuration, Specialized Conjuration and Opposed Conjuration. This is the reason for the need of additional categories.

I am planning to do the same with Paladins and Priests, replace their base subclasses with more unique variants.

Quote

This script should do the trick, just replace the contents of the SubclassPairs: https://gitlab.com/noqn/apotheosis-user-scripts/-/blob/main/swap_subclass_checks.cs
(Note that IsPaladinOrder or IsDeity are used in some conversations instead of the HasSubclass conditional. In case you specifically want to replace Paladin/Priest subclass checks, you would have to edit this script to properly replace those checks too.)

Since I will be replacing subclasses with abilities (instead of a different subclass) for example Enchanter subclass with an ability, I assume I need the modify the following? Specifically Parameters = conditional.Data("hasAbility(this,"Specialized_Enchanter")?

  result = conditional with {
    Data = conditional.Data with {
      Parameters = conditional.Data.Parameters.SetItem(1, pair[1])
    }
  };

Sorry, I am not that familiar with scripting and the lack of auto-completes. Is there any documentation that I can reference to?

Quote

Editing the CharacterProgressionTable or ClassProgressionTable objects directly will however allow you to edit the existing abilities, at the cost of overriding/getting overriden by all other mods that edit the same table. 

That answered my question. I made a subclass that adds new and modifies existing abilities.  Since modifying abilities cannot be done through BaseProgressionTableAppend as well, there is no way to make it compatible with other mods without making patches.  

Thanks again for your help.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

On 10/29/2023 at 11:36 AM, Cmushi said:

Since I will be replacing subclasses with abilities (instead of a different subclass) for example Enchanter subclass with an ability, I assume I need the modify the following? Specifically Parameters = conditional.Data("hasAbility(this,"Specialized_Enchanter")?

Aaah, replace that piece with this:

  result = conditional with {
    Data = conditional.Data with {
      FullName = "Boolean HasAbility(Guid, Guid)",
      Parameters = conditional.Data.Parameters.SetItem(1, pair[1])
    }
  };
Quote

Sorry, I am not that familiar with scripting and the lack of auto-completes. Is there any documentation that I can reference to?

There's this documentation page, but it's lacking: https://gitlab.com/noqn/apotheosis/-/blob/main/Docs/User Scripts.md?ref_type=heads

I'm aware the UserScripts are not very user fiendly at all, the lack of autocompletions especially is a big pain point. I'm considering adding a page to explain how to set up dotnet-script and importing the Apotheosis dlls so that so that the scripts can be edited in VS Code with full language analysis (which is what I've been doing recently), then the user can copy-paste that code into Apotheosis.

On 10/29/2023 at 11:36 AM, Cmushi said:

I turned Wizard base subclasses into a selectable ability and this is the result:

CDN media

Base subclasses have 1 specialized and 2 opposed schools. You can mix and match specialized and opposed schools with this new system.

Ooh, I'm loving this, would open up for a lot more combinations and playstyles than vanilla wizard specializations

Link to comment
Share on other sites

  • 4 weeks later...

I'm trying to add a new Objective Node to the quest Hunting Season to make an alternate route to account for the player heading to Bentbranch Bog before the animal attack takes place on Sayuka. I can't seem to get it to work though.

The quest seem to start and displays the string for the new Objective in the left hand corner, but shows it with a check mark as if it were just completed. And the quest log displays only the description.

fg404qo.png

The output_log.txt shows the the following error that I believe is connected:

Invalid Quest Tracker size!
 
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)

ERROR: Failed to execute compiled script Void StartQuest(Guid). See the following exception.
 
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)

ArgumentOutOfRangeException: Argument is out of range.
at System.Collections.BitArray.Set (int,bool) <0x000f2>
at Game.QuestManager.SetStateVisited (Game.Quest,int) <0x0011e>
at Game.Quest.EnterState (int) <0x003b4>
at Game.Quest.AdvanceHelper (bool) <0x00ae4>
at Game.Quest.Advance (bool) <0x00051>
at Game.Quest.Advance () <0x0001e>
at Game.Quest.StartQuest (int) <0x0007e>
at Game.QuestManager.StartQuest (System.Guid,int,UnityEngine.GameObject) <0x003bd>
at Game.QuestManager.StartQuest (System.Guid,UnityEngine.GameObject) <0x0003b>
at Game.Scripts.StartQuest (System.Guid) <0x0004c>
at (wrapper dynamic-method) System.Runtime.CompilerServices.ExecutionScope.lambda_method (System.Runtime.CompilerServices.ExecutionScope) <0x0007a>
at Game.ScriptManager.ExecuteScriptMethod (OEIFormats.FlowCharts.ScriptCall,bool,Onyx.ExceptionMode) <0x002a5>

The only way I've found around this is linking to node 5 instead of creating the new Objective Node. This actually functions pretty flawlessly, except for the text in the strings containing mentions of events that don't occur when taking this route.
Interestingly looking at the .questbundle in Visual Studio there would seem to be a "AlternateDescriptionIDs": field on a each node. But I can't see that there would be any way to add alternate description IDs to the nodes or really anyway to activated an alternate description on a specific event node.

Edited by Kvellen
  • Like 1
Link to comment
Share on other sites

On 12/5/2023 at 8:03 PM, Kvellen said:

I'm trying to add a new Objective Node to the quest Hunting Season to make an alternate route to account for the player heading to Bentbranch Bog before the animal attack takes place on Sayuka.

Oh nice, that would be great! Is the quest triggering in vanilla when you enter the bog before the druid attack or are you doing that by script hooks btw?

On 12/5/2023 at 8:03 PM, Kvellen said:

But I can't see that there would be any way to add alternate description IDs to the nodes or really anyway to activated an alternate description on a specific event node.

I don't know if this was because I only half-accounted for the alternate descriptions, or because I realized they weren't usable for Objective Nodes, I'll double check later.

It's possible to select alternate descriptions for the Quest (root) Node tho, but I noticed that Apotheosis only lets you select already defined alternate descriptions (with id >= 40_000) but not add new ones... I'll fix that for sure...

image.png.3ef7230625e50a85fe9b7888525e3155.png

On 12/5/2023 at 8:03 PM, Kvellen said:

The quest seem to start and displays the string for the new Objective in the left hand corner, but shows it with a check mark as if it were just completed. And the quest log displays only the description.

Could you send me the version of the mod where this happens, if you still have the files?

  • Thanks 1
Link to comment
Share on other sites

On 9/17/2023 at 6:27 PM, abot said:

another thing that is not a bug, but could be nice to have: I noticed that the game seems to sort the in game quest steps list by string ids, so a way to automatically recalculate the ids from Apotheosis so they keep the sorting as displayed in the quest tree editor would be ace, at the moment you have to painstakingly renumber them with a text editor in the quest and strings tables to sort them

Speaking of quests, I will take the opportunity to take a look at this as well (better late than never 😅)

  • Like 1
Link to comment
Share on other sites

23 hours ago, Noqn said:

Could you send me the version of the mod where this happens, if you still have the files?

Sure! Hunting Season Alt.zip

23 hours ago, Noqn said:

Oh nice, that would be great! Is the quest triggering in vanilla when you enter the bog before the druid attack or are you doing that by script hooks btw?

Yup I am using a script hook to start the quest:

if
{
	IsInScene(Player, AR_1507_Bog)
	and not HasQuestStarted(15_QST_Hunting_Season)
}
then
{
	StartQuest(15_QST_Hunting_Season)
}

The animal attack on Sayuka is the only way to start the quest strangely. Though entering Bentbranch Bog does set the "b_HS_Entered_Bog" to "1". Which actually... Now that I'm typing this out that might actually be the issue! Since this variable triggers an event on the original route through the quest... 🤔

Pretty much my goal with making this alternate route is that it will fix a minor bug that can come from killing the druids before being tasked to. If I can't get it to work there are other solutions I can take like disabling the ability to travel to Bentbranch Bog without Hunting Season active. But at least in theory an alternative quest route seems to me the least intrusive from a player's perspective. And as a plus allows the quest to be completed without needing to go through the RDC faction quest.

23 hours ago, Noqn said:

It's possible to select alternate descriptions for the Quest (root) Node tho, but I noticed that Apotheosis only lets you select already defined alternate descriptions (with id >= 40_000) but not add new ones... I'll fix that for sure...

Oh yeah that would be great! Could you do this for addendums as well?

I actually created an alternate description for the quest, but removed it just in case that was the source of the issue.

 

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...

So I've managed to get it to work by changing the new node's number from "19" to "11" in Visual Studio. Which was an unused node number (presumably removed by the quest's designer when refining the quest). Honestly though I really have no idea why that worked. However any new nodes past "18" still seem to have the same issue. At this point I not so sure that this is an Apotheosis specific issue as I first thought. 🤔

Here's the working version should you want to take a look: Hunting_Season_Alt_Working.zip

I dunno, I swear every time I try to figure out how the quest system works in Deadfire it really just leaves me baffled...
Regardless I'm just going to put it to the side for 2024 to try to figure out.

I've also got some feedback that I'll write up then as well. Can't believe this tool has only been around a year! I'm still in awe of how simple this tool has made modding Deadfire!

Thanks for all the work your doing on it, hope you have a great New Year!

  • Like 1
Link to comment
Share on other sites

Hi @Kvellen sorry for late reply, I wanted to reply and post an update in the same go but I ran into what I suspect is corona 🥲
Fever is down and headaches gone so I'm sit down and finish the last pieces now

Thank you so much for your words and happy new year to you too ❤️

On 12/20/2023 at 4:04 AM, Kvellen said:

So I've managed to get it to work by changing the new node's number from "19" to "11" in Visual Studio. Which was an unused node number (presumably removed by the quest's designer when refining the quest). Honestly though I really have no idea why that worked. However any new nodes past "18" still seem to have the same issue. At this point I not so sure that this is an Apotheosis specific issue as I first thought. 🤔

I'll see if I can look into this later on. Maybe it's something Apotheosis could automatize.

  • Thanks 1
Link to comment
Share on other sites

  • 5 weeks later...

On windows? Apotheosis.exe is the file you want to run.

image.png.e3a082d2b5fa64ef921c59e580ddbe57.png

If that file is not working, I don't know what could be wrong. Can you specify which OS and version you're running?

Sorry for the inconvenience :(

Link to comment
Share on other sites

  • 2 weeks later...
  • 2 weeks later...

2024-02-18

Added support for editing StringTables of all localizations!

  • Users can now switch languages with the dropdown located to the right in the headerbar, which determines from which StringTables to load and save text.
  • Note that this update may increase load times and memory usage. For a future release, users will have the option to omit loading localization files to mitigate this impact.

____
Got poked by someone asking for this, most of the code for supporting this has been in place for a long time but never finalized, so it wasn't too painful to complete 😄

 

  • Like 1
Link to comment
Share on other sites

Seem to be stuck trying to update the extracted icons and localized StringTables (Waited 10 minutes so far):
Y5SF89F.png

Have tried auto-updating and downloading the latest build from GitLab.

Edited by Kvellen
  • Gasp! 1
Link to comment
Share on other sites

****, I realized the app checks for missing exported data before checking for a new version, so everyone on 2024-02-18 will just be indefinitely stalled on the export and never get the update notification...

Everyone who updated to yesterdays version would have to install the latest release manually. Agh ****.

Link to comment
Share on other sites

Ooph, that's a pain.

The auto-update worked off a backup I had of a previous version though. Everything has extracted quickly and correctly this time. Also gave making edits to a few of the localized StringTables a test, all changes are saving and loading correctly. Great work! 

Edited by Kvellen
  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...