Fixing Baldur’s Gate 3 Wyrm’s lookout bug

Fixing Baldur’s Gate 3 Wyrm’s lookout bug

Tags
Games
Published
Aug 9, 2025
Description
My journey in debugging a game‑breaking bug in my save file for a computer game, Baldur’s Gate 3, using same techniques I’d use to debug software, such as enabling logs and comparing successful vs. failed runs. Even if you’ve never played the game, you should be able to follow along!
Created by
Baldur’s Gate 3 is a computer game based on the tabletop Dungeons & Dragons. I was playing the game’s most challenging difficulty called Honour mode. In this mode, there is only a single save file, so there is no reloading if things go badly, and if the entire party dies, it’s game over. I enjoyed how this mode forces me to plan ahead, adapt to setbacks, and live with my mistakes.
Things were going smoothly until I hit a game-breaking bug at the 50-hour mark of my playthrough, that prevented me from progressing. With no manual backups, I couldn’t reload a previous save to try to avoid the issue. Searching online, I discovered others had encountered the same bug, but none of the suggested fixes worked for me.
I was getting desperate, but I didn’t want to restart my playthrough from the beginning. Then an idea struck me: in software engineering, when something doesn’t work as expected, what do you do? Well, one way is to look at the logs. That simple thought sparked an unusual journey of debugging a video game save file.
In short, I managed to fix the issue by following similar steps I’d use to debug a software problem:
  • Enable and review logs to pinpoint when and where things went wrong.
  • Compare logs from a successful run and a failed run to identify the moment they diverged.
  • Swap out the suspected culprit, an in-game entity in this case, with a fresh one to confirm if it was causing the bug. Much like restarting a faulty software component.
I never discovered the exact cause of the bug since I did not have earlier saves to experiment with. But the process was surprisingly fun, and I thought it was worth documenting. In the end, I was able to complete my Honour mode run without encountering any further problems. 🥳

More details on the Wyrm’s lookout bug

This part is about the game itself rather than the debugging process, so feel free to skip ahead if this does not interest you.
Wyrm’s lookout is a mandatory area on the way to Act 3. Normally, your party rests here overnight, which triggers an ambush cutscene. However, that never happened to me.
I suspect the issue began when I exited the game just before resting at Wyrm’s lookout. When I reloaded my save, it was suddenly morning in-game, and I discovered many issues with my playthrough.
First, leaving camp caused my party to become stuck floating mid-air.
Second, taking a long rest simply advanced the day without triggering the ambush cutscene.
Third, I could return to Act 2, but every defeated NPC had respawned, as if the whole area had been reset.

Fixing the bug

I’ll walk you through my journey to fix this bug. If you just want the list of steps, skip ahead to the TLDR Fix section.

Enabling logs

My playthrough was modded and used Script Extender, which provides logging and a console, so I enabled both.
notion image
I then went back to my playthrough and retried the problematic action: taking a long rest at Wyrm’s lookout. Normally, this should trigger an ambush cutscene, but nothing happened.
The log file contained about 1600 lines of Osiris logs. Osiris is the scripting language used by Baldur’s Gate 3 developers, and I wasn’t familiar with it, but it seemed to list function calls with their arguments and return values.
exec [Osi user query] QRY_CampNight_TryStartSleepMoment_SCO( (DIALOGRESOURCE)INT_EmperorRevealed_WokenUpAtNight_SCO_2dd56c1b-66b0-5c6e-00d3-e6fdd5cab379, (CHARACTER)HalfElves_Female_Wood_Player_2a683790, (CHARACTER)S_Player_Astarion_c7c13742-bacd-460a-8f65-f864fe41f255, (CHARACTER)S_Player_Karlach_2c76687d-93a2-477b-8b18-8a14b549304c, (CHARACTER)S_Player_ShadowHeart_3ed74f06-3c60-42dc-83f6-f034cb47c679 ) exec [Osi user query] QRY_Camp_SleepCutsceneOverride_CustomDialogStart( INT_EmperorRevealed_WokenUpAtNight_SCO_2dd56c1b-66b0-5c6e-00d3-e6fdd5cab379, HalfElves_Female_Wood_Player_2a683790, S_Player_Astarion_c7c13742-bacd-460a-8f65-f864fe41f255, S_Player_Karlach_2c76687d-93a2-477b-8b18-8a14b549304c, S_Player_ShadowHeart_3ed74f06-3c60-42dc-83f6-f034cb47c679 ) exec [Osi user query] QRY_StartDialog_Fixed( (DIALOGRESOURCE)INT_EmperorRevealed_WokenUpAtNight_SCO_2dd56c1b-66b0-5c6e-00d3-e6fdd5cab379, HalfElves_Female_Wood_Player_2a683790, S_Player_Astarion_c7c13742-bacd-460a-8f65-f864fe41f255, S_Player_Karlach_2c76687d-93a2-477b-8b18-8a14b549304c, S_Player_ShadowHeart_3ed74f06-3c60-42dc-83f6-f034cb47c679, S_GLO_ThrallOfTheAbsolute_AbsoluteHelper_15d4bd12-855b-4483-a2e5-661bfeb96d1f ) ... exec [DIV query] DialogIsAllowingJoinCombat( INT_EmperorRevealed_WokenUpAtNight_SCO_2dd56c1b-66b0-5c6e-00d3-e6fdd5cab379, [out] (INTEGER) ) Query returns: DialogIsAllowingJoinCombat( INT_EmperorRevealed_WokenUpAtNight_SCO_2dd56c1b-66b0-5c6e-00d3-e6fdd5cab379, 0 ) ... 0> RuleActionPart of THEN at line 8129 fires. Rule variables: 1--> SysClear( "DB_StartOverrideDialog_PlayerSpeaker", 1 ) [Osiris internal call] 0> [end of rule action part] exec [Osi user query] QRY_StartOverrideDialog_SetIfPlayer( NULL_00000000-0000-0000-0000-000000000000 ) *** Query failed! *** Query returns: QRY_StartOverrideDialog_SetIfPlayer( NULL_00000000-0000-0000-0000-000000000000 )
I tried to spot anything unusual, even turning to ChatGPT to explain some of the function calls, but nothing stood out.

Triggering cutscenes via the console

Since I had the console enabled, I wondered if I could trigger the cutscene directly. Searching online, I found resources for teleporting to the next act and triggering romance cutscenes.
For example:
-- Teleport to Act 3 Osi.PROC_Debug_TeleportToAct("Act3") -- Trigger the proposal scene of a character named Wyll Osi.ClearFlag("GLO_Ravengard_State_Defeated_7bb624ef-09cb-4e55-b035-832c05427a61", Osi.DB_Avatars:Get(nil)[1][1]) Osi.QRY_StartDialogCustom_Fixed("CAMP_Wyll_CRD_Act3Romance_599fe884-f39f-a3b5-7a86-ca239e016a05", "S_Player_Astarion_c7c13742-bacd-460a-8f65-f864fe41f255", Osi.DB_Avatars:Get(nil)[1][1], 1, 1, -1, 1 )
I could have teleported straight to Act 3 to bypass the issue where the ambush cutscene wouldn’t trigger. However, from those examples, I suspected the game heavily relies on flags and tags to track story choices, and skipping content might break things later. So, I decided against it.
From those examples and my logs, I found the ambush cutscene’s ID and my characters’ ID, allowing me to attempt the function call directly:
Osi.QRY_CampNight_TryStartSleepMoment_SCO("INT_EmperorRevealed_WokenUpAtNight_SCO_2dd56c1b-66b0-5c6e-00d3-e6fdd5cab379", "HalfElves_Female_Wood_Player_2a683790", "S_Player_Astarion_c7c13742-bacd-460a-8f65-f864fe41f255", "S_Player_Karlach_2c76687d-93a2-477b-8b18-8a14b549304c", "S_Player_ShadowHeart_3ed74f06-3c60-42dc-83f6-f034cb47c679")
Unfortunately, it still failed — the function returned false.

Comparing successful and failed logs

Then I remembered I had an older non-Honour mode save just 5 minutes away from reaching Wyrm’s lookout. Perfect!
I recorded the logs of taking a long rest there, which worked fine, then compared them with my buggy Honour mode logs. The first major difference? The IsCharacter function call on my main character returned false, something I definitely wasn’t expecting.
-- failed logs exec [DIV query] IsCharacter( HalfElves_Female_Wood_Player_2a683790, [out] 1 ) Query returns: IsCharacter( HalfElves_Female_Wood_Player_2a683790, 0 ) -- sucessful logs exec [DIV query] IsCharacter( Elves_Male_Wood_Player_Strong_0f737390-471e-7734-f057-f4af197feae6, [out] 1 ) Query returns: IsCharacter( Elves_Male_Wood_Player_Strong_0f737390-471e-7734-f057-f4af197feae6, 1 )

Replacing the main character

This gave me an idea: replace my main character with a new one to see if the function call to trigger the ambush cutscene would work.
To do this, I simulated a multiplayer game by running two instances of Baldur’s Gate 3, where one hosts and the other joins. When the second player joined, the character creation screen appeared, giving me a second “main character”.
I then used the in-game “wardrobe” feature to store my old main character. Normally, this is used for temporarily removing a friend’s character in co-op, for example, when they are not playing.
Finally, the moment of truth, I triggered the cutscene via the console using the new main character’s ID… and it worked! The ambush cutscene played, and I could finally continue my Honour mode run. What a relief!

TLDR fix

  1. Back up your save file first to be safe. Be sure to copy both profile.lsf and the save folder as described here: https://www.reddit.com/r/BaldursGate3/comments/1bktzhv/technical_how_to_back_up_save_games_in_bg3_on_pc/
  1. Setup Baldur's Gate 3 Mod Manager (BG3MM) and Script Extender.
    1. Install BG3MM: https://github.com/LaughingLeader/BG3ModManager
    2. Open BG3MM, then go to Tools → Download & Install the Script Extender.
    3. Open the game once to finish setting up Script Extender, then close the game.
  1. Replace your main character.
    1. Exit Steam.
    2. Navigate to the bin folder of the game e.g. C:\Program Files (x86)\Steam\steamapps\common\Baldurs Gate 3\bin .
    3. Start the first game instance by running bg3_dx11.exe, set resolution and graphics to low to reduce resource usage, then load your save file.
    4. Go to Settings → Multiplayer → cog icon on the top → tick the “Direct Connections” and take note of the Direct Connect ID.
    5. Start the second game instance by running bg3_dx11.exe again, then join the multiplayer game via Direct Connect using the previously noted ID. Upon joining, finish creating the new main character.
    6. Close the second game instance.
    7. In the first game instance, dismiss the old main character by talking to them with the new main character and choosing the dismiss dialogue option.
    8. Close the first game instance.
  1. Enable logs and console in BG3MM.
    1. Go to Settings → Preferences.
    2. Tick the boxes for “Create Console” and “Enable Osiris Logging”.
    3. Set “Log Directory” to an existing folder e.g. C:\Users\<username>\Documents\osirisLogs.
  1. Prepare the command to trigger the ambush cutscene.
    1. Find your main character’s ID from the most recent log file. Example log file name: Osiris Runtime 2025-06-24 07-57-42.log Example player IDs: HalfElves_Female_Wood_Player_2a683790 Elves_Male_Wood_Player_Strong_0f737390-471e-7734-f057-f4af197feae6
    2. Take note of the other origin characters’ ID in your party.
      1. Character
        ID
        Astarion
        S_Player_Astarion_c7c13742-bacd-460a-8f65-f864fe41f255
        Gale
        S_Player_Gale_ad9af97d-75da-406a-ae13-7071c563f604
        Wyll
        S_Player_Wyll_c774d764-4a17-48dc-b470-32ace9ce447d
        Shadowheart
        S_Player_ShadowHeart_3ed74f06-3c60-42dc-83f6-f034cb47c679
        Laezel
        S_Player_Laezel_58a69333-40bf-8358-1d17-fff240d7fb12
        Karlach
        S_Player_Karlach_2c76687d-93a2-477b-8b18-8a14b549304c
        Minthara
        S_GOB_DrowCommander_25721313-0c15-4935-8176-9f134385451b
        Halsin
        S_GLO_Halsin_7628bc0e-52b8-42a7-856a-13a6fd413323
    3. Prepare the command to trigger the cutscene:
      1. Osi.QRY_CampNight_TryStartSleepMoment_SCO("INT_EmperorRevealed_WokenUpAtNight_SCO_2dd56c1b-66b0-5c6e-00d3-e6fdd5cab379", "<main character ID>", "<origin party member 1 ID>", "<origin party member 2 ID>", "<origin party member 3 ID>") -- Example: Osi.QRY_CampNight_TryStartSleepMoment_SCO("INT_EmperorRevealed_WokenUpAtNight_SCO_2dd56c1b-66b0-5c6e-00d3-e6fdd5cab379", "HalfElves_Female_Wood_Player_2a683790", "S_Player_Astarion_c7c13742-bacd-460a-8f65-f864fe41f255", "S_Player_Karlach_2c76687d-93a2-477b-8b18-8a14b549304c", "S_Player_ShadowHeart_3ed74f06-3c60-42dc-83f6-f034cb47c679")
  1. Trigger the ambush cutscene.
    1. Open the game, load your save file, go to Wrym’s lookout, and ensure it is night time. Taking a long rest will make it night.
    2. Click the Script Extender console window, press Enter once to bring up the terminal, then run the prepared command.