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

Inventory item schema redesign #480

Open
kpreid opened this issue Mar 13, 2024 · 5 comments
Open

Inventory item schema redesign #480

kpreid opened this issue Mar 13, 2024 · 5 comments
Labels
area: data Things related to the data structures underlying the world, and the functions that manipulate them. area: simulation Things related to what can happen in the world as time progresses. area: ui kind: incomplete A feature is partially implemented; the current state of the code is inconsistent

Comments

@kpreid
Copy link
Owner

kpreid commented Mar 13, 2024

I sat down to implement blocks containing and displaying inventories, and discovered a problem: right now, the signature of Tool::icon() is

pub fn icon<'a>(&'a self, predefined: &'a BlockProvider<Icons>) -> Cow<'a, Block>

which can't be called inside of block evaluation because there's no place for the BlockProvider to come from — block evaluation takes no context inputs. More abstractly, the idea that the appearance of tools depends on the viewer is incompatible with the idea of letting them appear in the world. (Unless we add a whole special system for displaying intangible viewer-dependent voxels, which is, well, probably something we want to do, but not now and not part of normal block rendering.)

Therefore, we need to change something so that the necessary information is available:

  • the items always own their icons (this probably makes sense on general extensibility grounds),
  • Inventory has a BlockProvider<Icons> associated when it's created, or
  • the inventory-in-a-block has a BlockProvider<Icons> associated when it's created.

If we go with items/tools owning their icons, then either:

  • the all-is-cubes crate built-in tools have specific icons intrinsically — but we've so far avoided having any voxel block definitions be part of all-is-cubes itself, and they'd need to be a new Primitive,
  • tools can't be put in inventories until they're paired with icons (...unless they're PlaceBlock?), or
  • tools — or inventory items that contain tools, if we add such a distinction — have definitions that include an icon (like Tool::Custom does now), separate from the tool's action definition (which might be the current Tool enum or it might be Operation?).

I think that it probably makes sense to go with that third option, because that also gives us a place to stand to customize the gameplay rules for tools (e.g. which blocks can be removed from the world, and which blocks can be automatically displaced by placing another block). But it will require thinking up various new schema pieces.

@kpreid kpreid added kind: incomplete A feature is partially implemented; the current state of the code is inconsistent area: ui area: simulation Things related to what can happen in the world as time progresses. area: data Things related to the data structures underlying the world, and the functions that manipulate them. labels Mar 13, 2024
@kpreid
Copy link
Owner Author

kpreid commented May 30, 2024

Brainstorming. New schema idea no. 1:

  • There is a new universe member type; let's tentatively call it ToolDef. It works like Tool::Custom currently does.

    struct ToolDef {
      icon: Block,
      operation: Operation,
    }
  • Each inventory item (the thing currently known as Tool) is a pair of a Handle<ToolDef> and a Block.

  • For icon display, the item's block is added as the contents of a Modifier::Inventory to the ToolDef's block.

  • When a tool's operation is executed, one of its arguments is the specific inventory slot the item is in, and the operation can use the Block from that slot, such as by placing it in the world. (This requires adding support for parameters inside operation definitions, but we wanted to do that anyway.)


Hmm, that's a bit complex, and is using Blocks in several ways. Idea no. 2:

  • Each inventory item is a Block — the Tool type goes away entirely.
  • Blocks can carry arbitrary “when placed” Operations, which don't necessarily actually place the block but could do any other things.
  • When we want a kind of tool that does something with a particular Block (e.g. current Tool::InfiniteBlocks), we use a Modifier::Inventory to attach that block to the tool block. (And that modifier sticks around as part of the Inventory data, rather than being ephemeral for icon computation, so we avoid a caching problem.)
  • When a tool takes a block from the world and puts it into inventory, it can do so directly or wrap it in one of these inventories, as determined by its operation.

Advantages over no. 1:

  • Fewer types which need API and editors
  • “tools which act on the world” and “blocks which have special placement rules” are simply the same thing.

Disadvantages:

  • We might end up regretting that conflation.
  • There's no place to put tool metadata that isn't a block attribute. For example, where does max stack size go? (Perhaps it goes in the same place Modifier::Inventory rendering information goes!)

@kpreid
Copy link
Owner Author

kpreid commented May 30, 2024

There's no place to put tool metadata that isn't a block attribute. For example, where does max stack size go?

I think I need to think harder about what characteristics items/tools should have that aren't their icons or their operations. What characteristics might tools have? Which ones fit well into being just block attributes? I think the following are conditionally good fits:

  • Item name — this is already currently done via block display name. We would want to be able to use the block's contained inventory item's name, but that makes sense as something to be able to do with inventory-bearing blocks anyway. That is, the block display name will become potentially a template filled out by the inventory contents.
  • Inventory-related properties that might make sense as a bundle within block attributes:
    • Stack count (this makes lots of sense because insofar as custom stack counts are used at all, blocks will want to have them)
    • Inventory-affecting effects (e.g. undroppable items)
    • Tags for custom game mechanic systems to read?

Bad fits for this model:

  • Equipment effects, like (now) the jetpack and (in the future) armor etc — this doesn't fit into either 'block attributes' or 'operations'. It will probably be part of some larger story about custom game mechanics, but I don't know what that looks like yet.
  • Labels/FX that appear on an inventory slot but aren't the icon block, such as:
    • Status text (that's not drawn on the block itself and isn't the stack count)
    • Specifying the mouse cursor

@kpreid
Copy link
Owner Author

kpreid commented May 31, 2024

  • Blocks can carry arbitrary “when placed” Operations, which don't necessarily actually place the block but could do any other things.

Note that Tools currently act on two adjacent cubes: the cube hit by the cursor (for removal/modification) and the cube in front of that one (for placement). Therefore, if we define all tools in terms of block placement, then we need to do one of these things:

  1. The placement-action includes a flag specifying which of those two cubes to act on.
    • Note that not every action that's semantically placement of a block should use the cube in front. In particular, we might want to set up a Composite, or replace a specific existing block with a “more filled” one.
    • Having this structure could also be a place to put the inventory-item-metadata discussed above? That is, consider the placement operation and the stack count to be the same kind of thing?
  2. Try the operation on the two cubes in sequence and take the first successful outcome. This feels elegant but might result in tools having surprising effects — tools that shouldn't act on the cube in front would need operations designed to reject air-like blocks.
  3. Position offset baked into the Operation. Probably don't do this because it would have undesired effects on rotation (or would it? not if the placed-block-rotation is done inside the operation rather than as its transform), and doesn't make sense for other use of a tool action, e.g. in bulk on a volume selection. This is a thing particular to the “DWIM when I click” basic mode of operation.)

@kpreid
Copy link
Owner Author

kpreid commented May 31, 2024

Belated thought: rotation during placement (something we already have a block attribute field for) is very similar to "which of these two cubes". Not sure what that tells us.

@kpreid kpreid changed the title Inventory items must intrinsically provide icons? inventory item data model redesign May 31, 2024
@kpreid kpreid changed the title inventory item data model redesign inventory item schema redesign May 31, 2024
@kpreid kpreid changed the title inventory item schema redesign Inventory item schema redesign May 31, 2024
kpreid added a commit that referenced this issue Nov 8, 2024
Part of <#480>; this moves
in the direction of being able to eliminate `Tool` entirely in favor of
`Block`s with extra behaviors.

Missing functionality: The placement action cannot have any custom
interaction with the character's inventory. This should be fixed as part
of generally making `Operation`s more able to interact with inventories.
@kpreid
Copy link
Owner Author

kpreid commented Nov 8, 2024

Commit d241be8 adds BlockAttributes::placement_action.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: data Things related to the data structures underlying the world, and the functions that manipulate them. area: simulation Things related to what can happen in the world as time progresses. area: ui kind: incomplete A feature is partially implemented; the current state of the code is inconsistent
Projects
None yet
Development

No branches or pull requests

1 participant