Easy to Reproduce Lag Issue (FPS RTS hybrid)
by Vijay Myneni · in RTS Starter Kit · 11/28/2004 (9:39 pm) · 92 replies
Okay, this might not actually be an issue, but it's driving me crazy. Hopefully, someone can try this out and let me know if I'm just seeing things. It's fairly quick to set up and try. This post also doubles as a good set of instructions for the basics of getting the FPS player into your RTS game (I want to ultimately make this a resource combined with instructions for setting up clean switching between RTS and FPS control).
1. Start with a clean RTS Engine build, and a clean starter.RTS project. Also have a starter.fps directory around to grab files from.
2. Grab the server/scripts/player.cs file from starter.fps and copy it to server/scripts/avatars/fpsPlayer.cs in starter.RTS.
3. Grab the data/shapes/player directory from starter.fps and copy it to data/shapes/fpsPlayer in starter.RTS.
4. In server/scripts/avatars/fpsPlayer.cs, change the very first exec line to point to your new data directory:
6. Repeat step 5 in your server/scripts/core/game.cs file. My understanding is that the exec's should happen in the same order in both these files. I have mine happening right after player.cs gets exec'd. Also, I had to ultimately add a line for scripts/fx/environment.cs into my game.cs, so that it matched up with init.cs. If I don't do this, the game crashes during datablock transfer.
7. In server/scripts/core/gameConnection.cs, replace the existing onClientEnterGame with this:
8. Also in gameConnection.cs, add the following function:
Continued...
1. Start with a clean RTS Engine build, and a clean starter.RTS project. Also have a starter.fps directory around to grab files from.
2. Grab the server/scripts/player.cs file from starter.fps and copy it to server/scripts/avatars/fpsPlayer.cs in starter.RTS.
3. Grab the data/shapes/player directory from starter.fps and copy it to data/shapes/fpsPlayer in starter.RTS.
4. In server/scripts/avatars/fpsPlayer.cs, change the very first exec line to point to your new data directory:
exec("~/data/shapes/fpsPlayer/player.cs");5. In server/init.cs, add a line to exec your new fpsPlayer.cs script: exec("./scripts/avatars/fpsPlayer.cs");. 6. Repeat step 5 in your server/scripts/core/game.cs file. My understanding is that the exec's should happen in the same order in both these files. I have mine happening right after player.cs gets exec'd. Also, I had to ultimately add a line for scripts/fx/environment.cs into my game.cs, so that it matched up with init.cs. If I don't do this, the game crashes during datablock transfer.
7. In server/scripts/core/gameConnection.cs, replace the existing onClientEnterGame with this:
function GameConnection::onClientEnterGame(%this)
{
commandToClient(%this, 'SyncClock', $Sim::Time - $Game::StartTime);
%clientIndex = %this.getClientIndex();
%this.setTeam(%clientIndex);
%offset = ((%this.getTeam()-1) * (%unitsPerDir + 5));
// Create a new camera object.
%this.camera = new Camera() {
dataBlock = Observer;
};
MissionCleanup.add( %this.camera );
%this.camera.scopeToClient(%this);
// Setup game parameters, the onConnect method currently starts
// everyone with a 0 score.
%this.score = 0;
// Create a player object.
%this.createFPSPlayer((%offset*5) SPC (%offset*5) SPC "250");
}8. Also in gameConnection.cs, add the following function:
function GameConnection::createFPSPlayer(%this, %spawnPoint)
{
if (%this.player > 0) {
// The client should not have a player currently
// assigned. Assigning a new one could result in
// a player ghost.
error( "Attempting to create an angus ghost!" );
}
// Create the player object
%player = new Player() {
dataBlock = PlayerBody;
client = %this;
};
MissionCleanup.add(%player);
// Player setup...
%player.setTransform(%spawnPoint);
%player.setShapeName(%this.name);
// Starting equipment
%player.setInventory(Crossbow,1);
%player.setInventory(CrossbowAmmo,10);
%player.mountImage(CrossbowImage,0);
// Update the camera to start with the player
%this.camera.setTransform(%player.getEyeTransform());
// Give the client control of the player
%this.player = %player;
%this.setControlObject(%player);
}Continued...
About the author
#2
I haven't yet checked to see if the RTS SK by itself has the appropriate engine code for the fully functional GameConnection, but I would suggest that you take a look at that and see if anything becomes obvious.
NOTE: This is an edjamacated guess (and at a middle school level), not a "real" answer--just kind of brainstorming along with you.
11/29/2004 (4:20 am)
My gut instinct is that you are trying to force too much through your lean and mean RTSConnection, while the starter.fps uses the big and fat (but much more applicable for fps-style play) GameConnection.I haven't yet checked to see if the RTS SK by itself has the appropriate engine code for the fully functional GameConnection, but I would suggest that you take a look at that and see if anything becomes obvious.
NOTE: This is an edjamacated guess (and at a middle school level), not a "real" answer--just kind of brainstorming along with you.
#3
11/29/2004 (4:45 am)
I agree with Stephen, you will have to really get into the code and create a custom connection and player to create the game you are imaging. The RTS enviroment, puts a lot of the game logic in the client that would have been a big no no for the standard FPS games. Only other way would be to fake FPS by putting the camera at the player position but retaining RTS style interaction.
#4
Still think it's what you need to look at.
11/29/2004 (5:05 am)
Well, I do know that the GameConnection is viable in the SK, I just don't know how much of it has changed and/or been overloaded for the performance tweaks. Both Ben and I think Josh have mentioned that it shouldn't be too difficult to re-implement GameConnection as primary controlling connection for a subset of players, but that was off the cuff--not tested as far as I am aware.Still think it's what you need to look at.
#5
Furthermore, I did a diff on the entire engine code directory, and you can count the number of changes to non-RTS files on your fingers (which is great, in my opinion). There was absolutely no change to gameconnection.cc, one change to gameconnectionevents.cc (added an assert), a few changes to gameprocess.cc (to deal with vismanager) and no changes to any other files which I consider relevant. The rest of the changes are in files like explosion.cc and audioemitter.cc. I've been through them all, and none of them see relevant.
I've debugged to the point where I can confirm that my RTSConnection is not using any of its RTS functionality (because I have no RTSUnits). None of the code in RTSConnection is getting called. It's all getting passed up to the GameConnection parent.
I must have missed something, for the behaviour to be different. But I have no idea what. Maybe at this point, the solution is for me to go back to the FPS engine, and slowly add in RTS functionality.
11/29/2004 (10:50 am)
Well, that's what confuses me. In effect, by using a Player instead of an RTSUnit, and by using a Camera instead of an RTSCamera, I thought I had effectively turned this back into a GameConnection. My reasoning was that an RTSConnection is basically a GameConnection, with a few extra methods (to send RTSMove and RTSAttack events, and to deal with visibility). The methods getting overridden by RTSConnection are the constructor, onAdd, onRemove, and onDisconnect. And all of those just do extra visManager or team-related stuff and then call the GameConnection versions.Furthermore, I did a diff on the entire engine code directory, and you can count the number of changes to non-RTS files on your fingers (which is great, in my opinion). There was absolutely no change to gameconnection.cc, one change to gameconnectionevents.cc (added an assert), a few changes to gameprocess.cc (to deal with vismanager) and no changes to any other files which I consider relevant. The rest of the changes are in files like explosion.cc and audioemitter.cc. I've been through them all, and none of them see relevant.
I've debugged to the point where I can confirm that my RTSConnection is not using any of its RTS functionality (because I have no RTSUnits). None of the code in RTSConnection is getting called. It's all getting passed up to the GameConnection parent.
I must have missed something, for the behaviour to be different. But I have no idea what. Maybe at this point, the solution is for me to go back to the FPS engine, and slowly add in RTS functionality.
#6
11/29/2004 (10:55 am)
@Anthony, you say that the RTS environment puts a lot of game logic in the client. By this, you mean all the stuff going on in RTSUnits and RTSCameras and RTSProjectiles right? If I'm using a regular Player class and a regular Camera class, shouldn't these behave the same way as they do in an FPS environment? Assuming I am correct in my analysis that an RTSConnection is the same as a GameConnection for all intents and purposes if you're using it with non-RTS objects.
#7
Your logic/troubleshooting however does seem to imply otherwise, and it looks like you did a pretty complete job, so I don't know what to say for sure.
Unfortunately, this task isn't on our plate for quite a while for my project, so I'm not going to be able to help out much in further troubleshooting, at least not enough to meet your timeline, but I'll try to get back to you as soon as we get it working (or not, it seems like you're doing a damn good job trying), with any info we find out.
Maybe as an experiment you can search the client side scripts for "new RTSConnection", change them to GameConnection, and see what happens?
@Josh/Ben/GG: Did any of you experiment with this during kit development, and/or do you notice anything obvious he's missing?
11/29/2004 (11:00 am)
I agree with everything except for the fact that when you create the connection, you create an RTSConnection, not a GameConnection (client side). The server actually initially treats it as a GameConnection when synching up files and such, but it "auto-converts" to an RTSConnection in about the middle of that process (I had to debug this like crazy when importing the RTS SK into our project).Your logic/troubleshooting however does seem to imply otherwise, and it looks like you did a pretty complete job, so I don't know what to say for sure.
Unfortunately, this task isn't on our plate for quite a while for my project, so I'm not going to be able to help out much in further troubleshooting, at least not enough to meet your timeline, but I'll try to get back to you as soon as we get it working (or not, it seems like you're doing a damn good job trying), with any info we find out.
Maybe as an experiment you can search the client side scripts for "new RTSConnection", change them to GameConnection, and see what happens?
@Josh/Ben/GG: Did any of you experiment with this during kit development, and/or do you notice anything obvious he's missing?
#8
Now I"m looking through the .cs scripts to see if anything there could be affecting it, like maybe a pref or default or something. Not seeing much at the moment though.
11/29/2004 (11:42 am)
@Stephen Thanks for your help thus far. What I'm basically trying to say is that even if it's an RTSConnection, as far as I can tell from the code it, should behave exactly like a GameConnection the way I'm using it (no RTS Units, no RTSCamera, no RTSMove events, etc...). I'll keep working on it, and hopefully get it resolved by the time you need to deal with it. It's soooo close. :)Now I"m looking through the .cs scripts to see if anything there could be affecting it, like maybe a pref or default or something. Not seeing much at the moment though.
#9
11/29/2004 (11:44 am)
Yeah, I understand what you're saying, and it does make sense. I also remember however someone implying that you would want separate connection types for separate player types--I could have misread it of course!
#10
12/23/2004 (3:58 am)
Looks like a good thread for me to keep an eye on, working on a FPS/RTS hybrid game and will hopefully be starting this kind of thing soon, depends how much xmas/new year slows me down! ;)
#11
12/23/2004 (11:20 am)
Follow up to this, in case anyone's monitoring. I ended up going back to the FPS engine, and pulled in the RTS stuff I needed. That seemed to fix my problems. I never could figure out why I was seeing more lag using the RTS engine with an FPS player.
#12
12/23/2004 (6:16 pm)
Just out of curiosity, what exactly did you pull, Vijay? Did any of it give you problems? Did any of it work without a hitch? Any advice to someone considering doing the same?
#13
Was there any complications with having an rts player and an fps player withing the same game.
Ive yet to fully delve into how to merge it all into our codebase but if someone has already done the same i would love to learn about any potential hitches that can occur.
12/23/2004 (6:53 pm)
I too would like to know more. Perhaps even a resource on the projectWas there any complications with having an rts player and an fps player withing the same game.
Ive yet to fully delve into how to merge it all into our codebase but if someone has already done the same i would love to learn about any potential hitches that can occur.
#14
1. Mouse selection (with rubberband selection box). This went without a hitch, from what I remember.
2. Parts of the RTSCamera (see other posts for a detailed discussion of this)
3. Building construction, including the pre-place marker (although my buildings are derived from the Player class, instead of the RTSPlayer class. Implementing that change was very simple).
4. Using the GuiRTSTSCtrl class (love that name). This was the easiest way to get the mouse-hits-the-side-of-the-canvas-to-pan action going, as well as mouse selection. Also using most of the RTS versions of the GUI, including the selection display window and the canvas.
So not that much yet. I'm actually not using RTS units at all. I don't need the streamlined networking, and it wouldn't really work that well for my game anyways. I also don't need the Visibility Manager.
None of it was terribly hard to accomplish. Just a lot of searching around to figure out which files I needed to draw code from.
@Ian, although I don't really have an RTS player and an FPS player within the same game (I have been changing everything to work with regular FPS players), I don't see that there would be any complications.
One big difference between the two types of players is that RTS players don't use "moves". Their whole processTick is overridden to just follow the events you have asked them to follow. So if you do have both kinds of players in the game, it might be hard to make one unit do both different kinds of movement.
At some point, I'm going to be putting some RTSUnits into the game, at which point I'll be doing more hardcore merging. I'll let you guys know if I run into any serious problems.
A great way to start is to do a windiff (or whatever) between the two projects. You'll see that most of the changes are in the files in the RTS directory, which makes it easy to see what's different. On the scripting side, it's a little trickier. I did end up spending some time hunting around trying to figure out where the relevant script code was to implement the selection box, for example. But at least this proves it's possible.
I'm not using the RTSConnection class. The only .cc files I added to my project whole were GuiRTSTSCtrl and RTSBuilding.
I can go into detail on any of these if someone is having a hard time getting it to work.
12/23/2004 (7:52 pm)
So this is the stuff I have pulled into the FPS engine so far:1. Mouse selection (with rubberband selection box). This went without a hitch, from what I remember.
2. Parts of the RTSCamera (see other posts for a detailed discussion of this)
3. Building construction, including the pre-place marker (although my buildings are derived from the Player class, instead of the RTSPlayer class. Implementing that change was very simple).
4. Using the GuiRTSTSCtrl class (love that name). This was the easiest way to get the mouse-hits-the-side-of-the-canvas-to-pan action going, as well as mouse selection. Also using most of the RTS versions of the GUI, including the selection display window and the canvas.
So not that much yet. I'm actually not using RTS units at all. I don't need the streamlined networking, and it wouldn't really work that well for my game anyways. I also don't need the Visibility Manager.
None of it was terribly hard to accomplish. Just a lot of searching around to figure out which files I needed to draw code from.
@Ian, although I don't really have an RTS player and an FPS player within the same game (I have been changing everything to work with regular FPS players), I don't see that there would be any complications.
One big difference between the two types of players is that RTS players don't use "moves". Their whole processTick is overridden to just follow the events you have asked them to follow. So if you do have both kinds of players in the game, it might be hard to make one unit do both different kinds of movement.
At some point, I'm going to be putting some RTSUnits into the game, at which point I'll be doing more hardcore merging. I'll let you guys know if I run into any serious problems.
A great way to start is to do a windiff (or whatever) between the two projects. You'll see that most of the changes are in the files in the RTS directory, which makes it easy to see what's different. On the scripting side, it's a little trickier. I did end up spending some time hunting around trying to figure out where the relevant script code was to implement the selection box, for example. But at least this proves it's possible.
I'm not using the RTSConnection class. The only .cc files I added to my project whole were GuiRTSTSCtrl and RTSBuilding.
I can go into detail on any of these if someone is having a hard time getting it to work.
#15
As for what im trying to achieve.
I too am not interested in rts units (at this stage) indeed it probably will work the same way your trying to achieve.
One player seeing the view like the commander and everyone else in fps view.
My ultimate goal will be to allow the commander to select and give orders to actual fps players. Orders would just appear as waypoints though. So no forced movement or attacking e.t.c. Just visual markers.
Eventually adding placeable objects e.t.c down the line but for now nothing that extreme.
Ill do a windiff over the weekend and hopefully dont get too many problems :)
12/23/2004 (7:58 pm)
Thanks for the writeup vijay. would love to chat to you more about your project e.t.c. email me at iroach@westnet.com.au if your interested.As for what im trying to achieve.
I too am not interested in rts units (at this stage) indeed it probably will work the same way your trying to achieve.
One player seeing the view like the commander and everyone else in fps view.
My ultimate goal will be to allow the commander to select and give orders to actual fps players. Orders would just appear as waypoints though. So no forced movement or attacking e.t.c. Just visual markers.
Eventually adding placeable objects e.t.c down the line but for now nothing that extreme.
Ill do a windiff over the weekend and hopefully dont get too many problems :)
#16
12/24/2004 (2:05 am)
Lol Ian, my project sounds very similar to yours :)
#17
Our project is between milestones at the moment while we evaluate what we need for our next one, and this is something that we'll be looking for as well down the road, so I'm going to spend a few hours today going over the overview design for your concept, and throw out some ideas on how to pass the orders along to the players as given by the commander.
I think that the underlying tech part of getting the FPS players working alongside the RTS players is really a topic in and of itself, and I don't have quite as much insight into that yet (I don't know exactly how we want to implement it yet in our project), so I'm going to leave that part alone for now!
12/24/2004 (2:16 am)
Heh..as does ours in one form or another!Our project is between milestones at the moment while we evaluate what we need for our next one, and this is something that we'll be looking for as well down the road, so I'm going to spend a few hours today going over the overview design for your concept, and throw out some ideas on how to pass the orders along to the players as given by the commander.
I think that the underlying tech part of getting the FPS players working alongside the RTS players is really a topic in and of itself, and I don't have quite as much insight into that yet (I don't know exactly how we want to implement it yet in our project), so I'm going to leave that part alone for now!
#18
And heh, all our projects are going to sound somewhat similar guys we're working with a FPS codebase modified to run some RTS type game, it almost goes without saying that just about anyone here is going to be working on a hybrid of some sort or another. >;>
12/24/2004 (7:39 am)
Thanks for the info, Vijay. Maybe I'll try my hand at it this weekend. See what I can break ;)And heh, all our projects are going to sound somewhat similar guys we're working with a FPS codebase modified to run some RTS type game, it almost goes without saying that just about anyone here is going to be working on a hybrid of some sort or another. >;>
#19
I'd like to add my request for more detail on exactly how to go about adding RTS features into Torque 1.3 FPS. Specifically, the mouse selection, RTS navigation and RTS Camera . I know this is asking a lot.
Thanks,
John
12/25/2004 (9:36 pm)
Vijay, I'd like to add my request for more detail on exactly how to go about adding RTS features into Torque 1.3 FPS. Specifically, the mouse selection, RTS navigation and RTS Camera . I know this is asking a lot.
Thanks,
John
#20
@Ian, ya, our game sounds similar too.
@John:
1. as far as mouse selection goes and RTS navigation, you will need to:
a. bring over GuiRTSTSCtrl.cc into your project and use that instead of TSCtrl.
b. I also brought over most of playGui.cs (to get the selectionDisplay). At the very least, bring over the GuiRTSTSCtrl part of it.
c. bring over selection.cs and inputHandler.cs and ring_white.png (i think that's what it's called)
d. change inputHandler.cs to work with Player objects and not just RTSUnits, if that's what you need (just find all instances of "RTSUnit" and add in handling for Players)
e. bring over the changes from terrSelection.cc and terrRender.cc/h and terrData.cc/h
f. turn the mouse cursor on if it isn't already
That should do it, unless I'm forgetting something.
For the RTSCamera, you may be able to just bring over RTSCamera.cc/h and use that instead of the default Observer camera. But i suspect you would have to also switch your game connection to an RTSConnection to keep the networking parts of it working. I never actually did this, because I built a new camera from scratch. If you just use the RTSCamera client-side and take out all the network-related calls, it will work with the regular gameConnection.
12/28/2004 (8:19 am)
Sorry all, been away for a while. @Ian, ya, our game sounds similar too.
@John:
1. as far as mouse selection goes and RTS navigation, you will need to:
a. bring over GuiRTSTSCtrl.cc into your project and use that instead of TSCtrl.
b. I also brought over most of playGui.cs (to get the selectionDisplay). At the very least, bring over the GuiRTSTSCtrl part of it.
c. bring over selection.cs and inputHandler.cs and ring_white.png (i think that's what it's called)
d. change inputHandler.cs to work with Player objects and not just RTSUnits, if that's what you need (just find all instances of "RTSUnit" and add in handling for Players)
e. bring over the changes from terrSelection.cc and terrRender.cc/h and terrData.cc/h
f. turn the mouse cursor on if it isn't already
That should do it, unless I'm forgetting something.
For the RTSCamera, you may be able to just bring over RTSCamera.cc/h and use that instead of the default Observer camera. But i suspect you would have to also switch your game connection to an RTSConnection to keep the networking parts of it working. I never actually did this, because I built a new camera from scratch. If you just use the RTSCamera client-side and take out all the network-related calls, it will work with the regular gameConnection.
Torque Owner Vijay Myneni
Now for the test. If you run the game now you'll start up in control of the FPS orc, and you can run him around using the arrow keys (although you won't be able to rotate him or look around). It should work fine in a combined client/server game.
But, if you launch up a separate server and then a separate client and join the server's game and try running around, you'll notice that it is a little jumpy. Watch the terrain closely as you run around, and you'll see it jump back and forth somewhat frequently. This doesn't seem like a big deal in this view, but it is very noticeable from a 3rd person view (which is what I've got in my real project).
If you think you can't see the jumpiness, do the same thing with starter.fps and the old fps build of the engine. Run a game with a split client/server. Run around that same orc and it is so much smoother. Virtually perfect even. That's what I want to be able to get with my orc in RTS mode, and for the life of me I can't understand why it's not as smooth.
Please help! Thanks,
Vijay