I'm creating a web based snail simulation using PHP (I know.) with Laravel. I am using HTML5 canvas/JS to render moving snails on jar and snail profile pages. MySQL is used for the db. Each snail has several senses that are determined by its training/treatment and genetics, dictating how well it can smell, see, feel, etc other objects within its jar. So, I need to store x and y positions for each object in the jar (snails, consumables, decoration, etc), which will then be used when each snail's "brain" processes incoming data (does the snail see this object that's a certain distance away? Does it smell the object? Does it perceive it at all with any of the senses? Once an object is perceived I will get stuff like how much attention the snail dedicates to the object, whether it has any short or long term memories of it, etc (basically decide if the snail reacts and how). (This is a very long term hobby project, so I realize that it's overly ambitious and I don't care )
However, I'm not sure how to approach the first step of this - I'm not quite sure what the best way to set snail position is. Currently I set a position within the jar at random whenever a snail hatches from its egg (posX and posY, based in part on jar capacity). From there, when I view the profile page of the jar that snail is in, the snail is spawned in that position. It then chooses a direction to crawl in at random and crawls in that direction based on its currentSpeed attribute. When it hits the edge of the jar it just turns back around. All of this, after getting the first spawn position of the snail, is random and purely client-side JS. Nothing is stored back in the DB just yet.
Here's what it looks like (each snail here is is moving toward the edge of the canvas, where it will flip around):
Right now I'm trying to find the best approach to take when making movement that actually persists, and not just random back and forth on the client. Snails move and perform actions even when nobody is watching them, so I know I will need to run a recurring job on the server at regular intervals for this. Things I'm unsure about are:
- How to make this scalable to support movement (and then decision-making) calculations for potentially thousands of snails. I guess I should run this job at staggered intervals and not have one giant job for all the snails in the world, but is that really enough to totally mitigate potential performance problems caused by this? I already run recurring jobs for things like snail growth, ageing, and energy depletion. I am fully aware that it's highly unlikely anybody will actually use this simulation or that I'll ever have thousands of (living) snails in the world, but I still want to make it scalable for my peace of mind.
- How best to have the HTML5/JS rendered version of the snails on the client see and follow the actions on the server in real time. I guess I'll need to project some sort of targetPosition from server to client and then have the client draw the snail crawling toward that point? Or would it be better to have a target direction? Or maybe do it an entirely different way :S
- How best to send some actions from the client back to the server in real time (like dragging an item or snail while in jar-view, thereby repositioning that object in the db).
I suppose I'll have to use something like Ratchet (or in this case maybe Latchet), but I'm in general looking for any examples or high level advice on how to approach this sort of thing best - the actual implementation I can then sort out on my own. I just want to have a solid plan for how to structure this before I dig in and could use some advice/starting point suggestions for how a system like this should work.
Thanks in advance for any advice/suggestions!