Open kpreid opened 3 months ago
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,
}
Tool
) is a pair of a Handle<ToolDef>
and a Block
.Modifier::Inventory
to the ToolDef
's block.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 Block
s in several ways. Idea no. 2:
Block
— the Tool
type goes away entirely.Block
s can carry arbitrary “when placed” Operation
s, which don't necessarily actually place the block but could do any other things.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.)Advantages over no. 1:
Disadvantages:
Modifier::Inventory
rendering information goes!)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:
Block
s can carry arbitrary “when placed”Operation
s, which don't necessarily actually place the block but could do any other things.
Note that Tool
s 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:
Composite
, or replace a specific existing block with a “more filled” one.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.)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.
I sat down to implement blocks containing and displaying inventories, and discovered a problem: right now, the signature of
Tool::icon()
iswhich 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:
Inventory
has aBlockProvider<Icons>
associated when it's created, orBlockProvider<Icons>
associated when it's created.If we go with items/tools owning their icons, then either:
all-is-cubes
crate built-in tools have specific icons intrinsically — but we've so far avoided having any voxel block definitions be part ofall-is-cubes
itself, and they'd need to be a newPrimitive
,PlaceBlock
?), orTool::Custom
does now), separate from the tool's action definition (which might be the currentTool
enum or it might beOperation
?).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.