Add a plant-like voxel
What you will build
Section titled “What you will build”Bramble Block is a placeable, hand-breakable foliage voxel with an alpha-cutout leaf texture. It uses the same authored-content route as Leaves: a BlockDefinition, matching ItemDefinition, palette/tint/material slot, and normal physical block drop. It is a plant-like voxel, not a harvestable crop: breaking it returns the block item, and it has no growth state, berries, seeds, biomass batch, or alkaloid chemistry.
Assign its stable block/item id from the next unreleased catalogue id when landing the change. Do not copy an id from a wiki example: ids are permanent once released, and the current composer roster is the source of truth.
Where this sits
Section titled “Where this sits”- Data owns the stable block and item identities and marks the block
Cutout. - World maps the palette slot to its terrain material and emits the existing cube geometry.
- Player breaks the voxel and spawns the matching physical item through the ordinary drop path.
- Voxel Workshop composes the authored assets and lets Block Library verify the result.
flowchart TD CONTENT["GameplaySceneComposer\ncontent + item definitions"] BLOCK["BlockDefinition\nCutout foliage block"] ITEM["ItemDefinition\nplaceable block item"] PALETTE["GenerationBlockPalette\ntint slot"] MATERIAL["Terrain material\nHDRP alpha clip"] MESH["Chunk mesher\nexisting cube faces"] BREAK["Block interaction\nworld edit"] DROP["DroppedItemSpawnerRuntime\nphysical cube pickup"] CONTENT --> BLOCK CONTENT --> ITEM BLOCK --> PALETTE --> MATERIAL PALETTE --> MESH BREAK --> DROP ITEM --> DROP
The material can discard transparent texels, but the mesh remains a cube. This is the existing Leaves capability. A crossed-quad stem, a non-cubic collision volume, or a multi-block plant is a renderer/interaction feature and must not be hidden inside one new catalogue row.
Before you start
Section titled “Before you start”Read Docs/MASTERPLAN.md §12.1.1 for the physical-drop contract and §36.4 for the catalogue-to-matter boundary. Then inspect:
GameplaySceneComposer.ContentDefinitions, the paired block/item authoring roster.BlockDefinition, especiallyrenderClass,isSolid, tool gate, and empty-by-default chemistry composition.GameplaySceneComposer.SlotIsCutout, which converts an authoredCutoutclass into HDRP alpha clipping.ChunkMeshingJob, which still emits six axis-aligned cube faces for every non-air voxel.
Decide these before writing code:
| Decision | Bramble Block | Why |
|---|---|---|
| Physical form | full voxel cube | This is what the present mesher, collider, and drop visual can represent faithfully. |
| Render class | Cutout |
Leaf texture transparency is alpha-tested in the existing HDRP material path. |
| Solid/collision intent | match Leaves until non-solid voxel collision is implemented |
Do not infer collision behavior from alpha clipping. |
| Break tool | None |
The normal interaction service therefore permits hand breaking. |
| Chemistry | empty | A foliage texture does not establish a material composition or a harvest yield. |
The build, step by step
Section titled “The build, step by step”1. Add paired content entries
Section titled “1. Add paired content entries”Append a ContentDefinition for Bramble Block in GameplaySceneComposer.ContentDefinitions, mirroring Leaves (GameplaySceneComposer.cs:275). Use the next permanent id and renderClass: BlockRenderClass.Cutout.
// illustrative — choose the next unreleased stable id at implementation timenew(nextStableId, "Bramble Block", renderClass: BlockRenderClass.Cutout),EnsureCatalogs creates or updates both its BlockDefinition and matching ItemDefinition. Do not add a block without its item mapping: breaking checks that mapping before it edits the world.
2. Add the palette and texture slot together
Section titled “2. Add the palette and texture slot together”Follow the six-edit palette pattern in Add a voxel block type: serialized id, fallback tint, accessors, KnownTints, validation, and the composer’s matching TerrainTintSlotNames entry. The order of KnownTints and TerrainTintSlotNames is an index contract; a mismatch binds the bramble geometry to another block’s material.
Add the same slot name to both project texture generators. Give it an alpha-bearing foliage tile and ensure the generated albedo’s import settings preserve transparency. The material composer asks SlotIsCutout whether to enable alpha clip; it does not derive this from the PNG filename or colour.
3. Compose and inspect the authored assets
Section titled “3. Compose and inspect the authored assets”Run Tools → Voxel Sandbox → Voxel Workshop → Scene Composer → Compose Gameplay with Active Skin. It creates or updates the block and item assets, registers them in their catalogues, and builds the terrain material. In Block Library, confirm the row has the intended stable id, display name, and Cutout render class.
At this point the voxel can be made available through an existing item/source path for testing. Do not add it to world generation merely to see it in game: a decorative or biological placement rule is a separate design decision from registering a block.
4. Verify break, placement, and drops
Section titled “4. Verify break, placement, and drops”The standard interaction route already applies. InventoryBlockInteractionService.TryBreak first validates the item mapping and tool requirement, then applies the authoritative voxel edit. On success, DroppedItemSpawnerRuntime reacts to that event and spawns a collectible cube using the terrain material.
Do not put direct inventory addition into the break service. A full inventory must leave the physical drop available for later pickup, not prevent the block edit or delete the item.
5. Add only the tests this path needs
Section titled “5. Add only the tests this path needs”Extend the catalogue/composer coverage so the new id is unique and the item maps back to the same block. Add an interaction fixture that proves hand breaking succeeds, a drop is requested, and placement consumes exactly one matching item only after the voxel edit succeeds. Keep the existing managed/Burst meshing parity test green; a Cutout definition does not justify different geometry until a real alternate mesh path exists.
Verify
Section titled “Verify”Run the focused Data, World, and Player EditMode fixtures from Unity’s Test Runner. In particular, keep catalogue duplicate-id coverage, ChunkMeshBuilderTests.BurstMeshingJob_MatchesManagedFaceCullingAndQuadOrder, and InventoryBlockInteractionServiceTests green. Then compose gameplay and verify:
- Block Library shows exactly one Bramble Block definition and one placeable item mapping.
- The terrain material alpha-clips the foliage texture without changing adjacent cube-face culling.
- Hand breaking removes the voxel and creates a physical drop.
- Picking it up and placing it consumes one item only after successful placement.
- A full inventory leaves the drop in the world.
Now do your own
Section titled “Now do your own”- Name the plant-like block and reserve the next stable id from the current composer roster.
- Decide whether the existing cube-plus-cutout form is truthful for it; create renderer work instead of faking a stem if not.
- Add matching block, item, palette, composer slot, and both texture-generator entries in the same order.
- Select an explicit tool and collision policy; do not infer either from a transparent texture.
- Keep chemistry composition empty until you can author a real material/harvest model.
- Compose, inspect Block Library, and run the focused catalogue, mesh-parity, and interaction tests.
Pitfalls
Section titled “Pitfalls”| Symptom | Cause | Fix |
|---|---|---|
| Leaves render as another block’s material. | Palette and composer tint-slot orders differ. | Make the matching ordered insertion in both arrays and cover it with the palette-order test. |
The texture is opaque although the definition says Cutout. |
The source albedo has no usable alpha or was imported without it. | Fix the alpha-bearing texture/import path; do not change the render class to conceal the asset issue. |
| The block looks like a cube with holes, not crossed leaves. | The current meshers emit only cube faces for non-air voxels. | Accept the cube form for this feature or implement a dedicated managed/Burst alternate geometry path with its own collider and tests. |
| Breaking fails before the voxel changes. | No matching ItemDefinition exists for the new block. |
Keep the paired composer entry and verify TryGetItemForBlock through an interaction test. |
| A “plant” creates biomass or an alkaloid when punched. | Rendering/identity was confused with harvest chemistry. | Leave composition empty; use From plant to harvestable chemistry to design the future persistent harvest path. |
User-contributed notes
Corrections, clarifications, and practical tips for this page. Anonymous is fine — a name is optional. Basic Markdown works:
**bold**,*italic*,`code`, and links.Notes policy
Notes are lightly filtered for spam and may be edited or removed. Keep them about this page — no support requests, no personal data, nothing you would not publish. Links are limited and marked
nofollow.