ItemFoodAsset — Food Consumables
Understanding how the Unturned food asset system works requires recognizing that ItemFoodAsset is an empty subclass whose entire behavior derives from its parent's stat modifier pipeline, the EItemType.FOOD enum assignment, and the quality-to-mold degradation mechanics that transform food into virus-carrying hazards. ItemFoodAsset is an empty subclass of ItemConsumeableAsset. It defines no fields, properties, or methods of its own — all behavior comes from the ItemConsumeableAsset base class and the EItemType.FOOD type assignment in the item registry.
Source code location: Unturned/Bundles/ItemFoodAsset.cs
Inheritance Chain
ItemAsset
→ ItemWeaponAsset
→ ItemConsumeableAsset
→ ItemFoodAsset (empty)Class Definition
csharp
public class ItemFoodAsset : ItemConsumeableAsset
{
}The class body is completely empty. No constructors, no overrides, no fields, no properties. The EItemType.FOOD enum value is set in the ItemAsset.PopulateAsset method when the .dat file's Type key is parsed. This is what distinguishes food from water and medical items at runtime — an enum value, not a class difference.
Why an Empty Subclass?
The separation into empty subclasses is a design pattern that avoids runtime type checking against EItemType. Rather than writing:
csharp
if (asset is ItemConsumeableAsset && asset.type == EItemType.FOOD)The code can use the cleaner pattern:
csharp
if (asset is ItemFoodAsset)In practice, the type enum dominates runtime branching in the UseableConsumeable system, but the empty subclasses provide cleaner C# APIs for inventory filtering, crafting recipes, and spawn table queries.
Inherited Behavior from ItemConsumeableAsset
Since ItemFoodAsset is empty, all functionality comes from the parent chain. The following is a comprehensive reference for what food items inherit:
Stat Modifiers (byte values)
| Field | .dat Key | Typical Food Values | Effect |
|---|---|---|---|
_food | Food | 15-45 | Primary food stat restoration |
_water | Water | 0-10 | Incidental water gain (if any) |
_health | Health | 0-10 | Minor health restoration |
_virus | Virus | 0-5 | Food poisoning risk |
_disinfectant | Disinfectant | 0 | Not typical for food |
_energy | Energy | 0-10 | Minor stamina restoration |
_vision | Vision | 0 | Not typical for food |
oxygen | Oxygen | 0 | Not typical for food |
_warmth | Warmth | 0-50 | Warmth from hot food items |
experience | Experience | 0 | Not typical for food |
Medical Modifiers
| Field | Typical Value |
|---|---|
bleedingModifier | None |
bonesModifier | None |
Food items rarely modify bleeding or bones. These are reserved for medical items.
Consumption Constraints
| Field | Default | Description |
|---|---|---|
shouldDeleteAfterUse | true | Food is consumed (deleted) on use |
_hasAid | false | Food cannot be applied to other players |
foodConstrainsWater | food >= water | May clamp water gain |
Quality and Mold
showQuality returns true for EItemType.FOOD, enabling the quality display in the item description. The quality-to-mold pipeline:
- Quality ≥ 50: Normal stat restoration.
- Quality < 50: The item appears "Moldy." Food restoration is reduced to
floor(food * quality / 100). Virus gain is amplified byvirusBonus * (100 - quality) / 50. - Quality = 0: Minimal benefits, maximum virus.
Quality degrades by 1 per consumption tick when the game mode config enables decay. Newly crafted or admin-spawned items start at 100 quality.
The Food Stat Pipeline
When a food item is consumed through UseableConsumeable, the food stat is processed through a tick-based pipeline:
Per-Tick Application
csharp
// Each tick (32 ticks/second):
float tickFraction = 1.0f / totalTicks;
float foodGain = _food * tickFraction;
player.food = Mathf.Min(player.food + foodGain, 100.0f);Food Constrains Water
When foodConstrainsWater is true and both food and water stats are present:
csharp
if (foodConstrainsWater)
{
float potentialWater = player.water + waterGain;
float potentialFood = player.food + foodGain;
if (potentialFood + potentialWater > 100.0f)
{
float excess = (potentialFood + potentialWater) - 100.0f;
waterGain = Mathf.Max(0.0f, waterGain - excess);
}
}This ensures the combined food and water stats don't exceed 100, prioritizing food over water when the constraint is active.
Starvation and Food Thresholds
The food stat affects gameplay through thresholds defined in the game mode config:
| Food Level | Status | Effects |
|---|---|---|
| 90-100 | Full | No effects |
| 60-89 | Normal | No effects |
| 30-59 | Hungry | Minor health loss |
| 0-29 | Starving | Significant health loss, reduced stamina regen |
Food items are the primary defense against starvation. The stat decays at a configurable rate per game tick.
Vanilla Food Items
Vanilla food items demonstrate the range of food stat configurations:
| Item | Food | Water | Health | Virus | Warmth |
|---|---|---|---|---|---|
| Canned Beans | 30 | 10 | 5 | 0 | 0 |
| Canned Tuna | 25 | 5 | 5 | 2 | 0 |
| MRE | 40 | 10 | 10 | 0 | 0 |
| Chocolate Bar | 15 | 0 | 5 | 1 | 0 |
| Chips | 20 | -5 | 3 | 2 | 0 |
| Instant Noodles | 35 | 5 | 5 | 0 | 0 |
| Pizza (cooked) | 45 | 5 | 10 | 0 | 20 |
| Beef Jerky | 20 | -5 | 5 | 0 | 0 |
| Granola Bar | 15 | 0 | 3 | 0 | 0 |
| MRE (cold) | 20 | 0 | 5 | 2 | 0 |
Notable Patterns
- Canned goods (beans, tuna) provide balanced food and water with minimal virus.
- Dry foods (chips, jerky) have negative water (they dehydrate).
- Cooked foods (pizza) provide warmth in addition to food.
- MREs provide the highest food and health values.
- Low-quality foods (cold MRE, chocolate) carry virus risk.
Audio
Food items inherit the consumption audio from ItemConsumeableAsset:
- Loaded from the bundle as "Use" or redirected via
.datkeyConsumeAudioClip. ShouldRandomizeUseAudioPitchdefaults to true (pitch varies ±0.1).- Different food items typically use distinct eating sounds (crunching, chewing, can opening).
Common Issues
- Type must be FOOD — An
ItemFoodAssetwithEItemType.WATERorEItemType.MEDICALmisconfigured in the.datwill have the wrong runtime behavior. TheshowQualitycheck, mold behavior, and crafting category filtering all use thetypeenum, not the C# class. - Negative water on dry foods — Some dry foods have positive food but negative water values. The negative water is applied on a separate UI line in red. Players may not notice the dehydration effect on foods they expect to be neutral.
- Virus on seemingly safe foods — Several vanilla food items have small virus values (1-2). This represents mild food poisoning risk. The virus gain is invisible on low-quality items (under 50 quality) because the mold amplification can make the virus substantial.
- Food constrains water counter-intuitiveness — When
foodConstrainsWateris active, a meal with 80 food and 80 water only provides 20 water. This is a legacy behavior and can surprise modders who define generous water values on food items. - Food items as explosives — Since
ItemConsumeableAssetextendsItemWeaponAsset, food items can technically be configured as explosives via theExplosionkey. A soup can withExplosionand damage multipliers functions as a grenade substitute. - No crafting-only flag — Food items have no
canBeUsedInCraftingor similar flag to restrict them to crafting ingredients only. An item with high food values and low crafting value may confuse players who try to eat it. - Quality decay on admin spawn — Admin-spawned food items start at 100 quality, but quality still decays over time if the game mode enables it. This can surprise administrators who expect permanent perfect food.
Worked Code Example: Food Quality Monitor
csharp
using SDG.Unturned;
public static class FoodQualityMonitor
{
public static (byte foodGain, byte virusRisk, byte warmth) GetEffectiveStats(
ItemFoodAsset food, byte quality)
{
byte effectiveFood = food.food;
byte effectiveVirus = food.virus;
if (quality < 50)
{
effectiveFood = (byte)(effectiveFood * quality / 100);
effectiveVirus = (byte)(effectiveVirus + (byte)(effectiveVirus * (100 - quality) / 50));
}
return (effectiveFood, effectiveVirus, food.warmth);
}
public static bool IsFoodSafe(ItemFoodAsset food, byte quality, byte maxSafeVirus)
{
var stats = GetEffectiveStats(food, quality);
return stats.virusRisk <= maxSafeVirus;
}
}Mermaid Diagram: Food Consumption Pipeline
Comparison: Food vs. Other Consumables
| Feature | ItemFoodAsset | ItemWaterAsset | ItemMedicalAsset |
|---|---|---|---|
| Primary stat | Food | Water | Health |
| Mold/quality | Yes (quality < 50) | No | No |
| Virus risk | Yes (amplified low quality) | No | No |
| Warmth | Yes (hot food) | No | No |
| Dehydrates | Possible (negative water) | No | No |
How This Differs from SDG Docs
- SDG docs list food as standalone type. In SDK,
ItemFoodAssetis empty — inherits all fromItemConsumeableAsset. Distinction is onlyEItemType.FOOD. - SDG docs claim mold "spreads." Mold is per-item. A moldy food does not affect adjacent inventory items.
- SDG docs reference "cooking" quality. Cooking is handled by campfire/stove logic in
ItemBarricadeAsset, notItemFoodAsset.
Performance Considerations
Per-tick stat application: one multiply + one Mathf.Min × 32 ticks/second. With 100 players eating: 3200 ops/sec — negligible. Quality check is one integer comparison per tick.
Deeper FAQ
Q: Can food items have negative food values?
Yes. Food=-10 depletes the stat — effectively poison. Applied as player.food += foodGain where foodGain can be negative.
Q: How does negative water on dry foods affect gameplay?
Negative water decrements player.water stat. Players eating chips/dry foods see water bar decrease. Red UI line indicates dehydration.
Q: Does cooking reset food quality?
Crafting cooked food from base ingredients creates a new item at 100 quality. Moldy food cannot be "re-cooked" to improve quality.
Cross-References
- ItemConsumeableAsset — Food/Water/Medical Base — Stat pipeline and quality system.
- ItemWaterAsset — Water Consumables — Water items using same pipeline.
- UseableConsumeable — Eating/Drinking — Runtime consumption class.
