The strategy pattern is one of my go to tools for building game features - you can use it to make things as modular as you need, and it makes it really easy to swap out pieces of behavior as you’re prototyping new ideas. This video - I’m sure has been shared many times here - covers a way to implement the strategy pattern in Godot using custom resources, but I’ve found that using a node hierarchy for choosing strategies is actually more useful in certain applications.
The video I just mentioned is great, and if you haven’t watched I’d highly recommend. But I’ve realized pretty quickly that it doesn’t fit as well for every use case of the strategy pattern. The problem in particular comes in when your strategy depends on data from another node in your scene. You can only export node members if it’s also a member of a node. So if your strategies are all subclasses of a resource, referencing members from external nodes is no longer as trivial as dragging them in from the editor.
Let’s take for example a project I’m currently working on as an exercise in game prototyping - a clone of Coffee Caravan. In this game you have interactable stations that each represent a part of the process of making coffee. E.g. “Grab beans from this sack” or “Grind into coffee grounds” or “brew coffee.” Each of these stations have some kind of an inventory, but what these inventories can accept depends on the kind of station it is - a perfect place for the strategy pattern.
For example, you can only put whole coffee beans back into the sack of beans - so its “inventory condition strategy” might be something like “only accept items with type” with an exported resource that can change what type of item it accepts. However, the coffee grinder and the coffee brewer are in some sense “crafting stations” - they have a recipe that accepts inputs and produces an output. So we might want a different behavior for these stations: “only accept crafting items” that references the input and output items from another node that represents a crafting component.
But how do you reference the crafting component from the inventory condition strategy? My default approach would be to put an export variable directly on the strategy so you can choose the crafting component on the strategy instance in the editor. However, this isn’t possible if your strategy is a resource, since resources can’t export node members.
What I’ve done instead that so far seems to work nicely is to make use of the node hierarchy: whatever node that wants to use a strategy will simply look for instances of that strategy in its children. In my example, I have an “InteractableInventory” component that’s responsible for translating player input into messages sent to the inventory component. When checking to see if the inventory can accept the item in the player’s hand, it will look through its children for nodes that implement an “InventoryAcceptCondition” interface (interfaces are most straightforward in C#, but they can be crudely implemented in gdscript). Now I can reference the crafting component on node that represent the strategy instance via an export variable.