Let�s develop: Monster Sight Calculation

Moderator: GZDoom Developers

User avatar
Sphagne
Posts: 513
Joined: Wed Jul 16, 2003 3:36 am

Let’s develop: Monster Sight Calculation

Post by Sphagne »

Let’s develop: Monster Sight Calculation

-------------------------------------------------------

Preface:

As this is the first post of its kind, I would like to add some info here:

Here is a test, to see if this kind of approach would fare better than my last approaches.

In this kind of threads, we can suggest our features as a cooperative event in which, we want to develop a feature ourselves (as teamwork) and when done, offer it to Randy to see if he would accept them.

It would require a volunteer programmer that has enough time to spend on it and likes the idea enough to decide to join in, and other people can join in with their ideas, solutions, or any other comments, but please let’s keep them organized enough to be able to complete the features.

I know at first, it may look a bit daunting, but after that, it would find its pace, and hopefully would become promising enough for Randy to decide to join in and help us along.

Oh, yes, I will update this first post to include our progression of ideas and actions.

-------------------------------------------------------

Info:

With this feature, we want to infuse some stealth factor into our levels, i.e. if you stay in the dark areas it would be harder for monsters to see you than light places, and the nearer you go to them the more likely it is that you would be seen.

-------------------------------------------------------

Result:

If this feature is fully implemented:

There would be no change in the gameplay for current available levels, unless the player specifies in an options menu to activate it for all the levels.

There would be a MAPINFO entry, which would let us activate the stealth factor for our levels.

When activated for a level, monsters would see other actors depending on their distance and the light level of the target actor’s sector, and their “Sight” power, and the target’s “Visibility” factor.

There would be two additional DECORATE parameters for each actor: Sight and Visibility.

Finally, Adding two additional actor properties to help us manage this feature, like decreasing the player’s visibility factor as he uses the cloaking device.

Optional: When a monster is still unaware, its sight power is decreased by a factor.

Optional: When an actor is moving, its visibility factor is increased, depending on the movement speed.

Optional: When an actor is in its “Full Bright” frames, its visibility factor is temporarily doubled, like lost souls or firing frames of normal actors.

Optional: When an actor is shown fuzzily, its visibility factor is temporarily halved, like specters, or blur-spheres.

Optional: When an actor is shown transparent, its visibility factor is decreased accordingly.

Optional: Stealth monsters, are totally hidden, when not shown, (I don’t know if it is hard to implement, or if it is such a good idea)

Optional: Try to include Caligari_87’s suggested chance percent in the visibility formula.

Complexity: low to moderate, but with each optional feature, a bit more complex.

P.S. Any suggestions for additional features?

-------------------------------------------------------

Detail:

Thanks Graf for the info:

We need to change the function "P_CheckSight", which is the place that all the LOS (Line of Sight) calculations are done.

It is called before the actors “See” their target and wake up, and before they attempt an attack on the target, and before “A_Refire” would decide to cease fire for chain gunners and the like, and when we want to search for an actor.

The LOS check would decide if the actor can see it’s target, i.e. whether it is blocked from the sight by the geometry or not, and would give the result of TRUE if the target can be seen.

Our task would be to add the Visibility check after the LOS check to decide if the target is close enough to the actor to be seen.

For this reason we can add the visibility check inside the “P_CheckSight” function but would only check it if the target is not already blocked from the actor’s sight.

Thus, if the function’s result is already FLASE, then the target is already blocked from the view, so there is nothing to do, thus we would branch out of the function.

But if the target is not blocked, i.e. function result is TRUE, we should perform the visibility check, and after that if we decide that the target should not be seen, then we change the function’s result back to FALSE, and that would do the job.

The end result would be that, if the target is further than the visible range, it is hidden from the actor’s sight, just as if it is blocked by a wall or something.

This means that the monster would not be awakened, or would not start an attack toward you, or the chain gunner would stop shooting toward you as you back away into the darkness.

However, at first, we would have to prepare the required parameters for the formula.

-------------------------------------------------------

Step 1:

We need to add two integer fields to our actors for their Sight power, and Visibility factor.

They would by default initialize to 100, unless defined differently in the DECORATE lumps, which as Graf says, is an easy task, so no problem here.

We would also need to add a global boolean variable that would toggle this feature ON or OFF. This variable should be defined from within the MAPINFO lump, but for now, we can initialize it to TRUE for the development’s sake.

-------------------------------------------------------

Step 2:

As Graf says, the “P_CheckSight” function is called from any place that the code wants a LOS calculation, and some of these calls may need the additional visibility check.

Thus, we can change the function and add another boolean parameter to it, to trigger the additional visibility check inside it, and it would automatically force the compiler to give an error on all the calls to the function, so it would be easy for us to find their places.

After that we can check the place to decide if it needs the additional check and if so we pass the function a TRUE, and otherwise a FALSE.

Inside the function, and after the original LOS check, we can check this boolean value to decide if the additional visibility check is required, and if so then we need another check as well, to see if the visibility check is actually enabled for the level or not.

For this reason, we need to check the variable initialized in the MAPINFO, and (or) it with the CVAR that would be defined in the option menus, and if the result is FALSE we branch out of the function.

After that, we can calculate this formula:

D = ( Sqrt(L*L*L) * S * V )/DF

D: maximum visible distance (in map grid units)
L: target sector light value (0-255)
S: actor sight factor
V: target visibility factor
DF: distance factor

DF should by default be probably something around 25000 for this formula, but the level designers should be able to change it via the MAPINFO command, (more on that later), thus, we can initialize it to 25000 by default, but it might change later via MAPINFO.

After calculating the maximum visible distance of the target actor, we can calculate the distance between the two actors, (in map grid units), and check if it is more than the maximum visible distance, and if so then the target is not visible to the monster, so we would change the result back to FALSE.

P.S. Any suggestion for a better formula is gladly accepted.

-------------------------------------------------------

Step 3:

The next step would be:

Add a new CVAR to trigger this check for all the current maps.

Add the options menu-item to let the users toggle this CVAR.

Add this CVAR to list of CVARs that are saved to the configuration file, if it is not automatically done.

After this stage, we can test our newborn feature in any current level.

-------------------------------------------------------

Step 4:

Add two new actor properties to the current list, like: APROP_Sight and APROP_Visibility.

-------------------------------------------------------

The next steps are currently under construction. :wink:

-------------------------------------------------------

Action log:

OK, now is the critical part:

Is there any volunteer programmer who likes to join in, so that we can develop this new feature?

I am sure that it is worth the effort, and the time spent on it, would not be a wasted time.

I know at first, it may look a bit daunting, but after that, it would find its pace, and hopefully would become promising enough for Randy to decide to join in and help us along.

Hey pals, this is not that complicated, and would not take a lot of your time. Don’t you want to say “I added stealth factor to ZDoom.”? :wink:

Thanks in advance.
Last edited by Sphagne on Mon May 16, 2005 7:01 am, edited 2 times in total.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49066
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Let’s develop: Monster Sight Calculation

Post by Graf Zahl »

Don't worry, I won't post any negative comment. This approach is definitely better and might even lead to results.
But I'd like to issue one warning: You are aware that all of this might be affected by Randy's float rewrite, aren't you?

Sphagne wrote: Result:

If this feature is fully implemented:

There would be no change in the gameplay for current available levels, unless the player specifies in an options menu to activate it for all the levels.

There would be a MAPINFO entry, which would let us activate the stealth factor for our levels.

When activated for a level, monsters would see other actors depending on their distance and the light level of the target actor’s sector, and their “Sight” power, and the target’s “Visibility” factor.

There would be two additional DECORATE parameters for each actor: Sight and Visibility.

Finally, Some additional ACS functions to help us with managing this feature, like decreasing the player’s visibility factor as he uses the cloaking device.

Optional: When a monster is still unaware, its sight power is decreased by a factor.

Optional: When an actor is moving, its visibility factor is increased, depending on the movement speed.

Optional: When an actor is in its “Full Bright” frames, its visibility factor is temporarily doubled, like lost souls or firing frames of normal actors.

Optional: When an actor is shown fuzzily, its visibility factor is temporarily halved, like specters, or blur spheres.

Optional: When an actor is shown transparent, its visibility factor is decreased accordingly.

Optional: Stealth monsters, are totally hidden, when not shown, (I don’t know if it is hard to implement, or if it is such a good idea)

Complexity: low to medium, but with each optional feature, a bit more complex.

P.S. any suggestion for additional features?

-------------------------------------------------------

Detail:

My guess is: when the engine wants to decide if a monster can see an actor, it would check the BSP geometry or something like that to see if the target is blocked from the view of the monster.
The function is called P_CheckSight, located in p_sight.cpp and returns true when the monster can see the target and false when not.
This would happen before the monster jumps to the “See” state, before it jumps to “Missile Attack” state, and before deciding to cease fire for chain gunners and the like, and I do not know if all these checks are done in the same place or in their own different places. Hopefully, in the same place.

We can add another check after the geometry check, to add our sight calculation formula, and if the result were that the monster should not see the actor, we would behave exactly as if the actor is blocked by the geometry, i.e. as if a wall is blocking the actor.
All checks are in different functions but all call the same P_CheckSight function. Logically P_CheckSight is the point where you should hook in your code. But you should be aware that this function is also used for other LOS calculations so you'd have to add more flags to the existing flag parameter.
That means, that in the code, we should branch to the exact place that the failed geometry check would have branched away.

The result would be that the monster would not be awaken, or would not start to shoot at you, or the chain gunner would stop shooting toward you as you back away into the darkness.
If done in P_CheckSight and some flag use that will happen automatically. I don't think you need to modify anything but the calls themselves (it aren't that many but make sure you get all of them. Some are in code pointer functions - not only Doom but from the other games as well.)
Step 1:

We need to add two integer fields to our actors for their Sight power, and Visibility factor.

They would by default initialize to 100, unless defined differently in the DECORATE lumps, which would come later.
Why later? Adding new properties to DECORATE is the smallest issue of all. ;)
We would also need to add a global boolean that would toggle this feature ON or OFF, and in the current state we initialize it as ON, for the development.
Best use a CVAR or a MAPINFO option which are or'd. If one is true the feature is active, otherwise not.

We would search for and find all the places that the level geometry is checked to see if the target is blocked away from the monster’s sight, and if they are in separate places and are exactly the same, then we can extract them and place them in a separate function, and use that function in their place.
Here's the list of functions:

p_enemy.cpp
bool AActor::CheckMeleeRange ()
bool P_CheckMeleeRange2 (AActor *actor)
BOOL P_CheckMissileRange (AActor *actor) // this is the most important one!
AActor *LookForTIDinBlock (AActor *lookee, int index)
BOOL P_LookForTID (AActor *actor, BOOL allaround)
AActor *LookForEnemiesInBlock (AActor *lookee, int index)
BOOL P_LookForPlayers (AActor *actor, BOOL allaround)
void A_Look (AActor *actor)
void A_Look2 (AActor *self)
void A_Chase (AActor *actor)
void A_FastChase (AActor *actor)

p_interaction.cpp
bool AActor::OkayToSwitchTarget (AActor *other)

p_mobj.cpp
bool AActor::IsOkayToAttack (AActor *link) // only used by friendly Minotaur in Hexen

g_doom/a_archvile.cpp
void A_Fire (AActor *self)
void A_VileAttack (AActor *actor)

g_doom/a_possessed.cpp
void A_CPosRefire (AActor *self)

g_doom/a_scriptedmarine.cpp
void A_M_Refire (AActor *self)

g_doom/a_spidermaster.cpp
void A_SpidRefire (AActor *self)

g_Hexen/a_serpent.cpp
void A_SerpentChase (AActor *actor)
void A_SerpentWalk (AActor *actor)

g_Raven/a_minotaur.cpp
bool AMinotaur::IsOkayToAttack (AActor *link)

g_Strife/a_crusader.cpp
bool Sys_1ed64 (AActor *self)
void A_CrusaderRefire (AActor *self)

g_Strife/a_inquisitor.cpp
bool Sys1ED64 (AActor *self) // no idea why this is duplicated...

g_Strife/a_sentinel.cpp
void A_SentinelRefire (AActor *self)

g_Strife/a_stalker.cpp
bool AStalker::CheckMeleeRange ()

g_Strife/a_strifestuff.cpp
void A_TurretLook (AActor *self)

g_Strife/a_strifeweapons.cpp
void P_DaggerAlert (AActor *target, AActor *emitter)




-------------------------------------------------------
Step 3:

The next step would be adding the Menu item in the options menu to toggle this feature for any current map, and adding the means for this configuration option to be saved with other options, and initialize our global toggle variable depending on the option.

After this stage, we can test our newborn feature in any current level.

-------------------------------------------------------
No need to delay this. Just add one line of data to the menu you want this in. ;)
User avatar
Tormentor667
Posts: 13533
Joined: Wed Jul 16, 2003 3:52 am
Contact:

Post by Tormentor667 »

Great, this really seems to lead to a very useful result :)
User avatar
Sphagne
Posts: 513
Joined: Wed Jul 16, 2003 3:36 am

Post by Sphagne »

Hey, Graf thanks for the help, it seems that it was only my previous style and atitude, that you disliked, sorry that I misjudged you. :smile:

As for the floting point problem, I do not think that would chenge the logic so much that would affect this part of the code, but the final reintegration of the new logic to the new code might require a bit more of work.

As for the list, well, none of "Look for" codes would require it, but all the attack initialization codes would need this, and all the chases and walkes, if they want to decide for an attack on the target (or heal it in the case of ArchVile), and also all the refire codes.

We can add another bool parameter to the P_CheckSight function that would trigger the additional stealth check, and this would automatically force the compiler to show us all the places that the function is used.

We can check the place and decide if we want the additional sight check at that place or not, and if not then we would pass the function a "False" value.

But if we want the check, then we would pass the new CVar or'ed with the bool value initialized via MAPINFO, and that would do the job.

OK, that's great, but the important question is, "Who would decide to do the job?", any volunteers? :wink:

P.S. Tormentor667, Maybe you are not a programmer, but you are definitely a good level designer, so you may have some good ideas, to add to the bunch, so don't leave us.
User avatar
Caligari87
Admin
Posts: 6174
Joined: Thu Feb 26, 2004 3:02 pm
Preferred Pronouns: He/Him
Contact:

Post by Caligari87 »

I posted a thread about this kind of thing a little while back. Graf has already said this would require a major re-write, but then again so would everything you proposed. :)

This is my personal idea for monster AI, and most of it duplicates your ideas. It's a little more fleshed out with numbers and examples, so if there's anything you like, go ahead and take it (with due credit, of course :) ).

BTW, I can't program C++ worth crap, so I couldn't really help with this. :cry: Hope it wouldn't be too much extra work.

(copied from my other thread...)
Spoiler:
User avatar
Sphagne
Posts: 513
Joined: Wed Jul 16, 2003 3:36 am

Post by Sphagne »

Hey, you have exactly my problem: "Some good ideas that you can not develop them yourself.", so why not start another "Let's develop" thread and try to persuade a programmer here to do them for you?

I want to start small, so I would try to do only the sight calculation fo rthe monsters, in this thread, but maybe when it is completed, we would figure out how to do the rest of your ideas, in other threads, after that. OK for you?

And your definitions for the sight calculation are more complex than mine, so I would wait to see if my formula is accepted, or not, then if it was implemented, and before it was official, we may try to change it to something like your suggestions.

Thanks for your suggestions. :smile:
User avatar
Sphagne
Posts: 513
Joined: Wed Jul 16, 2003 3:36 am

Post by Sphagne »

So, no C programmer present, or interested, OK, another failure, I guess. :sad:
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49066
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Post by Graf Zahl »

Patience!

There aren't that many programmers and most simply don't have the time to spend on something like this. But that can change.
User avatar
Hirogen2
Posts: 2033
Joined: Sat Jul 19, 2003 6:15 am
Graphics Processor: Intel with Vulkan/Metal Support
Location: Central Germany
Contact:

Re: Let’s develop: Monster Sight Calculation

Post by Hirogen2 »

Sphagne wrote:Let’s develop: Monster Sight Calculation
...lot of text...
Thanks in advance.
May I remind you that I think that you already have posted this. (I think it ended in "zombies see in the dark anyway" :-) )
User avatar
Sphagne
Posts: 513
Joined: Wed Jul 16, 2003 3:36 am

Post by Sphagne »

Remember it? That was about two year ago, but now I have decided to retry it with another method.

If an interested programmer would help me to finish this feature, we could offer it to Randy to see if he would include it in the next ZDoom.

By the way, as I remember, you were a programmer yourself. Dont you want to give it a try?

I dont think that it would waste more that two or tree weekends, to finish the first stages, to complete the feature, (without the optional features).

The guidelines at the first of this post are quite clear by now, and I do not foresee much problem there.

Please think about it. :smile:
User avatar
Cutmanmike
Posts: 11335
Joined: Mon Oct 06, 2003 3:41 pm
Operating System Version (Optional): Windows 10
Location: United Kingdom
Contact:

Post by Cutmanmike »

If I was a programmer I probably would. However, code is still in the back of my brain.
User avatar
Hirogen2
Posts: 2033
Joined: Sat Jul 19, 2003 6:15 am
Graphics Processor: Intel with Vulkan/Metal Support
Location: Central Germany
Contact:

Post by Hirogen2 »

Sphagne wrote:Remember it? That was about two year ago
Either I have a good memory, or two years pass fly-by. I still remember the NEURONS thing heh.
User avatar
Sphagne
Posts: 513
Joined: Wed Jul 16, 2003 3:36 am

Post by Sphagne »

Please, dont remind me of that.

By the way, if I can persuade Randy to add "Use Specials" and also seperate "Hate Target" from "Destination Target" and give us the power to force monsters to "Use" other items, then all those "Neuron" thingies could be done right away. :wink:

Hey man, are you still enthusiastic about developing new features? This stealthy one is real practical, and ready for action.
User avatar
Hirogen2
Posts: 2033
Joined: Sat Jul 19, 2003 6:15 am
Graphics Processor: Intel with Vulkan/Metal Support
Location: Central Germany
Contact:

Post by Hirogen2 »

Enthusiastic? Not quite. A working linux port is missing to get me going. (Really, I do seem to start on everything I get. Last thing was openttd, wuftpd, and...things.)

I would not wonder if Sphagne would even propose the binary details of a new map format... sigh.
User avatar
Jim
Posts: 535
Joined: Mon Aug 11, 2003 10:56 am

Post by Jim »

There is an unofficial patch by Chris that makes it work on Linux just fine.
Post Reply

Return to “Closed Feature Suggestions [GZDoom]”