Nutrition System
EmakiCooking provides a balanced-diet style nutrition system: eating accumulates different nutrition values, and crossing thresholds triggers server-defined actions. The nutrition system only provides the mechanics (value changes, edge-triggered thresholds, persistence); gameplay such as nausea, lasting buffs, and decay is assembled by the server admin 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 | Default | Description |
|---|---|---|---|
id | string | file name | Unique nutrition type id. |
display_name | string | equals id | Display name. |
min | double | 0 | Lower bound. |
max | double | 100 | Upper bound. |
default | double | equals min | 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:
# 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 | Aliases | Description |
|---|---|---|
item_sources | item_source, item, source | Item source list; any match applies. |
nutrition | — | nutrition-type-id: amount mapping. |
actions | — | Extra CoreLib actions to run on match (optional). |
Item sources use CoreLib item source prefixes: minecraft-<id>, craftengine-<id>, itemsadder-<id>, nexo-<id>, mmoitems-<id>, neigeitems-<id>. A rule is skipped if item_sources is empty or if both nutrition and actions are empty.
nutrition:
food_sources:
- item_sources:
- minecraft-apple
- minecraft-sweet_berries
nutrition:
fruit: 20
- item_sources:
- minecraft-cake
- minecraft-cookie
nutrition:
sugar: 30
actions:
- 'playsound sound=entity.player.burp volume=1.0 pitch=1.0'Eating 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 | Aliases | Default | Description |
|---|---|---|---|
id | — | single_<index> | Rule id. |
types | type | [] (empty = all types) | Nutrition types to evaluate. |
value | — | 0 | Threshold. |
compare | operator, op | >= | Comparison operator. |
actions | on_meet, on_pass | [] | Actions on meet. |
on_recover | on_fail, recover_actions | [] | Actions when dropping back below. |
Combo thresholds
Counts whether enough nutrition types are above their value.
| Field | Aliases | Default | Description |
|---|---|---|---|
id | — | combo_<index> | Rule id. |
types | type | [] (empty = all types) | Nutrition types to count. |
value | — | 0 | Each type must reach this value to "qualify". |
compare | operator, op | >= | Comparison operator. |
required_count | count | 5 | How many types must qualify at once to trigger. |
actions | on_meet, on_pass | [] | Actions when the required count is met. |
on_recover | on_fail, recover_actions | [] | Actions when the count drops back below. |
compare supports >=, >, <=, <, ==, != (aliases such as gte, gt, lte, lt, eq, ne are also accepted). 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:
loopsync template=<template> times=<count> interval=<interval> key=<unique-key> mode=replace stop_if_offline=true: start a loop in the met actions (such as periodically draining nutrition or applying a buff).cancelloop key=<same-key>: cancel the loop inon_recover.
Loop templates must be defined under CoreLib's config.yml → action.loop.templates. The default "all five nutrition types full triggers nausea and decay" combo threshold:
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:
- 'sendmessage text=<red>You overate and feel sick...'
- 'playsound sound=entity.player.burp volume=1.0 pitch=0.8'
- 'givepotioneffect type=NAUSEA level=1 duration=200'
- 'loopsync template=nutrition_decay times=999999 interval=40t key=nutrition_overeat:%player_name% mode=replace stop_if_offline=true'
on_recover:
- 'cancelloop key=nutrition_overeat:%player_name%'Nutrition operation actions
Nutrition add/remove/set, clear/reset, threshold recheck, and recipe reward actions are registered to the CoreLib ActionRegistry by EmakiCooking and can be used in any CoreLib action chain. Current action IDs use only canonical names; historical aliases are no longer registered. See CoreLib Actions for complete parameters.
| Operation | Action ID |
|---|---|
| Add nutrition | emakicookingaddnutrition |
| Remove nutrition | emakicookingremovenutrition |
| Set nutrition | emakicookingsetnutrition |
| Clear nutrition | emakicookingclearnutrition |
| Reset nutrition | emakicookingresetnutrition |
| Recheck thresholds | emakicookingrechecknutritionthreshold |
| Run recipe reward | emakicookingrunrecipereward |
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.
schema_version: 1
uuid: <player-UUID>
name: <player-name>
values:
fruit: 60
vegetable: 40
protein: 80
sugar: 20
grain: 50Configuration overview
| Key | Type | Default | Description |
|---|---|---|---|
nutrition.enabled | boolean | true | Nutrition system master switch. |
nutrition.save_interval_seconds | int | 300 | Periodic save interval in seconds; 0 saves only on quit or shutdown. |
nutrition.food_sources | list | see above | Food-to-nutrition mapping. |
nutrition.thresholds.single | list | see above | Single-type threshold rules. |
nutrition.thresholds.combo | list | see above | Combo threshold rules. |
External plugin integration
For nutrition-related Bukkit events see Event API: PlayerNutritionConsumeEvent (before consumption, cancellable) and NutritionThresholdChangeEvent (threshold met/recovered, informational).