Hi fellows!

While helping Darkinfermo, I noticed that an example for serverside movement could be useful for you.

How it works:
The client that created the entity, sends its control input to the server. The server does the movement (you can also use the physic engine here) and sends the new position (if changed) in skill[1]-skill[3] to all the other participants. The position is sent after the time set up in update_rate has passed. The clients interpolate for a smooth movement.

The code:

Code:
#define update_rate 0.1 //time in seconds that passes between the updates

function control_player();

function move_player()
{
	var save_pan = 0; //stores the entity.pan (needed to find out if the pan has changed)
	VECTOR save_pos; //stores the entity.pos (needed to find out if the position has changed)
	
	while(enet_ent_globpointer(my) == -1) {wait(1);} //wait until the entity gets a global pointer
	
	//If the entity was created by this client, control it:
	if(enet_ent_creator(enet_ent_globpointer(my)) == enet_get_clientid())
	{control_player();}
	
	//The Server or ClientServer moves the entity:
	if(enet_get_connection() == SERVER_MODE || enet_get_connection() == CLIENT_SERVER_MODE)
	{
		var update_time = update_rate; //time that has to pass until an update must be sent
		
		//If you are using the physicengine, set up the physic parameters here
		
		while(1)
		{
			//Ge the sent control input:
			var forward_key = my.skill[0]&0x00000001; //get bit1
			var backward_key = (my.skill[0]&0x00000002)>>1; //get bit2
			var left_key = (my.skill[0]&0x00000004)>>2; //get bit3
			var right_key = (my.skill[0]&0x00000008)>>3; //get bit4
			
			//Do the entitymovement here
			
			//sends the position if changed and an update is needed:
			if((save_pos.x != my.x || save_pos.y != my.y || save_pos.z != my.z) && update_time <= 0)
			{
				my.skill[1] = my.x;
				my.skill[2] = my.y;
				my.skill[3] = my.z;
				enet_send_skills(enet_ent_globpointer(my),1,3,BROADCAST);
				vec_set(save_pos,my.x);
				update_time = update_rate;
			}
			//sends the angles if they changed
			if(save_pan != my.pan) {enet_send_angle(enet_ent_globpointer(my),BROADCAST);save_pan = my.pan;}

			update_time -= time_step/16.0; //reduce the time
			wait(1);
		}
	}
	else
	{ //On all participants except the server or server-client:
		VECTOR new_pos;
		VECTOR old_pos;
		var time_passed = 0;
		
		new_pos.x = 0;
		new_pos.y = 0;
		new_pos.z = 0;
		
		//wait for the first data to arrive
		while(new_pos.x == my.skill[1] && new_pos.y == my.skill[2] && new_pos.z == my.skill[3]) {wait(1);}
		while(1)
		{
			//If a new position was sent, use the new position as destination for the interpolation
			if(new_pos.x != my.skill[1] || new_pos.y != my.skill[2] || new_pos.z != my.skill[3])
			{vec_set(new_pos.x,my.skill[1]);vec_set(old_pos.x,my.x);time_passed = 0;}
			
			//Interpolate between the current and the last received position
			time_passed += time_step/16.0;
			var factor = time_passed/(update_rate+0.1); //using a little higher update_rate for interpolation makes it look smoother
			if(time_passed/(update_rate+0.1) > 1) {factor = 1;} //Stops interpolating after the destination position was reached
			vec_lerp(my.x,old_pos.x,new_pos.x,factor); //interpolate
			
			wait(1);
		}
	}

}

function control_player()
{
	var oldskill0;
	
	if(enet_get_connection() == CLIENT_SERVER_MODE) proc_mode = PROC_LATE;
	
	while(1)
	{
		//Do the camera movement here:
		vec_set(camera.x,my.x);
		
		my.skill[0] = 0;
		my.skill[0] |= key_pressed(key_for_str("w")); //forward key in bit0
		my.skill[0] |= key_pressed(key_for_str("s"))<<1; //backward key in bit1
		my.skill[0] |= key_pressed(key_for_str("a"))<<2; //left key in bit2
		my.skill[0] |= key_pressed(key_for_str("d"))<<3; //right key in bit3
		
		//Sends the skill if it has changed to the Server:
		if(my.skill[0] != oldskill0 && enet_get_connection() != CLIENT_SERVER_MODE)
		{
			enet_send_skills(enet_ent_globpointer(my),0,0,SERVER);
			oldskill0 = my.skill[0];
		}
		wait(1);
	}
}



How to use this snippet:
- If you are new to ANet, download the free ANet version from my site and read you through the first HowTo (in the manual) and the Simple3DChat tutorial (on the hp)
- When you create an entity using enet_ent_create(), pass move_player as functionname
- The client that called enet_ent_create() controls the entity.
- The movementcode is completly missing in this snippet. You will have to add your own movement code where the comment tells you (No worry, this is a normal movement code that isn't different to code than in singleplayer)

What is missing:
This code sends the pan every frame if it has been changed. It also could use the update_rate and a clientside interpolation. Sadly I currently have no time to do that.

Request:
It would be cool if somebody who has experience with ANet finds time to improve this code (adding pan inerpolation for example) or/and to create a whole small example (maybe using the physicengine for the movement). I would also upload this example in the third party section of my downloadsite (if you want).

Have fun!




ANet - A stable and secure network plugin with multi-zone, unlimited players, voip, server-list features,... (for A7/A8)!
get free version