New widget: Enemy Spotter - Page 2

New widget: Enemy Spotter

Discuss Lua based Spring scripts (LuaUI widgets, mission scripts, gaia scripts, mod-rules scripts, scripted keybindings, etc...)

Moderator: Moderators

User avatar
smoth
Posts: 22309
Joined: 13 Jan 2005, 00:46

Re: New widget: Enemy Spotter

Post by smoth »

TradeMark wrote:oh no, soon my thread gets locked again ;_;
.. stop trolling trademark smoth. - Moderator
User avatar
Wombat
Posts: 3379
Joined: 15 Dec 2008, 15:53

Re: New widget: Enemy Spotter

Post by Wombat »

isnt team platter enough ?
SirMaverick
Posts: 834
Joined: 19 May 2009, 21:10

Re: New widget: Enemy Spotter

Post by SirMaverick »

Wombat wrote:isnt team platter enough ?
Team platter uses team color. They can be similar. Other problem that you see circles around your own units and allies. It's a bit harder to distinguish.
User avatar
smoth
Posts: 22309
Joined: 13 Jan 2005, 00:46

Re: New widget: Enemy Spotter

Post by smoth »

Wombat wrote:isnt team platter enough ?
don't use it. Trademark wanted this so he made it. you don't have to use this.
User avatar
Niobium
Posts: 456
Joined: 07 Dec 2008, 02:35

Re: New widget: Enemy Spotter

Post by Niobium »

Code: Select all

function widget:DrawWorldPreUnit()
   glDepthTest(true)
   glPolygonOffset(-50, -2)

   for _,unitID in ipairs(spGetAllUnits()) do
      if (spIsUnitVisible(unitID)) then
This = bad. This widget will be the laggiest widget anyone runs.

1. Use Spring.GetVisibleUnits(...), it is much more efficient than checking visibility of every unit.
2. Also, instead of calling it every drawframe, you should call it in Update() or something a few times per second and store the result in a global table which DrawWorldPreUnit can use. Move enemy checking here as well.
3. Don't use this strange GetUnitDefRealRadius function... Use a table like 'table[uDefID] = radius' instead, which you fully build on initialize().
User avatar
smoth
Posts: 22309
Joined: 13 Jan 2005, 00:46

Re: New widget: Enemy Spotter

Post by smoth »

Niobium wrote:

Code: Select all

function widget:DrawWorldPreUnit()
   glDepthTest(true)
   glPolygonOffset(-50, -2)

   for _,unitID in ipairs(spGetAllUnits()) do
      if (spIsUnitVisible(unitID)) then
This = bad. This widget will be the laggiest widget anyone runs.

1. Use Spring.GetVisibleUnits(...), it is much more efficient than checking visibility of every unit.
My lua understanding is limited.. what is the reason? As in why is this faster?
User avatar
Niobium
Posts: 456
Joined: 07 Dec 2008, 02:35

Re: New widget: Enemy Spotter

Post by Niobium »

smoth wrote:
Niobium wrote:

Code: Select all

function widget:DrawWorldPreUnit()
   glDepthTest(true)
   glPolygonOffset(-50, -2)

   for _,unitID in ipairs(spGetAllUnits()) do
      if (spIsUnitVisible(unitID)) then
This = bad. This widget will be the laggiest widget anyone runs.

1. Use Spring.GetVisibleUnits(...), it is much more efficient than checking visibility of every unit.
My lua understanding is limited.. what is the reason? As in why is this faster?
Put simply, as it appears from the source, spring will only check the visibility (expensive) of a subset of all units, rather than all of them.

There's also other reasons, like the returned table being much smaller and that spring doing the visibility checking as it steps through doesn't incur the extra overhead of Spring.IsUnitVisible() calls.
User avatar
Wombat
Posts: 3379
Joined: 15 Dec 2008, 15:53

Re: New widget: Enemy Spotter

Post by Wombat »

can i join smoth ?

anything > trademark < enemy spotter < team platter
User avatar
TradeMark
Posts: 4867
Joined: 17 Feb 2006, 15:58

Re: New widget: Enemy Spotter

Post by TradeMark »

Niobium wrote:2. Also, instead of calling it every drawframe, you should call it in Update() or something a few times per second and store the result in a global table which DrawWorldPreUnit can use. Move enemy checking here as well.
how do i do that? i dont think it will work... it needs to be drawn every frame when unit has moved, or it will "lag" the movements...
Niobium wrote:3. Don't use this strange GetUnitDefRealRadius function... Use a table like 'table[uDefID] = radius' instead, which you fully build on initialize().
if you read the GetUnitDefRealRadius function further, you notice it will store the data in table, and once it has the data, it returns it straight from the table instead of calculating it again. this will have no impact on efficiency at all.

i havent noticed this widget to be any laggier than TeamPlatter, this widget uses less triangles in rendering, and less checking etc... more optimized now. should be faster actually.

i dont see why anyone would use TeamPlatter widget after they get their hands on this one... you dont need to know which color your ally is, just gives extra confusion and makes more lag since you draw more triangles per frame.

This widget only draws those enemies you see, and you rarely actually see enemies alive (if you are pro).

checking few hundred units or thousand units shouldnt make any more lag, unless you own really crappy CPU...
User avatar
Tribulex
A.N.T.S. Developer
Posts: 1894
Joined: 26 Sep 2009, 21:26

Re: New widget: Enemy Spotter

Post by Tribulex »

this widget takes up 3.2 times the cpu of my entire gui framework that draws res bars, control panel, 3d buildpics, console, and tooltip. Seems a bit excessive. Thx nio very helpful.
slogic
AI Developer
Posts: 626
Joined: 17 Mar 2008, 19:03

Re: New widget: Enemy Spotter

Post by slogic »

TradeMark wrote:checking few hundred units or thousand units shouldnt make any more lag, unless you own really crappy CPU...
This is stupid statement, especially for games.

Niobium gave you very valuable info.

As i know Update () is called each game frame. There are 30 game frames per sec. DrawWorldPreUnit() should be called (in theory) at videocard framerate. Feel the difference. In DrawWorldPreUnit() you should prefer draw stuff only, not calculation.
User avatar
TradeMark
Posts: 4867
Joined: 17 Feb 2006, 15:58

Re: New widget: Enemy Spotter

Post by TradeMark »

yeah im not calculating anything in drawing frame


i didnt notice any FPS difference with the new GetVisibleUnits() function... tested with 1500 units randomly placed all over the map and seeing only few enemies

Edit: more examples of use:

strong edges settings:
Image

Code: Select all

local circleDivs = 16 -- how precise circle? octagon by default
local innersize = 1.5 -- circle scale compared to unit radius
local outersize = 0.9 -- outer fade size compared to circle scale (1 = no outer fade)

local fadefrom = { 0, 0, 1, 0 } -- inner color
local colorSet = { 0, 0, 1, 0.23 } -- middle color
local fadeto = { 0, 0, 1, 0.4 } -- outer color
short outer fade settings:
Image

Code: Select all

local circleDivs = 16 -- how precise circle? octagon by default
local innersize = 1.5 -- circle scale compared to unit radius
local outersize = 1.1 -- outer fade size compared to circle scale (1 = no outer fade)
long outer fade, settings (least polygons used):
Image

Code: Select all

local circleDivs = 8 -- how precise circle? octagon by default
local innersize = 1.5 -- circle scale compared to unit radius
local outersize = 1.75 -- outer fade size compared to circle scale (1 = no outer fade)
updated the code on first post.
User avatar
smoth
Posts: 22309
Joined: 13 Jan 2005, 00:46

Re: New widget: Enemy Spotter

Post by smoth »

COOL! go go trademark!

+1 lua guy?
SirMaverick
Posts: 834
Joined: 19 May 2009, 21:10

Re: New widget: Enemy Spotter

Post by SirMaverick »

slogic wrote:As i know Update () is called each game frame. There are 30 game frames per sec. DrawWorldPreUnit() should be called (in theory) at videocard framerate. Feel the difference. In DrawWorldPreUnit() you should prefer draw stuff only, not calculation.
Update is called at the same rate as the Draw functions. To update unit (simulation) related stuff you should use GameFrame().
User avatar
Niobium
Posts: 456
Joined: 07 Dec 2008, 02:35

Re: New widget: Enemy Spotter

Post by Niobium »

TradeMark wrote:
Niobium wrote:2. Also, instead of calling it every drawframe, you should call it in Update() or something a few times per second and store the result in a global table which DrawWorldPreUnit can use. Move enemy checking here as well.
how do i do that? i dont think it will work... it needs to be drawn every frame when unit has moved, or it will "lag" the movements...
I have a widget that maintains a global (across all widgets) table of visible units. It updates visible units only once per second, or whenever the camera changes position/direction (But no more than 10 times per second). You are somewhat correct with this 'lag' thing, in that, it is possible that a visible unit is not in the table, or vice-versa. But every 1 second, and on camera changes, is more than sufficient, I never see a case of a unit not being seen as visible. I'll attach it at the end so you can see what I do.
TradeMark wrote:
Niobium wrote:3. Don't use this strange GetUnitDefRealRadius function... Use a table like 'table[uDefID] = radius' instead, which you fully build on initialize().
if you read the GetUnitDefRealRadius function further, you notice it will store the data in table, and once it has the data, it returns it straight from the table instead of calculating it again. this will have no impact on efficiency at all.
This is what I use in my custom teamplatters-like widget:

Code: Select all

local radiusDefs = {}
for uDefID, uDef in pairs(uDefs) do
	radiusDefs[uDefID] = uDef.radius
end
And then I can get any radius from a single table lookup, like your way does, but without the function call overhead, the silly if check, and in far less code.

It is true that your widget might not have a hugely noticeable effect on framerate, but its impact is going to be much higher than it could be if you made the small changes I mentioned.
Attachments
nio_vis_units.lua
Efficiently maintaining visible units table.
(2.47 KiB) Downloaded 41 times
User avatar
TradeMark
Posts: 4867
Joined: 17 Feb 2006, 15:58

Re: New widget: Enemy Spotter

Post by TradeMark »

ah, i get it now...

wouldnt it be smarter if we could directly use the array spring creates every frame for visible units? if it doesnt create such array, then it should... i mean, it has to render the units, why not add unit ID's in some array whenever unit was rendered? could use static array size up to 32000 units, and array length variable. fast to write and read.
User avatar
manolo_
Posts: 1370
Joined: 01 Jul 2008, 00:08

Re: New widget: Enemy Spotter

Post by manolo_ »

@Niobium i dled ur widget and nothing happens (fast game vs ai), what should it do?
SirMaverick
Posts: 834
Joined: 19 May 2009, 21:10

Re: New widget: Enemy Spotter

Post by SirMaverick »

manolo_ wrote:@Niobium i dled ur widget and nothing happens (fast game vs ai), what should it do?
Like he explained it provides a list of visible units for other widget to work with. It has no direct functionality for the user.
User avatar
Niobium
Posts: 456
Joined: 07 Dec 2008, 02:35

Re: New widget: Enemy Spotter

Post by Niobium »

SirMaverick wrote:
manolo_ wrote:@Niobium i dled ur widget and nothing happens (fast game vs ai), what should it do?
Like he explained it provides a list of visible units for other widget to work with. It has no direct functionality for the user.
All it does is provide a way for widgets to quickly get access to visible units, instead of having many widgets constantly calling GetVisibleUnits.

Usage: Use 'local visUnits = WG.visUnits or {}' instead of 'local visUnits = spGetVisibleUnits()' in any widget.

In my case I have three widgets that are faster because of the global visunits widget I posted; healthbars, teamplatter, and unit experience.
User avatar
TradeMark
Posts: 4867
Joined: 17 Feb 2006, 15:58

Re: New widget: Enemy Spotter

Post by TradeMark »

Niobium wrote:In my case I have three widgets that are faster because of the global visunits widget I posted; healthbars, teamplatter, and unit experience.
yeah thats also why there should be some better way to do this... than making some widget mess for it.

as i explained in my previous post, do you guys think it would be the best way?
Post Reply

Return to “Lua Scripts”