Gamestudio Links
Zorro Links
Newest Posts
Zorro Trader GPT
by TipmyPip. 04/27/24 13:50
Trading Journey
by 7th_zorro. 04/27/24 04:42
Help with plotting multiple ZigZag
by M_D. 04/26/24 20:03
Data from CSV not parsed correctly
by jcl. 04/26/24 11:18
M1 Oversampling
by jcl. 04/26/24 11:12
Why Zorro supports up to 72 cores?
by jcl. 04/26/24 11:09
Eigenwerbung
by jcl. 04/26/24 11:08
MT5 bridge not working on MT5 v. 5 build 4160
by EternallyCurious. 04/25/24 20:49
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
2 registered members (AndrewAMD, TipmyPip), 747 guests, and 4 spiders.
Key: Admin, Global Mod, Mod
Newest Members
wandaluciaia, Mega_Rod, EternallyCurious, howardR, 11honza11
19049 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
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 Offline OP
Serious User
Scorpion  Offline 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:
Code:
#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 Offline
Serious User
Rackscha  Offline
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
S
SchokoKeks Offline
User
SchokoKeks  Offline
User
S

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: Scorpion] #333658
07/18/10 03:56
07/18/10 03:56
Joined: Mar 2003
Posts: 5,377
USofA
fastlane69 Offline
Senior Expert
fastlane69  Offline
Senior Expert

Joined: Mar 2003
Posts: 5,377
USofA
If you use the appropriate "if(connection == 1,2,3)" switches, then the entity will have only one action defined for yet it will be executed one way on the client and another on the server. This way when the server creates the client, everyone acts the way they should without proc'ing a thing.

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 Offline
Senior Expert
fastlane69  Offline
Senior Expert

Joined: Mar 2003
Posts: 5,377
USofA
Second problem:

choose one:

Quote:
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: fastlane69] #333674
07/18/10 10:29
07/18/10 10:29
Joined: Jan 2007
Posts: 1,619
Germany
Scorpion Offline OP
Serious User
Scorpion  Offline OP
Serious User

Joined: Jan 2007
Posts: 1,619
Germany
@rackscha SchokoKeks is right there. That wouldn't make a difference...

@SchokoKeks The repositioning is probably a great way to do that. I will look into those methods.

@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.

to my code: it should be like this (If it really does what I want is another thing - maybe you can tell?):

the client gets the players input and moves it on the client, then sends the keys at the same time to the server and there the same movement (not exactly - different time_step...) is done. The server sends the new position and rotation to all the clients, but the owner of the player. (There is the need to synchronize the clients position with the servers one, but first I have to get the absolute basics right)

BUT I just tried the code with a friend over the internet and it's jittering like hell, because somehow the server still corrects the position and rotation of the player. Can you please help me getting such a basic thing to work?

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
S
SchokoKeks Offline
User
SchokoKeks  Offline
User
S

Joined: Nov 2002
Posts: 913
Berlin, Germany
Originally Posted By: Scorpion
@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":
Code:
if (me == player) ...


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:
Code:
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:
Code:
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: SchokoKeks] #333678
07/18/10 11:17
07/18/10 11:17
Joined: Sep 2003
Posts: 929
Spirit Offline

Moderator
Spirit  Offline

Moderator

Joined: Sep 2003
Posts: 929
Quote:
if (my.KEYS != my.OLD_KEYS) {my.OLD_KEY = my.KEYS; send_skill(my.KEYS, SEND_UNRELIABLE);

You should send reliable in that case, because its sent only once.

When you send something every frame you can send it unreliable, but when its a single event like hitting a key, it should be sent reliable.

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 Offline OP
Serious User
Scorpion  Offline 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 laugh


Moderated by  HeelX, Spirit 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1