Hey everyone! 👋

One of the core pillars of A Witch’s Path is how the player interacts with the environment. I’ve always loved how games like Breath of the Wild and Tears of the Kingdom make the world feel alive. Throw something weird at it, and the game often has a response. That level of reactivity? I knew I wanted something similar in my own game.

It just so happened to pair perfectly with another core mechanic: crafting your own spells.

So let’s talk about how I built this with Unreal Engine and how surprisingly simple (yet powerful) the system is under the hood.

✨ The Big Idea

In A Witch’s Path, spells aren’t for combat, they’re tools for solving puzzles, revealing secrets, and even altering the world itself. Fire burns objects. Wind pushes things. Light uncovers hidden secrets.

To make that happen, I built a modular system that allows anything in the world to react to spells using a single UObject, a Blueprint Interface, and an Actor Component.

🔌 Blueprint Interface – BPI_Reactor

This is where the magic starts. BPI_Reactor is a simple interface with one function: ReactToEffects.

That function accepts an array of WorldEffect objects. These are custom UObject classes I’ve implemented in C++ that store metadata for effects—like type (Fire, Light, Wind), strength, duration, and more.

If something in the world should react to a spell or environmental change, it implements this interface. From there, it can decide how to respond based on the effects it receives.

But let’s make it even better…

🧩 Actor Component – BPC_WorldEffectApplicator

Instead of duplicating code in every actor that can react to effects, I built a Blueprint Actor Component to handle the glue logic.

BPC_WorldEffectApplicator has one job:
Call ApplyWorldEffectsToReactor(WorldEffectsArray) and it’ll do the work of passing those effects along to any compatible components or interfaces on the actor.

This is great for spells like fireball. When it hits a surface, it spawns a new actor that emits a fire-type WorldEffect. That actor then overlaps with nearby objects and calls into their interfaces via the Applicator.

Here’s a quick breakdown of some of the interfaces I’m using:

  • BPI_Activatable – Can be toggled on/off
  • BPI_Burnable – Catches fire with fire-based spells
  • BPI_Revealable – Reacts to light spells to show hidden objects

So instead of hardcoding logic everywhere, I can mix and match components and interfaces to create layered reactions.

🔥 Fire in Action

Let’s say the player casts a fireball.

  • The projectile hits a flammable crate.
  • A WorldEffect with the Fire tag and intensity is created.
  • The effect overlaps the crate’s collider.
  • The crate implements BPI_Burnable, so it receives the fire effect.
  • The StartBurning function is triggered.
  • 🔥 Boom—animated fire, damage over time, and maybe it burns away.

Fire Spell Showcase

🌱 Why It Matters

This system means I don’t need dozens of hardcoded responses for every spell. I just keep building out my library of WorldEffect types and Blueprint Interfaces, and the reactivity of the world grows organically.

The more spells I add, the more creative and weird the interactions can become—and since players can craft their own magic, I want the world to feel like it notices.

Also: this system will evolve. I’ve got plans for elemental combos, timeline-altering effects, and even world-state changes based on spells.

🧪 Want a Deep Dive?

I kept this post light, but if you want a deeper technical breakdown (with more code or use cases), let me know on Bluesky! Always happy to chat systems and nerd out about Unreal 💚

Thanks for reading! I’ll be sharing more dev logs like this soon, including footage from the demo build. Stay tuned.