I finally got around to placing the scripted driver into a network car.
This car can be driven either on the server, or on the client.
You will not be able to drive the car on the client without the server running, since it actually does nothing, but mimic the location and orientation of the car on the server. The client uses iObjectPositionReset to place a 3d Rad car, and not a skinmesh, just to make things a little more interesting
Compile both the server and the client projects, in order to test them properly. A project that runs in the editor "freeze" and will not be responsive if it loses mouse focus. Run the projects windowed, since you wont be able to see both client and server views if one of them is run in full screen (This may be an overstatement, but you never know what silly questions will pop of in this regard)
First start the server, and wait till it says "Server controlled car" at the bottom of the screen, indicating that the server is ready to accept client connections.
Next, start the client, and connect it to the server via the connection dialog.
Once both server and client are running, set focus to the server's window and drive the car. You will notice that the client mimics the server's car exactly.
Press the F2 key to change control to the client, and notice that you will not be able to drive the car from the server window, since it is actually expecting to be controlled from a client
Set focus to the client window, and drive the car from there. Notice that the wheels of the car on the client do not actually turn, yet the car actually turns. All that is happening is that the controls are sent to the server, and the real car is driven on the server with the scripted driver, and the position of the car is then updated to the client
I had a few headaches using iNetArrays from the client to the server, so instead send the control info via a string to the server, where it is parsed back into float values
These two projects should have enough information for anyone who wishes to develop network racing games, and should give the newbie a good place to start from, and show what kind of logic needs to be implemented
1.. Client input for control
2.. Send controls to server
3.. Receive conteols
4.. Control vehicle from remote input
5.. Get vehicle location and orientation
6.. Send car info to client
7.. Update client car from server info
Now perhaps we will start seeing some more real technical questions, from people who are really interested in making games, and are wiling to learn from the ground up .... and less of the "help - I don't know what to do" type.
SERVER
CLIENT
This car can be driven either on the server, or on the client.
You will not be able to drive the car on the client without the server running, since it actually does nothing, but mimic the location and orientation of the car on the server. The client uses iObjectPositionReset to place a 3d Rad car, and not a skinmesh, just to make things a little more interesting
Compile both the server and the client projects, in order to test them properly. A project that runs in the editor "freeze" and will not be responsive if it loses mouse focus. Run the projects windowed, since you wont be able to see both client and server views if one of them is run in full screen (This may be an overstatement, but you never know what silly questions will pop of in this regard)
First start the server, and wait till it says "Server controlled car" at the bottom of the screen, indicating that the server is ready to accept client connections.
Next, start the client, and connect it to the server via the connection dialog.
Once both server and client are running, set focus to the server's window and drive the car. You will notice that the client mimics the server's car exactly.
Press the F2 key to change control to the client, and notice that you will not be able to drive the car from the server window, since it is actually expecting to be controlled from a client
Set focus to the client window, and drive the car from there. Notice that the wheels of the car on the client do not actually turn, yet the car actually turns. All that is happening is that the controls are sent to the server, and the real car is driven on the server with the scripted driver, and the position of the car is then updated to the client
I had a few headaches using iNetArrays from the client to the server, so instead send the control info via a string to the server, where it is parsed back into float values
These two projects should have enough information for anyone who wishes to develop network racing games, and should give the newbie a good place to start from, and show what kind of logic needs to be implemented
1.. Client input for control
2.. Send controls to server
3.. Receive conteols
4.. Control vehicle from remote input
5.. Get vehicle location and orientation
6.. Send car info to client
7.. Update client car from server info
Now perhaps we will start seeing some more real technical questions, from people who are really interested in making games, and are wiling to learn from the ground up .... and less of the "help - I don't know what to do" type.
SERVER
Code: [Select]
int CAR = OBJ_0;
int PRINT = OBJ_22;
float steeringAngleDelta=0.02;
float steeringAngle=0;
float steeringResetTimer=0;
string S,STATE;
bool SERVERPLAYER = true;
bool SERVERACTIVE = false;
///-------------------------------------------------------------------------
//array = split(string-to-split, split-on-this-character
string[] split(string s, string c)
{
int p;
string[] strList();
int valve = 0;
bool done = false;
string s1,s2,s3;
int Idx = 0;
s3 = s;
strList.resize(0); //clear the array
while (!done)
{
valve++; if(valve == 1000) break; //while pressure valve
p = iStringFind(s3,c,0,false); //find splitter
if(p != -1)
{
iStringLeft(s1,s3,p-1); //get the 1st part
iStringRight(s2,s3,iStringLen(s3)-p); //get the second part
Idx = strList.length();
Idx++;
strList.resize(Idx); //increase list size
strList[Idx-1] = s1; //stort string part in array
s3 = s2;
}
else
{
if(iStringLen(s3) > 0) //tail piece of the string
{
Idx++;
strList.resize(Idx);
strList[Idx-1] = s3;
done = true;
}
}
}
return strList;
}
///-------------------------------------------------------------------------
void Main()
{
Quaternion orientation;
Vector3 location;
int len=0;
float acceleration;
string driveString;
string []msg();
if(iInitializing()){ //when script starts
if(!SERVERACTIVE){ //if the server is not active
SERVERACTIVE = iNetServerStart( //start server
"Network Driver Tester",//game name
"Test Server 00", //server name
2111, //game port
0, //game number
100000); //buffer length
}
}
if (iKeyDown(iKeyCode("DIK_F1"))) SERVERPLAYER = true;
if (iKeyDown(iKeyCode("DIK_F2"))) SERVERPLAYER = false;
//Server controlled car input
if(SERVERPLAYER){
STATE = "Server controlled car";
//Accelerate
OUT_1 = 0;
acceleration = 0;
if (iKeyDown(iKeyCode("DIK_UP"))){
OUT_1 = 1;
acceleration = 1;
}
if (iKeyDown(iKeyCode("DIK_DOWN"))){
OUT_1 = -1;
acceleration = -1;
}
//steering
steeringResetTimer++;
if(steeringResetTimer > 1){
steeringResetTimer = 0;
if(steeringAngle > 0) steeringAngle -= steeringAngleDelta*4;
if(steeringAngle < 0) steeringAngle += steeringAngleDelta*4;
}
if (iKeyDown(iKeyCode("DIK_LEFT"))){
steeringAngle += steeringAngleDelta;
if(steeringAngle > 1) steeringAngle = 1;
steeringResetTimer = 0;
}
if (iKeyDown(iKeyCode("DIK_RIGHT"))){
steeringAngle -= steeringAngleDelta;
if(steeringAngle < -1) steeringAngle = -1;
steeringResetTimer = 0;
}
OUT_0 = steeringAngle;
}
//Client controlled car
len = iNetStringReceive(driveString);
if(!SERVERPLAYER && SERVERACTIVE){
STATE = "Client controlled car";
if(len > 0){
msg = split(driveString,";");
acceleration = iStringVal(msg[0]);
steeringAngle = iStringVal(msg[1]);
OUT_1 = acceleration; //set car acceleration
OUT_0 = steeringAngle; //set car steering
}
}
if(SERVERACTIVE){
//Send car info to all connected players
iObjectLocation(CAR,location);
iObjectOrientation(CAR,orientation);
iNetFloatArraySet(0,1); //car ID, useful for multiple cars
iNetFloatArraySet(1,location.x); //car location values
iNetFloatArraySet(2,location.y);
iNetFloatArraySet(3,location.z);
iNetFloatArraySet(4,orientation.x);//car orientation values
iNetFloatArraySet(5,orientation.y);
iNetFloatArraySet(6,orientation.z);
iNetFloatArraySet(7,orientation.w);
iNetFloatArraySet(8,IN_2); //send steering angle as well
iNetFloatArraySendEx(0,9,0,false);
}
//Cleanup
if (iDeinitializing())
{
//De-activate the network
if (SERVERACTIVE)
{
iNetStop();
SERVERACTIVE = false;
}
}
iPrint("CLIENT: "+len+" "+driveString,-14,-9,PRINT);
iPrint(STATE,-14,-11,PRINT);
iPrint(S=acceleration+" "+steeringAngle,-14,-10,PRINT);
}
CLIENT
Code: [Select]
int CAR = OBJ_0;
int PRINT = OBJ_22;
float steeringAngleDelta=0.02;
float steeringAngle=0;
float steeringResetTimer=0;
string S;
bool CLIENTACTIVE = false;
///-------------------------------------------------------------------------
void Main()
{
int numFloats;
float steeringDegrees;
Quaternion orientation;
Vector3 location;
if(iInitializing()){
if(!CLIENTACTIVE){
CLIENTACTIVE = iNetClientStart(
"127.0.0.1:2111",
"client 01",
0, //game number
100000,
"Select Game",
-1, //select a game
30);
}
}
///Get car acceleration
float acceleration = 0;
if (iKeyDown(iKeyCode("DIK_UP"))){
acceleration = 1;
}
if (iKeyDown(iKeyCode("DIK_DOWN"))){
acceleration = -1;
}
///Get steering
steeringResetTimer++;
if(steeringResetTimer > 1){
steeringResetTimer = 0;
if(steeringAngle > 0) steeringAngle -= steeringAngleDelta*4;
if(steeringAngle < 0) steeringAngle += steeringAngleDelta*4;
}
if (iKeyDown(iKeyCode("DIK_LEFT"))){
steeringAngle += steeringAngleDelta;
if(steeringAngle > 1) steeringAngle = 1;
steeringResetTimer = 0;
}
if (iKeyDown(iKeyCode("DIK_RIGHT"))){
steeringAngle -= steeringAngleDelta;
if(steeringAngle < -1) steeringAngle = -1;
steeringResetTimer = 0;
}
///Update the car location and orientation from the server
if(CLIENTACTIVE){
numFloats = iNetFloatArrayReceive();
if(numFloats == 9){
//car ID (0) not used in this example
location.x = iNetFloatArrayGet(1);
location.y = iNetFloatArrayGet(2);
location.z = iNetFloatArrayGet(3);
orientation.x = iNetFloatArrayGet(4);
orientation.y = iNetFloatArrayGet(5);
orientation.z = iNetFloatArrayGet(6);
orientation.w = iNetFloatArrayGet(7);
steeringDegrees = iNetFloatArrayGet(8);
iObjectPositionReset(CAR,orientation,location);
}
}
///Send acceleration and steering info to the server
///Sending as a string, since inetArray screws up from a client
if(CLIENTACTIVE){
S = acceleration+";"+steeringAngle;
iNetStringSend(S,0,true);
}
///Cleanup
if(iDeinitializing()){
if(CLIENTACTIVE){
iNetStop();
}
}
iPrint(S=acceleration+" "+steeringAngle,-14,-10,PRINT);
}