English
Nutrition System
EmakiCooking provides a balanced-diet style nutrition system: eating accumulates different nutrition values, and crossing thresholds triggers the actions you configured yourself. The nutrition system only provides the mechanics (value changes, edge-triggered thresholds, persistence); gameplay such as nausea, lasting buffs, and decay is assembled by you using CoreLib actions
Basics
| Item | Value |
|---|---|
| Master switch | config.yml → nutrition.enabled (default true) |
| Type definition folder | nutrition/<id>.yml |
| Default nutrition types | fruit, grain, protein, sugar, vegetable |
| Player data | data/nutrition/<player-UUID>.yml |
| Main permissions | emakicooking.nutrition.use, emakicooking.nutrition.admin |
Nutrition type definitions
Each nutrition type maps to one .yml file under the nutrition/ folder; the file name (without .yml) is the default id. Five types ship by default and can be freely added or removed
| Field | Type | Required | Default | Range | Description |
|---|---|---|---|---|---|
id | string | No | File name without .yml | — | Unique nutrition type id |
display_name | string | No | Equals id | — | Display name; an empty value falls back to the id |
min | double | No | 0 | — | Lower bound |
max | double | No | 100 | — | Upper bound |
default | double | No | Equals min | Clamped to [min, max] | Player initial value |
Parsing rules:
- If
minis greater thanmax, they are corrected automatically (smaller becomes min, larger becomes max) defaultis clamped to[min, max]- An empty
display_namefalls back to the id
Default nutrition/fruit.yml example:
yaml
# Nutrition type: fruit
# Player nutrition value is clamped between min and max
id: fruit
display_name: "Fruit"
min: 0
max: 100
default: 0TIP
Single thresholds, combo thresholds, met/recover actions, and food-to-nutrition mappings are not in nutrition/*.yml. They are configured under the nutrition: section of config.yml. The nutrition/*.yml files only define these five fields of the type itself
Food-to-nutrition mapping
Which nutrition a food grants is configured under config.yml → nutrition.food_sources (a list)
| Field | Type | Required | Default | Range | Description |
|---|---|---|---|---|---|
item_sources | list<string> | No | [] | CoreLib item source shorthand | Allowed item sources, ANDed with the sibling matcher; the rule is skipped when both are omitted |
matcher | object | No | None | General matcher; item source conditions are not allowed | Extra component / PDC / lore conditions |
nutrition | map<string,double> | No | {} | nutrition-type-id: amount | Nutrition added on match; the rule is skipped when both this and actions are empty |
actions | list<string> | No | [] | CoreLib action strings | Extra actions run on match |
item_sources and matcher are sibling fields and both must hold (AND)
Item sources use CoreLib item source prefixes: minecraft-<id>, craftengine-<id>, itemsadder-<id>, nexo-<id>, oraxen-<id>, mmoitems-<id>, neigeitems-<id>. A rule is skipped if both item_sources and matcher are empty, or if both nutrition and actions are empty
yaml
nutrition:
food_sources:
- item_sources:
- minecraft-apple
- minecraft-sweet_berries
nutrition:
fruit: 20
- item_sources:
- minecraft-cake
- minecraft-cookie
nutrition:
sugar: 30
actions:
- 'play_sound sound=entity.player.burp volume=1.0 pitch=1.0'
# Only a cake that was never renamed: the two fields each cover half
- item_sources:
- minecraft-cake
matcher:
type: component
component: custom_name
operator: absent
nutrition:
sugar: 40Eating flow: the player eats an item, CoreLib identifies the item source, the food_sources rules are matched, nutrition values are added (clamped to min~max), rule actions run, and thresholds are re-evaluated. Vanilla food and CraftEngine/ItemsAdder/Nexo food implemented through the vanilla food component all go through the vanilla eating event; MMOItems and NeigeItems are wired in separately via soft dependencies and do not affect operation when absent
Threshold rules
Thresholds are configured under config.yml → nutrition.thresholds, split into single-type (single) and combo (combo). Both are edge-triggered: actions run once when the threshold is met, and on_recover runs once when it drops back below
Single thresholds
Each nutrition type is evaluated independently
| Field | Type | Required | Default | Range | Description |
|---|---|---|---|---|---|
id | string | No | single_<index> | — | Rule id |
types | list<string> | No | [] (empty = all types) | Registered nutrition type ids | Nutrition types to evaluate |
value | double | No | 0 | — | Threshold |
compare | string | No | >= | See the operator table below; an unrecognized value falls back to >= | Comparison operator |
actions | list<string> | No | [] | CoreLib action strings | Actions on meet |
on_recover | list<string> | No | [] | CoreLib action strings | Actions when dropping back below |
Combo thresholds
Counts whether enough nutrition types are above their value
| Field | Type | Required | Default | Range | Description |
|---|---|---|---|---|---|
id | string | No | combo_<index> | — | Rule id |
types | list<string> | No | [] (empty = all types) | Registered nutrition type ids | Nutrition types to count |
value | double | No | 0 | — | Each type must reach this value to "qualify" |
compare | string | No | >= | See the operator table below; an unrecognized value falls back to >= | Comparison operator |
required_count | int | No | 5 | — (not validated; a non-number falls back to 5) | How many types must qualify at once to trigger |
actions | list<string> | No | [] | CoreLib action strings | Actions when the required count is met |
on_recover | list<string> | No | [] | CoreLib action strings | Actions when the count drops back below |
Operators supported by compare and all of their accepted spellings (case-insensitive; an unrecognized value falls back to >=):
| Operator | Accepted spellings |
|---|---|
| Greater or equal | >=, gte, at_least, ge |
| Greater | >, gt, greater |
| Less or equal | <=, lte, at_most, le |
| Less | <, lt, less |
| Equal | ==, =, eq, equal, equals |
| Not equal | !=, <>, ne, not_equal |
A rule is skipped if both actions and on_recover are empty
Assembling nausea and lasting buffs
The nutrition service does not hard-code nausea or buffs; it relies on CoreLib loop actions:
start_task sequence=<template> times=<count> interval=<interval> key=<unique-key> on_conflict=replace stop_when_offline=true: start a loop in the met actions (such as periodically draining nutrition or applying a buff)stop_task key=<same-key>: cancel the loop inon_recover
Loop templates must be defined under CoreLib's config.yml → action.loop.templates, and times is capped by EmakiCoreLib's action.loop.max_times. The default "all five nutrition types full triggers nausea and decay" combo threshold:
yaml
nutrition:
thresholds:
combo:
- id: overeat
types: [] # empty = count all nutrition types
value: 100 # each type at 100 counts as "full"
compare: ">="
required_count: 5 # all 5 full to trigger
actions:
- 'send_message text=<red>You overate and feel sick...'
- 'play_sound sound=entity.player.burp volume=1.0 pitch=0.8'
- 'give_potion_effect type=NAUSEA level=1 duration=200'
- 'start_task sequence=nutrition_decay times=100 interval=40t key=nutrition_overeat:%caster.uuid% on_conflict=replace stop_when_offline=true'
on_recover:
- 'stop_task key=nutrition_overeat:%caster.uuid%'Nutrition operation actions
Nutrition add/remove/set, clear/reset, threshold recheck, and recipe reward actions are registered to the CoreLib action registry by EmakiCooking and can be used in any CoreLib action chain. Current action IDs use only canonical names; historical aliases are no longer registered. The old emakicookingaddnutrition is now written cooking_add_nutrition, and the others follow the same rule. See CoreLib Actions for complete parameters
| Operation | Action ID |
|---|---|
| Add nutrition | cooking_add_nutrition |
| Remove nutrition | cooking_remove_nutrition |
| Set nutrition | cooking_set_nutrition |
| Clear nutrition | cooking_clear_nutrition |
| Reset nutrition | cooking_reset_nutrition |
| Recheck thresholds | cooking_recheck_nutrition_threshold |
| Run recipe reward | cooking_run_recipe_reward |
Commands and permissions
See Commands & Permissions for nutrition commands. See Placeholders for nutrition placeholders
Persistence
- Path:
plugins/EmakiCooking/data/nutrition/<player-UUID>.yml, one file per player - Save timing: periodic save (
nutrition.save_interval_seconds, default 300 seconds,0means save only on quit or shutdown), and on player quit - Loaded on player join; after a reload, online players are topped up with defaults for any newly added types
yaml
schema_version: 1
uuid: <player-UUID>
name: <player-name>
nutrition:
fruit: 60
vegetable: 40
protein: 80
sugar: 20
grain: 50Configuration overview
| Field | Type | Required | Default | Range | Description |
|---|---|---|---|---|---|
nutrition.enabled | boolean | No | true | true / false | Nutrition system master switch |
nutrition.save_interval_seconds | int | No | 300 | ≥ 0 (seconds), values below 0 are treated as 0 | Periodic save interval; 0 saves only on quit or shutdown |
nutrition.food_sources | list<object> | No | Sample rules shipped | See "Food-to-nutrition mapping" | Food-to-nutrition mapping |
nutrition.thresholds.single | list<object> | No | Sample rules shipped | See "Single thresholds" | Single-type threshold rules |
nutrition.thresholds.combo | list<object> | No | Sample rules shipped | See "Combo thresholds" | Combo threshold rules |
External plugin integration
For nutrition-related Bukkit events see Event API: PlayerNutritionConsumeEvent (before consumption, cancellable) and NutritionThresholdChangeEvent (threshold met/recovered, informational)