Closed SomeGuyIGues closed 1 week ago
Can confirm and apparently this is related to pockets. Apparently this is not a full freeze by the way as I could coax the game into exiting cleanly.
0x563,f83,a15,a59 src/debug.cpp:966 bt_full
0x563,f83,a15,a59 src/debug.cpp:1,231 debug_write_backtrace(std::ostream&)
0x563,f83,9ed,b98 src/crash.cpp:89 log_crash
0x563,f83,9ed,ee5 src/crash.cpp:146 signal_handler
0x7f0,15a,56e,76f [unknown src]:0 [unknown func]
0x7f0,15a,5bf,32c [unknown src]:0 [unknown func]
0x7f0,15a,56e,6c7 [unknown src]:0 [unknown func]
0x7f0,15a,556,4b7 [unknown src]:0 [unknown func]
0x7f0,15a,556,3db [unknown src]:0 [unknown func]
0x7f0,15a,566,d45 [unknown src]:0 [unknown func]
0x563,f84,4cf,720 src/third-party/imgui/imgui_impl_sdl2.cpp:645 ImGui_ImplSDL2_NewFrame()
0x563,f83,871,6da src/cata_imgui.cpp:256 cataimgui::client::new_frame()
0x563,f84,539,15b src/ui_manager.cpp:355 ui_adaptor::redraw_invalidated()
0x563,f83,e60,e36 src/main.cpp:176 exit_handler
0x7f0,15a,56e,76f [unknown src]:0 [unknown func]
0x563,f83,d5b,3d9 src/item_pocket.cpp:609 item_pocket::item_size_modifier() const
0x563,f83,cf9,b4e src/item_contents.cpp:2,547 item_contents::item_size_modifier() const
0x563,f83,ca4,3a6 src/item.cpp:7,414 item::volume(bool, bool, int) const
0x563,f83,d5b,bef src/item_pocket.cpp:2,312 item_pocket::contains_volume() const
0x563,f83,d5b,c0e src/item_pocket.cpp:580 item_pocket::remaining_volume() const
0x563,f83,ca5,277 src/item.cpp:10,161 item::can_contain(item const&, int&, bool, bool, bool, bool, item_location const&, units::quantity<int, units::volume_in_milliliter_tag>, bool) const
0x563,f83,ca5,432 src/item.cpp:10,109 item::can_contain(item const&, bool, bool, bool, bool, item_location const&, units::quantity<int, units::volume_in_milliliter_tag>, bool) const
0x563,f83,8f7,a01 src/character_attire.cpp:1,801 outfit::can_pickVolume(item const&, bool, bool) const
0x563,f83,8a6,cd6 src/character.cpp:3,230 Character::can_pickVolume(item const&, bool, item const*, bool) const
0x563,f83,91b,f61 src/character_inventory.cpp:460 Character::i_add_or_drop(item&, int, item const*, item const*)
0x563,f83,c07,f72 src/iexamine.cpp:3,983 iexamine::compost_full(Character&, tripoint const&)
0x563,f83,b91,5ab src/game.cpp:6,263 game::examine(tripoint const&, bool)
0x563,f83,b91,c67 src/game.cpp:6,116 game::examine(bool)
0x563,f83,bde,162 src/handle_action.cpp:2,336 game::do_regular_action(action_id&, avatar&, std::optional<tripoint> const&)
0x563,f83,be1,f0b src/handle_action.cpp:3,146 game::handle_action()
0x563,f83,a76,a63 src/do_turn.cpp:578 do_turn()
0x563,f83,578,8fa src/main.cpp:868 main
0x7f0,15a,557,ccf [unknown src]:0 [unknown func]
0x7f0,15a,557,d89 [unknown src]:0 [unknown func]
0x563,f83,6e0,1bd [unknown src]:0 [unknown func]
0xf,fff,fff,fff,fff,fff [unknown src]:0 [unknown func]
However I find this trace more verbose than actually running it in gdb (are the debug symbols faulty?). gdb.txt
Didn't reproduce it at the first run, tried again and the game freezed. In the first time I debug spawned the fermentable liquid mixture without container, and only experienced a small lag when finishing fermenting. In the second time I debug spawned the fermentable liquid mixture with container(2000 jug), and first experienced a lag when adding liquid to the digester, then a freeze when finishing fermenting. Tested again, found out that if the avatar is carrying more than 30 containers, the game will freeze. If only less than 30 containers carried, the game will not freeze, but lag for a second.
https://github.com/CleverRaven/Cataclysm-DDA/blob/0b5152225c8f0db46c736782cf228b765c6d333c/src/character_inventory.cpp#L451-L470
Seems that the reason is I used Character::i_add_or_drop
to collect the generated biogas, as the amount of biogas generated by 2000 units of fermentable liquid mixture is 6666500 charge, the loop will be called for ridiculous times🤐
How can I fix this, is there another function usable?
CC @mqrause, since you are our charges specialist, maybe you know what to optimize here.
If it's count by charges the item ought to contain all the charges and the quantity should be 1. If you feed millions of single charge items into the call the item construction is probably incorrect. It might also be that a different operation (presumably geared towards the collection of some or all charges) should be called, but you still shouldn't feed it with millions of single charge items.
If it's count by charges the item ought to contain all the charges and the quantity should be 1. If you feed millions of single charge items into the call the item construction is probably incorrect. It might also be that a different operation (presumably geared towards the collection of some or all charges) should be called, but you still shouldn't feed it with millions of single charge items.
Thanks, I realized how to fix this.
Well, tested again, and unfortunately, you can't set the quantity to 1, otherwise you are unable to gather biogas properly without a debug pocket or something that big. To perfectly resolve this, we still need to find a replacement.
I can then modify my function to improve the performance a bit, but lag or freeze is still a problem when you are carrying too many containers.
OK, I made a compromise solution. Now the game will still freeze if you are wearing the debug pocket with 2000 jugs in it when gathering biogas. On the other hand, if you are carrying your backpack and other normal gears, but with some extra containers (like 500 condoms) , only minor lag occurs. Just not to walk around carrying thousands of containers, and everything should be fine.
@PatrikLundell
Forgot to explain why you can't set the quantity to 1.
In Character::i_add_or_drop
, Character::can_pickWeight
and Character::can_pickVolume
are called to check if your have enough room for the item. If you want to add items count by charges, the functions need to check per charge. If you set the quantity to 1, the functions will see if you have a big big pocket for the whole bulk of item. If not, not a single charge will be added to your pocket.
Annoying. It seems like you'd need similar logic to the one used to collect fluids, so rather than trying to pour everything in the source to the destination, you instead try to fill the destination with as much as you can from the source (and all of it if it's less than the destination can hold). I don't know where that code is located, though.
I would need to look at how the digester works to give real advice here, but ultimately we probably want something like the liquid_handler but for gases.
Annoying. It seems like you'd need similar logic to the one used to collect fluids, so rather than trying to pour everything in the source to the destination, you instead try to fill the destination with as much as you can from the source (and all of it if it's less than the destination can hold). I don't know where that code is located, though.
There are two differences in the case of biogas and biomass fluids.
First, your don't need to "pick up" the fluids at once, they are kept in the tank. You can use handle_liquid_from_ground
to obtain them at any time.
Second, the amount of the fluids is smaller, 2000 vs 6666500 max charges.
Anyway, after changing my function, I'm also trying to modify Character::i_add_or_drop
, to make the loop be called less, without breaking the tests.
Describe the bug
After waiting 60 days for the anaerobic digester to finish fermenting the game will likely freeze itself if the tank is too full.
Attach save file
N/A
Steps to reproduce
Expected behavior
The game shouldn't shit itself. If I can load the tank with that much fluid, then I should be able to complete fermenting after 60 days.
Screenshots
No response
Versions and configuration
Additional context
I'm using a laptop computer to play DDA. However considering my computer didn't become hotter and the game just froze, I doubt it was a hardware issue.