What is a spoilable item?
A spoilable item is an item that after a certain amount of time expires, removing its self from the storage component holding it. Spoilable items are an advanced example of using the Dynamic Data system. I'll give you a breakdown of how Spoilables leverage Dynamic Data in the How Spoilable Items Work section below.
Create a Spoilable Item
- Open the Items data table and select your item.
- Add a new element to the DynamicData map. Set the key as spoil and set the value as the number of seconds you would like the item to take before it spoils.
- (Optional) If you would like a new item to spawn when this one spoils add another element to the DynamicData map for your first item and set the key to onspoil and the value to the ItemRowName of the new spawned item.
That is it! your item is now integrated into the spoil system. You will however need to drop any current instances of the items and pickup (not the one you dropped) or add a new copy of it. Remember Dynamic Data lives on the instance, and since we just added spoil to our data, it will only apply to new instances of the items.
Freezer & Rapid Spoiler Examples
The demo content includes a Freezer and Rapid Spoiler container blueprint. These are normal containers with the added benefit of implementing our BPI_SpoilSpeedMultiplier blueprint interface which lets us customize the spoil speed multiplier for any items added to our container. With these specialized containers using this interface, when a spoilable is added to it we either slow down or speed up the spoiling process. This is handled by the onTransfer event for the Spoilable Dynamic Data State Event.
The Freezer & Rapid spoiler inherit from the BP_Interactable_SpoilMultiplierContainer which inherits from the base BP_Interactable_Container. The only difference with the SpeedMultiplier one is that it includes this BPI already intergrated.
Change the Spoil Speed Multiplier
If you are using the included Freezer or Rapid Spoiler you can change the SpoilSpeedMultiplier variable in the blueprint, or if you are using the interface on your own implementation you will return the SpoilSpeedMultiplier float value from the getSpoilSpeedMultiplier implemented function (from the BPI_SpoilSpeedMultiplier). You will want to implement on the same actor that has the storage component(s). If you wanted to control the speed while in the player storage you would implement this blueprint interface on your player controller.
To slow down spoiling you would use a value lower then 1.0. The Freezer's value is 0.1. Compared to our default value of 1 it would take 10x longer for an item to spoil in the freezer compared to our inventory.
To speed up spoiling you would use a value higher then 1.0. The Rapid Spoiler value is set to 10.0. Compared to our default value of 1 it would take 1/10th the amount of time for an item to spoil in the rapid spoiler compared to our inventory.
To change the default spoil speed multiplier of 1.0 open the BPO_DDSE_Spoilables object in the Blueprint/Objects/DynamicDataStateEvents/ folder. The currentSpoilSpeedMultiplier float variable is where you would set the default. Remember though, this value is overriden by a call to the owner with getSpoilSpeedMultiplier.
How Spoilable Items Work
Spoilables are built on top of the Dynamic Data system. This allows us to keep it completely optional without taking on the overhead to power the system if we don't actually want to use it. It only activates if it detects our trigger in the DynamicData of items added to our storage components. For spoilables that trigger is spoil, which we also use to define how much time it should take to spoil.
Dynamic Data Variables
We set these in the DynamicData field for the Item in the Items data table.
Dynamic Data State Events
These are the dynamic data state events as defined in our DT_DynamicDataHelpers. All of them are handled with BPO_DDSE_Spoilable object in the Blueprints/Objects/DynamicDataStateEvents/ folder. This handler is linked to the spoil dynamic data key on our item through the Dynamic Data Helpers data table, DT_DynamicDataHelpers in the Blueprints/Variables/DataTables/DynamicData/ folder.
Visit the dynamic data page to learn more about dynamic data helpers.
We use this function to initilize our spoilable item, by calculating our first expiration date based on our spoil speed multiplier. We save this expiration date, and our current spoil speed multiplier back to the item's dynamic data. By default these extra variables are hidden on the player UI.
We use this function to see our spoil speed multiplier has changed, if it has we recalculate our new spoil expiration based on the new multiplier, our starting time, and current percentage of spoil completed. We save this new expiration date, and our new spoil speed back to the item dynamic data.
We use this function to check and see if our item spoiled. If it did we remove it and reset the spoil timer for the next item in the stack. If we are using the onspoil dynamic data variable to create a new item in the spoiled items place we also handle adding that at this time.
Customized Spoilable Item UI Widgets
The UIs/Shared/DynamicData/Spoilables/ folder contains two twidgets, UI_Spoilable_Item and UI_Spoilable_Tooltip. These are the widgets that are appended to our UI_Item and UI_Item_Tooltip to show the spoil time remaining. For the UI_Item it is a simple progress bar. For the Tooltip it is a seconds remaining countdown.
These UIs are also added automatically to any item that has the spoil dynamic data key through the Dynamic Data Helpers data table, DT_DynamicDataHelpers in the Blueprints/Variables/DataTables/DynamicData/ folder. Visit the dynamic data page to learn more about dynamic data helpers.