All Mods Resource Packs Data Packs Shaders Modpacks Plugins
Spice of Life: Classic Edition [1.20.1]

Spice of Life: Classic Edition [1.20.1]

by lepoko2525 • Downloads: 0 • Followers: 0
Description
Gallery
Changelog
Versions

This mod is not a fork of Spice of Life, but the content is similar. Instead of a policy of rewarding and encouraging eating, which is common, it encourages eating by debuffing.

Overview

This mod increases the difficulty of managing food in Minecraft by introducing mechanics that decrease food recovery values the more you consume the same item. It adds both short-term and long-term food debuffs, making food choices more strategic. Also, add a basket that can carry more than one food item.

Short-Term Food Debuff

If you eat the same food within the last 5 meals, the following debuffs will occur:

  • 1st time: 100% recovery (normal)
  • 2nd time: 90% recovery
  • 3rd time: 75% recovery
  • 4th time: 50% recovery
  • 5th time: 05% recovery

This is considered the short-term debuff.

Long-Term Food Debuff

Over time, the more you consume a specific food, its recovery will decrease by 1% per consumption, up to a history of 100 meals. This simulates a long-term debuff.

Items added

Baskets should contain multiple food items. It can be opened by right-clicking.

Basket:It can hold 9 stacks of food.

basket recipe

Large Basket:It can hold 9 stacks of food. Right click to eat the food inside. Compatible with AppleSkin.

large basket recipe

Configurable Settings

All debuff values, as well as the number of meals tracked for the history, are configurable through the config file. These settings are world-specific, so you can adjust them per save file.

Mod Compatibility

  • AppleSkin: This mod is fully compatible with AppleSkin. Changes to the food recovery will be reflected in the HUD. It also displays the amount of Wicker Basket recovery.
  • Farmer's Delight: While tested and working with Farmer's Delight, full compatibility is not guaranteed.

Feedback and Usage

This is my first mod, so I would love to hear any suggestions or improvements you have!

  • You are welcome to include this mod in modpacks.
  • Feel free to showcase it in videos.
  • No notification is required, but I would be delighted to hear about it if you do!

Prior to the change, the name was "FoodVariation".

All Versions

+ Add Version
Name Game version Platforms Published Downloads Actions
1.20.1
Fabric
2mo ago 1
1.20.1
Forge Neoforge
2mo ago 1
1.21.1
Fabric
2mo ago 1
1.21.1
Neoforge
2mo ago 1
1.21.1
Fabric
6mo ago 1
1.21.1
Neoforge
6mo ago 1
1.21.1
Fabric
6mo ago 1
1.21.1
Neoforge
6mo ago 1
1.20.1
Fabric
7mo ago 1
1.20.1
Forge Neoforge
7mo ago 1
1.20.1
Fabric
8mo ago 1
1.20.1
Forge Neoforge
8mo ago 1
1.21.1
Fabric
8mo ago 1
1.21.1
Neoforge
8mo ago 1
1.20.1
Fabric
8mo ago 1
1.20.1
Forge
8mo ago 1
1.21.1
Fabric
8mo ago 1
1.21.1
Neoforge
8mo ago 1
1.21.1
Fabric
8mo ago 1
1.21.1
Neoforge
8mo ago 1
1.20.1
Fabric
8mo ago 1
1.20.1
Forge
8mo ago 1
1.21.1
Fabric
8mo ago 1
1.21.1
Neoforge
8mo ago 1
1.20.1
Fabric
8mo ago 1
1.20.1
Forge
8mo ago 1
1.21.1
Fabric
8mo ago 1
1.21.1
Neoforge
8mo ago 1
1.20.1
Fabric
8mo ago 1
1.20.1
Forge
8mo ago 1
1.21.1
Fabric
8mo ago 1
1.21.1
Neoforge
8mo ago 1
1.21.1
Fabric
8mo ago 1
1.21.1
Neoforge
8mo ago 1
1.20.1
Fabric
8mo ago 1
1.20.1
Forge
8mo ago 1
1.21.1
Fabric
8mo ago 1
1.21.1
Neoforge
8mo ago 1
1.20.1
Fabric
8mo ago 1
1.20.1
Fabric
8mo ago 1
1.20.1
Forge
8mo ago 1
1.20.1
Fabric
8mo ago 1
1.20.1
Forge
8mo ago 1
1.20.1
Fabric
8mo ago 1
1.20.1
Forge
8mo ago 1
1.20.1
Forge Neoforge
last yr. 1
1.20.1
Fabric
last yr. 1
1.20.1
Forge Neoforge
last yr. 1
1.20.1
Forge Neoforge
last yr. 1
1.20.1
Forge Neoforge
last yr. 1
1.20.1
Forge Neoforge
last yr. 1
1.20.1
Forge Neoforge
last yr. 1
1.20.x
Forge
last yr. 1
1.20.1
Forge Neoforge
last yr. 1
1.20.1
Forge Neoforge
last yr. 1
1.20.1
Forge
last yr. 1
1.20.1
Forge
last yr. 1
1.20.1
Forge
last yr. 1
### Added
  • Added Chinese (zh_cn) localization. Thanks to [@pyf6trb](https://github.com/pyf6trb) (#53).
  • Added a basketBlacklist config option listing food items that cannot be put into the Basket or the Wicker Basket. Items already inside a basket are never deleted — they can still be taken out, and the Wicker Basket simply skips them when picking the most nutritious food to eat. This is separate from foodBlacklist, which excludes items from decay tracking. Requested in #52.

### Changed
  • Food history now caches per-item consumption counts in a Map<Item, Integer> alongside the ItemStack queue, so countFoodEaten() (used by the long-term decay calculation) is O(1) instead of scanning the whole history. Thanks to [@DaPlumer](https://github.com/DaPlumer) (#55).

### Fixed
  • Cake now loses hunger recovery like any other food. CakeBlock.eat() calls FoodData.eat(int, float) directly instead of going through Player.eat(Level, ItemStack), so the PlayerMixin redirect never fired and eating cake was neither decayed nor recorded in the food history. Added CakeBlockMixin on both platforms. Cake is the only vanilla food block that takes this path — candle cakes go through the same CakeBlock.eat(). Reported in #3.
  • Fixed a NullPointerException in FoodEventHandlerForge.countFoodEatenRecent() that dereferenced .consumedItems before the null check. Running /resetfoodhistory removes the map entry without re-syncing, so the next meal crashed on Forge.
  • Restored the defensive copy in FoodHistoryComponentFabric.setFood() and added a self-assignment guard. Without it, calling setFood() with the component's own history would clear() it and wipe the player's food history.
  • FoodHistory no longer throws IllegalStateException when the queue and the count cache disagree. It now logs the inconsistency and rebuilds the cache instead of crashing inside Player.eat().
  • Fixed FoodHistory.toString() using the %b format specifier, which printed true instead of the actual contents in diagnostic logs.
  • Fixed a NullPointerException in the Fabric config loader when an array key is missing from an existing solclassic-server.toml. TomlTable#getArray returns null for an absent key, and the previous code called .toList() on it before the null check, so adding any new array key would have broken every existing config file on load.

### Added
  • Added Chinese (zh_cn) localization. Thanks to [@pyf6trb](https://github.com/pyf6trb) (#53).
  • Added a basketBlacklist config option listing food items that cannot be put into the Basket or the Wicker Basket. Items already inside a basket are never deleted — they can still be taken out, and the Wicker Basket simply skips them when picking the most nutritious food to eat. This is separate from foodBlacklist, which excludes items from decay tracking. Requested in #52.

### Changed
  • Food history now caches per-item consumption counts in a Map<Item, Integer> alongside the ItemStack queue, so countFoodEaten() (used by the long-term decay calculation) is O(1) instead of scanning the whole history. Thanks to [@DaPlumer](https://github.com/DaPlumer) (#55).

### Fixed
  • Cake now loses hunger recovery like any other food. CakeBlock.eat() calls FoodData.eat(int, float) directly instead of going through Player.eat(Level, ItemStack), so the PlayerMixin redirect never fired and eating cake was neither decayed nor recorded in the food history. Added CakeBlockMixin on both platforms. Cake is the only vanilla food block that takes this path — candle cakes go through the same CakeBlock.eat(). Reported in #3.
  • Fixed a NullPointerException in FoodEventHandlerForge.countFoodEatenRecent() that dereferenced .consumedItems before the null check. Running /resetfoodhistory removes the map entry without re-syncing, so the next meal crashed on Forge.
  • Restored the defensive copy in FoodHistoryComponentFabric.setFood() and added a self-assignment guard. Without it, calling setFood() with the component's own history would clear() it and wipe the player's food history.
  • FoodHistory no longer throws IllegalStateException when the queue and the count cache disagree. It now logs the inconsistency and rebuilds the cache instead of crashing inside Player.eat().
  • Fixed FoodHistory.toString() using the %b format specifier, which printed true instead of the actual contents in diagnostic logs.
  • Fixed a NullPointerException in the Fabric config loader when an array key is missing from an existing solclassic-server.toml. TomlTable#getArray returns null for an absent key, and the previous code called .toList() on it before the null check, so adding any new array key would have broken every existing config file on load.

### Added
  • Ported the basketBlacklist setting from the 1.20.1 branch. Food items listed here cannot be put into the Basket or the Wicker Basket, and are skipped by the Wicker Basket's automatic food selection. This is a separate setting from foodBlacklist, which excludes items from decay tracking. The check is only applied on the paths that put *new* items in (FoodSlot.mayPlace(), FoodContainer.canPlaceItem()/addItem()/canAddItem()), never on FoodContainer.setItem(), so items already inside a basket can still be taken out after an item is added to the blacklist. On NeoForge the value is declared with defineListAllowEmpty rather than defineList, because defineList binds a NON_EMPTY (>= 1) size range that does not fit a setting whose default is an empty list. Requested in #52.
  • Ported the Chinese (zh_cn) localization from the 1.20.1 branch.

### Fixed
  • Fixed cake not being subject to food decay and not being recorded in the food history. CakeBlock.eat() does not go through Player.eat(Level, ItemStack, FoodProperties); it calls FoodData.eat(int, float) directly, so PlayerMixin's @Redirect never fired. Added CakeBlockMixin on both platforms with the shared logic in CakeEatHandler. Candle cakes go through the same CakeBlock.eat() and are covered as well. Reported in #3.
  • Fixed items disappearing from a Basket after roughly three stacks were inserted. The menu was opened with the vanilla MenuType.GENERIC_9x1, so the client built a vanilla ChestMenu + SimpleContainer with no food validation while the server used FoodChestMenu + FoodContainer + FoodSlot. The mismatch desynced slot contents. Registered a custom MenuType (solclassic:food_chest) via Architectury's MenuRegistry.ofExtended() so both sides build the same menu, and added the missing FoodContainer.canPlaceItem() override. Reported in #51.

### Changed
  • Ported the consumption-count cache from the 1.20.1 branch. Food history is now held in a FoodHistory object that keeps a Map<Item, Integer> counter alongside the queue, making the total-count lookup used by long-term decay O(1) instead of a linear scan of up to 300 entries. IFoodEventHandler now passes FoodHistory instead of LinkedList<ItemStack>.

### Added
  • Ported the basketBlacklist setting from the 1.20.1 branch. Food items listed here cannot be put into the Basket or the Wicker Basket, and are skipped by the Wicker Basket's automatic food selection. This is a separate setting from foodBlacklist, which excludes items from decay tracking. The check is only applied on the paths that put *new* items in (FoodSlot.mayPlace(), FoodContainer.canPlaceItem()/addItem()/canAddItem()), never on FoodContainer.setItem(), so items already inside a basket can still be taken out after an item is added to the blacklist. On NeoForge the value is declared with defineListAllowEmpty rather than defineList, because defineList binds a NON_EMPTY (>= 1) size range that does not fit a setting whose default is an empty list. Requested in #52.
  • Ported the Chinese (zh_cn) localization from the 1.20.1 branch.

### Fixed
  • Fixed cake not being subject to food decay and not being recorded in the food history. CakeBlock.eat() does not go through Player.eat(Level, ItemStack, FoodProperties); it calls FoodData.eat(int, float) directly, so PlayerMixin's @Redirect never fired. Added CakeBlockMixin on both platforms with the shared logic in CakeEatHandler. Candle cakes go through the same CakeBlock.eat() and are covered as well. Reported in #3.
  • Fixed items disappearing from a Basket after roughly three stacks were inserted. The menu was opened with the vanilla MenuType.GENERIC_9x1, so the client built a vanilla ChestMenu + SimpleContainer with no food validation while the server used FoodChestMenu + FoodContainer + FoodSlot. The mismatch desynced slot contents. Registered a custom MenuType (solclassic:food_chest) via Architectury's MenuRegistry.ofExtended() so both sides build the same menu, and added the missing FoodContainer.canPlaceItem() override. Reported in #51.

### Changed
  • Ported the consumption-count cache from the 1.20.1 branch. Food history is now held in a FoodHistory object that keeps a Map<Item, Integer> counter alongside the queue, making the total-count lookup used by long-term decay O(1) instead of a linear scan of up to 300 entries. IFoodEventHandler now passes FoodHistory instead of LinkedList<ItemStack>.

### Fixed
  • Fixed Fabric server config not taking effect on dedicated servers. The config path was resolved as a relative path, which could point to a different location depending on the working directory of the startup script. Now resolved to an absolute path via toAbsolutePath(). Config file location remains <world>/serverconfig/solclassic-server.toml.
  • Fixed potential NullPointerException in config array parsing (shortFoodDecayModifiers, foodBlacklist) that could silently prevent all config values from being applied.
  • Config values are now applied in the correct order: scalar values are written before array values, so scalar settings are always applied even if array parsing fails.

### Fixed
  • Fixed Fabric server config not taking effect on dedicated servers. The config path was resolved as a relative path, which could point to a different location depending on the working directory of the startup script. Now resolved to an absolute path via toAbsolutePath(). Config file location remains <world>/serverconfig/solclassic-server.toml.
  • Fixed potential NullPointerException in config array parsing (shortFoodDecayModifiers, foodBlacklist) that could silently prevent all config values from being applied.
  • Config values are now applied in the correct order: scalar values are written before array values, so scalar settings are always applied even if array parsing fails.

### Fixed
  • Fixed a crash on dedicated Fabric servers caused by NetworkManager.registerS2C() being annotated @Environment(EnvType.CLIENT). Following Architectury 13.0.8's documented pattern: server-side init now calls registerS2CPayloadType (type registration only), while client-side init continues to call registerReceiver with the packet handler.

### Fixed
  • Fixed a crash on dedicated Fabric servers caused by NetworkManager.registerS2C() being annotated @Environment(EnvType.CLIENT). Following Architectury 13.0.8's documented pattern: server-side init now calls registerS2CPayloadType (type registration only), while client-side init continues to call registerReceiver with the packet handler.

### Fixed
  • Fixed Wicker Basket / Lunch Basket slot desync bug where placing food items would cause other items to be displaced or lost after approximately 3 items. The root cause was using vanilla MenuType.GENERIC_9x1, which caused the client to create a vanilla ChestMenu + SimpleContainer (no food validation) while the server used FoodChestMenu + FoodContainer + FoodSlot (with food validation). This client-server mismatch led to slot synchronization failures during item placement. Registered a custom MenuType via Architectury's MenuRegistry.ofExtended() so both client and server use FoodChestMenu with consistent FoodSlot + FoodContainer validation.
  • Added canPlaceItem() override to FoodContainer as an additional safety net for food-only validation at the container level (defense-in-depth alongside FoodSlot.mayPlace()).

### Fixed
  • Fixed Wicker Basket / Lunch Basket slot desync bug where placing food items would cause other items to be displaced or lost after approximately 3 items. The root cause was using vanilla MenuType.GENERIC_9x1, which caused the client to create a vanilla ChestMenu + SimpleContainer (no food validation) while the server used FoodChestMenu + FoodContainer + FoodSlot (with food validation). This client-server mismatch led to slot synchronization failures during item placement. Registered a custom MenuType via Architectury's MenuRegistry.ofExtended() so both client and server use FoodChestMenu with consistent FoodSlot + FoodContainer validation.
  • Added canPlaceItem() override to FoodContainer as an additional safety net for food-only validation at the container level (defense-in-depth alongside FoodSlot.mayPlace()).

### Added
  • Added compatibility with Sophisticated Backpacks' Feeding Upgrade (auto-feeding feature). SoL Classic now directly integrates with SB's FeedingUpgradeWrapper via conditional Mixin.
  • Food with 0% recovery rate (fully decayed) is now skipped by SB's auto-feeding, preventing wasteful consumption.
  • When a Wicker Basket is in an SB backpack, the Feeding Upgrade will prioritize eating from the Wicker Basket, selecting the most nutritious food inside (with decay considered).
  • SB compatibility Mixin is conditionally loaded only when SophisticatedCore is present on the classpath, preventing crashes when SB is not installed.

### Added
  • Added compatibility with Sophisticated Backpacks' Feeding Upgrade (auto-feeding feature). SoL Classic now directly integrates with SB's FeedingUpgradeWrapper via conditional Mixin.
  • Food with 0% recovery rate (fully decayed) is now skipped by SB's auto-feeding, preventing wasteful consumption.
  • When a Wicker Basket is in an SB backpack, the Feeding Upgrade will prioritize eating from the Wicker Basket, selecting the most nutritious food inside (with decay considered).
  • SB compatibility Mixin is conditionally loaded only when SophisticatedCore is present on the classpath, preventing crashes when SB is not installed.

### Added
  • Added Sophisticated Backpacks (SophisticatedCore) Feeding Upgrade compatibility. SoL Classic's food decay is now correctly applied when SB's Feeding Upgrade auto-feeds the player.
  • Foods with 0% decay recovery are excluded from Feeding Upgrade's auto-feeding.
  • Wicker Basket in SB backpacks now correctly feeds from the basket's inventory instead of being consumed as an item.
  • Conditional Mixin loading via SBCompatMixinPlugin: SB compatibility mixins are only loaded when SophisticatedCore is present, preventing crashes when SB is not installed.

### Added
  • Added Sophisticated Backpacks (SophisticatedCore) Feeding Upgrade compatibility. SoL Classic's food decay is now correctly applied when SB's Feeding Upgrade auto-feeds the player.
  • Foods with 0% decay recovery are excluded from Feeding Upgrade's auto-feeding.
  • Wicker Basket in SB backpacks now correctly feeds from the basket's inventory instead of being consumed as an item.
  • Conditional Mixin loading via SBCompatMixinPlugin: SB compatibility mixins are only loaded when SophisticatedCore is present, preventing crashes when SB is not installed.

### Fixed
  • Fixed basket (Lunch Basket) slot bug where placing a 4th item would overwrite the item in the first slot. When replacing Slots with FoodSlot/LockedSlot via this.slots.set() in FoodChestMenu, the slot.index field (menu slot position ID) was not set, defaulting to 0 for all replaced slots. This caused incorrect slot identification during item placement. Reported on Mohist (Bukkit+Forge hybrid) servers.

### Fixed
  • Fixed basket (Lunch Basket) slot bug where placing a 4th item would overwrite the item in the first slot. When replacing Slots with FoodSlot/LockedSlot via this.slots.set() in FoodChestMenu, the slot.index field (menu slot position ID) was not set, defaulting to 0 for all replaced slots. This caused incorrect slot identification during item placement. Reported on Mohist (Bukkit+Forge hybrid) servers.

### Fixed
  • Fixed a bug in FoodChestMenu where replacing slots via this.slots.set() did not set Slot.index (menu slot position ID), leaving it at the default value of 0. This caused slot identification to break, resulting in items in slot 0 being overwritten when inserting a 4th item into the basket, particularly in Bukkit bridge environments such as Mohist.

### Fixed
  • Fixed a bug in FoodChestMenu where replacing slots via this.slots.set() did not set Slot.index (menu slot position ID), leaving it at the default value of 0. This caused slot identification to break, resulting in items in slot 0 being overwritten when inserting a 4th item into the basket, particularly in Bukkit bridge environments such as Mohist.

### Added
  • Added enableTooltip config option (default: true): controls whether the food decay tooltip ("Hunger recovery reduced by X%") is shown on food items.
  • Added enableItemDescription config option (default: true): controls whether description tooltips are shown on mod items (Wicker Basket, Food History Book).

### Added
  • Added enableTooltip config option (default: true): controls whether the food decay tooltip ("Hunger recovery reduced by X%") is shown on food items.
  • Added enableItemDescription config option (default: true): controls whether description tooltips are shown on mod items (Wicker Basket, Food History Book).

### Added
  • Added enableTooltip config option to toggle the food decay tooltip on food items. When set to false, the decay percentage tooltip will not be displayed. Default is true.
  • Added enableItemDescription config option to toggle the description tooltip on mod items (Wicker Basket, Food History Book, etc.). When set to false, item descriptions will not be displayed. Default is true.

### Added
  • Added enableTooltip config option to toggle the food decay tooltip on food items. When set to false, the decay percentage tooltip will not be displayed. Default is true.
  • Added enableItemDescription config option to toggle the description tooltip on mod items (Wicker Basket, Food History Book, etc.). When set to false, item descriptions will not be displayed. Default is true.

### Added
  • Added enableTooltip config option (default: true): controls whether the food decay tooltip ("Hunger recovery reduced by X%") is shown on food items.
  • Added enableItemDescription config option (default: true): controls whether description tooltips are shown on mod items (Wicker Basket, Food History Book).

### Added
  • Added enableTooltip config option (default: true): controls whether the food decay tooltip ("Hunger recovery reduced by X%") is shown on food items.
  • Added enableItemDescription config option (default: true): controls whether description tooltips are shown on mod items (Wicker Basket, Food History Book).

### Added
  • Added compatibility with Quality Food mod. SoL Classic's food decay now correctly applies to quality-modified nutrition values instead of base values. Food history treats items of different quality as the same food.

### Fixed
  • Fixed dedicated server crash caused by FoodHistoryBookItem directly referencing client-only classes (Screen, Minecraft). Replaced client references with a Consumer<Player> callback pattern, registering the screen opener only on the client side via ClientTooltipHandler.init().

### Added
  • Added compatibility with Quality Food mod. SoL Classic's food decay now correctly applies to quality-modified nutrition values instead of base values. Food history treats items of different quality as the same food.

### Fixed
  • Fixed dedicated server crash caused by FoodHistoryBookItem directly referencing client-only classes (Screen, Minecraft). Replaced client references with a Consumer<Player> callback pattern, registering the screen opener only on the client side via ClientTooltipHandler.init().

### Fixed
  • Fixed dedicated server crash caused by FoodHistoryBookItem importing client-only classes (FoodHistoryBookScreen, Minecraft). Refactored to use a Consumer<Player> callback pattern, with the screen opener registered from ClientTooltipHandler.init() on the client side only.

### Fixed
  • Fixed dedicated server crash caused by FoodHistoryBookItem importing client-only classes (FoodHistoryBookScreen, Minecraft). Refactored to use a Consumer<Player> callback pattern, with the screen opener registered from ClientTooltipHandler.init() on the client side only.

### Added
  • Added compatibility with Quality Food mod. SoL Classic's food decay now correctly applies to quality-modified nutrition values instead of base values. Food history treats items of different quality as the same food.

### Added
  • Added compatibility with Quality Food mod. SoL Classic's food decay now correctly applies to quality-modified nutrition values instead of base values. Food history treats items of different quality as the same food.

Spice of Life: Classic Edition [1.20.1] Icon
Download Spice of Life: Classic Edition [1.20.1]
Select game version
Select platform