Well, that’s why I’m going to assume that since this has not yet answered, there is no “easy” solution baked in the loop of reacting events, although I would like to be mistaken in that. Until then, I decided that I would publish my decision.
Note. I have no idea what the consequences of this are. I have no idea how scalable it is. It has not been tested in a live environment with multiple processes and players.
I think this is a worthy solution. My particular game is focused on a player base, perhaps 20-30, so I think that the only problem that I can run into is that at that very moment empty lines fired.
To the code!
The first thing I did (some time ago) was to add a periodic timer at server startup:
public function __construct(React\EventLoop\LoopInterface $loop) { $update = new Update(); $update->doTick(); $loop->addPeriodicTimer(1, function() { $this->doBeat(); }); }
I also have some global variables in my "world" class:
// things in the world public $beats = 0; public $next_tick = 45; public $connecting = array(); public $players = array(); public $mobiles = array(); public $objects = array(); public $mobs_in_rooms = array(); public $mobs_in_areas = array(); public $in_combat = array( 'mobiles' => array(), 'players' => array() ); public $process_queue;
Note also removes process_queue .
My doBeat () function looks like this:
public function doBeat() { global $world; ++$world->beats; foreach($world->process_queue as $trigger_beat => $process_array) {
Now, on my global “World” object, I have a couple of other functions:
function addToProcessQueue($process_obj) {
Now, to add the process to the queue, here is my new mobile onSay () command:
function onSay($string) { global $world; $trigger_words = array( 'hi', 'hello', 'greetings' ); $triggered = false; foreach($trigger_words as $trigger_word) { if(stristr($string, $trigger_word)) { $triggered = true; } } if($triggered) { $process_array = array( 'trigger_beat' => $world->beats + 2, 'function' => 'toRoom', 'class' => 'PlayerInterface', 'params' => array($this->mobile->in_room, $this->mobile->short . " says '`kOh, hello!``'") ); $world->createProcessObject($process_array); } }
So, if a mobile phone hears “hello”, “hello” or “greetings”, the “toRoom” function (which sends a line to each character in the same room) will be added to the process queue and will work 2 seconds from the moment the original function was executed .
I hope this all makes sense, and if anyone knows how best to do this in php and inside the event loop, please reply / comment. I do not consider this “right”, as I said above, I do not know how effective it is in production.