Food Spoilage
A standalone plugin that gives food an expiry date carried on the item stack itself, with no database and no repeating task — spoilage is evaluated the moment a player touches the item.
Food Spoilage gives every edible item an expiry date, and keeps that date on the item. There is no table, no cache file and no repeating task: the expiry is a string in the stack's persistent data container, mirrored into its lore, and it travels with the stack through hoppers, chests, drops and restarts because Minecraft already persists item metadata.
Stamp on arrival, judge on use
Eleven listeners cover the ways food enters play — crafting, fishing, mob drops, item spawns, pickups, joining, and opening or closing a container — and each one stamps anything edible that is not already stamped. Nothing sweeps inventories looking for expired food. The check happens at the point of contact: interact with a stack whose date has passed and it is replaced in your hand with rotten flesh and the interaction cancelled.
Because state lives on the item rather than in storage, the plugin needs nothing like the Repository Pattern the flagship uses. It does still read the older lore-only representation, the same "keep reading the previous format" instinct as Legacy Data Migration at a much smaller scale — and that fallback is load bearing: the expiry is written with ISO_OFFSET_DATE, which carries no time-of-day, so the same formatter cannot parse it back into an OffsetDateTime and the persistent-data read fails silently every time. I verified that round trip against the JDK rather than finding it stated anywhere; no comment, commit or issue in the repository records whether it is intended.
The furnace is left alone
The one deliberate hole is cooking. BlockCookListener handles the event and does nothing, and its Javadoc records why: since Minecraft 1.20.5 the furnace re-runs canBurn() every tick, comparing the vanilla recipe result against the output slot by strict data-component equality. A stamped output no longer matches, so the furnace stops after one item. Leaving furnace output vanilla and stamping it later, when it reaches a player, is the workaround — and it is why InventoryCloseListener exists at all.
Related
The plugin extends PonderBukkitPlugin and registers its listeners through Ponder's EventHandlerRegistry. It ships in the curated jar set on DPC Minecraft Server, and unlike an Expansion Plugin it has no dependency on Medieval Factions — its only optional integration is with RPKit's food library, which it serves by registering itself as that library's expiry service.