CleverRaven / Cataclysm-DDA

Cataclysm - Dark Days Ahead. A turn-based survival game set in a post-apocalyptic world.
http://cataclysmdda.org
Other
10.59k stars 4.17k forks source link

Strange: player is already assigned to mission 1 through 10 #67277

Closed Inglonias closed 9 months ago

Inglonias commented 1 year ago

Describe the bug

DEBUG : strange: player is already assigned to mission 1

FUNCTION : assign FILE : D:\a\Cataclysm-DDA\Cataclysm-DDA\src\mission.cpp LINE : 300 VERSION : 6956921

Attach save file

N/A

Steps to reproduce

  1. Install the latest experimental as of this issue
  2. Go to create a character
  3. Encounter the errors shown
  4. No further issues?

Expected behavior

No error messages

Screenshots

N/A

Versions and configuration

Additional context

No response

Inglonias commented 1 year ago

It's entirely possible I have some old data somewhere - I'm using the catapult launcher which separates user data out from the game files.

MrHrulgin commented 1 year ago

I've seen the same thing, using the fork of the CDDA Launcher.

NetSysFire commented 1 year ago

I can confirm this, although I get mission 1-128.

Inglonias commented 1 year ago

Error is thrown at L300 of mission.cpp

https://github.com/CleverRaven/Cataclysm-DDA/blob/master/src/mission.cpp#L300

Inglonias commented 1 year ago

The cause of this bug appears to be the ten starting missions being assigned to the player more than once.

Brambor commented 1 year ago

Stack trace image

Termineitor244 commented 1 year ago

Happened to me too, in the most recent experimental version, for me the missions are 1 and 2.

DEBUG : strange: player is already assigned to mission 2

FUNCTION : assign FILE : D:\a\Cataclysm-DDA\Cataclysm-DDA\src\mission.cpp LINE : 300 VERSION : 838f893

lispcoc commented 11 months ago

I think this is probably a problem that occurs with a specific MOD configuration, but the following MOD cannot be found.

Fewer Soldier Extras [Fewer_Soldiers], Lonely Evac Scenario [Lonely_Evac]

Inglonias commented 11 months ago

I wrote those mods, so you wouldn't have them. Fewer Soldier Extras does what it says on the tin. Cute the number of soldier extras in half.

Lonely Evac adds a starting scenario that is identical to the standard start minus the NPC.

Other people, presumably with different mod setups, have already reported this issue.

lispcoc commented 11 months ago

I tried both the latest development version and the version mentioned in the issue, but was unable to reproduce the issue. It seems that no special settings are required, but perhaps the incidence is simply low?

NetSysFire commented 11 months ago

I can still reproduce. At least on older worlds.

Inglonias commented 11 months ago

I reinstalled the game and cleared my save files - looks like the issue is gone for me.

If it's still reproducible with older saves, I feel the issue should stay open, but I don't know if it really counts as a release blocker, since it doesn't actually do much to harm things. That said, I'm not the one in charge. It's the core dev team's call.

NetSysFire commented 11 months ago

Most people will be reusing their old worlds and if these come with persistent errors this is not acceptable.

BrettDong commented 11 months ago

Just encountered this bug in a freshly created world (created by New Game -> Play Now!)


Update: stack trace:

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
  * frame #0: 0x00000001804e7ea8 libsystem_kernel.dylib`__semwait_signal + 8
    frame #1: 0x00000001803cb2f8 libsystem_c.dylib`nanosleep + 220
    frame #2: 0x00000001061d6ba4 libSDL2-2.0.0.dylib`SDL_Delay_REAL + 80
    frame #3: 0x00000001038319e8 cataclysm-tiles`input_manager::get_input_event(this=0x00000001041fcd08, preferred_keyboard_mode=<unavailable>) at sdltiles.cpp:3833:13 [opt]
    frame #4: 0x0000000102a42458 cataclysm-tiles`debug_error_prompt(filename=<unavailable>, line=<unavailable>, funcname=<unavailable>, text=<unavailable>, force=<unavailable>) at debug.cpp:379:26 [opt]
    frame #5: 0x0000000102a42a3c cataclysm-tiles`realDebugmsg(filename="src/mission.cpp", line="300", funcname="void mission::assign(avatar &)", text="strange: player is already assigned to mission 5") at debug.cpp:540:5 [opt]
    frame #6: 0x0000000103261e38 cataclysm-tiles`mission::assign(avatar&) [inlined] void realDebugmsg<int&>(filename=<unavailable>, line=<unavailable>, funcname=<unavailable>, mes=<unavailable>, args=<unavailable>) at debug.h:78:12 [opt]
    frame #7: 0x0000000103261e04 cataclysm-tiles`mission::assign(this=0x0000600000e14118, u=0x00000001311de800) at mission.cpp:300:9 [opt]
    frame #8: 0x000000010350d784 cataclysm-tiles`std::__1::__function::__func<talk_effect_fun_t::set_assign_mission(JsonObject const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>)::$_249, std::__1::allocator<talk_effect_fun_t::set_assign_mission(JsonObject const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>)::$_249>, void (dialogue&)>::operator()(dialogue&) [inlined] talk_effect_fun_t::set_assign_mission(JsonObject const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>)::$_249::operator()(this=0x00006000047bc428, d=0x000000016d8b2220) const at npctalk.cpp:4306:22 [opt]
    frame #9: 0x000000010350d724 cataclysm-tiles`std::__1::__function::__func<talk_effect_fun_t::set_assign_mission(JsonObject const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>)::$_249, std::__1::allocator<talk_effect_fun_t::set_assign_mission(JsonObject const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>)::$_249>, void (dialogue&)>::operator()(dialogue&) [inlined] decltype(std::declval<talk_effect_fun_t::set_assign_mission(JsonObject const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>)::$_249&>()(std::declval<dialogue&>())) std::__1::__invoke[abi:v160006]<talk_effect_fun_t::set_assign_mission(JsonObject const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>)::$_249&, dialogue&>(__f=0x00006000047bc428, __args=0x000000016d8b2220) at invoke.h:394:23 [opt]
    frame #10: 0x000000010350d724 cataclysm-tiles`std::__1::__function::__func<talk_effect_fun_t::set_assign_mission(JsonObject const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>)::$_249, std::__1::allocator<talk_effect_fun_t::set_assign_mission(JsonObject const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>)::$_249>, void (dialogue&)>::operator()(dialogue&) [inlined] void std::__1::__invoke_void_return_wrapper<void, true>::__call<talk_effect_fun_t::set_assign_mission(JsonObject const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>)::$_249&, dialogue&>(__args=0x00006000047bc428, __args=0x000000016d8b2220) at invoke.h:487:9 [opt]
    frame #11: 0x000000010350d724 cataclysm-tiles`std::__1::__function::__func<talk_effect_fun_t::set_assign_mission(JsonObject const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>)::$_249, std::__1::allocator<talk_effect_fun_t::set_assign_mission(JsonObject const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>)::$_249>, void (dialogue&)>::operator()(dialogue&) [inlined] std::__1::__function::__alloc_func<talk_effect_fun_t::set_assign_mission(JsonObject const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>)::$_249, std::__1::allocator<talk_effect_fun_t::set_assign_mission(JsonObject const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>)::$_249>, void (dialogue&)>::operator()[abi:v160006](this=0x00006000047bc428, __arg=0x000000016d8b2220) at function.h:185:16 [opt]
    frame #12: 0x000000010350d724 cataclysm-tiles`std::__1::__function::__func<talk_effect_fun_t::set_assign_mission(JsonObject const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>)::$_249, std::__1::allocator<talk_effect_fun_t::set_assign_mission(JsonObject const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>)::$_249>, void (dialogue&)>::operator()(this=<unavailable>, __arg=<unavailable>) at function.h:356:12 [opt]
    frame #13: 0x00000001034b4aa8 cataclysm-tiles`talk_effect_t::apply(dialogue&) const [inlined] std::__1::__function::__value_func<void (dialogue&)>::operator()[abi:v160006](this=0x0000600001a1fa68, __args=0x000000016d8b2220) const at function.h:510:16 [opt]
    frame #14: 0x00000001034b4a98 cataclysm-tiles`talk_effect_t::apply(dialogue&) const [inlined] std::__1::function<void (dialogue&)>::operator()(this=0x0000600001a1fa68, __arg=0x000000016d8b2220) const at function.h:1156:12 [opt]
    frame #15: 0x00000001034b4a98 cataclysm-tiles`talk_effect_t::apply(dialogue&) const [inlined] talk_effect_fun_t::operator()(this=0x0000600001a1fa68, d=0x000000016d8b2220) const at dialogue_helpers.h:140:20 [opt]
    frame #16: 0x00000001034b4a90 cataclysm-tiles`talk_effect_t::apply(this=0x0000000116ff52b8, d=0x000000016d8b2220) const at npctalk.cpp:5764:13 [opt]
    frame #17: 0x0000000102b33018 cataclysm-tiles`effect_on_condition::activate(this=0x0000000116ff5240, d=0x000000016d8b2550) const at effect_on_condition.cpp:302:21 [opt]
    frame #18: 0x0000000102b34bf0 cataclysm-tiles`eoc_events::notify(this=<unavailable>, e=0x000000016d8b2770, alpha=talker @ 0x000060000742ed80, beta=nullptr) at effect_on_condition.cpp:551:13 [opt]
    frame #19: 0x0000000102b34678 cataclysm-tiles`eoc_events::notify(this=<unavailable>, e=<unavailable>) at effect_on_condition.cpp:493:5 [opt]
    frame #20: 0x0000000102b46404 cataclysm-tiles`event_bus::send(this=<unavailable>, e=0x000000016d8b2770) const at event_bus.cpp:67:12 [opt]
    frame #21: 0x00000001037ddce0 cataclysm-tiles`stats_tracker::deserialize(this=<unavailable>, jo=<unavailable>) at savegame_json.cpp:4703:29 [opt]
    frame #22: 0x00000001036521f0 cataclysm-tiles`decltype(fp.deserialize(*this), true) JsonValue::read<stats_tracker>(this=0x000000016d8b2970, v=0x0000000111c240d0, throw_on_error=true) const at flexbuffer_json-inl.h:319:11 [opt]
    frame #23: 0x0000000103650dbc cataclysm-tiles`bool JsonObject::read<stats_tracker>(this=0x000000016d8b2c50, name=<unavailable>, t=0x0000000111c240d0, throw_on_error=true) const at flexbuffer_json-inl.h:1065:28 [opt]
    frame #24: 0x00000001036506b8 cataclysm-tiles`past_game_info::past_game_info(this=0x0000000111c23580, jo=0x000000016d8b2c50) at past_games_info.cpp:41:12 [opt]
    frame #25: 0x0000000103651d88 cataclysm-tiles`past_game_info& std::__1::vector<past_game_info, std::__1::allocator<past_game_info>>::emplace_back<JsonObject>(JsonObject&&) [inlined] past_game_info::past_game_info(this=<unavailable>, jo=0x000000016d8b2c50) at past_games_info.cpp:35:1 [opt]
    frame #26: 0x0000000103651d80 cataclysm-tiles`past_game_info& std::__1::vector<past_game_info, std::__1::allocator<past_game_info>>::emplace_back<JsonObject>(JsonObject&&) [inlined] void std::__1::allocator<past_game_info>::construct[abi:v160006]<past_game_info, JsonObject>(this=<unavailable>, __p=<unavailable>, __args=0x000000016d8b2c50) at allocator.h:168:28 [opt]
    frame #27: 0x0000000103651d80 cataclysm-tiles`past_game_info& std::__1::vector<past_game_info, std::__1::allocator<past_game_info>>::emplace_back<JsonObject>(JsonObject&&) [inlined] void std::__1::allocator_traits<std::__1::allocator<past_game_info>>::construct[abi:v160006]<past_game_info, JsonObject, void>(__a=<unavailable>, __p=<unavailable>, __args=0x000000016d8b2c50) at allocator_traits.h:296:13 [opt]
    frame #28: 0x0000000103651d80 cataclysm-tiles`past_game_info& std::__1::vector<past_game_info, std::__1::allocator<past_game_info>>::emplace_back<JsonObject>(JsonObject&&) [inlined] void std::__1::vector<past_game_info, std::__1::allocator<past_game_info>>::__emplace_back_slow_path<JsonObject>(this=0x00000001041cf158 size=2, __args=0x000000016d8b2c50) at vector:1582:5 [opt]
    frame #29: 0x0000000103651cf8 cataclysm-tiles`past_game_info& std::__1::vector<past_game_info, std::__1::allocator<past_game_info>>::emplace_back<JsonObject>(this=0x00000001041cf158 size=2, __args=0x000000016d8b2c50) at vector:1603:9 [opt]
    frame #30: 0x0000000103651508 cataclysm-tiles`past_games_info::ensure_loaded(this=0x00000001041cf128) at past_games_info.cpp:146:19 [opt]
    frame #31: 0x0000000103651e04 cataclysm-tiles`get_past_games() at past_games_info.cpp:178:16 [opt]
    frame #32: 0x0000000103809d98 cataclysm-tiles`scenario::can_pick(this=0x0000000128008000) const at scenario.cpp:613:9 [opt]
    frame #33: 0x00000001033f2a68 cataclysm-tiles`avatar::randomize(this=0x00000001311de800, random_scenario=<unavailable>, play_now=<unavailable>) at newcharacter.cpp:442:81 [opt]
    frame #34: 0x00000001033f404c cataclysm-tiles`avatar::create(this=0x00000001311de800, type=FULL_RANDOM, tempname="") at newcharacter.cpp:0:13 [opt]
    frame #35: 0x000000010304a4b0 cataclysm-tiles`main_menu::new_character_tab(this=0x000000016d8bed70) at main_menu.cpp:992:17 [opt]
    frame #36: 0x000000010304766c cataclysm-tiles`main_menu::opening_screen(this=0x000000016d8bed70) at main_menu.cpp:863:29 [opt]
    frame #37: 0x000000010303c664 cataclysm-tiles`main(argc=<unavailable>, argv=0x000000016d8bf508) at main.cpp:791:19 [opt]
    frame #38: 0x00000001801a90e0 dyld`start + 2360

It looks like the game is deserializing past game info from memorial files into the current avatar instance in the new world.


Update:

Steps to reproduce:

  1. Download memorial.zip, decompress and put memorial folder in game folder
  2. Launch game, start a new game: New Game -> Play Now!
  3. Bug
Inglonias commented 11 months ago

That's actually really good info. So a workaround is just to delete the memorial folder.

lispcoc commented 11 months ago

Perhaps the cause of this problem lies in void stats_tracker::deserialize( const JsonObject &jo ) in src\savegame_json.cpp If there is data before game_avatar_new was implemented in memorial, a dummy game_avatar_new event will be issued to match the statistical information. If there is an event that assigns a mission triggered by the issuance of game_avatar_new, this will cause mission duplication. If there is an event that assigns a mission based on the issuance of game_avatar_new (specifically "MISSION_CAMP_LEADERSHIP_CHANGE"), there is a possibility that IDs will overlap with characters that already exist in the world. This is because the avatar's ID is a provisional value at this time.