Basic crops system

This commit is contained in:
2026-09-25 22:49:27 -03:00
parent ef25e66f08
commit 099811670f
22 changed files with 985 additions and 178 deletions
+83 -3
View File
@@ -20,6 +20,7 @@ too, since the client is already a web page.
- [Identifiers](#identifiers)
- [Textures](#textures)
- [Blocks](#blocks)
- [Block models](#block-models)
- [Items](#items)
- [Recipes](#recipes)
- [Server scripts](#server-scripts)
@@ -89,6 +90,7 @@ mods/
copper_tools/
manifest.json
blocks/*.json
models/*.json
items/*.json
recipes/*.json
worldgen/ores.json
@@ -194,7 +196,9 @@ program**, so the server and each client can number blocks differently. Saves an
| Field | Default | Maps to `BlockRegistry` | Meaning |
| ---------------------- | ----------- | ----------------------- | -------------------------------------------------------------------------------------------- |
| `id` | required | `id` | The block's id. |
| `textures` | required | `textures` | One texture id, `{ top, bottom, side }` or `{ front, side }`. |
| `textures` | required | `textures` | One texture id, `{ top, bottom, side }` or `{ front, side }`. With another `model`, the model's texture variables, like `{ "crop": "..." }`. |
| `model` | `engine:cube` | `model` | The [block model](#block-models). |
| `variants` | none | `variants` | A different `model`, `textures` or `y` rotation for some states, see [block models](#block-models). |
| `render_layer` | `solid` | `render_layer` | `solid`, `cutout` (texels fully opaque or fully clear, like leaves) or `translucent` (blended, like water and glass). Non-solid blocks don't hide their neighbors' faces. |
| `cull_same` | see meaning | `cull_same` | Hide faces between two of this block. Defaults to `true` for translucent blocks, `false` otherwise. |
| `light_emission` | `0` | `light_emission` | Light level 0-15 it gives off, like a torch (14). |
@@ -216,8 +220,84 @@ functions.
Block states are declared like `[{ "name": "facing", "bits": 2, "default": 0 }]`, at most 16 bits in total. A block
starts with its defaults when it's placed or generated, and server scripts read and change them with
`ctx.world.get_state` / `set_state`. States are saved with the world and synced to players. They can't change textures
yet, because the mesher ignores them. `variants` is reserved for that.
`ctx.world.get_state` / `set_state`. States are saved with the world and synced to players. `variants` changes how the
block looks with them.
## Block models
A block's shape comes from its model, `engine:cube` unless it sets `model`. The engine has three:
| Model | Texture variables | Shape |
| -------------- | -------------------------------------------------- | --------------------------------------------- |
| `engine:cube` | one texture, `{ top, bottom, side }` or `{ front, side }` | A full block. |
| `engine:cross` | `cross` | Two crossed planes, like flowers and saplings. |
| `engine:crop` | `crop` | Four planes in a # shape, like wheat. |
Blocks that aren't full cubes should use the `cutout` (or `translucent`) render layer, because `solid` blocks hide their
neighbors' faces. This is what minecraft's `"render_type": "minecraft:cutout"` does. They usually want
`"collision": false` too, and show as a flat sprite of their first texture in inventories.
`blocks/wheat.json` picks a texture per growth stage with `variants`. The keys are conditions on the block's states,
`"age=3"` or `"age=3,facing=1"` (all have to match), and the first variant that matches replaces the block's `model`,
`textures` or turns it by `y` (0, 90, 180 or 270 degrees, clockwise seen from above):
```json
{
"format_version": 1,
"block": {
"id": "bworld:wheat",
"model": "engine:crop",
"textures": { "crop": "bworld:wheat_stage_0" },
"variants": {
"age=0": { "textures": { "crop": "bworld:wheat_stage_0" } },
"age=1": { "textures": { "crop": "bworld:wheat_stage_1" } }
},
"render_layer": "cutout",
"collision": false,
"states": [{ "name": "age", "bits": 3, "default": 0 }]
}
}
```
Mods add their own models in `models/`, in minecraft's block model format: boxes in pixels (0-16 is the block) with a
texture per face. `models/slab.json`:
```json
{
"format_version": 1,
"model": {
"id": "copper_tools:slab",
"textures": { "top": "#side", "bottom": "#side" },
"elements": [{
"from": [0, 0, 0],
"to": [16, 8, 16],
"faces": {
"top": { "texture": "#top" },
"bottom": { "texture": "#bottom", "cullface": "bottom" },
"north": { "texture": "#side", "cullface": "north" },
"south": { "texture": "#side", "cullface": "south" },
"west": { "texture": "#side", "cullface": "west" },
"east": { "texture": "#side", "cullface": "east" }
}
}]
}
}
```
| Field | Meaning |
| ---------------------------- | ---------------------------------------------------------------------------------------------- |
| `id` | The model's id, in the mod's namespace. |
| `textures` | Defaults for texture variables. Values are texture ids or other variables (`"#side"`). |
| `elements[].from`, `to` | Opposite corners of the box, `[x, y, z]` in pixels. |
| `elements[].rotation` | `{ origin, axis, angle, rescale }`: turns the box around `origin` on `x`, `y` or `z` by -45, -22.5, 0, 22.5 or 45 degrees. `rescale` stretches it back to the block's width. |
| `elements[].shade` | Darker faces on the sides and bottom, `true` by default. Plants turn it off. |
| `elements[].faces` | `top`, `bottom`, `north`, `south`, `west` and `east`. Faces are only drawn from the front, so a flat plane needs one face each way. |
| `faces.*.texture` | A variable (`"#side"`, filled in by the block's `textures`) or a texture id. |
| `faces.*.uv` | `[u1, v1, u2, v2]`, the part of the texture in pixels. Defaults to the part the face covers. |
| `faces.*.cullface` | Hidden when the neighbor on that side is a solid block. Only for faces on the block's edge. |
Faces flat against the block's edge get smooth lighting and ambient occlusion like a full block's. Anything inside the
block is lit evenly with the block's own light.
## Items