Cataclysm-dda: Individual-component-aware crafting

Created on 6 Feb 2017  路  5Comments  路  Source: CleverRaven/Cataclysm-DDA

Current crafting system is very tightly bound to item types rather than individual items.
This is a problem whenever ANYTHING related to the crafting recipe is supposed to depend on components:

  • Rotten items are consumed without asking. This can't be easily fixed in a way that would still allow using rotten components for anything non-hardcoded (say, plant mutant wanting a rotten soup).
  • Poisonous mushrooms can't be crafted into anything. Alternative would be to automatically supply poisonous shrooms, without asking the player, or to horribly hardcode it specifically for this interaction type (and another hardcode for cannibalism, another for allergies and so on - unworkable).
  • Items used can't be remembered, so even if you selected the right items at the prompt, you could get different ones if something changed in the meantime (say, fire burning the duster you were working on, making you cut the sleeves of the one you wear instead)

This makes it very hard to meaningfully extend the crafting system.
For example, I tried to add project crafting (first craft "unfinished hoodie", then work on it until it is finished), but quickly noticed it isn't really possible to do it right (respect tool choices) with the current system, at least without overhauling it heavily.

The ideal, perfect solution (not just to this problem btw) would be something along the lines of #19437
For example:

  • Remember items with IDs A,B and C for crafting
  • When needed, call "find item with ID" function to get cached location of given item (or null location if it isn't in the bubble) in sensible time, without having to scan whole nearby area
  • If all locations are not null and the items match the "description" (type and state necessary for the recipe), clone them, remove the originals and use the clones as ingredients

It would be doable in a very ugly, hacky way by doing this:

  • Flag selected items as "used in recipe instance XYZ" (we can assume that some generated XYZ is "unique enough" since collisions wouldn't be fatal, just mildly annoying)
  • When needed, brute-force scan nearby items for those with the flag

But this would be a partial workaround that would only solve a subset of the problems.
Any other ideas?

<Enhancement / Feature> Crafting / Construction / Recipes

Most helpful comment

Physically claim components immediately on craft action start by moving
them into a "crafting object" (an actual item with metadata about the
crafting operation attached to it, probably named "partially crafted foo"
or similar), subsequent activities would just reference this object,
including picking it up and moving it around if needed.
The crafting item could also contain references to tools used in the craft
as hints, but they don't need to be claimed in the same way since you can
just find a different screwdriver and keep going, on each ticket you'd just
want to verify that all needed tools are still available.

Side note resurrecting an ooold issue about workspaces, the crafting code
could physically place the in progress craft on furniture designated as a
"workspace" if available, and the crafting activities could get bonuses
from it.

All 5 comments

Physically claim components immediately on craft action start by moving
them into a "crafting object" (an actual item with metadata about the
crafting operation attached to it, probably named "partially crafted foo"
or similar), subsequent activities would just reference this object,
including picking it up and moving it around if needed.
The crafting item could also contain references to tools used in the craft
as hints, but they don't need to be claimed in the same way since you can
just find a different screwdriver and keep going, on each ticket you'd just
want to verify that all needed tools are still available.

Side note resurrecting an ooold issue about workspaces, the crafting code
could physically place the in progress craft on furniture designated as a
"workspace" if available, and the crafting activities could get bonuses
from it.

Physically claim components immediately on craft action start by moving them into a "crafting object" (an actual item with metadata about the crafting operation attached to it, probably named "partially crafted foo" or similar)

I tried exactly that, but the current crafting system successfully prevented me from it:

  • You can't "maybe-claim" an item: you either don't claim it and just skip it or claim it and it is removed from the map
  • Charged tools can't be cached. They are pretty important if the same tool is supposed to be used through the whole crafting process. Doesn't matter for qualities, matters for any expansion of crafting system like "use chainsaw to saw wood in half the time, without making an extra recipe, but consume charges"

What we want is some way of mapping individual items. IDs would be perfect, a map of locations (exact) would be tolerable.
I also tried doing that map of locations thing, but got bogged down with inventory letters - surprisingly trivial detail, yet scrambling them would hurt.

On Mon, Feb 6, 2017 at 11:25 AM, Coolthulhu notifications@github.com
wrote:

Physically claim components immediately on craft action start by moving
them into a "crafting object" (an actual item with metadata about the
crafting operation attached to it, probably named "partially crafted foo"
or similar)

I tried exactly that, but the current crafting system successfully
prevented me from it:

  • You can't "maybe-claim" an item: you either don't claim it and just
    skip it or claim it and it is removed from the map

Why do you need to "maybe claim" anything? If in doubt, just over-claim,
then once the craft is done the remnants can be either returned to their
original locations or dropped in a pile.

>

  • Charged tools can't be cached. They are pretty important if the same
    tool is supposed to be used through the whole crafting process. Doesn't
    matter for qualities, matters for any expansion of crafting system like
    "use chainsaw to saw wood in half the time, without making an extra recipe,
    but consume charges"

I don't know what you mean by cached, the options are moving tools into the
crafting object to claim them like you do with components or stashing
references to them like you suggest. The reference can just be the
coordinates of the tool, all we care about is accelerating lookup so we can
do it every tick, not the specific identity of the tool. If you want to
make lookup misses less likely, you could extract a list of tool
coordinates from the crafting inventory instead of a single candidate tool
coordinate, then if your hammer or welder goes missing you can just grab
another one that was there at the start of the craft. If you run out of
valid references to tools, you can make a new crafting inventory and pull a
new list of tools out of it, if THAT fails crafting halts until you can
find an appropriate tool. This goes for fire sources too BTW, you
fundamentally can't pack those into the crafting object.

I'm not really a fan of bundling the tools into the crafting item because
of use cases like moving your in-progress craft to a different workshop, or
halting one craft and then starting another one. "Claiming" tools is also
problematic, we definitely want to use the same system for NPC crafting,
and ideally you'd be able to share a workshop with several NPCs without
having to have totally duplicate sets of tools for everyone.

>
>

What we want is some way of mapping individual items. IDs would be
perfect, a map of locations (exact) would be tolerable.

Do we? I'm not sure we care that much about the identity of the tool being
used. Worst case if you really care about which tool charges come from,
those charges can be pulled out of the tool immediately and marked in the
crafting item, from then on all you care about is that the tool qualities
required by the recipe are satisfied.

I also tried doing that map of locations thing, but got bogged down with
inventory letters - surprisingly trivial detail, yet scrambling them would
hurt.

I see the map of locations as a hint for where to find the tool so you
don't search the whole map, in that case you don't worry about inventory
letters.

Kevin

Why do you need to "maybe claim" anything? If in doubt, just over-claim, then once the craft is done the remnants can be either returned to their original locations or dropped in a pile.

It's more complicated than it looks:

  • Vehicle tanks can't be dropped in a pile
  • Liquid contents can't be easily returned to containers
  • Even if it did work, it would make a giant mess of any semi-orderly crafting base
  • The whole thing would still be a barrier towards sensible display: you couldn't display "You can craft this item, but you'll need to use a vacuum-packed component, when you could use perishable ones" with this approach. Or "you will need to use worn item as a component".
  • This would make a giant mess of sealed containers

The reference can just be the coordinates of the tool, all we care about is accelerating lookup so we can do it every tick, not the specific identity of the tool.

This is what I tried to do at first. The idea is imperfect and only a workaround for lack of IDs, but it would work for the most general case.
The problem was mostly that adding this would be a surprising volume of code, because it means reimplementing interface (for crafting_interface) to remember locations.
Then the new interface would need to be hooked up to all relevant usages.

Doable, but not necessarily faster or less work than The Right Thing, while certainly clunkier and less useful.

"Claiming" tools is also problematic, we definitely want to use the same system for NPC crafting, and ideally you'd be able to share a workshop with several NPCs without having to have totally duplicate sets of tools for everyone.

Claiming in some way is more or less mandatory for tools that consume charges. Hammers and screwdrivers are just qualities, those would only need to be noted as "the best hammering quality in area is 3".
This could be delayed, but in the end it would be good to be able to say, start with a chainsaw, but finish with a wood axe (when chainsaw goes out of fuel).
Without claiming, the only thing we can do is using up all the tools at the end. Which is what we have now so no regression, but it would be better if tools could be used during crafting, not after.

Do we? I'm not sure we care that much about the identity of the tool being used.

Not the exact identity, but we need to be able to pick specific sub-kind of tool. It isn't acceptable to mix handheld soldering iron charged with non-renewable batteries with a soldering iron hooked up to a giant generator. And going for exact identity is less work than special casing all the edge cases.
If the exact item goes missing, we can just re-ask, since this would be a rare special case.

I see the map of locations as a hint for where to find the tool so you don't search the whole map, in that case you don't worry about inventory letters.

The problem was mostly just integration. In order to implement this with the least amount of big code changes, I need to derive it from inventory class, which does some weird inventory letter manipulations.

Would it be possible to just add a warning that rotten items will be used. I would suppose not from your post that they are considered the same TYPE of item rather then being identified as a rotten item. I am guessing also that the code for crafting does not check birthdays on items as well.

Was this page helpful?
0 / 5 - 0 ratings