Cmushi Posted March 26 Posted March 26 On 3/21/2025 at 7:16 PM, Noqn said: On another note, I've completed Avowed now so I'll have a lot more time to spend on Apotheosis Spoiler Who did you side with and did you free Sapadal? 1
Noqn Posted March 27 Author Posted March 27 On 3/26/2025 at 2:27 PM, Cmushi said: Spoiler Who did you side with and did you free Sapadal? Spoiler I started out kinda Aedyr loyalist first and foremost, but after I assembled the first God totem I realized to my disappointment that Woedica's voice actor had changed, after that I move gradually more towards Sapadal. In the end I merged with Sapadal (little sad this wasn't mentioned at all in the ending slides...) and mainly to please Sapadal went for Aedyr-free Living Lands What did you choose? 1
Cmushi Posted March 27 Posted March 27 8 minutes ago, Noqn said: Reveal hidden contents I started out kinda Aedyr loyalist first and foremost, but after I assembled the first God totem I realized to my disappointment that Woedica's voice actor had changed, after that I move gradually more towards Sapadal. In the end I merged with Sapadal (little sad this wasn't mentioned at all in the ending slides...) and mainly to please Sapadal went for Aedyr-free Living Lands What did you choose? Ha! That was an easy was to resolve a dilemma. Spoiler I freed Sapadal and drove Aedyr out. The toughest decision was whether to sever the Adra or destroy the ruins. Ultimately, I reluctantly chose Lödwyn's path, as I believed severing the Adra would have disrupted the flow of souls, delaying their return to the Wheel and making things worse in the long run. 1
Larkin Posted April 9 Posted April 9 I have a question as to whether something is possible in Apotheosis. Ultimately, I'd like to turn the Wintertide Bulwark into a bashing shield. My fiddling in the game data has led me to believe the main thing seperating bashing shields from the others is that they have a weapon component affixed alongside their shield & item components. Is their something I've missed that's more complicated, or is adding that component to an item just not something apotheosis can do/do yet? 1
Noqn Posted April 10 Author Posted April 10 On 3/8/2025 at 1:37 AM, Noqn said: On 3/6/2025 at 6:54 AM, brokensave said: it just hangs there indefintly and becomes unresponsive too so I can't cancel it after clicking ok. Any ideas on why this is happening or how to fix? Sorry about this, I think it happens any gamedata or (most likely) localization files are corrupt. I'll try to take a look at it during the weekend to make Apotheosis produce an error message instead of freezing, once and for all If you want Apotheosis to start working meanwhile, my only suggestion is to reinstall/repair your Deadfire installation. Again, sorry for the issues : ( Sadly @brokensave seems to have deleted their account but I've improved the behavior of the export setup dialog now 2025-04-10 Improved initial setup dialog behavior when extracting icons and loose data files into apotheosis_exported: Export progress is now visualised by progress bars. Apotheosis no longer freezes indefinitely if an error occurred during exporting, instead a message box will pop up. I put some extra work into making sure progress is displayed to the user, so it doesn't just feel like the program has frozen: 2
Noqn Posted April 10 Author Posted April 10 18 hours ago, Larkin said: I have a question as to whether something is possible in Apotheosis. Ultimately, I'd like to turn the Wintertide Bulwark into a bashing shield. My fiddling in the game data has led me to believe the main thing seperating bashing shields from the others is that they have a weapon component affixed alongside their shield & item components. Is their something I've missed that's more complicated, or is adding that component to an item just not something apotheosis can do/do yet? Hi, I think this is actually a very similar issue as the one @Adonis Jorge Silva Santos had (which I've been planning on working on soon). Basically the shield has to be upgraded from EquippableGameData -> WeaponGameData, and then have an WeaponComponent added to it, but Apotheosis does not support this yet. Spoiler On 3/16/2025 at 10:45 PM, Adonis Jorge Silva Santos said: I have a doubt, how do i add aura ability component or Special Generic Ability component on abilities that do not have this options before? On 3/21/2025 at 7:14 PM, Noqn said: Hi, sorry for the late reply. Short version: Apotheosis does not support this yet. You have to change the GameData type of the ability to the appropriate type that can hold one of those components. I'll start working on adding support for that after I'm done with the export freeze and Chatters.
Larkin Posted April 10 Posted April 10 @Noqn I appreciate the response, & while I've got ya just wanted to thank you for your work on Apotheosis. It's a really impressive tool, & I think very intuitive. Killer work chief. 2
Noqn Posted April 10 Author Posted April 10 34 minutes ago, Larkin said: @Noqn I appreciate the response, & while I've got ya just wanted to thank you for your work on Apotheosis. It's a really impressive tool, & I think very intuitive. Killer work chief. Thank you so much 1
Noqn Posted May 6 Author Posted May 6 Btw @Kvellen I'm still working on the chatterbundles, just letting you know I've know abandoned that . I noticed a lot of code related to the flowchart bundles could be refactored so I'm taking the time to get that done, while I've been working some other stuff in parallel that turned up 1
Larena27 Posted May 22 Posted May 22 Hi, this tool is so cool, I've been able to fix up a few of the mods I've made through simple text file editing to have more robust solutions and it's really great. But I've been trying to make a mod that sets it so that the last stage of Xoti's quest - when she asks you to take the souls to a Luminous Adra pillar - doesn't trigger until after you've completed Magran's teeth, but I'm having some trouble. I tried setting the relevant conversation nodes to check for that as a conditional, but that hasn't seemed to do anything. So my next thought was modifying the quest stages, but it's a little unclear to me where I find the stuff I need. I can't quite tell where the game triggers quest event progressions from - they aren't in the conversation nodes I'd expect them to be, and the actual quest flowchart hasn't been a lot of help. Any help on where I should start? 2
Kvellen Posted May 23 Posted May 23 (edited) Hey @Larena27, I've looked at somethings around Xoti's quest before. Did you try adding the condition on Conversation Tigger node "403" of "companion_cv_xoti_main"? That's what seemed to start the conversation that leads into the final parts of the quest when I was looking into it. Though maybe there is another place it can trigger like after a rest? If that's the case it could be tricky to alter as, just like Conversation Tigger nodes, scripts will ignore any condition on whatever node it points at by design. Edited May 23 by Kvellen 1
Larena27 Posted May 24 Posted May 24 @Kvellen Yeah, there's an alternate version of the conversation that triggers on rest I was having trouble with. I assume on-rest scripts aren't easily moddable? I ended up figuring out that either version of the conversation is triggered by a "xoti_nightmare" variable and so I just removed that from the conversation node that triggers it, and added a script to her initial dialogue hub node that triggers it if Magran's teeth is completed and that *seems* to work. 1
Kvellen Posted May 24 Posted May 24 (edited) 10 hours ago, Larena27 said: Yeah, there's an alternate version of the conversation that triggers on rest I was having trouble with. I assume on-rest scripts aren't easily moddable? Ah I thought I had remembered there being a version of it on rest. Annoyingly on-rest scripts are located in an ".assets" or sometimes a "level" file. Unless they have a referenced to a globalscript/globalexpression it's not something that Apotheosis is capable of editing. And as far as my experience goes, even with a tool like UABE that can open assetbundles, such files seem prone to corrupting or are very finicky to make alterations to. 10 hours ago, Larena27 said: I ended up figuring out that either version of the conversation is triggered by a "xoti_nightmare" variable and so I just removed that from the conversation node that triggers it, and added a script to her initial dialogue hub node that triggers it if Magran's teeth is completed and that *seems* to work. Removing the script setting "b_Xoti_Nightmare" from the Gaun statue conversation would have been my next suggestion. Really my only hesitation in suggesting it first, would be that doing so makes it so that once that conversation has played the next step in Xoti's quest becomes reliant on the mod to progress. All things considered though, it's the best solution. I would suggest moving your script for Magran's teeth completion to a mod scripthook instead. That way you'll avoid the possibility of conflicts arising from other mods that make changes to Xoti's hub. Great idea for a mod by the way! The pacing of Xoti's quest has always struck me as pretty bizarre. Edited May 24 by Kvellen 2
Larena27 Posted May 24 Posted May 24 Oh do modscripts work? I'm definitely in deeper waters than I'm used to so I wasn't sure what's possible. Will the script run on its own just by existing or would I still need to find a way to trigger it? 2
Noqn Posted May 25 Author Posted May 25 (edited) 10 hours ago, Larena27 said: Oh do modscripts work? I'm definitely in deeper waters than I'm used to so I wasn't sure what's possible. Will the script run on its own just by existing or would I still need to find a way to trigger it? Each ModScriptHook will automatically trigger every time the player enters a new scene or loads a save. You can add conditionals to the hook, and set whether it should only trigger a single time, etc: https://eternity.obsidian.net/game-data-formats/components#modscripthookcomponent In Apotheosis it can be found under Game Data -> ModScriptHooks -> ModScriptHook Edited May 25 by Noqn 2
Larena27 Posted May 25 Posted May 25 Awesome, thanks y'all! I think I've got it where I want it to be 2
Larena27 Posted May 29 Posted May 29 Sorry to post back-to-back but another question: I'm having trouble figuring out where the game stores what equipment slots characters have. I'd like to make it so "Can I Pet Him Too?" unlocks pet slots on *all* party members, but not sure if this is possible. Is this another thing that's kinda locked away and I'd have to figure how to script around it, or am I just missing something?
Noqn Posted May 29 Author Posted May 29 The Pet slot is unlocked with a specific ability (Unlock_Pet_Slot), iirc a script in one of the the prologue conversations give this ability to Eder. There's actually an existing mod that does this more or less: https://www.nexusmods.com/pillarsofeternity2/mods/400 (though I think it unlocks the pet slots without taking Can I Pet Him Too into account) I checked and it does it by creating a BaseProgressionTableAppendGameData object that effectively adds the Unlock_Pet_Slot ability to all party members' Ability Trees (though hidden). 1
Noqn Posted June 1 Author Posted June 1 @Kvellen I thought I'd write down some discoveries about Chatters and show some progress: Nodes - Chatters only have 2 noteworthy Node types - ChatterNode and ChatterEventData. ChatterEventData each act like a "Root Node" (see the video below ) and will contain one or more ChatterNode children. Each ChatterEventData is connected to a specific event (such as casting a spell or being given a unique item by the Watcher) that could trigger a voice line. ChatterNode - defines a specific voice line that could be played. Each ChatterNode has a corresponding .wem audio file. ChatterNodes can't have children. ScriptNode - may be inserted between ChatterEventData and ChatterNode children to add common Conditionals to several children. StringTableFilenames - Defines which StringTables the Chatter should fetch entries from. Each Chatter will utilize its own unique table (should be the first in the StringTableFilenames list), but also has the option to fetch entries from other "generic" tables. Which table in StringTableFilenames a ChatterNode should fetch text from will be determined from the NodeID. Nodes with a NodeID starting with X0'000 will fetch the table with (zero-based) index X in StringTableFilenames. If we have for example "NodeID": 20017, then the from the tables below it should fetch "chatter/parents/chp_chanter_casts.stringtable" (the 3rd entry in the list) "StringTableFilenames": [ "chatter/00_companions/ch_companion_pallegina_voice_set.stringtable", "chatter/parents/chp_barbarian_shout.stringtable", "chatter/parents/chp_chanter_casts.stringtable", "chatter/parents/chp_cipher_casts.stringtable", "chatter/parents/chp_common.stringtable", "chatter/parents/chp_ko.stringtable", "chatter/parents/chp_paladin_commands.stringtable", "chatter/parents/chp_wizard_casts.stringtable" ], As you can see in the video below, I've removed the "edit text button" from Nodes with IDs greater than 10'000, so that the user is only able to edit the Chatter's own string table entries. AudioLookup - These can be auto-generated and refreshed when the Chatter is edited, how the strings are calculated is similar to .wem paths which is described below. Manifests - From what I looked at the decompiled code, Chatters will require a manifest file similar to Conversations, though the contents seem to be a bit different. It's something I'll have to look a bit more into. .wem paths - The path to the .wem file of a ChatterNode will be determined by The character's SpeakerGameData -> SpeakerComponent -> ChatterPrefix The EventType value of the ChatterNode's ChatterEventData parent. (The exact EventType -> string mappings are defined in the ChatterEventsGameData named "chatter" available under "Audio"). The ChatterNode ID <SpeakerComponent.ChatterPrefix>\ch_<SpeakerComponent.ChatterPrefix>_<EventType>_<NodeID>.wem eder\ch_eder_item_purchase_rare_0153.wem \PillarsOfEternityII_Data\StreamingAssets\Audio\Windows\Voices\English(US)\eder\ch_eder_item_purchase_rare_0153.wem I added a button for opening and highlighting a ChatterNode's .wem file in the users file manager. (Though not included in the preview video...) 1 1
Kvellen Posted June 1 Posted June 1 (edited) Oooo that's look great! Have had a few projects I have been putting off due to drudgery of making manual edits to .chatterbundle entries. Thanks a lot for the break down, this does confirm a lot of assumptions I've had over the years on how these files worked! The need for a manifest entry isn't something I have come across though. The couple of new chatters I have made from duplicating existing ones then generating a new GUID, have seemed to function without the need for one. Additionally in my experience .chatterbundle files seem to have no need to maintain the same directory structure as their origin file. I wonder if maybe the need for a manifest entry is some vestige from Deadfire's development. Like the "ConversationType" having 2 states: "0" for Conversations, or "1" for Chatter. But this never seeming to be used in conversations from what I have seen. Maybe at some point conversations and chatters once shared a filetype and structure? 14 hours ago, Noqn said: StringTableFilenames - Defines which StringTables the Chatter should fetch entries from. Each Chatter will utilize its own unique table (should be the first in the StringTableFilenames list), but also has the option to fetch entries from other "generic" tables. Which table in StringTableFilenames a ChatterNode should fetch text from will be determined from the NodeID. Nodes with a NodeID starting with X0'000 will fetch the table with (zero-based) index X in StringTableFilenames. If we have for example "NodeID": 20017, then the from the tables below it should fetch "chatter/parents/chp_chanter_casts.stringtable" (the 3rd entry in the list) "StringTableFilenames": [ "chatter/00_companions/ch_companion_pallegina_voice_set.stringtable", "chatter/parents/chp_barbarian_shout.stringtable", "chatter/parents/chp_chanter_casts.stringtable", "chatter/parents/chp_cipher_casts.stringtable", "chatter/parents/chp_common.stringtable", "chatter/parents/chp_ko.stringtable", "chatter/parents/chp_paladin_commands.stringtable", "chatter/parents/chp_wizard_casts.stringtable" ], The stringtables always seemed an odd inclusion to me when I was looking at .chatterbundles purely as voice sets. With the knowledge that a lot of the ambient townie barks comes from chatter it make more sense. I'm still not really sure what function the "generic" stringtables serve in game though. The thought of chatter appearing as text in game would have been a bit of a nightmare! Edited June 1 by Kvellen 1
Kvellen Posted June 2 Posted June 2 On 6/1/2025 at 1:26 AM, Noqn said: I added a button for opening and highlighting a ChatterNode's .wem file in the users file manager. (Though not included in the preview video...) How does this work for things like the Player voice sets, where 2 speakers share the same chatter? 1
Noqn Posted Monday at 08:32 PM Author Posted Monday at 08:32 PM (edited) 2 hours ago, Kvellen said: How does this work for things like the Player voice sets, where 2 speakers share the same chatter? I might've misunderstood the question but the SpeakerComponent.ChatterPrefix value will be used when determining the .wem path, so two speakers will have separate file paths for identical nodes even if they point to the same Chatter Aah wait, nvm I get it... Yeah as I've implemented it right now, it will select the .wem of the first matching speaker with that Chatter. I'll maybe have to think a bit more about that feature later... Edited Monday at 09:22 PM by Noqn 1
Noqn Posted Monday at 09:34 PM Author Posted Monday at 09:34 PM On 6/1/2025 at 5:22 PM, Kvellen said: The stringtables always seemed an odd inclusion to me when I was looking at .chatterbundles purely as voice sets. With the knowledge that a lot of the ambient townie barks comes from chatter it make more sense. I'm still not really sure what function the "generic" stringtables serve in game though. Honestly, I hadn't considered this until you wrote it I imagine it was useful from a developer perspective, for stuff like syncing voice actor lines. It could maybe be useful for us if I make some templates based on these? Like if someone's adding a ChanterChant1 "branch" it'll always default to this: On 6/1/2025 at 5:22 PM, Kvellen said: The thought of chatter appearing as text in game would have been a bit of a nightmare! This is gold, I'm still laughing at this image 1
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now