kpreid / all-is-cubes

Yet another block/voxel game; in this one the blocks are made out of blocks. Runs in browsers on WebGL+WebAssembly.
https://kpreid.dreamwidth.org/tag/all+is+cubes
Apache License 2.0
147 stars 8 forks source link

Inventory item schema redesign #480

Open kpreid opened 3 months ago

kpreid commented 3 months ago

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:

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

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 commented 1 month ago

Brainstorming. New schema idea no. 1:


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

Advantages over no. 1:

Disadvantages:

kpreid commented 1 month ago

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:

Bad fits for this model:

kpreid commented 1 month ago
  • 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 commented 1 month ago

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.