2 registered members (AndrewAMD, juanex),
1,247
guests, and 6
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
let the server do the work
#333593
07/17/10 13:27
07/17/10 13:27
|
Joined: Jan 2007
Posts: 1,619 Germany
Scorpion
OP
Serious User
|
OP
Serious User
Joined: Jan 2007
Posts: 1,619
Germany
|
hello everyone, I just tried to put my hands on the gamestudio multiplayer engine again. The last time I did that, I ended up nearly exclusively using send_data - only to get something in the direction of client side prediction working. But now I found the new 3rd value for dplay_smooth, which stops the engine predicting the players movement. So I wrote a small code, that lets you control a player with your keyboard. The only problem is, that I give the client too much power by letting him choose the position he wants to spawn. Whats the best way to avoid that? The greatest problem I see is that you can only use some handy functions like proc_client and everything that is related to checking where the entity belongs to, when you executed that ent_create on a client - what I think is a no go... How should I rewrite my code to conform with these conditions? Thank you Scorpion Here's the code I hacked together:
#define rand_area(x) vector(x-2*random(x),x-2*random(x),x-2*random(x))
#define KEYS skill1
#define SPEED skill2
#define ASPEED skill3
#define KEY_FORWARD (1<<0)
#define KEY_BACKWARD (1<<1)
#define KEY_LEFT (1<<2)
#define KEY_RIGHT (1<<3)
#define KEY_SHOOT (1<<4)
#define k(x) sign(my.KEYS & (x)) //is key pressed?
//movement code for player - executed on server and client
void player_move(){
var dirX = k(KEY_FORWARD) - k(KEY_BACKWARD);
DEBUG_VAR(dirX, 30);
var dirY = k(KEY_LEFT) - k(KEY_RIGHT);
my.pan += accelerate(my.ASPEED, dirY*10, 0.7);
c_move(me, vector(accelerate(my.SPEED, dirX*10, 0.7), 0, 0), nullvector, IGNORE_PASSABLE);
}
//player action on client
void player_main_client(){
while(1){
//store keys in skill
my.KEYS = key_w *KEY_FORWARD
| key_s *KEY_BACKWARD
| key_a *KEY_LEFT
| key_d *KEY_RIGHT
| mouse_left *KEY_SHOOT;
send_skill(my.KEYS, SEND_VEC|SEND_UNRELIABLE);
player_move();
//adapt camera to new position
vec_set(camera.x, my.x);
vec_set(camera.pan, my.pan);
wait(1);
}
}
//player action on server
action player_main(){
proc_client(me, player_main_client);
while(1){
player_move();
wait(1);
}
}
int main(){
dplay_smooth = 3;//client side player-entity is not updated
while(1){
if(key_1){//server
if(!session_open("ilovecake")){
sys_exit("Couldn't create session!");
}
level_load(NULL);
break;
}
if(key_2){//client
session_connect("ilovecake", "127.0.0.1");
while(!connection) wait(1);
level_load(NULL);
randomize();
player = ent_create(SPHERE_MDL, vec_add(rand_area(50),vector(0,0,50)), player_main);
break;
}
wait(1);
}
return 0;
}
Last edited by Scorpion; 07/17/10 13:35. Reason: changed code to not require external resources for purpose of easy testing
|
|
|
Re: let the server do the work
[Re: Scorpion]
#333614
07/17/10 17:52
07/17/10 17:52
|
Joined: Dec 2008
Posts: 1,218 Germany
Rackscha
Serious User
|
Serious User
Joined: Dec 2008
Posts: 1,218
Germany
|
For the spawn problem:
Send a request from the client to the server. The server then sends back a new position.(send_skillto , as far as i know is possible to?!)
GReets Rackscha
Last edited by Rackscha; 07/17/10 17:52.
MY Website with news of my projects: (for example my current Muliplayer Bomberman, GenesisPrecompiler for LiteC and TileMaster, an easy to use Tile editor) Sparetime-Development
|
|
|
Re: let the server do the work
[Re: Rackscha]
#333634
07/17/10 19:41
07/17/10 19:41
|
Joined: Nov 2002
Posts: 913 Berlin, Germany
SchokoKeks
User
|
User
Joined: Nov 2002
Posts: 913
Berlin, Germany
|
Not sure if i unterstood you right rackscha, but I wouldn't call this a secure solution. a hacked client could still ignore this skill (or variable) and place his player anywhere he wants.
I know 2 solutions: 1. Let the client place the entity somewhere outside of the level or at the nullvector. Let the server then place the entity at the right position, and use ent_sendnow to update the client. However, you'd have to detach the camera from the player as long as it is not inside the level and waiting for its new position.
2. use ent_create only on the server. you can't use proc_local and such then. The multiplayer plugins (gstnet and anet) don't rely on who the entity created. The native system is limited there.
Additionally, you have to make sure that the clients can only send their input to the server, and not their absolute position. Always let the server's view of the game be the one you transfer.
EDIT: it looks like you're already doing that. Sorry, I can't help you with the code, don't have much time currently..
Last edited by SchokoKeks; 07/17/10 19:42.
|
|
|
Re: let the server do the work
[Re: fastlane69]
#333660
07/18/10 03:58
07/18/10 03:58
|
Joined: Mar 2003
Posts: 5,377 USofA
fastlane69
Senior Expert
|
Senior Expert
Joined: Mar 2003
Posts: 5,377
USofA
|
Second problem: choose one: movement code for player - executed on server and client You either have the server be responsible for movement and rely results to the client or you can have the client do their own movements and then update the server with the results. You can use either depending on your application, but not both at the same time.
|
|
|
Re: let the server do the work
[Re: Scorpion]
#333676
07/18/10 10:44
07/18/10 10:44
|
Joined: Nov 2002
Posts: 913 Berlin, Germany
SchokoKeks
User
|
User
Joined: Nov 2002
Posts: 913
Berlin, Germany
|
@fastlane69 When using branching with 'connection', how can I identify the client, who controls the entity - he needs different code than the other clients ofc. For that, I use the following "branch": Just make sure that the player pointer is set, and you know that this client can controll the entity. There is another problem in your code that can lead to lagging or jittering over the internet:
send_skill(my.KEYS, SEND_VEC|SEND_UNRELIABLE);
This sends the 3 skills every frame, something you may never do. use a code like this to send the skill only when it has changed:
if (my.KEYS != my.OLD_KEYS) {my.OLD_KEY = my.KEYS; send_skill(my.KEYS, SEND_UNRELIABLE);
I also removed the SEND_VEC, cause you don't need to send the SPEED and ASPEED skills in this example. And there is another thing you should do: the server now receives the my.KEYS for the players. It should now send it to all clients (SEND_ALL) and they should also c_move the entity for smooth movement. the server will still send the absolute positions of the entitys every x frames (can be controlled with dplay_entrate). In my game survive, i was able to set dplay_entrate to 2 ( 8 updates per second) and it was still working very smooth. Also, set dplay_smooth to 0, because the build in smoothing algorithm doesn't work well in many cases.
|
|
|
Re: let the server do the work
[Re: Spirit]
#333684
07/18/10 13:14
07/18/10 13:14
|
Joined: Jan 2007
Posts: 1,619 Germany
Scorpion
OP
Serious User
|
OP
Serious User
Joined: Jan 2007
Posts: 1,619
Germany
|
Thank you, that helped. Well, I just forget to delete the SEND_VEC - I first did that with position and then left it in... I think it will be better to resend the keys every frame in unreliable mode, so that it can account for packet loss and won't hurt players with low bandwidth Maybe you're right in relinquishing the gs movement prediction, I will try those changes and come back with the results
|
|
|
|