Fix for Karlach romance bug in Baldur's Gate 3

Fix for Karlach romance bug in Baldur's Gate 3

First published: December 25, 2023
Last updated: September 29, 2024

There seems to be a bug in Baldur's Gate 3 which prevents the romance with NPC Karlach to progress further even though it is pretty clear that it should. During our playthrough, I seem to have run into exactly that bug where the story would not progress in that regard after we started Act 2.

Googling the bug, most recommendations are about how to potentially prevent running into bug by doing certain things, however not many seem to have been able to fix it - and so far, no official hotfix by Larian Studios has fixed it (I do hope they will in the future).

However, after some committed research followed by expeperimentations poking around the game databases and files, I actually managed to fix it - and have so far (knocking on wood) not run into other issues with the game yet. So it looks like I did not break it.
This post might seem very long with a lot of steps. As soon as you figured out what is happening, it is pretty straight forward, though.

Background in the game:
We started Act 2 and spoke to the smith Dammon, who could Karlach's engine. We kissed and she very directly said that we should go to camp to ... you know.
After that, nothing happened. We rested many times and progressed in Act 2. I always tried to talk to her, but did not get any new options.

A kiss is all my character Krystal got.

Disclaimer

I'm not a game developer og software engineer. I really didn't know what I was doing and experimented and tried a lot. I don't even know exactly what the fix was in the end cause I restarted the game so many times under different conditions. I have a hypothesis though, and will flag that one in the post.

This is no guarantee this will work exactly like that for you - or that it won't break your game. Do this at your own risk, as I did.

The reason I'm still blogging about this is that the original Reddit post containing these tips does not show up immediatly when searching for Karlach romance bug fixes and thus might not get as much traction as it could/should.

Please check out the Reddit post and corresponding comments for more details, options, or to ask questions,

Original Reddit post by DimakSerpg: Setting up a romantic relationship

Additional comment with more tips by nathdragon-5 (I think these were essential in my case):
"I was already dating Karlach but couldn't trigger her act 2 cutscene so if you aren't already at that step, then view the main guide for those."

How I fixed my Karlach romance bug

We are about to make changes in the heart of the game, but to be able to get access to it, we first need to install some software that gives us access to it. Luckily, that is pretty easy to do and also to reverse again.
The game should not be running currently.

Installing Script Extender Launcher

  1. Download the Script Extender Launcher for BG3 from here on GitHub. Under "Assets", make sure to pick the version that includes "with-console" in the name.
  2. Install the Script Extender Launcher by extracting the two files (DWrite.dll and ScriptExtenderSettings.json) to the Baldurs Gate 3\bin directory (for example C:\Program Files (x86)\Steam\steamapps\common\Baldurs Gate 3\bin)

When you want to uninstall the launcher again, just remove these two files.

As soon as you start the game, an additional console window should open - it might be hidden behind the game.
We are going to use this console to access game information and change them.

This is how the console window looks when brought to the foreground.

Using the console to ensure relationship status

The following commands did not yet fix my bug. However, I am not sure whether they might have aided the process of fixing it in the end, so I will still share them.

  1. Start the game and load your save.
  2. Paste the following in the console and hit enter:
    \_D(Osi.DB_Players:Get(nil))

You should get a list of characters as return. The first one is your character's UUID - copy the whole line and save it somewhere - make sure to get the full UUID even if it is too long for the console window and is partly hidden. We need this information to change the history of this character.

  1. We want to find out, whether any of the player characters are dating anyone. Type the following in the console:
    \_D(Osi.DB_ORI_Dating:Get(nil, nil))
    If the response is empty ([]), you're good. If you see your own character listed as dating someone, we want to delete information. You do that by pasting the following into the console - make sure to insert the UUIDs for your player character and the one listed as your dating companion into the command between the "" (deleting one of the quotation marks is a typical mistake that will throw an error):
    Osi.DB_ORI_Dating("[Your Player UUID]", "[Your dating companion UUID]")

If you want to check whether the deletion of the dating companion worked, you can just paste _D(Osi.DB_ORI_Dating:Get(nil, nil)) in the console again and should now get [] as return.

  1. Now, add a dating entry for your character player and Karlach manually. Paste the following command into the console, again replacing the UUID with your own and that of Karlach (you should be able to find hers from the very first character list you got from the very first command. If you can't find that, you can just paste it into the console againt to copy those information.)
Osi.DB_ORI_Dating("[Your Player UUID]", "[Karlach's UUID]")
  1. Save your game and load it again.
  2. Rest at camp a couple of times.

According to the original post, this might be enough to trigger a conversation prompt with Karlach. If it does - lucky you!

The different databases of the game store different points of information. The dating database we checked before, simply stores the state of our relationship with Karlach - it is important to make sure it is correct.

However, to be able to trigger certain conversation prompts, the game needs to know, where we are in our relationship timeline. This is where I think my bug is rooted as some kind of action is not logged that is required for that camp scene.

Using the console to fill the gaps in the timeline

We were still in Act 2, so I don't know how starting Act 3 might influence this fix.

  1. The dialogues and conversation prompts that get triggered at night, get queued as only a certain amount of them can happen each night. To make sure we are in full control over what happens and when, we want to know whether any events are queues for the next night. You do that with the following command:

    \_D(Osi.DB_Camp_QueuedNight:Get(nil))

    If the list is not empty ([]), rest at camp a couple of times to trigger them and empty the list.

  2. Now, we're going to delete some of the events that should have been logged and add them again to make sure they are properly added as the most recent events. Use these commands after each other:

    Osi.DB_GlobalFlag:Delete("NIGHT_Karlach_TheForgingOfTheHeart_0d3a46b9-074c-4d71-aa11-ff078e8017b5")
    Osi.DB_GlobalFlag:Delete("ORI_Karlach_State_CanHaveSex_1ea8dd6c-0562-473d-8310-6fdfdbffadca")
    Osi.DB_GlobalFlag:Delete("GLO_ForgingOfTheHeart_State_KarlachSecondUpgrade_f6dc0de4-1089-43c0-b392-306a9a44387c")
    Osi.DB_GlobalFlag:Delete("ORI_Karlach_Knows_EngineIsGoingToExplode_20cff0c8-ed5e-e672-73cb-b2f500bdb303")
  3. With the following commands, we add the events back in - now as the most recent events in the timeline.

    Osi.DB_GlobalFlag("ORI_Karlach_Knows_EngineIsGoingToExplode_20cff0c8-ed5e-e672-73cb-b2f500bdb303")
    Osi.DB_GlobalFlag("GLO_ForgingOfTheHeart_State_KarlachSecondUpgrade_f6dc0de4-1089-43c0-b392-306a9a44387c")
    Osi.DB_GlobalFlag("ORI_Karlach_State_CanHaveSex_1ea8dd6c-0562-473d-8310-6fdfdbffadca")

    Yes, we're only adding three events after deleting four.

  4. Now we are going to look at the log of night events - this one tracks what you did each night. Use the following command to get the list as respons.

    \_D(Osi.DB_CAMP_METRIC_NIGHT:Get(nil, nil))

    The console should show a long list now.

  5. In the list, find the log for "TheForgingOfTheHeart" and note the number above it. Replace [NUMBER] in the following command with that number:

    \_D(Osi.DB_CAMP_METRIC_NIGHT:Delete([NUMBER], "NIGHT_Karlach_TheForgingOfTheHeart_0d3a46b9-074c-4d71-aa11-ff078e8017b5"))
  1. We also need to delete the event from the following table.

    \_D(Osi.DB_CampNight_Completed:Delete("NIGHT_Karlach_TheForgingOfTheHeart_0d3a46b9-074c-4d71-aa11-ff078e8017b5"))
  2. Make camp. (I am actually not sure whether I only went to camp, or rested as well in this step. My guess is that it does not matter.)

  3. Add the following event in progress flag:

    Osi.DB_GlobalFlag("ORI_Karlach_State_RomanceSceneInProgress_cbce4176-b581-4fd8-8abb-1d2421a79741")
  4. We also need to add the following two conversation triggers:

    Osi.DB_Camp_QueuedNight("NIGHT_Karlach_TheForgingOfTheHeart_0d3a46b9-074c-4d71-aa11-ff078e8017b5")
    Osi.DB_HandlingRelationshipDialog("S_Player_Karlach_2c76687d-93a2-477b-8b18-8a14b549304c","CAMP_Karlach_CRD_ForgingOfTheHeart_57604b76-d93e-053c-2b9c-e53c747b684f","NULL_00000000-0000-0000-0000-000000000000","CAMP",1,-100)
  5. Talk to Karlach. You should get new conversation prompts. Don't follow up on Karlach's invitation (that you're hopefully getting) just yet, though!

Now we are going to add the events that are required to pass the test for a night with Karlach.

  1. Use command _D(Osi.DB_CampNight:Get(nil, nil))
    If you see the following line, skip this step, otherwise add it:

    \_D(Osi.DB_CampNight("NIGHT_Karlach_TheForgingOfTheHeart_0d3a46b9-074c-4d71-aa11-ff078e8017b5", 4030))
  2. Depending on where you are currently making camp, you need to use one of the following location names in the next command.

    • If your camp is in the main shadow area, use SCLMAIN
    • If your camp is in the town Haven, use HAVEN
    • If your camp is in the Moonrise towers, use MOONRISE
    • If your camp is in the Gauntle of Shar, use SHARTEMPLE

First, check whether the line is already in your table with the following command:

\_D(Osi.DB_CampNight_Requirement:Get(nil, nil))

If it is not in there, add the line - replace [LOCATION] with one of the above (keep the ""):

\_D(Osi.DB_CampNight_Camp("NIGHT_Karlach_TheForgingOfTheHeart_0d3a46b9-074c-4d71-aa11-ff078e8017b5", "[LOCATION]"))
  1. Use command: _D(Osi.DB_CampNight_Requirement:Get(nil, nil))
    If you see the following line, skip this step, otherwise add it:

    \_D(Osi.DB_CampNight_Requirement("NIGHT_Karlach_TheForgingOfTheHeart_0d3a46b9-074c-4d71-aa11-ff078e8017b5", "GLO_ForgingOfTheHeart_State_KarlachSecondUpgrade_f6dc0de4-1089-43c0-b392-306a9a44387c"))
  2. Use command _D(Osi.DB_CampNight_RomanceNight:Get(nil, nil, nil, nil))
    If you see the following line, skip this step, otherwise add it:

    \_D(Osi.DB_CampNight_RomanceNight("NIGHT_Karlach_TheForgingOfTheHeart_0d3a46b9-074c-4d71-aa11-ff078e8017b5", "S_Player_Karlach_2c76687d-93a2-477b-8b18-8a14b549304c", "CAMP_Karlach_SD_ROM_ForgingOfTheHeart_c2fbbf85-71d0-d4aa-07df-21abbb9f303a", "HAV_ForgingOfTheHeart_State_SelectedAvatar_ca71655f-3dec-44f7-8222-cfa2e1db4d9e"))
  3. Use command _D(Osi.DB_CampNight_CRD:Get(nil, nil, nil, nil))
    If you see the following line, skip this step, otherwise add it:

    \_D(Osi.DB_CampNight_CRD("NIGHT_Karlach_TheForgingOfTheHeart_0d3a46b9-074c-4d71-aa11-ff078e8017b5", "S_Player_Karlach_2c76687d-93a2-477b-8b18-8a14b549304c", "CAMP_Karlach_CRD_ForgingOfTheHeart_57604b76-d93e-053c-2b9c-e53c747b684f", "NULL_00000000-0000-0000-0000-000000000000"))
  4. Use command _D(Osi.DB_CampNight_Requirement_Dating:Get(nil, nil))
    If you see the following line, skip this step, otherwise add it:

    \_D(Osi.DB_CampNight_Requirement_Dating("NIGHT_Karlach_TheForgingOfTheHeart_0d3a46b9-074c-4d71-aa11-ff078e8017b5", "S_Player_Karlach_2c76687d-93a2-477b-8b18-8a14b549304c"))
  5. Use command _D(Osi.DB_Dialogs_DatingDialog:Get(nil))
    If you see the following line, skip this step, otherwise add it:

    \_D(Osi.DB_Dialogs_DatingDialog("CAMP_Karlach_CRD_ForgingOfTheHeart_57604b76-d93e-053c-2b9c-e53c747b684f"))
  6. Sleep. In the game, of course.

After those steps, I got all the appropiate dialogue prompts and the cutscene to progress triggered.

Again, this is not my solution. All the thanks go to DimakSerpg and nathdragon-5 on Reddit!

Did I photoshop heartshaped bokeh into all my screenshots? Maybe.

Did you like this?

Was this post useful to you? Follow me on Twitch or support me on Ko-Fi.

Read more: