Cataclysm-dda: a combat knife disappears after the game is saved and reloaded

Created on 10 Jul 2020  Â·  12Comments  Â·  Source: CleverRaven/Cataclysm-DDA

Edit: see https://github.com/CleverRaven/Cataclysm-DDA/issues/42002#issuecomment-656993566

Describe the bug

 DEBUG    : error: tried to put an item into a pocket that can't fit into it while loading.  err: item is too small

 FUNCTION : void item_contents::combine(const item_contents&)
 FILE     : src/item_contents.cpp
 LINE     : 283

Steps To Reproduce

  1. Wear an XL holster and a sheath (id: sheath)
  2. [I]nsert a combat knife into the sheath
  3. Insert the sheath into the XL holster
  4. Save and Quit
  5. Load
  6. See the above message
  7. You now have:

    • a sheath on the ground

    • an XL holster with none

    • no combat knife

Expected behavior

The items don't fall on the ground and don't get deleted.

Screenshots

none

Versions and configuration

- OS: Linux
    - OS Version: LSB Version: :core-4.1-amd64:core-4.1-noarch; Distributor ID: Fedora; Description: Fedora release 32 (Thirty Two); Release: 32; Codename: ThirtyTwo; 
- Game Version: 0.E-3920-g4ef634e [64-bit]
- Graphics Version: Tiles
- Game Language: System language []
- Mods loaded: [
    Dark Days Ahead [dda],
    Disable NPC Needs [no_npc_food]
]

Additional context

Please note that is is also possible to create an "XL holster with sheath" by performing the steps 1 through 3 and then dropping the combat knife. This configuration will also fail to load. The loading code should probably be less aggressive.

debug.log

-----------------------------------------
10:19:00.797 : Starting log.
10:19:00.798 INFO : Cataclysm DDA version 0.E-3920-g4ef634e
10:19:00.798 INFO : [main] C locale set to C.UTF-8
10:19:00.798 INFO : [main] C++ locale set to C.UTF-8
10:19:00.798 INFO : SDL version used during compile is 2.0.4
10:19:00.798 INFO : SDL version used during linking and in runtime is 2.0.12
10:19:00.937 INFO : Number of render drivers on your system: 4
10:19:00.937 INFO : Render driver: 0/opengl
10:19:00.937 INFO : Render driver: 1/opengles2
10:19:00.938 INFO : Render driver: 2/opengles
10:19:00.938 INFO : Render driver: 3/software
10:19:00.940 INFO : [options] C locale set to C.UTF-8
10:19:00.940 INFO : [options] C++ locale set to C.UTF-8
10:19:00.947 INFO : Active renderer: 3/software
10:19:00.962 INFO : USE_COLOR_MODULATED_TEXTURES is set to 0
10:19:01.143 WARNING : opendir [./mods/] failed with "No such file or directory".
10:19:11.018 WARNING : opendir [./save/Saltillo/mods] failed with "No such file or directory".
10:19:17.511 INFO : Loaded tileset: retrodays
10:20:29.504 WARNING : opendir [./save/Saltillo/mods] failed with "No such file or directory".
10:20:35.724 INFO : Loaded tileset: retrodays
10:20:36.947 ERROR : (error message will follow backtrace)
    ./cataclysm-tiles(_Z21debug_write_backtraceRSo+0x38) [0xafa15d]
    ./cataclysm-tiles(_Z8DebugLog10DebugLevel10DebugClass+0x1e1) [0xafadf5]
    ./cataclysm-tiles(_Z12realDebugmsgPKcS0_S0_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+0xb0) [0xafba83]
    ./cataclysm-tiles(_Z12realDebugmsgIINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvPKcS7_S7_S7_DpOT_+0x44) [0x9550c1]
    ./cataclysm-tiles(_ZN13item_contents7combineERKS_+0x2e9) [0xcb0b35]
    ./cataclysm-tiles(_ZN4item11deserializeER6JsonIn+0x23e) [0x110a650]
    ./cataclysm-tiles(_ZN6JsonIn4readI4itemEEDTcmcldtfp_11deserializedefpTELb1EERT_b+0x11) [0x939c91]
    ./cataclysm-tiles(_ZN6JsonIn4readINSt7__cxx114listI4itemSaIS3_EEELPv0EEEDTcmcldtfp_5frontELb1EERT_b+0xb9) [0x1126d65]
    ./cataclysm-tiles(_ZN9Character4loadERK10JsonObject+0x1d75) [0x1114df7]
    ./cataclysm-tiles(_ZN6player4loadERK10JsonObject+0x2f) [0x1116aa1]
    ./cataclysm-tiles(_ZN6avatar4loadERK10JsonObject+0x2f) [0x1117ac1]
    ./cataclysm-tiles(_ZN6avatar11deserializeER6JsonIn+0x35) [0x1118df3]
    ./cataclysm-tiles(_ZN4game11unserializeERSi+0xce2) [0x10f5f6a]
    ./cataclysm-tiles(_Z14read_from_fileRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt8functionIFvRSiEE+0x85) [0xa2a8a1]
    ./cataclysm-tiles(_ZN4game4loadERK6save_t+0x1f0) [0xbd253c]
    ./cataclysm-tiles(_ZN9main_menu18load_character_tabEb+0x9eb) [0xdb6f8f]
    ./cataclysm-tiles(_ZN9main_menu14opening_screenEv+0xca7) [0xdbb0af]
    ./cataclysm-tiles(main+0x1766) [0x88cb15]
    /lib64/libc.so.6(__libc_start_main+0xf2) [0x7dee1a28c042]
    ./cataclysm-tiles(_start+0x29) [0x914859]

    Attempting to repeat stack trace using debug symbols…
    debug_write_backtrace(std::ostream&)
    ??:?
    DebugLog(DebugLevel, DebugClass)
    ??:?
    realDebugmsg(char const*, char const*, char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
    ??:?
    void realDebugmsg<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(char const*, char const*, char const*, char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&)
    ??:?
    item_contents::combine(item_contents const&)
    ??:?
    item::deserialize(JsonIn&)
    ??:?
    decltype ((({parm#1}.deserialize)(*this)),(true)) JsonIn::read<item>(item&, bool)
    ??:?
    decltype ((({parm#1}.front)()),(true)) JsonIn::read<std::__cxx11::list<item, std::allocator<item> >, (void*)0>(std::__cxx11::list<item, std::allocator<item> >&, bool)
    ??:?
    Character::load(JsonObject const&)
    ??:?
    player::load(JsonObject const&)
    ??:?
    avatar::load(JsonObject const&)
    ??:?
    avatar::deserialize(JsonIn&)
    ??:?
    game::unserialize(std::istream&)
    ??:?
    read_from_file(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::function<void (std::istream&)> const&)
    ??:?
    game::load(save_t const&)
    ??:?
    main_menu::load_character_tab(bool)
    ??:?
    main_menu::opening_screen()
    ??:?
    main
    ??:?
    __libc_start_main
    ??:?
    _start
    ??:?
Backtrace emission took 1 seconds.
src/item_contents.cpp:283 [void item_contents::combine(const item_contents&)] error: tried to put an item into a pocket that can't fit into it while loading.  err: item is too small
<Bug> Containers

Most helpful comment

I can confirm this is fixed by #41917. Tested OK in that branch:

  • sheath with combat knife on the ground
  • backpack worn by character, containing combat knife, RM42 fighting knife, and sword bayonet
  • XL holster with sheath with combat knife, in backpack

All items were preserved on save/load:

image

All 12 comments

Possible fixes

Make the loading code take into account the contents of an item A when checking if it can fit inside of an item B

Edit: in light of new information revealed by more testing I now believe this to be a separate bug #42026

This would probably fix the edge case described above, but leave the following edge case uncovered:

  1. Wear an XL holster and a sheath (id: sheath)
  2. [I]nsert a combat knife into the sheath
  3. Insert the sheath into the XL holster
  4. Drop the combat knife
  5. You now have an "XL holster with sheath" even though an empty sheath is too small for the holster

Change the loading code to not create a none and not delete items when it detects a rules violation

This is not a complete fix, but it would make a whole class of bugs less severe. Examples: #41928 #41403 #41725

Strict fix: allow an item A to be stored inside of an item B if the smallest possible volume of A is greater than the minimum required volume for items stored inside B

This risks:

  • breaking saves
  • disallowing something that should be allowed

Lenient fix: allow an item A to be stored inside of an item B if the largest possible volume of A is greater than the minimum required volume for items stored inside B

This risks allowing something that should not be allowed

Change the loading code to not create a none and not delete items when it detects a rules violation

It does not delete items, it puts them into a hidden "migration" pocket and they drop a turn after you load.

It does not delete items, it puts them into a hidden "migration" pocket and they drop a turn after you load.

The sheath did drop, but I see no combat knife. The combat knife got deleted.

Conmfirmed in 0.E-3940-g0dc500f480

Spawned and inserted items as described - a combat knife, in a sheath, in an XL holster:

image

Game saved: Savegame-42002.zip

Immediately after loading the game (and skipping the debug message), the only thing in my inventory is "XL holster with none":

image

After waiting 1 turn, this turns into a plain "XL holster", and the "sheath" appears on the ground (though no drop message is displayed). The combat knife is nowhere to be found.

I think I know what is happening here.

  • The XL holster has a "min_item_volume": "750 ml"
  • The sheath has "volume": "500 ml" when empty - too small to go in the XL holster
  • When the sheath has a combat knife in it, because it is not rigid, its volume increases to 1 L - now it can go in the XL holster

So, as long as the knife is loaded in the sheath first, it's large enough to be compatible with the XL holster. Perhaps when the items are loaded again, this insertion order is not preserved, or the sheath volume is not correctly recalculated before inserting it into the XL holster.

By setting "min_item_volume": "1 ml" for the XL holster, I can load my save game with no errors - however, after loading, the XL holster contains only a sheath - the combat knife still disappears.

image

@wapcaplet, your observations prompted me to do more testing and I discovered that the XL holster has nothing to do with this bug: the sheath deletes the combat knife even without the holster.

  1. Wear a sheath (id: sheath)
  2. Put a combat knife into the sheath
  3. Save and Quit
  4. Load
  5. The combat knife is now gone

After even more testing it looks like the sheath is also not necessary to trigger the bug. A combat knife combat knife disappears after the game is saved and reloaded if it is stored in:

  • a sheath (id: sheath)
  • an ankle sheath
  • a backpack (id: backpack)
  • a duffel bag
  • a dive bag

A combat knife does not disappear if it is:

  • In your hands
  • On the ground

The disappearance itself does not trigger any assertions.

so by what wap is saying, i can say that the loading order is actually causing this issue; things load the "topmost" item first ,because that's how the json objects are nested. i do not have an idea for a fix at this time.

so by what wap is saying, i can say that the loading order is actually causing this issue; things load the "topmost" item first ,because that's how the json objects are nested. i do not have an idea for a fix at this time.

I believe you are mistaken, @KorGgenT. Here is a test that proves your hypothesis wrong by not triggering any assertions and not causing any items to disappear or be dropped on the ground:

  1. Wear an XL holster and a sheath (id: sheath)
  2. [I]nsert a hunting knife into the sheath
  3. Insert the sheath into the XL holster
  4. Save and Quit
  5. Load
  6. No assertions are triggered during loading
  7. After the loading you'll see that there is still an "XL holster with sheath with hunting knife" in your inventory

Removing the gunmod_data from the combat knife JSON data allowed me to save and load it successfully. I have not dug into the deeper reason yet, but all the other knives without gunmod_data can correctly be saved and loaded.

The "RM42 fighting knife" and "sword bayonet" items also have gunmod_data, and also cannot be saved/loaded.

I can confirm this is fixed by #41917. Tested OK in that branch:

  • sheath with combat knife on the ground
  • backpack worn by character, containing combat knife, RM42 fighting knife, and sword bayonet
  • XL holster with sheath with combat knife, in backpack

All items were preserved on save/load:

image

It looks like this bug have been fixed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nexusmrsep picture nexusmrsep  Â·  64Comments

Coolthulhu picture Coolthulhu  Â·  68Comments

Coolthulhu picture Coolthulhu  Â·  51Comments

Poragon picture Poragon  Â·  54Comments

chriseich21 picture chriseich21  Â·  67Comments