Skip to main content

Introduction

The RSG Inventory system features a sophisticated time-based decay mechanism that simulates realistic item deterioration. Food spoils, materials degrade, and items lose quality over time - adding depth and realism to your RedM economy and encouraging active gameplay. Version: 2.7.3+ (Updated November 2024)
Item decay runs automatically on the server-side based on real-world time, not playtime. You can now control whether items decay offline!
New in v2.7.3: Offline decay control, custom stash decay rates, and default item metadata!

Core Features

📉 Quality-Based Degradation

  • Quality Range: 0-100 (100 = perfect condition, 0 = destroyed)
  • Linear Decay: Predictable degradation over time
  • Item-Specific Rates: Each item defines its own decay speed
  • Passive System: Automatic calculation, no manual intervention needed

🔄 Automatic Management

  • Auto-Calculation: Decay computed on inventory load and item use
  • Auto-Deletion: Items at 0% quality are automatically removed (optional)
  • Timestamp Tracking: Uses Unix timestamps for accuracy
  • Offline Decay Control: NEW! Configure whether items decay while player is offline

🎯 Flexible Configuration

  • Per-Item Control: Each item has its own decay rate
  • Optional Deletion: Choose whether items delete at 0% quality
  • No Decay Option: Items without decay property never degrade
  • Quality Info: Quality stored in item metadata for access
  • Stash Decay Rates: NEW! Custom decay rates for specific stashes (coolers, freezers, etc.)
  • Default Metadata: NEW! Set default item info values in item definitions

How It Works

Decay Calculation Formula

The system uses a linear decay formula with optional modifiers:
Breakdown:
  1. Time Elapsed: Calculate seconds since last update
  2. Base Decay Rate: Convert minutes to per-second decay rate
  3. Decay Rate Modifier: Apply stash-specific multiplier (default: 1.0)
  4. New Quality: Subtract modified decay from current quality (minimum 0)
Decay Rate Modifier:
  • 1.0 = Normal decay (100%)
  • 0.3 = Slow decay (30% of normal) - refrigerator
  • 0.0 = No decay (0%) - freezer
  • 50.0 = Fast decay (5000% of normal) - composter

Decay Timeline Example

Item with decay = 300 (5 hours):
Calculation:
  • Decay rate: 100 / (300 * 60) = 0.00556% per second
  • After 1 hour (3600s): 100 - (3600 × 0.00556) = 80%
  • After 5 hours (18000s): 100 - (18000 × 0.00556) = 0%

Item Configuration

Item Definition Structure

Items with decay are defined in rsg-core/shared/items.lua:

Decay Properties

Items without a decay property never lose quality and last forever.

Decay Configuration

Offline Decay Setting

Configure whether items decay when players are offline in rsg-inventory/shared/config.lua:
When false (recommended):
  • Items only decay when player is online and playing
  • More forgiving for casual players
  • Prevents logging in to spoiled food after a few days offline
  • Decay timer pauses when player disconnects
When true:
  • Items decay based on real-world time
  • More realistic simulation
  • Encourages regular login to manage inventory
  • Food spoils even when offline
Setting this to false is recommended for most servers to improve player experience and prevent frustration from offline decay.

Default Item Metadata

You can now define default metadata for items in rsg-core/shared/items.lua:
When you add this item, the default info values are automatically included:
This dramatically simplifies item creation and ensures consistent metadata across all instances of an item type!

Custom Stash Decay Rates

Decay Rate Naming System

You can control decay rates for specific stashes using a special naming pattern:
Format:
  • Base stash name
  • Followed by -decay or _decay
  • Followed by percentage number (0-100+ allowed)
Examples:
  • basement69-decay30 → 30% decay rate (slower)
  • freezer111_decay0 → 0% decay rate (no decay)
  • refrigerator_decay20 → 20% decay rate (very slow)
  • composter333decay5000 → 5000% decay rate (50x faster!)

How Decay Rates Work

The percentage modifies the base decay rate:

Practical Examples

Example 1: Freezer (No Decay)

Result: Items in this stash never decay (perfect for long-term storage)

Example 2: Refrigerator (Slow Decay)

Result: Items decay at 20% of normal rate
  • Normal bread lasts 5 hours
  • Bread in fridge lasts 25 hours (5 ÷ 0.20)

Example 3: Root Cellar (Moderate Decay)

Result: Items decay at 50% of normal rate
  • Normal bread lasts 5 hours
  • Bread in cellar lasts 10 hours

Example 4: Composter (Accelerated Decay)

Result: Items decay 50x faster than normal
  • Normal bread takes 5 hours to decay
  • Bread in composter decays in 6 minutes (5 hours ÷ 50)
  • Use for converting organic matter to compost quickly

Example 5: Dynamic Decay Rates

Decay Rate Comparison Table

Decay rate modifiers are parsed from the stash identifier. Changing the identifier requires moving items to the new stash name!

Decay Rate Guidelines

Fast Decay (Perishables)

Use for: Fresh food, organic materials, perishable goods

Medium Decay (Cooked Food)

Use for: Prepared meals, baked goods, processed food

Slow Decay (Durables)

Use for: Tools, medicine, preserved goods

No Decay (Permanent)

Use for: Money, valuables, crafting materials, tools

Quality Metadata

Item Info Structure

Every item with decay has quality tracking in its info table:

Initial Quality Assignment

When items are added without quality info, the system initializes it automatically:

Manual Quality Setting


Decay Functions

CheckItemDecay

Manually check and update an item’s decay.
Parameters:
  • item (table) - Item object with info table
  • itemInfo (table|nil) - Item definition from RSGCore.Shared.Items (optional)
  • currentTime (number|nil) - Unix timestamp (optional, defaults to os.time())
  • decayRateModifier (number|nil) - Decay rate multiplier (optional, defaults to 1.0)
Returns:
  • shouldUpdate (boolean) - Whether item metadata was changed
  • newQuality (number|nil) - New quality value after decay
  • shouldDelete (boolean) - Whether item should be removed
Example:

CheckPlayerItemsDecay

Check and update all items in a player’s inventory.
Parameters:
  • player (table) - Player object from RSGCore.Functions.GetPlayer
Example:
This function is automatically called when inventory is loaded. Manual calls are rarely needed.

CheckItemsDecay

Check decay for a table of items (for stashes, drops, etc.).
Parameters:
  • items (table) - Table of items indexed by slot
  • decayRateModifier (number|nil) - Decay rate multiplier (optional, defaults to 1.0)
Returns:
  • needsUpdate (boolean) - Whether any items were updated
  • removedItems (table) - Table of items that should be deleted
Example:

Decay Timing

When Decay is Calculated

Decay calculations happen automatically at these times:
  1. Player Login - All inventory items checked when player loads
  2. Inventory Open - Items checked when opening inventory UI
  3. Item Use - Individual item checked before use callback
  4. Stash Open - Stash items checked when accessed
  5. Drop Pickup - Ground drop items checked when picked up

Decay Check Flow

Decay is calculated based on real-world time, not in-game time or playtime. Items continue to decay even when the server is offline!

Quality Thresholds and Effects

Example: Quality-Based Food Effects

Example: Tool Durability


Common Use Cases

Example 1: Portable Cooler with Decay Rate

Result: Items in portable cooler decay at 30% of normal rate (built-in system handles it automatically!) Before v2.7.3: Required complex manual timestamp resetting After v2.7.3: Just add _decay30 to the stash ID!

Example 2: Quality-Based Pricing

Example 3: Repair System

Example 4: Preservation Items

Example 5: Visual Quality Indicators (Client)


Best Practices

Balance decay times carefully: Too fast = frustrating, too slow = no gameplay impact
Don’t make everything decay: Only perishables, consumables, and tools should have decay
Provide preservation options: Give players ways to maintain items (coolers, repair, preservation)

Design Guidelines

Decay Time Recommendations:
  1. Perishables (Fresh Food): 30 minutes - 2 hours
  2. Cooked Food: 4 - 12 hours
  3. Preserved Food: 24 - 72 hours
  4. Medicine/Consumables: 24 - 48 hours
  5. Tools/Equipment: 3 - 7 days
  6. Valuables: No decay (gold, jewelry, money)
  7. Weapons: Use rsg-weapons durability instead

Testing Decay


Troubleshooting

Possible causes:
  • Item doesn’t have decay property in shared/items.lua
  • info.lastUpdate is missing (should auto-initialize)
  • Decay check functions aren’t being called
Solution: Verify item definition and ensure CheckItemDecay is called
Possible causes:
  • Incorrect decay value (remember: it’s in minutes)
  • Server time issues or clock skew
Solution:
  • Review decay value: decay = 60 means 1 hour
  • Use admin test command to verify decay rates
Possible causes:
  • delete = false or missing in item definition
  • Items not being checked for decay
Solution: Set delete = true and ensure decay checks run on inventory load
Possible causes:
  • Quality stored as decimal but displayed incorrectly
  • lastUpdate timestamp is invalid
Solution:
  • Use math.floor(quality) for display
  • Verify lastUpdate is a valid Unix timestamp (os.time())
Configuration: Check Config.ItemsDecayWhileOffline in rsg-inventoryWhen true (v2.7.3+):
  • Items decay based on real-world time
  • Decay calculated when player logs back in
  • Quality reflects total elapsed time
When false (recommended):
  • Items only decay when player is online
  • Decay timer pauses on disconnect
  • Prevents offline spoilage
Possible causes:
  • Incorrect stash ID format (use _decay30 or -decay30)
  • Percentage value missing or malformed
  • Using old inventory version (requires v2.7.3+)
Solution:
  • Verify stash ID format: stashname_decay{NUMBER}
  • Check inventory version in fxmanifest.lua
  • Examples: freezer_decay0, fridge-decay20
Possible causes:
  • Item definition missing info table
  • Using old rsg-core/rsg-inventory version
  • Manually providing info that overrides defaults
Solution:
  • Add info = { key = value } to item definition
  • Update to rsg-inventory v2.7.3+
  • Remember: Provided info merges with defaults

Technical Details

Implementation Location

Decay functions are implemented in:
  • rsg-inventory/server/functions.lua - Core decay calculation logic
  • rsg-inventory/shared/helpers.lua - Helpers.ParseDecayRate() function
  • rsg-inventory/server/exports.lua - Default metadata merging
  • rsg-inventory/shared/config.lua - ItemsDecayWhileOffline setting

Decay Rate Parsing

Default Metadata Merging

Database Storage

Quality is stored in the inventory column as JSON:

Performance Considerations

  • Decay calculations are O(1) per item
  • Only calculated when needed (not every frame)
  • Minimal performance impact even with many items
  • Database writes only on player save (every 5 minutes)
  • Stash decay rate parsing is cached (no repeated regex)

Version Compatibility


Next Steps


Need help? Join the RSG Framework Discord!