Alright bit of an update, feel free to skip all of this, if you aren't interested in technical design or discussion.
I've spent a good chunk of the day today, thinking about the various movement issues, and really the whole client synchronization issue in general. I even took a look at how some other titles handle this like Battle Academy, but was sad to find that they seem to let the client be authoritative, and within a few minutes I was able to cheat in online MP. Which is certainly not what I want for M.I.N.T
So I ended up writing out a couple pages in the ever growing M.I.N.T technical design notebook (Seriously I'm up to like 16 or 20 pages of tech stuff now, which blows my mind a bit.), and came to a a solution ultimately.
1. When a unit is moving, the unit will stop its movement if it sights a new enemy, or if it comes under fire during movement. The general plan at the moment is to have an Action Point pool, and if you want to move, you spend an action point and this fills a movement pool up with X level of points, based upon the units move rate. Your then free to spend those movement points whenever, or add more by spending more AP. So in the above scenario you might attempt to move 6 tiles, which we will say is going to cost 6 movement points for example sake, but on the 3rd tile moved to, a new enemy came into view. As such your movement stopped, and you only are down 3 movement points instead of the full 6. You also now can react to this new information however you deem.
What I really like about this, is it empowers the player, and speeds up turns. Smart players that are being careful would normally just move one tile at a time creeping to where they want to go. Now no one needs to do this, and its built in.
2. Now we have the problem of client/server synchronization. The solution I've decided upon as I talked about slightly before, is to switch to a command queue based client model. So what does this mean? Lets look at a simple example:
Client A: Sends a packet to the server requesting to move to destination x/y
Server validates if the move request is valid, if so it begins running the simulation on the server side. This means it generates the path on the server, and moves the unit along it tile by tile. Each tile moved it subtracts a movement pool point, and does things like check if new enemy units are visible, or reaction fire is occurring. Lets say this results in something like Move North, Move West, Move NorthWest, New Unit spotted, at which point the simulation is suppose to stop.
Now thats all fine, but we have the issue now of how to send back to the client all of this information, and make sure the client is synchronized so that they don't for instance draw the new unit spotted, before moving all 3 steps, there is also the issue that so far the client has no idea how many instructions it should be expecting from the server. So it might start immediately moving upon receiving the first Move North instruction, and then think its done.. as the following additional instructions got delayed for some reason.
Enter the command queue. With this flow, things are the same on the server side more or less, accept for every packet/instruction we would normally send, we instead add it to a command queue type container. Only once all of the simulation has been processed the command queue on the server is processed, and the first packet/instruction generated, is an instruction for the client to create a new instruction queue, that will contain X instructions/packets.
Now the client side when issuing a request, can simply enter a waiting for response state, it will receive the new "create command queue" instruction, and continue to wait until X additional instructions/packets are received and entered into the command queue. At which point its simply a matter of popping off each command which is really a packet from the queue, and handling it. We now have perfect synchronization.
We further are also able to mark packets if they are command packets, or not. This way something like a chat message is marked as a non-command packet, and is immediately handled and displayed, even when waiting for additional commands to arrive to finish a pending queue.
The trickest bit of all of this is really just handling the data that also goes to other players. You don't want to share that Client A's unit Y is moving to here and there, etc. Unless that unit is visible, or will become visible to a unit owned by that other player. Not doing this, allows for the creation of cheats like radar, or simply ignoring visibility and LOS and always drawing enemy units, even when you can't see them. Its vitally important to only send exactly the information a given client needs to know about something in order to prevent cheats.
Anyways that was probably to long, and I don't know if these long technical dumps really are of that much interest to anyone either
I should probably start to actually implement all of this now.