Most efficient way of communication between "unfamiliar" actors?

Title could look vague, so here’s what I actually mean.

Three groups of people are walking in the city. These are Guards, Thieves and Citizens.
Something has happened in the city, Thief have stolen a pocket from a Citizen, the Guard walking around was close enough to see the crime, so now he’s chasing Thief.

So here’s the question, how that chain work in blueprint perspective?
We can imagine there is a some kind of StateCheckingActor placed in the world. When Thief steals a pocket, it’s blueprint (or Citizen’s blueprint) would broadcast a message to the StateCheckingActor. After StateCheckingActor is aware of crime it would broadcast message to the Guards walking around making them aware of crime.

Well, broadcasting stuff doesn’t look complex, that could be a simple event dispatcher. But how would Thieves, Citizens and Guards hold a reference to StateCheckingActor? And what StateCheckingActor should even look like? Should it be an actor placed somewhere in the level? Should other actors access it when spawned with GetAllActorsOfClass(StateCheckingActor)?

The issue looks pretty similar to GTA where events are broadcaster to nearby police cars when crime is happening, but what would make a broadcast?

The obvious solution in this particular case would be using collision boxes, so when robbery is happening in Guard’s trigger box (eyesight) it would be triggered to chase thief.

But that’s not what is really interesting me. What bothers me is storing the fact of robbery somewhere. The information stored in some kind of object could be used later to add new dialogue branches, quests and something else.

I use GameState to store that kind of global info.

Here’s how I’d set it up.

For your StateCheckingActor, I’d actually use a Game Instance. You can add one of these by going to ‘Add New / Blueprint / expand All Classes and select GameInstance.’

Next, you’d need to set up a Blueprint Interface, which can be added by going to 'Add New / Blueprint / Blueprint Interface.

You’ll need to create two functions in here. One, here, I named ‘SoS Call’ that sends the crime scene’s location as well as a reference to the victim’s character.

You’ll need a second function, here, that I named ‘Dispatch Officer,’ as well, that tells the officer where to go.

Next, you need to send a SoS call to your Game Instance blueprint whenever a crime occurs. This will be called from your Character (citizen)'s blueprint. Here, I have added a screenshot demonstrating a SoS Message to the Game Instance blueprint whenever the citizen is being mugged or robbed. Also, make sure under your Class Settings you select to implement your Blueprint Interface. Here, I named mine CharacterToGameInstance. If you don’t, you won’t be able to find and add your node for sending a SoS Message.

You then receive the message in your Game Instance blueprint. Here, I named mine G_Instance. Again, under class settings, ensure you have implemented the blueprint interface. I also use ‘GetAllActorsOfClass’ in this blueprint to go through each officer in the entire map and determine if any are close enough to respond. If so, I send that officer a message using the other Blueprint Interface function, ‘Dispatch Officer.’

If you wanted to send other data as well it’d just be a case of adding additional variables into the functions in your Blueprint Interface to send. You could also change how you’re checking whether you want an officer to respond, and that’d be adding more to the Game Instance blueprint’s check when it gets a SoS Message event.

Your StateCheckingActor is actually the Game Instance blueprint here.

Also, if you wanted to store the robberies, I’d recommend creating an array in the Game Instance blueprint, sending the type of robbery as a message, perhaps even part of the SoS Call as another variable like Crime Type, and book keeping it all in here.

Thank you for such detailed and constructive answer, Predatoria!
I would try this setup out. Looks like Game Instance is kind of object I needed all the time.
There are way too much actors around the level so using GetAllActorsOfClass could be pretty slow. I would assign game instance to all guards as well and call them for action with an interface maybe.