Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

item: aggregate contents #70766

Merged
merged 7 commits into from
Jan 22, 2024
Merged

Conversation

andrei8l
Copy link
Contributor

@andrei8l andrei8l commented Jan 8, 2024

Summary

None

Purpose of change

Too many restrictive checks are performed when expanding contents name so a lot of containers that should reasonably be named container > contents_name (X) are instead shown as container > X items. And we can do even better by showing more common stats when most contents are of some particular type.

Describe the solution

  1. Break item::tname() into segments
  2. Break item::stacks_with() into bits corresponding to tname segments
  3. When determining item contents, aggregate all the stacking bits by type and category (ie. determine the common bits for each type and category)
  4. Display all the common segments for the dominant item or category. An item/category is dominant if it covers more than half of the contents

I'm also getting rid of the hidden marker because the chevron already conveys that information. I wanted to remove it back in #56630 but the chevrons were too new back then.

Some examples with pictures:
A bag of salt in a bag of salt (#69959)

0 - bag of salt in a bag of salt

Some pepper has snuck into this bag but the salt still dominates

1 - bag of salt in bos + pepper

A lot of pepper has snuck into this bag and the salt doesn't dominate anymore. But the dominant category is FOOD

2 - bag of salt in a bos + lotsa pepper

This bag holds several variants of the same item. Note that the common durability and poor fit are also mentioned

b0 - variants + poor fit + durability

One of the masks got damaged and the dominant type doesn't have common durability anymore

b1 - variants + poor fit - durability

Another clothing example - the common filthy state is also mentioned

3 - filthy clothing

Nested food of various type

4 - nested food of various type

Another FOOD example, showing aggregated perishability and freshness

5 - food cat color + aggregated fresh

Bag with various sawn-off guns, showing aggregated barrel mod

Screenshot from 2024-01-14 08-09-44

TODO:

Describe alternatives you've considered

Step 1 isn't strictly necessary but item::tname() was a monolithic monster. #67954 was the original attempt that didn't split tname and I didn't think was tenable. Similar for splitting item::stacks_with()

If there were some guarantee that insertion/removal/transformation had backlinks (ex: by using an item_location), there wouldn't be any need for a timestamp in the category cache.

Testing

Updated test units that cover the examples above. I don't expect to correctly cover all the cases in this PR, but I will address errors as they are discovered in gameplay.

There is a moderate performance impact. Timing for opening the pickup all in City of the Dalles.zip with a standard (-Os) release build

Before:
0 - before

After:
1 - after

Additional context

While this is a large PR, a big chunk of it is just moving code around (step 1 - fe3abb6). The second biggest chunk is mostly just not'ing boolean expressions and moving them to separate functions (step 2 - ec53b3e). The third biggest chunk is test code (3ba1213).

@github-actions github-actions bot added Info / User Interface Game - player communication, menus, etc. [JSON] Changes (can be) made in JSON Code: Tests Measurement, self-control, statistics, balancing. [C++] Changes (can be) made in C++. Previously named `Code` Items: Ammo / Guns Ammunition for all kinds of weapons and these weapons themselves <Bugfix> This is a fix for a bug (or closes open issue) labels Jan 8, 2024
@github-actions github-actions bot added the json-styled JSON lint passed, label assigned by github actions label Jan 8, 2024
@GuardianDll
Copy link
Member

Can you make category be not all caps?

@andrei8l
Copy link
Contributor Author

andrei8l commented Jan 8, 2024

Can you make category be not all caps?

Category names are defined in JSON (example) and I don't want to mangle them in code.

@github-actions github-actions bot added the BasicBuildPassed This PR builds correctly, label assigned by github actions label Jan 8, 2024
@akrieger
Copy link
Member

akrieger commented Jan 8, 2024

This definitely reverts #70685 and I'm not sure if I can restore that.

;_; sad. It's even worse because it unconditionally runs through the entire stacks_with function for every bit for every item.

@github-actions github-actions bot added Items: Containers Things that hold other things astyled astyled PR, label is assigned by github actions labels Jan 8, 2024
@andrei8l

This comment was marked as outdated.

@andrei8l andrei8l force-pushed the item-aggregate-contents branch 2 times, most recently from ea2518c to 2bbe8bb Compare January 8, 2024 18:29
@github-actions github-actions bot removed the BasicBuildPassed This PR builds correctly, label assigned by github actions label Jan 8, 2024
src/item.cpp Outdated Show resolved Hide resolved
src/item.cpp Outdated Show resolved Hide resolved
@PatrikLundell
Copy link
Contributor

This looks like a significant improvement.

However, I'm not too fond of the second Clothing example, as the impression would be that it included only clothing, but it may be that it wouldn't be too hard to learn to look at the 4/8 part to realize there's other stuff in there too.

I don't think there's a good way to show if a mixed container of food is all perishable, partially perishable, or non perishable (so you'd know whether to toss it onto a shelf, into the cellar, or sort it out now).

@Qrox
Copy link
Contributor

Qrox commented Jan 9, 2024

However, I'm not too fond of the second Clothing example, as the impression would be that it included only clothing, but it may be that it wouldn't be too hard to learn to look at the 4/8 part to realize there's other stuff in there too.

I have the same feeling about it. Perhaps it would be better to display it as xxx CLOTHING among yyy items/whatever description that fits all contained items?

@andrei8l
Copy link
Contributor Author

andrei8l commented Jan 9, 2024

I have the same feeling about it. Perhaps it would be better to display it as xxx CLOTHING among yyy items/whatever description that fits all contained items?

I'm a little confused. So is > 4/8 salt also bad? If the number/number is hard to read, I don't think a longer and wordier description is going to be easier.

I don't think there's a good way to show if a mixed container of food is all perishable, partially perishable, or non perishable (so you'd know whether to toss it onto a shelf, into the cellar, or sort it out now).

Screenshot from 2024-01-09 12-20-21
It was easy and had negligible perf impact so I'll add it next time I push. Doesn't work for nested food though.

@PatrikLundell
Copy link
Contributor

The 4/8 salt case would mean you somehow had 4 salt bags with 1 salt each in the top bag, if I understand things correctly, and so would mean you've got only salt and containers in it, which I think is fine. If it would also cover the case of 3 bags of salt, one salt, and one unrelated item I wouldn't like it (and my understanding is that it would end up in the least common denominator category, and so wouldn't happen).

@andrei8l
Copy link
Contributor Author

andrei8l commented Jan 9, 2024

The 4/8 salt case would mean you somehow had 4 salt bags with 1 salt each in the top bag, if I understand things correctly, and so would mean you've got only salt and containers in it, which I think is fine. If it would also cover the case of 3 bags of salt, one salt, and one unrelated item I wouldn't like it (and my understanding is that it would end up in the least common denominator category, and so wouldn't happen).

Woops, that's completely wrong so this isn't working the way I thought. The intention was that > 4/8 salt means 4 items out of the 8 total contents are salt (and they are the majority type). I'll have to rethink this if the interpretation is so far off.

@PatrikLundell
Copy link
Contributor

Don't accept my interpretation without checking it, as it's not unusual for me to be wrong...

However, 4/8 meaning 4 out of 8 items being salt would be correct, as the remaining objects would be plastic bags containing salt. If one of the bags was empty I'd expect the top bag to be considered a mixed container, not a salt containing one, i.e. containers would only "transform" to something else if it was a container for that something else.

@andrei8l
Copy link
Contributor Author

andrei8l commented Jan 9, 2024

Don't accept my interpretation without checking it, as it's not unusual for me to be wrong...

Quick poll on discord agrees with you and Qrox. What do you think about plastic bag > 4 salt / 8 items ?

@PatrikLundell
Copy link
Contributor

That display would indicate (to me) there are 8 unspecified items inside, 4 of which are specified to be salt, which I assume is what you're after.

However, I think it's worse from an information perspective, as it really only is of help compared to the pure "8 items" situation if I'm interested to get the salt items, but I still have to open it to see what the other stuff is (I wouldn't want to overload me with 4 zombie corpses or even 4 dirty rags, let alone 4 poisonous mushrooms (reference to recent report about inadvertent usage of those in cooking)).

@andrei8l
Copy link
Contributor Author

andrei8l commented Jan 9, 2024

However, I think it's worse from an information perspective, as it really only is of help compared to the pure "8 items"

Well yes, that was the goal. When you have a container of mostly X item, I don't want the header to hide X just because some other items snuck in there as well. I believe that's a more general solution to #69959 than propagating the type upwards. Propagating upwards only covers exactly one case that can be probably solved better with tighter whitelists.

But I think this framework is flexible enough that we can change the display to something else if players prefer it.

@andrei8l andrei8l force-pushed the item-aggregate-contents branch from 2bbe8bb to 8167c0d Compare January 9, 2024 16:53
@andrei8l andrei8l force-pushed the item-aggregate-contents branch from fff8c04 to 3471d50 Compare January 18, 2024 06:43
@github-actions github-actions bot removed the BasicBuildPassed This PR builds correctly, label assigned by github actions label Jan 18, 2024
src/item_tname.cpp Show resolved Hide resolved
src/item.cpp Show resolved Hide resolved
@andrei8l andrei8l force-pushed the item-aggregate-contents branch from 3471d50 to a7313e4 Compare January 18, 2024 11:04
andrei8l and others added 6 commits January 18, 2024 20:09
corresponding to tname() segments

split it to reduce cognitive complexity

Co-authored-by: Qrox <[email protected]>
Co-authored-by: inogenous <[email protected]>
Co-authored-by: Andrew Krieger <[email protected]>
timestamp needed due to lack of backlinks in item
@andrei8l andrei8l force-pushed the item-aggregate-contents branch from a7313e4 to b4b36bc Compare January 18, 2024 18:09
@github-actions github-actions bot added the BasicBuildPassed This PR builds correctly, label assigned by github actions label Jan 19, 2024
@akrieger
Copy link
Member

I'm currently looking at the perf and seeing if there's anything to be done or how bad it hurts.

@akrieger
Copy link
Member

akrieger commented Jan 19, 2024

I've instrumented game load a few times and TBH this doesn't really hurt it much? So I'm not super concerned. I'll wait & see if people report slowdowns for live actions like crafting or walking or whatnot but at first blush this is at worst only like 3% net slower, which is almost within the level of noise for the profiler.

src/item_tname.h Show resolved Hide resolved
src/item_tname.h Outdated Show resolved Hide resolved
src/item.cpp Outdated Show resolved Hide resolved
src/item.cpp Outdated Show resolved Hide resolved
src/item.cpp Show resolved Hide resolved
@github-actions github-actions bot removed the BasicBuildPassed This PR builds correctly, label assigned by github actions label Jan 20, 2024
Co-authored-by: Andrew Krieger <[email protected]>
@andrei8l andrei8l force-pushed the item-aggregate-contents branch from 4281ba8 to 223f906 Compare January 20, 2024 12:08
@akrieger
Copy link
Member

I managed to find like a 6ish% win for windows game load from avoiding a couple more temporary item objects, which basically makes up for the equivalent slowdown I can measure from this, fwiw.

@github-actions github-actions bot added the BasicBuildPassed This PR builds correctly, label assigned by github actions label Jan 20, 2024
@akrieger
Copy link
Member

@Qrox any final comments?

@Qrox
Copy link
Contributor

Qrox commented Jan 22, 2024

Looks good to me.

@akrieger akrieger merged commit 1c310e7 into CleverRaven:master Jan 22, 2024
26 checks passed
@andrei8l
Copy link
Contributor Author

Thanks for merging!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
astyled astyled PR, label is assigned by github actions BasicBuildPassed This PR builds correctly, label assigned by github actions <Bugfix> This is a fix for a bug (or closes open issue) [C++] Changes (can be) made in C++. Previously named `Code` Code: Tests Measurement, self-control, statistics, balancing. Info / User Interface Game - player communication, menus, etc. Items: Ammo / Guns Ammunition for all kinds of weapons and these weapons themselves Items: Containers Things that hold other things [JSON] Changes (can be) made in JSON json-styled JSON lint passed, label assigned by github actions
Projects
None yet
7 participants