Author: {wf}shadowspawn <shadowspawn_at_shadowspawn_dot_net>     Reply to Message
Date: 1/8/2004 8:17:01 AM
Subject: RE: SS

This is a copy and paste. it works. i have a variable called g_teststuff that i was using that basically allows you to do all sorts of stuff, one is dumping unlimited grenades. i had 50 turrets up. they all did nothing. this same code is for the proxies, the goodyears, the homing rockets (that one was tough), the plasmabombs, the lasers, the depots, the biosentry, the sentry, the sentry killers, and whatever else used a nextthink every server frame.

it now does ent->nextthink = DynamicThink(ent); which is pretty nifty and uses something like unlagged's method of calling the target's last 8 origins sampled in time and doing allot of math.



=========================================================


Background: I was watching some video on heat seeking missiles. I always noticed that someone had to 'lock on' to a target, then fire. If it wasn't locked, it would do a best guess and always stick to that target; if the target veered it would miss. You ever notice how that in WFA the sentry always fired at the target even if a bunch of targets came close? Chaff and flares wouldn't work really well if sidewinders had WFA code in them. Then some research led to why these high-technology items do what they do; it's because of conservation of valuable embedded processor cycles.

I have been constantly looking at how to improve performance for any server since q2/q3 on the OS side. No matter what server you have, I know how to squeeze as much as I can out of things.

There are however certain fundamental concepts tho on how quake works, and why it's such a hog on performance when it meets our code.

every entity thinks.

ok so for anyone who doesn't understand that, try to think of the world around you. the coffee mug next to your computer is always interacting with the world around you; you push it, it moves instantaneously. That's because it's part of the "interactive" world around you, it exists real-time with you. It's thinking, phsysics affect it. It is also at the same time seperate from everything in your world, it is it's own thing; an entity.

in a game on a computer, there are cycles to when such interactive things "think", or check their existance and react. if you start to push that coffee mug and the engine (server) isn't ready to acknowledge that the mug is going to be pushed because it hasn't (thinked/thunk) yet, there's going to be a delay between when you push that mug and when it actually moves. In the best possible scenerio the mug would be pushed that instant, but because of communication delays and processing orders it takes a finite amount of time for the engine to figure that out. Prediction can help alieviate that, if the client (your computer) is coded to moving that mug without the engine (the server) knowing about it or caring the communication delay is alleviated as well as the processing delay on the server, as long as the server knows where it is every so often, like to tell when it's gonna fall off your desk.

Well that's fine and dandy for a static object that does nothing, like shrapnel or particles, etc.

Let's take a guard dog now, who's supposed to bark whenever somone comes in the door. The dog is trained to bark at anyone (assume it ok), so when you open the door he's going to bark immediately because he sees and hears you. Relate this to a thinking reactive entity; if it doesn't see you it's not going to fire. But a dog isn't a sentry, in the game the sentry is always thinking about every entity in the map (doors, clients, packs, everything) and must process which entity to react to. A dog will sit there oblivious to everything until it has something to react to. A goodyear is omnipresent; it makes a line of choices based on an order of checks.

is it in use?
is it solid?
is it within range?
is it something to react to?
is it within a certain distance between itself?
is it not itself?
is it an enemy?
is it alive?
is it visible?
do something.

(the above might not be accurate for the sentry, I just winged it)

All these checks take time and valuable cycles for the final process to occur; and deciding on what order is best is also a factor. I flowchart this stuff in my mind, but I did have to write a few down to see how to best optimize it... and I'm sure my logic may be out of order but I used damn instinctive guesses; defensive items do stuff differently then melee items.

Items like cluster rockets, grenades also are a big consideration; they are created incrementally; shoving all other think functions out of place in order to create new ones; hence the new functions for 'blast' weapons. I tend to randomize some events, or even consolidate them whenever possible; having 4 proxies blow up and have the server process and broadcast 4 events one after another is a waste. I just made the effects bigger and staggered.

read on.

When you take into consideration that there can be at any time easily 20-40 such entities active in wf/wfa with just 4 players on the server... outside of what entities a mapper creates, the server is constantly running a stepped (not forked) process per entity that exists. This is where the server-side lag comes in (not client rendering/communication lag); the server load. No other game does this. Ever. Maybe some come close with AI, but hardly to the extreme that is what makes Weapons Factory. Serious sam does it to an extent, but their entity AI is very scaled; not every entity fires if there is a similar entity around; they follow each other. sorta.

It started with checking sound emitting entities. The human ear won't tell the difference between an ent 100 units apart from another one in quake. You can't put your ear up to it. So what I did was check distance between other like-sounding entities, if it has the same sound no reason to make that ent have another sound; a proxy in the middle of a pile will make the sound for all of them around. It will, however, get an increased volume when another proxy checks to be silent and finds another one within distance. This reduces the client/server-side memory requirement for sounds for items a bit; goodyears, proxy types.

Then I went a bit further. If an entity checks everything around it (and some other stuff like teleporters and linking them) and there is no enemy within any possible distance that it cannot think about it (which includes checking the distance of the possible DETERMINED target) it will sleep. It will stay idle just long enough to check for an incoming definite target based on range, not area or visibility. As the possible target gets closer, it starts decreasing it's sleep time dynamically based on the speed and prediction to where the target could move next at a maximum velocity.

So if you are alone and you put down 300 goodyears and there is no enemies on the map at all, it's going to be nothing more then a static entity that just sits there, doing nothing, and not thinking often.

As soon as an enemy exists within a maximum possible range, it will 'wake up' (perk it's ears) and determine if that enemy is going closer or farther based on information already stored for prediction. If it's coming closer, the next time it 'thinks' it will be a shorter time (it stands up and listens intently) and a shorter range, as it's more aware... When the target is within a distance where at any 2x distance check from where it's supposed to do anything (say it's supposed to react within 100 units, if the target is within 200) it will fully 'wake up', tail down, hair raised, and snarling.

This is sorta laymans speak, there is allot of math going on to figure out the best 'next think' for an entity and factoring timeouts, like when a grenade is set to explode after being idle so long.

There is some deviation with idle timeouts but it is maxed out within a second; noone's gonna notice that: I don't think anyone cares if a goodyear explodes +/- 1 seconds after it's placed; same with proxies and turrets. It saves literally up to tens of thousands of process cycles per entity; it's a fair trade.

but it's pretty cool nonetheless. On a map like q3ctf1 with the bots putting down proxies, the amount of 'thinks' for an entity decreased by allot (well considering how fast they used to think) in the same sample range using stock code; and were exactly as effective.

Teleporters are taken into consideration (yea llamas love putting ents at teleporter destinations, so a number is stored at spawn to check against) but otherwise, it's pretty cool.

  


_