No Entity synchronizing with Lite-C ?

Posted By: Henning

No Entity synchronizing with Lite-C ? - 12/07/07 01:26

After days of hard work I am close to confusion. I tried to set up a multiplayer
test with a red ball which is moved by the server (-cl -sv) and a blue box
moved by the client (-cl) just by the keys wsad.
All works fine, but the blue box is never moved by input from the client. I
even tried to convert the essential code lines from Locoweeds tutorial to
Lite-C; no success.
Either the skills (movement input) are not recieved by the server or the
movement function is not executed for the client object on the server. It
looks very much like the second option, I found no way to verify the first.

Has anyone an idea?

Here is the code:

// Simple Multiplayer
// 3D Gamestudio A7 Version 7.05 commercial

#include <acknex.h>
#include <default.c>

ENTITY* clPlayer;
ENTITY* svPlayer;

var isMove = 0;
var isInput = 0;
var showX = 0;
var showY = 0;

function moveMe () { // movement for both on server
while (1) {
my.x += my.skill1 * time_step;
my.y += my.skill2 * time_step;
ent_sendnow (me);

if (me == clPlayer) isMove++; // moveMe running for client? NO!
if (isMove > 999) isMove = 0; // remove 'if (me == clPlayer)' to see
wait (1); // that moveMe runs on server only
}
}

function getInput () { // wsad control on client and server separately
if (connection == 2) me = clPlayer;
if (connection == 3) me = svPlayer;

while (1) {
if (key_w == 1) my.skill1 = 5;
if (key_s == 1) my.skill1 = -5;
if (key_a == 1) my.skill2 = 5;
if (key_d == 1) my.skill2 = -5;
if (!key_any) {
my.skill1 = 0;
my.skill2 = 0;
}

if (connection == 2) send_skill (my.skill1, SEND_VEC|SEND_UNRELIABLE);

showX = my.skill1; // show input
showY = my.skill2; // show input
isInput++; // getInput running?
if (isInput > 999) isInput = 0;
wait (1);
}
}

////////////////////////////// main ///////////////////////////////////////
function main () {
level_load ("M.wmb"); // just a platform and a cylinder at +X for orientation
wait (-0.5);
vec_set(camera.x,vector(-200, 0 , 20));

while (connection == 0) wait (1);

if (connection == 2) { // client
clPlayer = ent_create ("BlueBox.mdl", vector (70, 30, 0), moveMe);
}

if (connection == 3) { // client / server
svPlayer = ent_create ("RedSphere.mdl", vector (70, -30, 0), moveMe);
}
wait (-0.5);

getInput();
}

PANEL* diag_pan = {
flags = VISIBLE;
digits (4,10,"Diagnostics",*,1,NULL);
digits (4,20,"connection =",*,1,NULL);
digits (80,20,3.0,*,1,connection);
digits (4,50,session_name,*,1,NULL);
digits (4,60,player_name,*,1,NULL);
digits (4,70,"Input :",*,1,NULL);
digits (80,70,3.0,*,1,isInput);
digits (4,80,"Move :",*,1,NULL);
digits (80,80,3.0,*,1,isMove);
digits (4,90,"Inp X :",*,1,NULL);
digits (80,90,3.0,*,1,showX);
digits (4,100,"Inp Y :",*,1,NULL);
digits (80,100,3.0,*,1,showY);
}
Posted By: fastlane69

Re: No Entity synchronizing with Lite-C ? - 12/07/07 16:30

Hi Henning,

Simple solution: you aren't sending the client skills at all.

Ent_sendnow is for updating the native 3dgs parameters like x, y, z, albedo, etc from server to client. So your intent is correct in that if my.x was changed, ent_sendnow would send the updated parameters. However, it will NOT force to send the skills on the client (or the server for that matter).

The problem therefore lies with your client. You need to do is make a specific send_skill call on the client so the server received the WASD instructions. Only then will my.x be updated and the ent_sendnow be sent.

A simple fix to your code therefore is:

{
if (key_w == 1)
{
my.skill1 = 5;
send_skill(my.skill1,0);
}

and replicate this throughout your WASD calls...
Posted By: Henning

Re: No Entity synchronizing with Lite-C ? - 12/08/07 12:24

Hello Fastlane69,

thank you for the quick answer, but unfortunately, the solution is not that
simple. I already had the line:

if (connection == 2) send_skill (my.skill1, SEND_VEC|SEND_UNRELIABLE);

in my getInput() function, maybe you did not see it. Just to be sure, I
implemented your change, but the problem is still the same. The purpose
of this line is to send skill1 and skill2 if getInput() is executed on the
client. Skill3 is sent, also, but it does not matter.

Therefore, the problem is still there.
Posted By: nfs42

Re: No Entity synchronizing with Lite-C ? - 12/08/07 15:59

i presume the my pointer isn't the one you expect.

Code:
ENTITY* entPlayer;

function getInput () { // wsad control on client and server separately

if (connection == 2) entPlayer = clPlayer;
if (connection == 3) entPlayer = svPlayer;

while (1) {
if (key_w == 1) entPlayer.skill1 = 5;
if (key_s == 1) entPlayer.skill1 = -5;
if (key_a == 1) entPlayer.skill2 = 5;
if (key_d == 1) entPlayer.skill2 = -5;
if (!key_any) {
entPlayer.skill1 = 0;
entPlayer.skill2 = 0;
}
}


Posted By: fastlane69

Re: No Entity synchronizing with Lite-C ? - 12/08/07 17:50

Oops, you're right... glossed right over that sorry.
Posted By: Henning

Re: No Entity synchronizing with Lite-C ? - 12/08/07 19:05

Hello Andreas,

I tried this at once, but, sorry, it does not work. Think this is a tough nut
to crack. Seems like the focal thing of multiplayer gaming is not done by
Lite-C as stated at the documentation:

"However, GameStudio makes this as easy as possible because the worst part of
it, the entity synchonizing and protocol handling, is already hardwired in the engine."

Or do I do something wrong?
Posted By: FBL

Re: No Entity synchronizing with Lite-C ? - 12/08/07 21:00

I think thre is a structural problem.

If you use ent_create() on the client then the fucntion is executed on the server!! Of course connection will be 3 then, not 2.

Inside this function use proc_local/proc_client to start another function on one or all clients.

edit: nervermind. mixed moveme and getinput up.
Posted By: FBL

Re: No Entity synchronizing with Lite-C ? - 12/08/07 21:10

Another one:

What version do you use? I remember a Lite-C bug with ent_create not starting function.
This has been fixed, but I'm not sure whether this was already included in the latest public beta.

Compare your version number to the bug list (link on bottom of this forum).

If you're using C-Script instead of Lite-C this bug does not show up.
Posted By: Henning

Re: No Entity synchronizing with Lite-C ? - 12/09/07 12:59

Hi Firoball,

I am using version 7.05, there are two relevant bugs at the bug list:
7.05 : Script functions and actions sent to the server or client in multiplayer mode didn't always make it due to a lite-C address bug (all lite-C and A7 versions; fixed in A7.06).
7.06 : Entity actions didn't start in compiled executables of lite-C multiplayer games under certain circumstances (all A7 versions; fixed in A7.07.0).
The last one is less probable, I do not compile to exe, just start two processes from SED (first -cl -sv, then -cl). I think, version 7.06 is beta, so I have no access to it, right?

I know that moveMe() is executed on the server for both entities, therefore I
use the entity name and not the connection variable there to discriminate for which entity the function is executed.
On the other hand, getInput() is not started by an entity, so I apply the proper entity using the connection variable there.

This I think is perfectly in line with the general philosophy to have an input function on each client seperately and a move function which is executed on the server for each client.
Nonetheless, I have implemented your change, erased the getInput() call at main
and wrote a proc_client() at moveMe(). At getInput() I do not need a
discrimination of entities any more, because it is called with an entity now
and running on the client.
See below:

function getInput () { // wsad control on client and server separately
while (1) {
if (key_w == 1) my.skill1 = 5;
if (key_s == 1) my.skill1 = -5;
if (key_a == 1) my.skill2 = 5;
if (key_d == 1) my.skill2 = -5;
if (!key_any) {
my.skill1 = 0;
my.skill2 = 0;
}

if (connection == 2) send_skill (my.skill1, SEND_VEC|SEND_UNRELIABLE);

showX = my.skill1; // show input
showY = my.skill2; // show input
isInput++; // getInput running?
if (isInput > 999) isInput = 0;
wait (1);
}
}

function moveMe () { // movement for both on server
wait (1); // have to wait 1 frame after entity creation
proc_client (me, getInput());
while (1) {
my.x += my.skill1 * time_step;
my.y += my.skill2 * time_step;
ent_sendnow (me);

isMove++;
if (isMove > 999) isMove = 0;
wait (1);
}
}

Result: Red ball on server is moved perfectly, but getInput() is never executed on the client. Tried some variations, also. Same result, red ball (server) moves on both processes, blue box never moves. With proc_local I get a runtime
crash on the client.

Sorry, problem persistent, still.
Posted By: nfs42

Re: No Entity synchronizing with Lite-C ? - 12/09/07 14:28

i don't know if you've seen it. you also have to change in getInput()

Code:
 if (connection == 2) send_skill entPlayer.skill1, SEND_VEC|SEND_UNRELIABLE);

showX = entPlayer.skill1; // show input
showY = entPlayer.skill2; // show input
isInput++; // getInput running?
if (isInput > 999) isInput = 0;
wait (1);
}



for timing issues i would put a
Code:
while(entPlayer==null){
if (connection==2)...
wait(1);}
}


at the start of getInput().
Posted By: Henning

Re: No Entity synchronizing with Lite-C ? - 12/09/07 17:52

Hi Andreas,

yes, I used entPlayer at the send_skill command.
I implemented your change, your proposed code now looks like this:

// Simple Multiplayer
// 3D Gamestudio A7 Version 7.05 commercial
// H.Berkelmann 2007

#include <acknex.h>
#include <default.c>

ENTITY* clPlayer;
ENTITY* svPlayer;
ENTITY* entPlayer;

var isMove = 0;
var isInput = 0;
var showX = 0;
var showY = 0;

function moveMe () { // movement for both on server
while (1) {
my.x += my.skill1 * time_step;
my.y += my.skill2 * time_step;
ent_sendnow (me);

isMove++;
if (isMove > 999) isMove = 0;
wait (1);
}
}

function getInput () { // wsad control on client and server separately
while (entPlayer == NULL) {
if (connection == 2) entPlayer = clPlayer;
if (connection == 3) entPlayer = svPlayer;
wait (1);
}

while (1) {
if (key_w == 1) entPlayer.skill1 = 5;
if (key_s == 1) entPlayer.skill1 = -5;
if (key_a == 1) entPlayer.skill2 = 5;
if (key_d == 1) entPlayer.skill2 = -5;
if (!key_any) {
entPlayer.skill1 = 0;
entPlayer.skill2 = 0;
}

if (connection == 2) send_skill (entPlayer.skill1, SEND_VEC|SEND_UNRELIABLE);
// send_skill (entPlayer.skill1, SEND_VEC|SEND_UNRELIABLE);

showX = entPlayer.skill1; // show input
showY = entPlayer.skill2; // show input
isInput++; // getInput running?
if (isInput > 999) isInput = 0;
wait (1);
}
}

////////////////////////////// main ///////////////////////////////////////
function main () {
level_load ("M.wmb"); // just a platform and a cylinder at +X for orientation
wait (-0.5);
vec_set(camera.x,vector(-200, 0 , 20));

while (connection == 0) wait (1);

if (connection == 2) { // client
clPlayer = ent_create ("BlueBox.mdl", vector (70, 30, 0), moveMe);
}

if (connection == 3) { // client / server
svPlayer = ent_create ("RedSphere.mdl", vector (70, -30, 0), moveMe);
}
wait (-0.5);

getInput();
}

PANEL* diag_pan = {
flags = VISIBLE;
digits (4,10,"Diagnostics",*,1,NULL);
digits (4,20,"connection =",*,1,NULL);
digits (80,20,3.0,*,1,connection);
digits (4,50,session_name,*,1,NULL);
digits (4,60,player_name,*,1,NULL);
digits (4,70,"Input :",*,1,NULL);
digits (80,70,3.0,*,1,isInput);
digits (4,80,"Move :",*,1,NULL);
digits (80,80,3.0,*,1,isMove);
digits (4,90,"Inp X :",*,1,NULL);
digits (80,90,3.0,*,1,showX);
digits (4,100,"Inp Y :",*,1,NULL);
digits (80,100,3.0,*,1,showY);
}

When I execute it, I can see at the diagnostics panel that moveMe()
and getInput() are running on the server, and getInput() on the client.
Both process the keyboard input. But - as you may expect - no change.
The red ball is moved on both by input on the server, the blue box does not
move at all.
I always try the variant with 'if (connection == 2) send_skill...' and
without the condition, because I am not sure here. Has no influence.
Posted By: FBL

Re: No Entity synchronizing with Lite-C ? - 12/09/07 18:08

Quote:

Hi Firoball,

I am using version 7.05, there are two relevant bugs at the bug list:
7.05 : Script functions and actions sent to the server or client in multiplayer mode didn't always make it due to a lite-C address bug (all lite-C and A7 versions; fixed in A7.06).





This might be the problem (I was the guy running into it).
Do something simple like changing the frame, or doing a printf() and see what happens.

Have you checked the annoucnements thread whether there is a newer public beta available?
Posted By: Henning

Re: No Entity synchronizing with Lite-C ? - 12/09/07 21:52

Hello Firoball,

I saw that A7.06 is available, will download and install it tomorrow
and try another test. If it is this problem, A7.06 should solve it.
Thank you very much for the tip. Stay tuned.
Posted By: Henning

Re: No Entity synchronizing with Lite-C ? - 12/10/07 19:56

SHOCK ... JOY ... DEEP SATISFACTION ...

It runs with A7.06!

Exactly as I have written it at the beginning of this thread!

Just remove the 'if (me == clPlayer)' before the isMove++; statement at the moveMe() function and you have a nice, little, crude multiplayer example without any clutter.

Thank you all so much, now there is a chance I can finish my first with Gamestudio during my Christmas holydays.

All the best and a nice Christmas time
Henning
© 2024 lite-C Forums