Topic: Frisians 02 crash when red HQ destroyed before storehouse full

beng
Avatar
Topic Opener
Joined: 2023-07-03, 20:41 UTC+2.0
Posts: 29
OS: Debian 13
Version: 1.21 build 6 i think
Ranking
Pry about Widelands
Location: singapore
Posted at: 2025-12-23, 04:22 UTC+1.0

In Widelands 1.2.1 Frisians campaign mission 2

When the red tribe HQ is destroyed by the yellow tribe before the empire storehouse has been filled with the bribe wares, the game crashes once the empire storehouse does have the requested wares. The screenshot shows the lua error message.


Attachment: image/png
fri2crash.png

Top Quote
beng
Avatar
Topic Opener
Joined: 2023-07-03, 20:41 UTC+2.0
Posts: 29
OS: Debian 13
Version: 1.21 build 6 i think
Ranking
Pry about Widelands
Location: singapore
Posted at: 2025-12-23, 05:08 UTC+1.0

I think the crash is caused by the script in mission_thread.lua not checking if the player 2 HQ is still around here. How can I change it so that it checks first and then fails gracefully instead of crashing the game? Maybe there needs to be a function that checks if the red player HQ has been destroyed by the yellows before the human player has the all items in the empire warehouse?


Attachment: image/png
script-error.png

Top Quote
kaputtnik
Avatar
Joined: 2013-02-18, 20:48 UTC+1.0
Posts: 2769
OS: Archlinux
Version: current master
Ranking
One Elder of Players
Location: Germany
Posted at: 2025-12-23, 09:50 UTC+1.0

If i undestand correctly MapObject.exists is the check what's missing, Eg.

if hq.exists then
   -- do some stuff

or simply (because the not exiting object is nil):

if hq then
   -- do some stuff

Changing the script and then reloading a save game will not load the changed script. To get the change work one has to start the scenario from scratch…


Top Quote
beng
Avatar
Topic Opener
Joined: 2023-07-03, 20:41 UTC+2.0
Posts: 29
OS: Debian 13
Version: 1.21 build 6 i think
Ranking
Pry about Widelands
Location: singapore
Posted at: 2025-12-23, 11:26 UTC+1.0

Thanks for the tip kaputtnik but since hq is a local variable which is an array of empire_headquarters from p2:get_buildings, and the game crashes trying to set that variable, it will crash before .exists can work. What I may try is to do something like

    if check_for_buildings(p2,{empire_headquarters = 1,}) then
        local hq = p2:get_buildings("empire_headquarters")[1]

and carry on the script part that transfers wares, so if p2 does not have any empire_headquarters it will just skip the whole wares transfer part.


Top Quote
Nordfriese
Avatar
Joined: 2017-01-17, 18:07 UTC+1.0
Posts: 2241
OS: Debian Testing
Version: Latest master
Ranking
One Elder of Players
Location: 0x55555d3a34c0
Posted at: 2025-12-23, 13:08 UTC+1.0

Actually in Lua, accessing an undefined array entry is valid, so hq is simply nil. It then crashes later on when trying to call a method on hq (hq:set_wares() and hq:get_wares()).

exists won't work here because hq would have to be valid when set, but it is nil right away. exists is only useful for non-nil references to since-deleted objects.

The best solution would be to try to find some other warehouse if the HQ no longer exists, or skip transferring the wares if p2 has no warehouses left at all. (using simply if hq ~= nil then do_stuff_with_hq end)

P.S. Thanks for finding and reporting this bug, I hadn't expected that the Barbarians would be able to defeat the Empire so quickly :)

Edited: 2025-12-23, 13:08 UTC+1.0

Top Quote
kaputtnik
Avatar
Joined: 2013-02-18, 20:48 UTC+1.0
Posts: 2769
OS: Archlinux
Version: current master
Ranking
One Elder of Players
Location: Germany
Posted at: 2025-12-23, 13:09 UTC+1.0

or get the array and check if it is empty:

local hq = p2:get_buildings("empire_heaquarters")
if #hq > 0:                       -- may be if #hq is enough, my brain is currently on python syntax…
    hq = hq[1]

or iterate over the array?

local hq = Nil
for building in p2:get_buildings("empire_heaquarters") do
     if building then
          hq = building

Top Quote
beng
Avatar
Topic Opener
Joined: 2023-07-03, 20:41 UTC+2.0
Posts: 29
OS: Debian 13
Version: 1.21 build 6 i think
Ranking
Pry about Widelands
Location: singapore
Posted at: 2025-12-23, 17:38 UTC+1.0

Nordfriese wrote

P.S. Thanks for finding and reporting this bug, I hadn't expected that the Barbarians would be able to defeat the Empire so quickly :)

It wasn't quick, just that I took a long time trying to get the amounts of bribe wares in that warehouse right. When they were almost all done, something would exit the warehouse like rations for mines, or iron ore, or gold ore, or something and that item would be below the trigger level, then when trying to get it back to the correct level, some other ware would exit the warehouse and drop below the trigger level. Like wack a mole. Really hard to get it all correct.


Top Quote
hessenfarmer
Avatar
Joined: 2014-12-11, 23:16 UTC+1.0
Posts: 2918
OS: Windows
Version: always the latest
Ranking
One Elder of Players
Location: Bavaria
Posted at: 2025-12-23, 23:11 UTC+1.0

well, that is surprising to me as well as this has never happened in testplay to me.
However, I think the fundamental question is whether the Barbarians shuld be allowed to win over the empire.
If yes we might need a different ongoing of the story like we were lucky to get rid of the empire by a foreign tribe, but they are hostile tous as well sowe need to finish them as well to male the island ours.
Or we need to take care that this can't happen by forbid fighting between them until several conditions have been met.

Personally I tend to like option 1 a bit more, but it is a lot of additional work on the story.


Top Quote
beng
Avatar
Topic Opener
Joined: 2023-07-03, 20:41 UTC+2.0
Posts: 29
OS: Debian 13
Version: 1.21 build 6 i think
Ranking
Pry about Widelands
Location: singapore
Posted at: 2025-12-25, 11:04 UTC+1.0

Another thing you may want to change: When the script is triggered where the Romans ask for a bribe and forbid expansion of territory, the human player may have military buildings in the process of being built but nearing completion and once that script triggers, the building gets completed and the romans turn hostile and start to attack, so the player has no chance to decide whether to destroy the warehouse or pay the bribe. Maybe put in a delay of 5 minutes or something before the romans count the military buildings so the player has a chance to find the building that are being built and cancel them or demolish others to keep the number the same.


1
Top Quote
beng
Avatar
Topic Opener
Joined: 2023-07-03, 20:41 UTC+2.0
Posts: 29
OS: Debian 13
Version: 1.21 build 6 i think
Ranking
Pry about Widelands
Location: singapore
Posted at: 2025-12-25, 11:12 UTC+1.0

hessenfarmer wrote

well, that is surprising to me as well as this has never happened in testplay to me.
However, I think the fundamental question is whether the Barbarians shuld be allowed to win over the empire.
If yes we might need a different ongoing of the story like we were lucky to get rid of the empire by a foreign tribe, but they are hostile tous as well sowe need to finish them as well to male the island ours.
Or we need to take care that this can't happen by forbid fighting between them until several conditions have been met.

Personally I tend to like option 1 a bit more, but it is a lot of additional work on the story.

The story could be that the Barbarians say the player should instead pay them for liberating them from the Roman yoke of oppression and they then impose their own bribe conditions and take the stuff in the warehouse if it contains what they want. The player has probably not been able to train their soldiers because they have been trying to micromanage the economy for the Roman warehouse, so this may give them some time to train up before the Barbarians finally attack.

Alternatively the story could be that some escaping Romans bring word that the Barbarians have caused the fall of their empire and can give the player some gold or swords or something saying to use them to avenge them by defeating the Barbarians.


Top Quote