CleverRaven / Cataclysm-DDA

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

Ages_into for much better rotting and for a ton of dynamic items #37054

Open I-am-Erk opened 4 years ago

I-am-Erk commented 4 years ago

Is your feature request related to a problem? Please describe.

Currently we have two features related to items getting older:

There is a huge demand for items to be able to age into a different type of item with more control and without active player input.

Describe the solution you'd like

Deprecate both current item aging codes. Add the ages_into JSON flag, for any type of item, not just comestibles.

Example usage:

"ages_into": {
  "time": "7 d",
  "time_variable": "1 d",
  "items": [
    { "item": "moldy_bread",, "weight": 100 },
    { "item": "stale_bread", "weight": 50 }
  ]
}
"ages_into": {
  "time": "3 years",
  "time_variable": "6 months",
  "items": [ { "group": "separated_gasoline_products" } ]

Description:

ages_into: A non-mandatory field for all item definitions. Accepts single entries, or lists. Lists are distributions - only one item from the list would be selected. time: Required argument. The amount of time that must pass from the item's birthday before it transforms into the new item time_variable: Optional argument. The amount of time to age could vary by this much. As the item approaches its age_into date, the chance of it aging into a new item increases. if the item's birthday reaches time+time_variable, the chance of ages_into occuring is 100%. items: Specify a list of item products the item can age into. This syntax could be the same as the item spawning syntax on maps, allowing item groups or inline itemgroups as well as individual items. By default it is a distribution.

Stretch features

Once this basic system is implemented, it would be good to have some sort of way to represent dry or wet storage. I think the easiest way to do that is just to track where the object is stored, with the options being "in a container", "in a storage furniture", "indoors but not in storage", "outdoors", or "submerged in water". The weight of certain ages_into transformations could be adjusted by the amount of time spent in one of these circumstances. Something like:

  "items": [
    { "item": "moldy_bread", "weight": 100, "storage": [
        { "stored": [ "outdoors" ], "time": "1 h", "bias": 2 },
        { "stored": [ "water" ], "time": "1 m", "bias": 5 }
      ]
    },
    { "item": "stale_bread", "weight": 50, "storage": [
        { "stored": [ "container" ], "time": "3 d", "bias": 5 },
      ]
    },
  ]

Basically, if the item was stored in the indicated way for at least the indicated time, the weight of the ages_into entry would be multiplied by the value listed in bias. I'm sure there's better ways of doing this but this is the one I can think of for now.

Summary

This feature could be used for all kinds of great stuff

Describe alternatives you've considered

I'm sure there are better ways to handle the impact of storage on aging than what I've pictured. For example, my suggested system doesn't take into account the impact of rainfall or humidity, and that would be great.

Otherwise, I think this is a system we really need.

JeanLucVanDamme commented 4 years ago

Homegrown penicillin, here we come!

KorGgenT commented 4 years ago

some note: in the nestable container work i'm doing, i have a spoilage modifier available for containers. I'm not sure how you might expect this to interact with your stretch feature goal, but I feel it important to let you know that this exists

I-am-Erk commented 4 years ago

Sweeeeet.

You might want to consider a "moisture resistance" kind of flag too, that would be useful for more advanced spoilage calculations

TechyBen commented 4 years ago
  • metal rusting if left outside

This would be VERY interesting for vehicles. Natural degradation would turn late games into steampunk/wooden wonders. Very very nice for "survivors" style lore and atmosphere. Most cars are fine for a few years (up to 10 IIRC with nice paint and no dents/scratches, others now also have plastic panels), but a poorly painted/cheapened on protection to the frame and a salt weather area, and rust in a few years is substantial (wheel arches and floors gone lol). So that would make for some fun experiences, seeing panels fall off while driving!

Hirmuolio commented 4 years ago

I think adding so many variants for every single item would be a problem. There are lots of food items.

Something similar to flags would be more flexible and general. Lets call them "faults".

So a bread would receive "moldy" fault. This fault would apply changes to the base item. Faults would change the name, description, item values and add or remove any properties. In extreme case it could rewrite the properties of the item completely. Practically turning it into different item. (hmm. Maybe "dried" foods could be just the base item with "dried" "fault").

Faults would be transferred to new items during crafting unless the recipe specifies that it removes certain faults. Same for disassembly.

This system could be expanded to other kinds of items with different faults. For example punctured tires, torn clothes, cracked armor plates. With "repair recipes" to fix the faults (or replace one fault with "fixed" fault to prevent fully fixing stuff).

I-am-Erk commented 4 years ago

While a faults system might be interesting, I don't know if it would necessarily be better. It adds a lot of contextualizing to recipes to allow or disallow food with particular faults, remove particular faults but not others, or adjust foods based on specific problems. A quick example is stale bread, which can still be used in some recipes that require bread... but other stale items wouldn't fit.

Adding a bunch of item id's is not as hard as you'd think. You'd get something like:

"id": "bread_stale",
"name": "stale bread",
"description": "stale bread",
"copy-from": "bread",

and then a handful of modifiers to reduce enjoyability and extend shelf life.

Hirmuolio commented 4 years ago

It adds a lot of contextualizing to recipes to allow or disallow food with particular faults, remove particular faults but not others, or adjust foods based on specific problems.

Individual aged item variants would have the exact same problem. You will still want to keep the rotting status of the ingredients. Or we would get good food from cooking bad ingredients.

A quick example is stale bread, which can still be used in some recipes that require bread... but other stale items wouldn't fit.

If aged items sometimes do not work the same as the original item then every single such aged item would need to be added to the recipes one by one. This would be much more work than adding the faults to the recipe.

A bunch of itme id's is quite an understatement. Just adding single aged stage to all foods would double the number of food items. And we already have three age levels for every food (fresh, normal, old, rotten). We would be looking at guadrupling the number of food items before we even add any new stages.

Also the item variants would be unable to handle having multiple stages at once. For example rotten fermented food.

I-am-Erk commented 4 years ago

'fresh', 'normal', and 'old' aren't state changes. They wouldn't require different IDs, they're just warnings related to item birthday relative to age time. At most, we might add some JSON to allow us to specify the terms for an item as it ages.

I don't think you're quite following the rest of what I'm saying with contextualizing recipes. I'm talking about how you'd have to go in and rewrite a huge amount of how recipes work in order to support a potentially extremely complex series of flags that would only appear in some pretty niche scenarios.

It is quite possible we'd end up with an element of what you're describing - the current 'rotten' flag as a default behaviour for food, for example, can probably be kept and just worked into the flag. Most food, like meat, doesn't develop significant new characteristics when aged, it just gets gross. However, most of the uses for ages_into versus current rotting system would be for things where applying a template doesn't make sense, because you'd be making a new template for each usage case. Adding an aged_wood template instead of an item ID for aged wood, or a stale_bread template, or what have you, is an entirely lateral shift. Instead of adding an item id, you added an age_template id. Except now you also have to code a new system that supports this new json element, with tendrils through items, itemgroups, mapgen, recipes, and probably other places.

foulman commented 4 years ago

For what it's worth, as someone that makes infinite whiskey with a feature for fermentation, I would throw in my two cents to support this. I would, however, suggest that multiple item outputs be possible rather than just one item. Considering that we have bizarrely alien blob, fungal, triffid, and increasingly mi-go content that operates on strange biological (or dare I say even magical ) rules, it's reasonable to think ahead and see uses for this where items might grow/evolve/split/multiply or degrade into more than one unit.

Anrock commented 4 years ago

This system could be expanded to other kinds of items with different faults. For example punctured tires, torn clothes, cracked armor plates. With "repair recipes" to fix the faults (or replace one fault with "fixed" fault to prevent fully fixing stuff).

Sounds like it's quite universal. [bleeding] leg, apply [bandage] to remove this fault, hm?

LyleSY commented 4 years ago

This would allow gasoline to go bad after six months. That should create some interesting gameplay changes.

solonkovda commented 2 years ago

Created a design doc for the feature. Feedback would be appreciated before I move to the implementation.

github-actions[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. Please do not bump or comment on this issue unless you are actively working on it. Stale issues, and stale issues that are closed are still considered.