Page 2 of 11

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 05:53
by smoth
TradeMark wrote:oh no, soon my thread gets locked again ;_;
.. stop trolling trademark smoth. - Moderator

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 07:40
by Wombat
isnt team platter enough ?

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 07:46
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.

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 08:46
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.

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 09:10
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().

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 09:44
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?

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 10:15
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.

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 10:39
by Wombat
can i join smoth ?

anything > trademark < enemy spotter < team platter

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 13:31
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...

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 14:02
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.

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 14:10
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.

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 14:23
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.

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 15:41
by smoth
COOL! go go trademark!

+1 lua guy?

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 20:21
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().

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 21:13
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.

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 21:27
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.

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 23:01
by manolo_
@Niobium i dled ur widget and nothing happens (fast game vs ai), what should it do?

Re: New widget: Enemy Spotter

Posted: 03 Dec 2009, 23:23
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.

Re: New widget: Enemy Spotter

Posted: 04 Dec 2009, 00:35
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.

Re: New widget: Enemy Spotter

Posted: 04 Dec 2009, 01:18
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?