Skip to content
View in the app

A better way to browse. Learn more.

Obsidian Forum Community

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Apotheosis - Mod Editor for Deadfire

Featured Replies

  • Author

Finally, new release! Chatter Support! 🥳

@Kvellen I changed the "highlight in folder"-button to instead play all matching files in the user's .wem associated media player, if available:

 

  • Author

I ended up doing some very heavy refactoring on flowchart-related code.

Everything should still work, but if you have some important conversation/chatter/quest projects in progress it might be a good time to take a backup on those just in case.

Thanks a lot, I'll give this a proper look when I can!

A quick glance, I did notice these 2 things:

  1. ScriptNodes in the chatter editor seem to be missing the Persistence and Play Type dropdowns menus. I'm not sure if Persistence is actually used in chatter, but one key place PlayType is used on a ScriptNode specifically is Selected chatter. If you take a look at companion and player chatter for this event you'll see that they all start by linking to 2 ScriptNodes. The first is for playing only the rare Humorus lines only when the character is clicked 15 times, and the second the more common selection lines that play otherwise. The PlayType on each 2 ScriptNodes needs to be able to be set to random play the nodes they are linking to. Otherwise it will only ever play first line from each.
  2. In the exported .chatterbundle files "Links": [] seems to be higher in the order of node parameters than normal. I haven't actually tested to see if this prevents it functioning but it stuck out to me when comparing to normal chatter.

Edited by Kvellen

  • Author
6 hours ago, Kvellen said:

A quick glance, I did notice these 2 things:

  1. Thanks, I messed up and didn't let the ScriptNode gui widgets inherit the elements from the DialogueNode widgets 😅
    I pushed a fix which should be available now.
  2. This is ok, it won't affect deserialization.
  • Author

2025-07-06 (2)

  • Added "Open WEM" button to Conversation Talk Nodes.

Found another chatter specific issue. When Play Type is set to Random or CycleRandom on a node it's links aren't getting random weight set. Which seems to prevent any of the linked nodes playing at all.

Dove into the chatter editor a little more just now and it's looking superb!
Was able to remake something that in the past took me several days of tedium in just under an hour!

On 7/6/2025 at 4:49 PM, Noqn said:

2025-07-06 (2)

  • Added "Open WEM" button to Conversation Talk Nodes.

Really fantastic feature! Was going to say this would make a great addition to conversations as well. Even better that you've set it to play a .wem off of nodes using Exterior VO as well! Great work!

Edited by Kvellen

  • 2 weeks later...
  • Author
On 7/7/2025 at 11:53 PM, Kvellen said:

Found another chatter specific issue. When Play Type is set to Random or CycleRandom on a node it's links aren't getting random weight set. Which seems to prevent any of the linked nodes playing at all.

2025-07-18

  • Adjusted buttons on Chatter nodes:
    • ChatterEventData - Removed Persistence dropdown, added NoPlayRandomWeight input if PlayType is set to Random or CycleRandom.
    • ChatterNode - Added PlayRandomWeight input.
    • ScriptNode - Added PlayRandomWeight input, added NoPlayRandomWeight input if PlayType is set to Random or CycleRandom.

(also ChatterLink RandomWeight is not properly initialized)

Basically the overlapping buttons will look like this:

  ChatterNode ScriptNode ChatterEventData
PlayType NO YES YES
NoPlayRandomWeight NO YES YES
RandomWeight YES YES NO
Persistence YES YES NO
DisplayType YES NO NO

 

  • Author

In a future update I want to hide the RandomWeight input unless the parent PlayType is random.

There are a few weird quirks in the .chatterbundle files that Apotheosis generates. The only potentially serious one is that adding a chatternode from a parent file doesn't seem to be adding it to "AudioLookup" list.

Otherwise it's all pretty minor stuff that isn't affecting the functionality of chatter from what I can tell.

Like the "Audiolookup" will rearrange when new nodes are added to existing chatter.

This sort of thing happens:

"AudioLookup": {
    "22": "ability_cast_interrupted_0022",
    "80": "ability_cast_interrupted_0080",
    "97": "ability_cast_interrupted_0097",
    "40001": "attack_40001",
    "40002": "attack_40002",
    "40003": "attack_40003",
    "10001": "barbarian_shout_10001",
    "28": "battlecry_0028",
    "29": "battlecry_0029",
    "30": "battlecry_0030"

And that I'm still not quite used to the order of things on chatternodes being different what they usually look like in Deadfire. Weirdly... Close to how "TalkNodes" are laid out for .conversation files in PoE1... What's with that? 🤨

Anyway, I can work these issues, thanks a lot Noqn!

Edited by Kvellen

  • Author

Ah good finds, new patch out 😅

2025-07-19

  • Chatter AudioLookup entries are now written ordered by keys.
  • Creating a ChatterNode from a parent String Table will now properly update the AudioLookup map.
  • Creating a ChatterNode from a parent String Table will now properly enable the popup's Accept button when an Entry is selected.
  • Author
On 3/9/2025 at 11:23 PM, Kvellen said:

Quest/Objective nodes seem to always have 2 strings entries attached to each node.

"0" is always the name of the quest, and "10000" is the initial description.
After that any single digit stringtable entry is an Objective Title, with an additional ~1000* entry that is will be the description for that objective.

On 3/9/2025 at 11:23 PM, Kvellen said:

It would be great to be able to have both string displayed and able to be edited on the relevant node in the Node Diagram.

Better late than never, but new patch out!

https://i.imgur.com/dETNGrL.png

2025-07-20

  • Quest Node descriptions are now displayed and editable.

2025-07-19 (2)

  • Quest Objective Node titles are now displayed and editable.

  

On 3/9/2025 at 11:23 PM, Kvellen said:

I have been doing a lot of investigation into quests, there are a few things I noticed as far as Apotheosis.

To start there is a bug where no changes made in the "Experience Level" field are ever saved.

Just realized I might've fixed this by accident in the 2025-07-18 release 😅

On 11/27/2022 at 1:46 PM, Noqn said:

Ah, yeah that does better address the root issue. Adding a ModScriptHook with SucceedOnlyOnce set to true and the following script:

if
{
	IsQuestCompleted(companion_qst_pallegina)
	and IsInActiveScene(8c9c23e0-6463-49aa-be47-0ceb2431a35d)
}
then
{
	ActivateObject(8c9c23e0-6463-49aa-be47-0ceb2431a35d, False)
}

If it is possible to "delete" a character with a script like that, would it be possible to instead swap out a character for an exported adventurer / sidekick light as per Kvellen's prototype?

  • Author
On 7/24/2025 at 10:21 PM, beatspores said:

If it is possible to "delete" a character with a script like that, would it be possible to instead swap out a character for an exported adventurer / sidekick light as per Kvellen's prototype?

Sorry for the late reply, I don't think that's possible based on the available scripts sadly https://eternity.obsidian.net/game-data-formats/scripts

  • 7 months later...

Hey been running into an crash lately when trying to re-parent nodes in the Conversation and Quest editors.

Steps to recreate:

  1. Child a node to another node.

  2. Delete the non-child version.

  3. CRASH.

Edited by Kvellen

  • Author

ah ship CTD bug report jumpscare

limmy.jpg

NEW RELEASE!!

image.png

I realized now that the right description would be "non-ghost child nodes", oh well...

Edited by Noqn

  • 1 month later...

Is there any way to use your editor to add the ability to summon a skeleton (or more) upon killing an enemy with a wizard spell? It's high time Deadfire got a proper taste of classic necromancy.

On 5/9/2026 at 12:01 AM, Ocsta said:

Is there any way to use your editor to add the ability to summon a skeleton (or more) upon killing an enemy with a wizard spell? It's high time Deadfire got a proper taste of classic necromancy.

I'm no wizard at modding but from what I've seen that should a 100 % be possible and probably not that difficult either if you know what other spells are doing something similar and you check what makes them work.

For example the Watcher's Blade has Deny the Wheel enchantment that spawns a Shadow when you kill a kith enemy with the weapon. I'd wager you can copy that enchantment's mechanism to your necromancer spells.

Also, as it happens, I'm doing precisely some necromancy-inspired modding with Apotheosis right now. I'm making my own sidekick. As in: an actual sidekick - not just an exported adventurer. It has custom voice, chatter, conversation, unique subclass, item, "altered subrace," and so on. The necromancer subclass is not for any spellcaster class; it will be unique for my sidekick's, and it's tied to the character's backstory.

My little project wouldn't have had a chance to begin with if it weren't for Apotheosis, among others; the tool is indispensable!

Edited by beatspores

A couple of questions or feedback on Apotheosis that I've considered, now that I have had some time to dive deeper in this awesome application.

  • I can't resize the list column widths. It would be very helpful as often there's a lot of x-space in the left columns that would be really beneficial to have on the "component side" on the right, especially when working with Conversations, which, by the way, is a level of refinement of a third party mod application I never ever would have expected.
    Also, if the column widths were adjustable, perhaps one can have the minimum x-size of the application smaller when multitasking with other windows, although this "requirement" is very seldom for me.
    -

  • Its main window's space is including the drop shadow behind it. Is it possible to send the application's shadow to be handled by the OS? It would be preferrable to have it that way I think, for several reasons; one of them being able to click to select some other application's window behind Apotheosis.
    A very, very small nitpick, but since it's also UI-OS related I'll mention it anyway: I think the commonly seen Linux-oddity of rounded top borders but not bottom borders has sneaked its way into MS Windows. If it is a stylistic choice, I have no arguments against it. But if not, I thought I could mention it. I tried to get into Linux, a year or so ago, by installing Zorin. I tried my hardest but it was all above my software maintenance comprehension so eventually, unfortunately, I had to choose between going insane or to go back to Mac.

And a final thing that crossed my mind is about the Game Data Query, which is very cool. I finally had some time to read through the instructions on how to use it correctly.

  • Is it possible to query for component entries where for example "_ext" or "upper," et cetera, is a part somewhere in the name or reference or what one would call it? For example "_ext" would throw back results such as "district_town_exterior" or "ability_extended_time."
    -

  • I was wondering, is it possible to export the entries in the query results as a list of some kind? Say the GUID's and / or the debug names. It could be very valuable if one is making a conditional script that must check against all the entries one caught through using the Query.

Maybe Apotheosis could save the list of results one generated in some simple tab inside Game Data Query. Then one could reference that list in a conditional script, from ModScriptHook et cetera. And then Apotheosis just hands over to you a standard script with a ton of:

IsRaining()
and {
	IsInActiveScene(the_huge_list[0])
	or IsInActiveScene(the_huge_list[1])
	or IsInActiveScene(the_huge_list[2])
	or IsAct...
}

But maybe it's very fringe stuff I'm touching here, maybe it's not worth the work needed to implement, I don't know.

Anyway, again, tremendous application this! I'm making good progress with my mod right now and having fun tinkering with stuff!

Edited by beatspores

  • Author
On 5/13/2026 at 8:25 PM, beatspores said:

My little project wouldn't have had a chance to begin with if it weren't for Apotheosis, among others; the tool is indispensable!

❤️

On 5/13/2026 at 9:43 PM, beatspores said:

I can't resize the list column widths. It would be very helpful as often there's a lot of x-space in the left columns that would be really beneficial to have on the "component side" on the right, especially when working with Conversations, which, by the way, is a level of refinement of a third party mod application I never ever would have expected.

Thanks, that's great feedback, I'll take a look at it when I next work on Apotheosis.

On 5/13/2026 at 9:43 PM, beatspores said:

Its main window's space is including the drop shadow behind it. Is it possible to send the application's shadow to be handled by the OS? It would be preferrable to have it that way I think, for several reasons; one of them being able to click to select some other application's window behind Apotheosis.

Ugh yeah this is incredibly obnoxious behavior from GTK. It also makes Windows' snippet tool and various recording software misjudge the size of the window...

iirc I found a way to strip the shadows away but it caused really small border margins for resizing the window, though I can see if I can enable it for the next release and see if anyone is bothered.

On 5/13/2026 at 9:43 PM, beatspores said:

And a final thing that crossed my mind is about the Game Data Query, which is very cool. I finally had some time to read through the instructions on how to use it correctly.

  • Is it possible to query for component entries where for example "_ext" or "upper," et cetera, is a part somewhere in the name or reference or what one would call it? For example "_ext" would throw back results such as "district_town_exterior" or "ability_extended_time."

Good feature request, I'll have to think about the syntax first, where to expose the DisplayName query

Really glad to hear people using the Query, it's another feature I'm very happy about 😊

On 5/13/2026 at 9:43 PM, beatspores said:

I was wondering, is it possible to export the entries in the query results as a list of some kind? Say the GUID's and / or the debug names. It could be very valuable if one is making a conditional script that must check against all the entries one caught through using the Query.

Ah yeah this feature does exist! If you right-click any item in the result view, you also get the option "Copy All DebugNames to Clipboard"

image.png

On 5/13/2026 at 9:43 PM, beatspores said:

Maybe Apotheosis could save the list of results one generated in some simple tab inside Game Data Query. Then one could reference that list in a conditional script, from ModScriptHook et cetera. And then Apotheosis just hands over to you a standard script with a ton of:

Another good feature suggestion, I'll think about this too.

On the top of my head, I've exposed some APIs for queries when writing User Scripts: https://gitlab.com/noqn/apotheosis/-/wikis/User-Scripts#api

You can see an example here: https://gitlab.com/noqn/apotheosis/-/wikis/User-Scripts#iterating-through-gamedataobjects

foreach (var grimoireWithFireball in GameData.Query("*Grimoire.Spells[*]=Fireball"))
{
    // Iterate through all GameDataObjects matching a specific Query
}

You could then dynamically build a big conditional/script based on these results, but then you would have to work with the ConditionalExpression/ScriptCall models which have a much more painful structure under the hood than the scripts you see in Apotheosis.

I'll also think about providing more convenience features for building conditionals/scripts with code.

  • Author
On 5/13/2026 at 9:43 PM, beatspores said:

Is it possible to query for component entries where for example "_ext" or "upper," et cetera, is a part somewhere in the name or reference or what one would call it? For example "_ext" would throw back results such as "district_town_exterior" or "ability_extended_time."

Hm, I think I'm going to combine this feature with something else I've been thinking about...

Combining GameDataObject-level queries, something like:

Item || GodChallenge

or more complex stuff like

GodChallenge || Item { Soulbind || #IsUnique }

In this case we could insert DebugName like this

DebugName &= "woedica" && (Item || GenericAbility)

Edited by Noqn

This is absolutely outstanding work. Thank you very much. I'm kinda late to the party but at least I can utilise it for future projects.

Would you consider allowing the linux client to pull data from the Windows version of the game? Unfortunately, I'm stuck with the Windows version since I couldn't get the Linux version run some of my mods (via BepInEx).

Sounds good!

Another thing that I've thought about a lot, that would be soooo nicely accomodating:

  • If one could set to have opened drop-down tabs for components, such as a GenericAbilityComponent's entry StatusEffects just as an example, stay open on all components when browsing around.

Since I often don't "get," thus cannot freestyle, what I have to do to make something work as I intend I need to look up examples of other component's makeup, which I can then base my own component on and alter to the way I want it. So I very often have to look through a lot of components and entries in them. One case where this would really speed up things is when using the arrow keys to traverse components and having the components' opened and open/open/opened entries stay open.

This feature would be sooo beautiful. 🤟

Perhaps a toggle next to the dark / light theme switch?

Edited by beatspores

Also, when I try to run the Linux version nothing happens. Running it via the Terminal returns the following error:

Failed to create CoreCLR, HRESULT: 0x80070057

Create an account or sign in to comment

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.