VisManager Discussion
by Thomas Huehn · in RTS Starter Kit · 04/24/2008 (4:00 am) · 7 replies
While I'am working on an other project some time i take a look at the rts kit ;)
For me the worst part of the kit is the visManager which does not really work
in multiplayer enviroment.
Problem: As long as your unit not move it cant see the oponents, no matter how close they are.
Patch applied but not fix it: http://www.garagegames.com/mg/forums/result.thread.php?qt=23701
Edit: but this fix is a requirement to get it work ;)
I'am still figure out whats going on there so maybe I missunderstood some parts so correct me please if iam wrong :
1.) gFogOfWarIsOn Test
First I set gFogOfWarIsOn to false to test if I can see all units. But then the oponent units were completly invisible.
1.1) At VisManager::onConnectionSet (on server ?) all units are add to the mVisibleUnits in RTSConnection - but there is no method to transfer this information to the client ?! This cause the clients stay blind.
1.2) VisManager::processServer is skipped if gFogOfWarIsOn==false but the server mVisibleUnits is senseless anyway if I'am right in 1.1.
1.3) VisManager::processClient() is also skipped but this function seams to be the key to make them visible.
So i made a test hack to set all visible:
And hurray while its not a nice hack I can see the units now!
------------------------------------------
Conclusion:
Currently the server side mVisibleUnits is senseless, because the informations are not send to the clients. The clients know about all units in game there is no ghosting. On the one hand the serverinformation could be transfered to the clients or only the client handles the visibility of all units.
For me the worst part of the kit is the visManager which does not really work
in multiplayer enviroment.
Problem: As long as your unit not move it cant see the oponents, no matter how close they are.
Patch applied but not fix it: http://www.garagegames.com/mg/forums/result.thread.php?qt=23701
Edit: but this fix is a requirement to get it work ;)
I'am still figure out whats going on there so maybe I missunderstood some parts so correct me please if iam wrong :
1.) gFogOfWarIsOn Test
First I set gFogOfWarIsOn to false to test if I can see all units. But then the oponent units were completly invisible.
1.1) At VisManager::onConnectionSet (on server ?) all units are add to the mVisibleUnits in RTSConnection - but there is no method to transfer this information to the client ?! This cause the clients stay blind.
1.2) VisManager::processServer is skipped if gFogOfWarIsOn==false but the server mVisibleUnits is senseless anyway if I'am right in 1.1.
1.3) VisManager::processClient() is also skipped but this function seams to be the key to make them visible.
So i made a test hack to set all visible:
void VisManager::processClient()
{
if (!mDirty) return;
RTSConnection* conn = RTSConnection::getServerConnection();
for (U32 i = 0; i < mObjectList.size(); i++)
{
RTSUnit* unit = (RTSUnit*)mObjectList[i];
// if (unit->getTeam() == conn->getTeam()) continue;
//need to see if any of the "targets" can see this "unit"
conn->setUnitVisible(unit);
}
mDirty = false;
}And hurray while its not a nice hack I can see the units now!
------------------------------------------
Conclusion:
Currently the server side mVisibleUnits is senseless, because the informations are not send to the clients. The clients know about all units in game there is no ghosting. On the one hand the serverinformation could be transfered to the clients or only the client handles the visibility of all units.
About the author
Contact: torque [AT] ohmtal [DOT] com
#2
The VisManager use Sim::getClientGroup to make a unit visible.
With my previous changes this would be not longer needed. But
it need the VisManager::onConnectionSet call to get visible.
This is called from setControllingConnection in RTSUnit.
Unfortually a AI-Player dont have an ClientConnection so I did add a
new console function to RTSUnit:
Now it is possible to add RTSUnits which are AI Controlled.
04/24/2008 (12:00 pm)
3.) Problem: How to add an AI controlled RTSUnit ?The VisManager use Sim::getClientGroup to make a unit visible.
With my previous changes this would be not longer needed. But
it need the VisManager::onConnectionSet call to get visible.
This is called from setControllingConnection in RTSUnit.
Unfortually a AI-Player dont have an ClientConnection so I did add a
new console function to RTSUnit:
//XXTH an AI RTS UNIT
ConsoleMethod( RTSUnit, setAIControlled, void, 2, 2, "(RTSConnection conn)"
"Sets this object as ai controlled.")
{
//FIXME: object->setAIControlled(true);
gServerVisManager->onConnectionSet(object, NULL);
}Now it is possible to add RTSUnits which are AI Controlled.
#3
Pesonally Ive rearely touched the visManager, knowing the dark waters it represents: I prefered always to leave it for a later big refactor, following the wise advice from those who tried before me.
However, is pretty useful to have it working -hacky or not- so tests that at some point make use of the visManager can be done.
04/26/2008 (11:09 am)
Cool to see someone working on this Thomas, great work.Pesonally Ive rearely touched the visManager, knowing the dark waters it represents: I prefered always to leave it for a later big refactor, following the wise advice from those who tried before me.
However, is pretty useful to have it working -hacky or not- so tests that at some point make use of the visManager can be done.
#4
05/01/2008 (4:02 am)
Novack, the changes at 2. and 3. are not sooo hacky. I test them several days and it works very good :)
#5
05/01/2008 (11:10 am)
Dont take it bad Thomas, I just made a quick read over your posts here, and wrote Hacky because you did, otherwise I wouldn't mention it at all.
#6
05/01/2008 (11:23 am)
Nah, no worries I didnt take it bad ;)
#7
When I approached units / buildings they would disappear once my unit stopped moving ... no (with your changes above) the units show up.
02/27/2010 (10:11 pm)
thanks Thomas! This was a life saver ... trying to get my RTS ready by wedneday to turn in for my class project --- and realized the vis manager was broken.When I approached units / buildings they would disappear once my unit stopped moving ... no (with your changes above) the units show up.
Torque 3D Owner Thomas Huehn
I got it work like expected with the following changes. The disadvantage is, that all Units transfered to all clients.
2.1) Make all units visible first:
At the top of void VisManager::onConnectionSet(RTSUnit* unit, RTSConnection* conn)
change:
to:
You may also remove the first code block but so i keep what it was.
2.2) Save serverload and skip a useless function (i think it is)
Add the return at the top of :
void VisManager::processServer() { [b]return;[/b] if (!mDirty || !gFogOfWarIsOn ) return; //nothing has changed...2.3) Rewritten VisManager::processClient():
remove / comment out the old VisManager::processClient() and add this new one:
//objects that won't be visible will be deleted next time they get an update void VisManager::processClient() { // XXTH rewritten: if (!mDirty) return; RTSConnection* conn = RTSConnection::getServerConnection(); for (U32 i = 0; i < mObjectList.size(); i++) { RTSUnit* unit = (RTSUnit*)mObjectList[i]; if (unit->getTeam() == conn->getTeam()) continue; if (!gFogOfWarIsOn) { conn->setUnitVisible(unit); } else { //need to see if any of the "targets" can see this "unit" conn->setUnitInvisible(unit); for (U32 k = 0; k < mObjectList.size(); k++) { RTSUnit* target = (RTSUnit*)mObjectList[k]; if (target->getTeam() != conn->getTeam()) continue; VectorF vec = unit->getPosition() - target->getPosition(); F32 lenSqr = vec.lenSquared(); F32 targetVision = ((RTSUnitData*)(target->getDataBlock()))->mVision + target->mNetModifier.mVision; if (targetVision * targetVision > lenSqr) { conn->setUnitVisible(unit); break; } } unit->setClean(); } } mDirty = false; }