Grid Placement can refund some or all of an object's build cost when that object is demolished. The plugin does not own your inventory; your game supplies a small id-based inventory bridge.
This feature applies to placed objects. Terrain painting is cell data, so terrain economy/refunds remain game-owned.
Data flow
SpendMaterialsRuleById defines cost
→ BuildCost resolves that cost for the placed object
→ demolish reaches the pre-demolish/refund path
→ RefundCalculator applies refund_ratio
→ RefundService sends id + amount to your inventory bridgeUse one cost source for both spending and refunds so those values cannot drift.
Main types
| Type | Purpose |
|---|---|
SpendMaterialsRuleById |
Defines id-keyed object build costs. |
BuildCost |
Resolved cost for a placed/manipulatable object. |
RefundCalculator |
Calculates refunded id→amount values. |
RefundService |
Applies refunds through the configured inventory bridge. |
Refunder |
Optional pre-demolish hook that can inspect/veto demolition. |
The current public service name is RefundService; old RefundSystem wording is legacy.
Inventory bridge
The same id contract can serve spending and refunding:
func get_count_by_id(id:StringName)-> int:
return GameInventory.get_item_count(id)
func try_remove_by_id(id:StringName, amount:int)-> int:
return GameInventory.remove_items(id, amount)
func try_add_by_id(id:StringName, amount:int)-> int:
return GameInventory.add_items(id, amount)Return the amount actually added/removed. That lets capacity-limited inventories report a partial refund correctly.
Configure refunds
RefundService owns the normal integration. Configure its refund ratio/rounding and make the inventory bridge reachable through the placement owner/bootstrap configuration.
Example policy:
build cost: 100 wood
refund_ratio: 0.5
refund: 50 woodConfigure one refund service for a placement setup. Do not attach an independent refund service to every building; multiple handlers can refund the same demolition more than once.
Use RefundCalculator directly only when your game intentionally owns a custom demolish pipeline. Use a custom Refunder when demolition itself needs a veto/inspection step.
Common mistakes
- Spend and refund ids differ (
&"Wood"vs&"wood"). - Several handlers refund the same object.
- The inventory bridge cannot be resolved from the active placement owner/configuration.
- A custom runtime discount changes the paid cost but the placed object's resolved
BuildCostis not updated. - Terrain painting is treated as if it were an object demolition workflow.