CleverRaven / Cataclysm-DDA

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

Slowdown when crafting items with lots of surrounding items in sight. #63586

Open CoroNaut opened 1 year ago

CoroNaut commented 1 year ago

Describe the bug

When crafting objects with none, or very few items in view range around the player, there is little to no process slowdown. Essentially the time it takes to pass 5 in-game minutes is for example, 1 second real-time. Crafting objects while there are lots of items, 500+ in sight (inside the "list all objects around player" menu, ctrl-v) will essentially add real-time to the crafting. So 5 in-game minutes will become 2, 3, 5 seconds real-time.

I believe this is due to the crafting process needing to continually check every in-game second if the required materials are in range. If I however move all the required tools and materials around a wall, such that these 500+ items are out of view range, but still in the same map chunk, the crafting takes much less real-time.

For crafts taking more than 5 hours in-game, it can take a while as you see the crafting progress tick up 1% or less every real second.

Attach save file

Save file and additional details ***N/A. Anyone can plop down lots of loot and see the performance slowdown.

Steps to reproduce

  1. collect and store lots of items in one small area, perhaps 50 tiles over the course of a playthrough.
  2. try to craft something that takes longer than 30 minutes while in sight range of all your exploits
  3. try to craft that same item but take all the required tools and materials around a corner
  4. compare real-time to complete crafts between steps 2 and 3.

Expected behavior

I expect the crafting process to not check every second if it is in range of tools and materials. The materials can just be consumed into the crafting recipe, while the tools only need to be checked once upon starting the craft from 0%, or any%. If the player needs to stop the craft and restart later, they set the in-progress craft down, then pick it up and re-check if the tools are present. Adding more loot around the player inside their view range should not increase the real-time to craft objects.

The player is locked on the spot while crafting. So to prevent the tools from wandering away, they can be put into an invisible inventory, or list, or something similar so that npc's cant take them, or they cant get destroyed by a meteor, or zombies don't break down walls and they get caved in on.

Ofcourse I haven't looked into the code as to how its handled. My observations may not represent the game's actual process for handling crafting. This is just how it looks and feels to a gamer.

Screenshots

No response

Versions and configuration

Additional context

No response

ZhilkinSerg commented 1 year ago

I expect the crafting process to not check every second if it is in range of tools and materials

Do not expect that - there could be a fire, a monster or an npc that would destroy any item any minute.

Qrox commented 1 year ago

Not sure if it is already doing this, but we can cache the item location of the last used tool and first check if the tool still exists and satisfies the requirements, and if not, look through the surrounding items again for the tool.

CoroNaut commented 1 year ago

Any solution that verifies that the tools and materials still exists in O(1) time is better than O(n) time. Caching their location is good idea, I hadn't thought of a fire reaching the tool while you're still crafting. Putting the items in an invisible inventory wouldn't work then. Having a listing for them separate from all the other items in view range may be the only way?

anoobindisguise commented 1 year ago

This is especially bad with non-charged items, getting tailoring materials in significant quantities really hampers your IRL:game time for example.

esotericist commented 1 year ago

attached is a trimmed save that replicates the issue, and provides additional data.

the test setup: image

there's a workbench on the left, with a welding station to the south (along with appropriate power supply). a concrete wall with some doors divides the crafting area from the material area. the anvil and raw materials are at the top on the right side. the = tiles are full of 4096 cotton scraps (i was on 0.G for this test, but it should still be valid for testing on experimental).

test usage: stand on the darkened concrete tile, close the door immediately to the right (keeping the bottom door open). examine the workbench, craft steel plate (currently the only favorited recipe). image

on my machine, this takes about 10-13 seconds. there's some variation, i'm not sure what causes that (i try to set the current turn back to 0 to minimize variables, but that didn't work out)

open the door, to make the piles of cotton scraps on the right visible, and do it again. image

this reliably takes well over 2 minutes, i've seen up to 2:40 on my machine.

notably, merely waiting six hours with the door shut takes about 6 seconds, and with the door open... takes about 6 seconds.

what this tells us:

this really doesn't make any sense, but i've gotten this about as empirical as i can get it. i'm marking this issue as 'confirmed' accordingly.

horde test-trimmed.tar.gz

esotericist commented 1 year ago

@CoroNaut for the record, the requested attached save was not "n/a" here; "anyone can do this" is not how you get issues addressed because how you go about things might not be how anyone else goes about things, and there might be something "obvious" that is subjective. in this case, it took quite a lot of time to successfully replicate the problem, and even further to narrow things down (like, i burnt well over two hours getting to the point i could post this).

in the future please actually provide the information the form asks. this easily could have been closed for being an incomplete/nonactionable report, and it would have been perfectly correct to do so.

BrettDong commented 1 year ago

image

The bottleneck in crafting in the save uploaded by @esotericist is in finding nearby lifting assists.

Adding an early exit for small weight and volume item crafts avoids the performance problem, but crafting heavy or bulky items still suffers.

diff --git a/src/crafting.cpp b/src/crafting.cpp
index 97904ed165..4a1495dc07 100644
--- a/src/crafting.cpp
+++ b/src/crafting.cpp
@@ -252,6 +252,10 @@ static float workbench_crafting_speed_multiplier( const Character &you, const it
     const units::mass &craft_mass = craft.weight();
     const units::volume &craft_volume = craft.volume();

+    if( craft_mass <= allowed_mass && craft_volume <= allowed_volume ) {
+        return multiplier;
+    }
+
     units::mass lifting_mass = you.best_nearby_lifting_assist();

     if( lifting_mass > craft_mass ) {

A deeper solution is to cache nearby lifting assists so it doesn't need to be recomputed every turn.

Lippiece commented 1 year ago

Despite the PR above, I'm still experiencing this.

I was wondering if there are ways to mitigate it until the solution is found. I've been thinking about the workshop layouts. Here's one way I've done this:

Screenshot ![image](https://github.com/CleverRaven/Cataclysm-DDA/assets/47634624/12a181c9-5a48-4a72-a9de-486a0b63cb92)

Edit: Nevermind, the problem seems to be unrelated to the visible items.

CoroNaut commented 12 months ago

As of version "4f24d43", this is still very prominent. I can start a craft in an area with 1000 items and it will max out my CPU and takes 10 seconds for every 5 minute ingame interval. Moving to a new location around a wall where the 1000 items aren't in sight or available for crafting, the craft barely uses its alotted CPU resources and there is no in-game slowdown.

CoroNaut commented 12 months ago

@esotericist Given that this is an issue that all players experience in a spectrum, I didn't think it productive to provide a save file, since a slowdown happens on all save files to some degree. I will however provide a more indepth process in which to recreate the problem here. My current save file below: Lenora.zip

Location 1 contains all the stuff I've gathered, almost 1000L of just random crap. If I start crafting the "20-round shotshell belt" in location 1, it will take 1 minute for my machine to progress 0 to 50% of the craft and max my CPU. If I then move to location 2 and continue the craft, it will take 2 seconds to progress 50% to 100%, and have no noticable effect on CPU. pic

I also tried the "peasant flail" and "wooden tonfa", both with significantly less components to craft, and the slowdown happens all the same

Omoteringendo commented 3 months ago

@CoroNaut I recently encountered a similar problem while crafting items. As it turned out it was all the fault of containers in the inventory of the character. Somehow they slow down crafting and skill training. In your save there are containers with a lot of items inside, this is the reason for the decrease in performance

CoroNaut commented 2 months ago

I know that containers with thousands of items in them really slow down the game all by themselves, but im not certain this is the reason for the performance slowdown in this particular case. It could just as easily contribute to the slowdown as well.

I encountered this issue again and have a slightly interesting development. Using my save file, I crafted a power converter on my workbench and recorded the IRL time taken to craft it for a few runs. it was about 15-18 seconds IRL. I then covered my entire base in an "unload everything" zone and unloaded everything from every container and dumped it straight onto the floor. I then went to craft a power converter, record its time, and it took about 230-250 seconds IRL (4 MINUTES!). I had to use the windows 10 stopwatch app for it. The power converter in-game takes almost 9 minutes. tiny compared to harder items.

This is 15x slower for a base full of items on the floor compared to those same items distributed almost as they normally are in their containers.

Of course, I still don't think it should even take 15 seconds in the first place, 5 seconds sounds reasonable, given that a quick test on a fresh save with the ingredients to craft a power converter takes about 3 seconds. So, end result: Time to craft power converter: Fresh save: 3 seconds My base (before unload): 15-18 seconds My base (after unload all): 230-250 seconds

Never under any circumstances unload your containers.

Before unload all containers: Grafton-trimmed.tar.gz

After unload all containers (took like 3 minutes to unload all): Grafton-trimmed.tar.gz