1 registered members (AbrahamR),
717
guests, and 4
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Re: POPULACE or 3DGS?
[Re: East_Coast_Games]
#104817
01/15/07 15:20
01/15/07 15:20
|
Joined: Nov 2000
Posts: 1,534 hamburg
Samb
Serious User
|
Serious User
Joined: Nov 2000
Posts: 1,534
hamburg
|
hi east coast games team two things first: when a player creates a multiplayerentity the game of the player lags for 1/8 oder 1/4 seconds. is there a way to avoid that lag? second: the game runs faster after someone connects to the game... why? btw. I tested the plugin successful over the internet. only the MPcreate command is really slow.
|
|
|
Re: POPULACE or 3DGS?
[Re: Samb]
#104818
01/15/07 17:07
01/15/07 17:07
|
Joined: Jun 2006
Posts: 2,640 Earth
Germanunkol
Expert
|
Expert
Joined: Jun 2006
Posts: 2,640
Earth
|
Same problem here. It's really annoying when I create two entities for lasers... every time I shoot it lags for that amount of time. I was gonna try it on a faster machine first before asking, but if others have the same problem, I guess it's not simply cause my computer's too slow. The dll seems to work nice and fast, as long as I don't create MP entities. But as soon as I do, it lags for about a quarter of a second. Should we create an entity using ent_create and then somehow register it after creation... or can that be done only to WED ents... ? Is there a way to make it create faster?
~"I never let school interfere with my education"~ -Mark Twain
|
|
|
Re: POPULACE or 3DGS?
[Re: ecg_dev_dude]
#104820
01/16/07 14:26
01/16/07 14:26
|
Joined: Jun 2006
Posts: 2,640 Earth
Germanunkol
Expert
|
Expert
Joined: Jun 2006
Posts: 2,640
Earth
|
Hmm, that sounds good. it'll work for all the upgrades we'll have for our spaceships. The main problem I'm having though is with laying mines, shooting rockets and lasers. I'd have to have a whole bunch of laser entities... and could only reuse them once they've hit something. Maybe for the laser entities I could just move them on one machine only, but the problem remains with the rockets, which will be visible. The good news is that the player will run out of rockets at some point, meaning that I could just create those once he buys them, and have them sitting somewhere passable and invisible. Same would work for the mines. Thanks, in case no one finds something else, this should work... Micha
~"I never let school interfere with my education"~ -Mark Twain
|
|
|
Re: POPULACE or 3DGS?
[Re: Germanunkol]
#104821
01/16/07 19:33
01/16/07 19:33
|
Joined: Nov 2000
Posts: 1,534 hamburg
Samb
Serious User
|
Serious User
Joined: Nov 2000
Posts: 1,534
hamburg
|
for my game (bomberman clon) I solved the problem by creating the entities local with ent_create. this runs on the player who creates a bomb: pentity.skill91=bomb_pos.x; // skill91-93 are tracked pentity.skill92=bomb_pos.y; pentity.skill93=bomb_pos.z; pentity.flag1=on; // also tracked. temp_ent = ent_create("bombe.mdl", bomb_pos,null); // creates the entity local temp_ent.passable=on; and set in on the player clientside passable while(key_a==1){wait(1);} // wait until a-button is off pentity.flag1=off; // send to all player that flag1 is really off. else populace wont send the a new flag1=on. and here is the code for all other players: while(1) { if(my.flag1) { temp.x=my.skill91; // get the position. why? it could be that the players position is on the "other client side" a little bit "slower". so the bomb would be not at the same position as it was created on the player-side... god, my english is terrible today.. and always temp.y=my.skill92; temp.z=my.skill93; ent_create("bombe.mdl", temp,null); // now create the bomb my.flag1=off; // and flagged off } wait(1); } this works for small games but not for rpgs or anything else. oh, and we REALLY need a command to check the ping of a player. so we can kick a slow player automatically.
|
|
|
Re: POPULACE or 3DGS?
[Re: Samb]
#104822
01/19/07 20:36
01/19/07 20:36
|
Joined: Jun 2006
Posts: 2,640 Earth
Germanunkol
Expert
|
Expert
Joined: Jun 2006
Posts: 2,640
Earth
|
My problem is: My rockets need to move. I would need to have an action assigned to them, and their pos etc need to be sent to the dummy on all other player's computers. With your method, I believe I could only get them to sit there. Help? Also, I don't quite get who runs the actions in your example. The player? or someone else??
~"I never let school interfere with my education"~ -Mark Twain
|
|
|
Re: POPULACE or 3DGS?
[Re: Germanunkol]
#104823
01/20/07 05:02
01/20/07 05:02
|
Joined: Oct 2002
Posts: 2,256 Oz
Locoweed
Expert
|
Expert
Joined: Oct 2002
Posts: 2,256
Oz
|
Hi,
Instead of using MP_EntityCreate() for rockets, lasers, etc. because there is a slight lag with that function(especially noticeable in combat), I use the the MP_SendChatMessage() for these types of entities and effects, which is very effective.
The steps to do this are as follows:
1) On the computer that is firing the weapon: a) Create the projectile like you would in single player with ent_create(). b) Encode a string with information about the projectile: start position, pan, etc. c) Send this string to all Players.
2) Once all the other machines receive this string: a) Decode the string and extract the information from it. b) Use ent_create() on those machines to create a local version of it on those machines.
Sounds a bit weird, but works very well. MP_SendChatMessage() is very fast over the net. I spend countless hours testing to figure this stuff out with online test, so take my word for it please. Although someone, someday will find a better method because they didn't listen to me.
Here is an example of this method which is very effient for you to deceifer if you want. Lets say we are shooting a projectile from a spaceship.
------------------------------------------------------------------------------
string strCommand = [256]; string strCommand1 = [256]; string strCommand2 = [256]; string strTemp = [256];
// command values for local projectiles var cmdRecID; var cmdRecPos[3]; var cmdRecPan[3];
action SpaceShip { while(1) { . . // Key d flag? Shoot weapon if(my.INPUT_FLAGS & fKeyD) { my.INPUT_FLAGS -= fKeyD; // create projectile in front of ship vec_for_angle(temp,my.pan); vec_scale(temp,(my.max_X+35)); // create missile 35 quants in front of ship vec_add(temp,my.x); // create projectile locally you = ent_create(mdlTorpedo,temp,ProjectileFunction); vec_set(you.pan,my.pan); you.peer_id = player_id; // send a command string to create projectile on all other peers/clients EncodeString(strCommand); // encode creation info into a string MP_SendChatMessage(strCommand, "ProjectileLocal", MP_ALL_PLAYERS, 0); // send this string to all peers to create // projectile locally on them } . . wait(1); }
// This function sets team and peer_id // it tracks peer_id & team long enough for them to be set // and then stops tracking them function SetTeamPeerID(pEnt) { my = pEnt; //make sure to track the peer_id MP_TrackSkill(my, MPUC_SKILL_39); //team MP_TrackSkill(my, MPUC_SKILL_42); //peer sleep(1); if(my) { MP_IgnoreSkill(my, MPUC_SKILL_39); //team MP_IgnoreSkill(my, MPUC_SKILL_42); //peer } }
//-------------------------------------------------------------------- // CREATE PLAYER - create player at random location // Ran Locally //-------------------------------------------------------------------- function CreatePlayer() { var temp1[3]; temp1.x =-1000 + random(2000); temp1.y =-1000 + random(2000); temp1.z = 0; // Host? if(player_team == 1) { player = MP_EntityCreate(mdlJFT, vector(temp1.x,temp1.y,temp1.z), "SpaceShip", ""); } else // Client? { player = MP_EntityCreate(mdlFighter, vector(temp1.x,temp1.y,temp1.z), "SpaceShip", ""); } // track pan, tilt, roll, health on peer that created entity over network // set peer_id & team on peer that created entity over network // track pan, tilt and roll MP_TrackField(player, MPUC_PAN); MP_TrackField(player, MPUC_TILT); MP_TrackField(player, MPUC_ROLL); //make sure to track the health MP_TrackSkill(player, MPUC_SKILL_1); //health
player.peer_id = player_id; player.team = player_team; SetTeamPeerID(player);// set team and peer_id for ship }
// ProjectileEvent function // Runs locally on each peer/client function ProjectileEvent() { // projectile hit a entity in level if(event_type == event_entity) { // only do damage to hit entity on the peer that created it // the peer that created the entity handles transmitting changes // to that entities skills to the other players, so to keep absolute // control of damage on all machines, we only want to do // damage on the machine that created the entity if(you.peer_id == player_id) { you.HEALTH -= my.HEALTH; } my.HEALTH = 0; } // projectile hit level geometry if (event_type == event_block) { my.HEALTH = 0; } }
// ProjectileFunction function // Runs locally on each Peer/Client function ProjectileFunction() { var distance; // set events my.enable_entity = ON; my.enable_block = ON; my.event = ProjectileEvent;
// set poly collision stuff c_setminmax(my); my.narrow = on; my.fat = on; my.polygon = on; my.FORCE_X = 100*time; // set speed of projectile my.RANGE = WEAPON_RANGE; my.push = -1; my.passable = on; // passable until a certain distance from emntity that created it my.health = int(random(30))+20; // set random damage of projectile
wait(1); // wait until pan set // while haven't hit something and range not reached while(my.HEALTH && distance<my.Range) { distance += c_move(my,my.FORCE_X, nullvector, ignore_passable); // make sure not in ship - not really necessary if projectile creation correct, but left in for reference if(distance > 10) { my.passable = off; } wait(1); } // hit something instead of reached range limit, so do explosion if(my.health <= 0) { effect(effect_explosion,50,my.X,normal.x); // do explosion effect locally } wait(1); // let effect start ent_remove(my); // remove pprojectile }
// This function recieves string to decode to create local projectile function ProjectileLocal(strCommand, playerId, teamId) { if ( playerId == player_id || playerId == MP_ALL_PLAYERS) { DecodeString(strCommand); } }
// This function encodes Projectile creation information into a command string function EncodeString(strCommand) { str_cpy(strCommand,""); // clear command string
// encode owner id str_for_num(strTemp,player_id); str_cat(strTemp,","); str_cat(strCommand, strTemp); // encode position str_for_num(strTemp,temp.x); str_cat(strTemp,","); str_cat(strCommand, strTemp); str_for_num(strTemp,temp.y); str_cat(strTemp,","); str_cat(strCommand, strTemp); str_for_num(strTemp,temp.z); str_cat(strTemp,","); str_cat(strCommand, strTemp); // encode pan, tilt, roll str_for_num(strTemp,my.pan); str_cat(strTemp,","); str_cat(strCommand, strTemp); str_for_num(strTemp,my.tilt); str_cat(strTemp,","); str_cat(strCommand, strTemp); str_for_num(strTemp,my.roll); str_cat(strTemp,","); str_cat(strCommand, strTemp); }
// This function decodes Projectile information from a string // and then creates this projectile locally on client/peer function DecodeString(strCommand) { var str_pos; var str_size; var clip_num; str_cpy(strCommand1, strCommand); // Get owner_id for this Projectile str_cpy(strTemp,strCommand1); str_pos = str_stri(strTemp,","); str_size = str_len(strTemp); clip_num = str_size - str_pos + 1; str_trunc(strTemp,clip_num); cmdRecID = str_to_num(strTemp); str_clip(strCommand1,str_pos); // Get position for this Projectile str_cpy(strTemp,strCommand1); str_pos = str_stri(strTemp,","); str_size = str_len(strTemp); clip_num = str_size - str_pos + 1; str_trunc(strTemp,clip_num); cmdRecPos.x = str_to_num(strTemp); str_clip(strCommand1,str_pos);
str_cpy(strTemp,strCommand1); str_pos = str_stri(strTemp,","); str_size = str_len(strTemp); clip_num = str_size - str_pos + 1; str_trunc(strTemp,clip_num); cmdRecPos.y = str_to_num(strTemp); str_clip(strCommand1,str_pos);
str_cpy(strTemp,strCommand1); str_pos = str_stri(strTemp,","); str_size = str_len(strTemp); clip_num = str_size - str_pos + 1; str_trunc(strTemp,clip_num); cmdRecPos.z = str_to_num(strTemp); str_clip(strCommand1,str_pos);
// Get pan, tilt, roll for this Projectile str_cpy(strTemp,strCommand1); str_pos = str_stri(strTemp,","); str_size = str_len(strTemp); clip_num = str_size - str_pos + 1; str_trunc(strTemp,clip_num); cmdRecPan.pan = str_to_num(strTemp); str_clip(strCommand1,str_pos);
str_cpy(strTemp,strCommand1); str_pos = str_stri(strTemp,","); str_size = str_len(strTemp); clip_num = str_size - str_pos + 1; str_trunc(strTemp,clip_num); cmdRecPan.tilt = str_to_num(strTemp); str_clip(strCommand1,str_pos);
str_cpy(strTemp,strCommand1); str_pos = str_stri(strTemp,","); str_size = str_len(strTemp); clip_num = str_size - str_pos + 1; str_trunc(strTemp,clip_num); cmdRecPan.roll = str_to_num(strTemp); str_clip(strCommand1,str_pos); // Create this projectile locally on all clients/peers based on decode string you = ent_create(mdlTorpedo,cmdRecPos,ProjectileFunction); vec_set(you.pan,cmdRecPan); you.peer_id = cmdRecID; }
------------------------------------------------------------------------
Hopes that helps some atleast.
This method is very effient like I said before. In the game I am working on there are missiles, bullets, laser effects, explosions, etc going on all over the place with no lag at all. My encoded strings and decoded string are much more complex than those shown though, I usually include in the strings the projectiles type (rocket, bullet, etc) and then take all the information and create the correct type of entity for that projectile.
Sometimes you have to think a bit outside of the box to get optimal performance with any networking code.
At some point when we get a beta out on a game using a hybrid of Populace done, I will put out some real tutorials, but it will probably be a while unfortuantely.
Loco
Professional A8.30 Spoils of War - East Coast Games
|
|
|
Re: POPULACE or 3DGS?
[Re: Locoweed]
#104824
01/20/07 06:24
01/20/07 06:24
|
Joined: Oct 2002
Posts: 2,256 Oz
Locoweed
Expert
|
Expert
Joined: Oct 2002
Posts: 2,256
Oz
|
One more note here.
If you have purchased Populace and I can verify, I can get you the full SpaceHate (simple PvP space game code) example source to look at.
Unfortunately, you will have to change the dll names in code and stuff, but other then that it should be fine I think.
Let me know if you want to see the complete source of that example which uses the MP_SendChatMessage() technique for projectiles and I will see what I can do. Basically, when I first was trying to figure out how the networking worked, this was my test project. It's nothing special, but it is the foundation of where I am at now, which is a pretty sweet place as far as multiplayer with 3DGS goes.
If you are interested in doing some minor leg work to test the code with the actual Populace dll PM me or respond here and I will get in contact with you asap. (The reason I need some help with the code is that I can't install Populace because it screws up the Hybrid version of it, I will fix this soon so I can use both, but right now I don't have time to be messing around with that.)
Actually Germanunkol, PM me. I want to work with you since I can see you really want to figure out how this all works. After we figure we get the procedure down for the Populace DLL I am sure James, aka, East_Coast_Games, will get the working example up at the ecgames forum for other Populace users.
Thanks, Loco
Professional A8.30 Spoils of War - East Coast Games
|
|
|
Re: POPULACE or 3DGS?
[Re: Locoweed]
#104825
01/21/07 10:48
01/21/07 10:48
|
Joined: Jun 2006
Posts: 2,640 Earth
Germanunkol
Expert
|
Expert
Joined: Jun 2006
Posts: 2,640
Earth
|
I'm starting to understand more and more about this. Thanks you so much for that code! I'm going through it atm and changing my code to work the same way. One thing I'm not sure about:
function ProjectileLocal(strCommand, playerId, teamId) { if ( playerId == player_id || playerId == MP_ALL_PLAYERS) { DecodeString(strCommand); } }
Does passing MP_ALL_PLAYERS to MP_SendChatMessage include the player that is executing the command? Because that would mean that the projectile is created on the sending machine twice. And if it's not the case, then why the line "PlayerId == player_id" ? Because that will never be true. And if it is the case, then you DON'T want the if statement to be true, because otherwise it will go on creating the projectile using the decoded message, even though it already created it on the machine before sending the message, and you end up having the projectile twice on one machine??
Micha
~"I never let school interfere with my education"~ -Mark Twain
|
|
|
|