Lua function to set an area of the map to block LoS

Lua function to set an area of the map to block LoS

Requests for features in the spring code.

Moderator: Moderators

User avatar
Nemo
Spring 1944 Developer
Posts: 1376
Joined: 30 Jan 2005, 19:44

Lua function to set an area of the map to block LoS

Post by Nemo »

SetLoSObstacle( number xmin, number ymin, number zmin, number xmax, number ymax, number zmax)

or something like that

I'd really love a way to create a los "wall" without needing to use terrain to do so. Params for the dimensions of the box; it would function just like a chunk of terrain plopped on that spot in terms of LoS. This would let us have map features (or gaia units, I guess) that block LoS, or modify LoS as part of a game mechanic.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Lua function to set an area of the map to block LoS

Post by Argh »

+1 Would be very useful, to set the ground blocking state with code, without having to have a Unit and a Footprint.
User avatar
Nemo
Spring 1944 Developer
Posts: 1376
Joined: 30 Jan 2005, 19:44

Re: Lua function to set an area of the map to block LoS

Post by Nemo »

I'm talking LoS (line of sight), not footprint. As in, I'd like to be able to define an invisible movement-passable 'box' that acts as a hill in regards to unit vision (blocks it). So, for example, a building feature can properly obstruct unit sight.
User avatar
Pxtl
Posts: 6112
Joined: 23 Oct 2004, 01:43

Re: Lua function to set an area of the map to block LoS

Post by Pxtl »

Sounds basically like a sort of layer of invisible terrain sitting on top of the existing terrain map, the sum of which being used for sight-blocking. Not as powerful as Argh's desired direct-manipulation of the LOS map, but good for making features block terrain.

Curious though: what's wrong with using real terrain instead of fake terrain for the blocking features? Assuming this is for features, I mean? Wouldn't that be a better solution? Use a column of terrain inside the feature?

Seems likely that otherwise, you'll run into a limitation - a "oops, our LOS solution doesn't support X".

Of course, then you could think about the extreme case - having a whole secondary "invisible additive terrain" map that is an offset from the existing terrain map, allowing you to create graphical (but fake) bridges by putting the "graphical" terrain below the "invisible/real" terrain, and using features to represent the "invisible/real" terrain. Would work particularly well with VoidWater.

And at this point I'm spitballing in a random direction. Ignore me.
User avatar
Nemo
Spring 1944 Developer
Posts: 1376
Joined: 30 Jan 2005, 19:44

Re: Lua function to set an area of the map to block LoS

Post by Nemo »

Pxtl: no, because that rules out doing things like smoke shells/smoke screens, or pretty much any usage of it as a game mechanic.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Lua function to set an area of the map to block LoS

Post by Argh »

I'm talking LoS (line of sight), not footprint. As in, I'd like to be able to define an invisible movement-passable 'box' that acts as a hill in regards to unit vision (blocks it). So, for example, a building feature can properly obstruct unit sight.
Whoops, terribly sorry, I am guilty of skimming.


Anyhow... yes, we need this. Badly.
User avatar
Pxtl
Posts: 6112
Joined: 23 Oct 2004, 01:43

Re: Lua function to set an area of the map to block LoS

Post by Pxtl »

Nemo wrote:Pxtl: no, because that rules out doing things like smoke shells/smoke screens, or pretty much any usage of it as a game mechanic.
Oh, right, forgot the smokescreen thing.

Yeah, now I'm thinking about all the clever stuff you can do with features using invisible-terrain... but yeah, that's neither here nor there. Some sort of mutable-invisible-LOS-blocking-only-landscape seems to be the most direct approach to create the functionality people are talking about WRT smoke and features.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Lua function to set an area of the map to block LoS

Post by Argh »

And buildings, as well. Right now, Units either can't shoot at buildings at all... or they can, and totally ignore that they're blocking the real LOS of their guns :P
User avatar
Pressure Line
Posts: 2283
Joined: 21 May 2007, 02:09

Re: Lua function to set an area of the map to block LoS

Post by Pressure Line »

not to mention the utter retarded-looking-ness of putting hills inside building w/respect to plane movement
User avatar
thesleepless
Posts: 417
Joined: 24 Oct 2007, 04:49

Re: Lua function to set an area of the map to block LoS

Post by thesleepless »

+1 could also be used for trees blocking LOS...
perhaps also being able to not 100% block LOS but for eg.
for a forest you can see into it a bit, but a shorter distance than you can normally see.
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Re: Lua function to set an area of the map to block LoS

Post by Tobi »

Pxtl wrote:Sounds basically like a sort of layer of invisible terrain sitting on top of the existing terrain map, the sum of which being used for sight-blocking. Not as powerful as Argh's desired direct-manipulation of the LOS map, but good for making features block terrain.
Direct manipulation of LOS map isn't a good solution in my opinion. It makes any optimization of LOS code hard because it would be inherently bound to the current implementation using rectangular fixed size grid as LOS map.

OTOH it would be easy to add to the engine, but it would be a hell of a lot of work to do anything useful with it. (Need to reimplement the entire LOS raycasting system in Lua, basically, to use it for actually blocking *lines* of sight, as opposed to just adding/removing "sight" on an area of the map.)



Adding an invisible LOS blocking map (that is put on top of the terrain) is a better solution IMO, but have to watch out with performance.

For one, I see no easy solution to calculate which units to recalculate LOS for, when this map is changed. Keep in mind a unit's LOS is not recalculated unless it moves. (disregarding map damage, see below)

Of course a similar thing happens when the map is deformed, but it seems this just recalculates LOS for units directly in the quads (CQuadField quads) in which the deformation happens, which means any unit slightly out of the explosion's radius (outside quads in which explosion happened, to be precise) that had LOS on the changed terrain will keep LOS on it (until it moves), although it possibly shouldn't.

To put up some random ideas:

One way this could be implemented is to use CQuadField::GetQuads with a radius of the unit with largest LOS radius in game, and recalculating LOS for all those units (except maybe those for which it's easily calculated their LOS radius does not overlap with the area that should be updated.)

Another idea could be to just add a callout to force a LOS update for a unit. This forces the game developer to have a thorough understanding of the implementation of this part of the engine tho, if he/she wants to implement a correct and reasonably fast solution, so I'm not really in favor of this.

Or maybe doing a LOS raycast in the opposite direction, from the changed area outwards, up to the largest LOS radius in game, and updating LOS of all units which are "visible" in this raycast.



Another thing which may be disappointing is the resolution of the LOS map; high resolution hurts performance a lot as game developers have figured out, and this feature in particular might need a reasonably high resolution to work as desired. (Or you should just only make mountain sized smoke screens or other LOS obstacles...)

So maybe time to do some research on other ways to calculate LOS accurately and fast with changing terrain (which this feature is, essentially) and moving units...
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Lua function to set an area of the map to block LoS

Post by Argh »

I have an idea.

Instead of raycasting to the terrain, and then updating to see if any Units are within a given LOS square... why not just raycast to all Units in the sphere of the LOS, using the position of the top of the Unit's height as the starting point, and checking versus a simplified version (I'm thinking, 2X smaller, 8-bit, averaged pixels) of the heightmap? I seem to recall reading an article somewhere about doing it with a fast check vs. a voxelized representation of a heightmap, which was really fast, because you're just checking the voxels in range, not the entire mesh.

IOW... getUnitsInSphere... get list... if not on my team or Allied and not already "seen", then do a raycast. It would save a huge number of redundant steps.

After all, the Unit just needs to know what Units it can "see", and that needs to be added to the global "this Unit is visible" list, for weapons that don't raycast, or weapons with an arc (which need to test if they can reach that target, obviously).

We don't need a true terrain LOS system, basically. We just need to know what Units are visible. We aren't hiding terrain, like some engines do, so we don't need to bother with that at all!

Ooh... and that would be a massive cost-savings for World Builder or for Features... because those objects wouldn't need to be updated in LOS, ever- they'd always be on the "seen" list. In fact, the easiest way would be to get the entire list of Units every time the LOS check ran, delete all Unit IDs that are "permanently seen"... and then you're only ever checking against stuff that may or may not be visible, immediately, instead of on a Unit-by-Unit basis. A much shorter, cleaner sort, basically- what's visible to my Team.

Then we just need a special object that will block a raycast, using a cuboid volume, and allow Lua to create and destroy them. Voila, problem solved.

I think that idea would be a lot cheaper than the current system, and would make more sense. We don't need to find a traditional solution to this, since we're not doing traditional "hide the terrain" nonsense. So, let's not bother at all.
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Re: Lua function to set an area of the map to block LoS

Post by Tobi »

Some people would rage when L view isn't present anymore :-)

But otherwise that would be a good alternate solution yeah, and probably quite good performing too. And, it can be easily optimized by making CQuadField faster (for which there are lots of ready made algorithms available.)

If I find some time I may actually try this.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Lua function to set an area of the map to block LoS

Post by Argh »

Some people would rage when L view isn't present anymore
I think that that can be faked adequately. Or L view could trigger the old behavior.

But yeah, I think that this is a very fast solution to this problem, and would greatly speed the game up.
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Re: Lua function to set an area of the map to block LoS

Post by KDR_11k »

So the callout would be something like SetTerrainLOSHeight(x,y,height)?
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Re: Lua function to set an area of the map to block LoS

Post by Tobi »

Depends, if LOS is changed like Argh suggested, using plain raycasting between units, it might be very feasible (and even faster) to treat LOS blocking things as real objects, instead of yet another big map. (in particular if the common case is there are no such objects nearby)

So it could be e.g. Spring.CreateLosObstacle(x, y, z, radius)
(and accompanying Spring.DestroyLosObstacle(id) of course.)
User avatar
thesleepless
Posts: 417
Joined: 24 Oct 2007, 04:49

Re: Lua function to set an area of the map to block LoS

Post by thesleepless »

sounds pretty good Tobi,
any ideas on how to work in a turn based strategy style forest LOS where when you're in a forest you can see a short distance, and from outside the forest you can see a short distance into it, but normally elsewhere.
so you can sneak a force through the forest without being seen from outside where you normally would be visible if it wasnt for the forest.
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Re: Lua function to set an area of the map to block LoS

Post by Tobi »

When using real raycasting you could, instead of a fixed radius, just give the ray a starting "energy" and lookup what to subtract from this every step, based on some map, and have the ray only continue until it's energy reaches zero.

In your example, forest tiles would subtract more then non-forest tiles, so in effect you'd be able to see less far in the forest then outside the forest.

This does remove possibility for certain optimizations tho. (E.g. line<->sphere intersection is just a single calculation, while with the algorithm outlined above there needs to be a loop stepping over all tiles along the ray.)
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Lua function to set an area of the map to block LoS

Post by jK »

doing a raycast for each unit each frame for rendering update is just insane :x (not to forget features etc.)
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Re: Lua function to set an area of the map to block LoS

Post by Tobi »

No one suggested doing a raycast for each unit in each frame.

(Note though that for moving units that is actually what is happening in the current code; if the LOS radius of a unit is bigger then 16/(2*pi) LOS squares, then for a moving unit every SlowUpdate more then 16 raycasts are performed [to update the LOS map], so on average more then 1 raycast per moving unit per frame.)

There's not much need to do it more often then current LOS update, ie. once every SlowUpdate, and I bet a lot of optimizations are possible to make the raycast very cheap. (quadtree for terrain so huge flat areas only need to be checked once, for example)
Post Reply

Return to “Feature Requests”