Game Development Community

Theif/stealth visibility meter

by Ed Johnson · in Torque Game Engine · 03/27/2005 (2:52 pm) · 15 replies

www.canofworms.com/game/thief/bafford3.jpg

Okay, I'm sure many of you have played either the Theif series or like Spliter Cell you know about the
gui display of how hidden (or visible) you are in the enviroment.
Are there ways to read how dark/light it is where something is?
I wanna open this functionality up to the script system so the AI can "see" properly.




P.S. the new Thief looks killer... TSE prolly could look better
www.gamegirlz.com/screenshots/thief-deadly-shadows/xbox_thief001.jpg

#1
03/27/2005 (3:41 pm)
Wow, very nice, I like the player moddel, shadows are very nice too.

Max
#2
03/27/2005 (4:01 pm)
Yeah they are. Theif has always made lighting and shadows a huge part of the game, as sneaking is the core gameplay.

Anyone know about reading light levels?
#3
03/27/2005 (5:52 pm)
There's a few ways to do this. If you are using all static lights, you could read the lightmap data from where the thief is standing. I'm not sure how fast this would be, but it would be pretty easy.
#4
03/27/2005 (5:58 pm)
First of all -- I loved the first 2 thief games.

In fact, I spent more time tweaking tiny elements in DromEd, going for specific looks and feels and environments, than I spent PLAYING any other game besides Tribes.

Tribes and Thief are the most influential games I've ever played, and in my opinion they are still the benchmarks by which multi and single-player games are to be measured, respectively. Between the two of them, they've occupied more of my attention than the rest of the gaming universe combined, and I played MMORPG's for probably close to 8 months.

As for Thief -- for one thing, they computed the light volumes and levels in the CSG portalization process. This is something that is NOT done in most portal-based engines; lighting is baked into textures, but The Dark Engine kept the volume information generated during the lightmap creation process (which is one reason that the file sizes were so large for their levels, although the bigger reason is just that using CSG/portals for the BULK of level geometry creation is not a very scalable solution, and they really pushed it to the limits of content richness).

Dynamic lights then added to this information at runtime for dynamic lights (which didn't cast shadows, not that any shadows were cast in thief 1/2 that weren't baked into the levels).

However, TDE made lighting an integral part of the engine. For Torque, I imagine that there are several less-holistic solutions that could be used -- possibly the easiest way would be to figure out how to poll the vertices of a model (or of a lower LOD version of a model) to determine how brightly they're lit, and make this a core property of all game objects whose visibility affects AI (or affects the server's determination of visibility/invisibility, which could help to provide a powerful invisibility that is not susceptible to graphics card or other client-side hacks).

That seems like the most direct method.

I have to imagine that since spawning new cameras/viewports in games is now pretty affordable, and since the demands for AI recognition of movement are becoming refined with an increasingly jaded gaming populace, and since there exists so much great, applicable, ongoing, open work on movement/image recognition for AI -- I have to imagine that an endgame for vision in AI is going to be to just plug in variations of agents that rely on research AI libraries. Game developers can make AI in their games much more effective than in real life because they can cheat and give their AI enormous, often very difficult-or-costly-to-acquire-in-real-time information about the surrounding areas -- for instance, the AI doesn't have to analyze the image to determine that there is a box and a wall at point x; we can give him information on the fixed and in-game objects that will help him to understand the input from his viewport, allowing the AI to focus on interpreting things like arms that stick out from boxes, whether or not the movement of that plastic bag caught in an updraft is in any way threatening, etc. And since we have access to the world that the simulation is taking place in, we can cheat by allowing selective raycasting to determine if, for instance, a visual movement was created by an important game object or not.

I think that for craps and giggles it would be cute to hook up, for instance, extra viewports from HL2 to image recognition bots and see what kind of stuff could be done, but I wouldn't know where to begin (on the game engine side; I have some good AI books).
#5
03/27/2005 (5:58 pm)
The problem w/static lightmaps is of course that it only tells you how visible a thief's toes are.
#6
03/28/2005 (4:19 pm)
Hmmm wonder how hard the "poll the vertices of a model to determine how brightly they're lit" would be.. are there any functions in the engine already to get lighting info of a model?

Or hmmm how realistic would it be if I used the lightmap info at his toes? I thought about that at first, thinking if the ground is shadowed he must be too? After reading Luc's post, it seemed unrealisitc in comparison to looking at the model itself. Is this information already present in the engine?
#7
03/29/2005 (2:58 pm)
.
#8
03/29/2005 (7:37 pm)
Wow, that would work, but it seems like too many objects to load lol
#9
07/21/2007 (7:30 pm)
Thanks to Edward Moyer for pointing this out to me:

http://www.garagegames.com/mg/forums/result.thread.php?qt=26055

Quote:Howard Dortch wrote:

ColorF SceneObject::getLastColor(void)
{
return mLightingInfo.smAmbientLight.mColor;
}
#10
07/22/2007 (12:20 am)
I've contemplated this. An idea I had would be to do raycasts from lights to the player, compute how many hit, for example, the corners of his bounding box, then average that to get an estimate. Would probably only work with placed lights, not DIF baked lightmaps.
#11
07/22/2007 (11:41 am)
I'm actually looking for a completely dynamic solution, or at least one that works with dynamic lights in addition to static scene lights. One of the fundamental aspects of Stealth-style games is being able to shut off or disable light sources.

Even though the method mentioned above (mLightingInfo) would only be useful for the static lighting, I attempted to add that function and a corresponding Console Method, using other methods in SceneObject as a reference.. but with no success.

This is where I was trying to place the getLastColor function:
In \Projects\Stealth\engine\sim\sceneObject.h
/// Gets the velocity of the object
   virtual Point3F getVelocity() const;

[b]   ColorF getLastColor(); // <- Stealth [/b]

   /// Sets the velocity of the object
   /// @param  v  Velocity
   virtual void setVelocity(const Point3F &v);

In \Projects\Stealth\engine\sim\sceneObject.cc
SceneObject::LightingInfo::LightingInfo()
{
   mUseInfo = false;
   mDirty = false;
   mHasLastColor = false;

   // set the colors to half white for invalid surfaces and all...
   mDefaultColor.set(0.5f, 0.5f, 0.5f);
   //mAlarmColor.set(0.5f, 0.5f, 0.5f);
   mLastColor.set(0.5f, 0.5f, 0.5f);

   mLastTime = 0;
}

[b]
ColorF SceneObject::getLastColor(void)
{
	return mLightingInfo.smAmbientLight.mColor;
}[/b]

//--------------------------------------------------------------------------
// Lighting update: not used directly by sceneobject...
// - if an interior, which contains this object, moves then this value will be incorrect
bool SceneObject::getLightingAmbientColor(ColorF * col)
{
[i]  .... edited for brevity [/i]

I wasn't sure where exactly to put the console method, so I added it at the end of sceneObject.cc after the function SceneObject::findLightGroup.

ConsoleMethod( SceneObject, getLastColor, void, 2, 2, "Get last color")
{
     return mLightingInfo.smAmbientLight.mColor;
}

Anyone care to try the above in a clean, fresh TGE 1.5 and see where I went wrong? I would like to figure this out and make it into a resource. Maybe eventually a Stealth Starter Kit...
#12
07/22/2007 (12:00 pm)
I think your console method should look more like this:

[*bzzz*] thanks for playing - look at Jeff's. Time for coffee.
#13
07/22/2007 (12:19 pm)
More like this actually:
ConsoleMethod( SceneObject, getLastColor, const char*, 2, 2, "Get last color")
{
    static char buffer[128];
    ColorF col = object->getLastColor();
    dSprintf(buffer, sizeof(buffer), "%f %f %f %f", col.red, col.green, col.blue, col.alpha);
    return buffer;
}
You could leave off the alpha if it's not applicable.

Edit: Sorry Andy, not trying to show you up. I nearly posted the same thing you did.
#14
07/22/2007 (1:20 pm)
Wow, thanks guys!

I was able to call that function from script, and walking around under differing shadowed areas get the following values:

0.080645 0.080645 0.129032 0.000000
0.087035 0.087035 0.135858 0.000000
0.109832 0.109832 0.160443 0.000000
0.162701 0.162701 0.220321 0.000000

Which I'm hoping will be useful for figuring out darkness/brightness levels.

Something I noticed though (hard not to) was lots and lots of the following warning after Mission lighting done (looks like every tick):


Warning: (f:\gamedev\projects\stealth\engine\scenegraph\scenegraph.cc @ 847) ZoneManagers are only allowed to belong to one and only one zone!


Any suggestions for the latter?
#15
11/15/2007 (10:20 pm)
Like do you have any interiors overlapping each other per chance?