Re: New widget: Enemy Spotter
Posted: 17 Dec 2009, 22:38
i dont see how that would be any better than my widget, screenshot?
Open Source Realtime Strategy Game Engine
https://springrts.com/phpbb/
Probably not the best pic for an example but a pic none the less.TradeMark wrote:i dont see how that would be any better than my widget, screenshot?
Now now, no need to get jealous. Just because your metal maps suck balls and you suck at the game, doesn't meat you should take it out on somebody who actually uses his GUI for gameplay measures rather than for smexy shine.TradeMark wrote: your UI looks like shit btw.
Code: Select all
For instance, the code
for i = 1, 1000000 do
local x = math.sin(i)
end
runs 30% slower than this one:
local sin = math.sin
for i = 1, 1000000 do
local x = sin(i)
end
Code: Select all
Access to external locals (that is, variables that are local to an enclosing
function) is not as fast as access to local variables, but it is still faster than
access to globals. Consider the next fragment:
function foo (x)
for i = 1, 1000000 do
x = x + math.sin(i)
end
return x
end
print(foo(10))
We can optimize it by declaring sin once, outside function foo:
local sin = math.sin
function foo (x)
for i = 1, 1000000 do
x = x + sin(i)
end
return x
end
print(foo(10))
This second code runs 30% faster than the original one.
Code: Select all
A good place to look for chances of reducing garbage creation is in loops. For instance, if a constant table is created inside a loop, you can move it out the loop, or even out of the function enclosing its creation. Compare:
function foo (...)
for i = 1, n do
local t = {1, 2, 3, "hi"}
-- do something without changing ÔÇÖtÔÇÖ
...
end
end
local t = {1, 2, 3, "hi"} -- create ÔÇÖtÔÇÖ once and for all
function foo (...)
for i = 1, n do
-- do something without changing ÔÇÖtÔÇÖ
...
end
end
Code: Select all
local function myFunction()
local foo1, foo2, foo3
...do stuff with foo1, foo2, foo3
end
Code: Select all
local foo1, foo2, foo3
local function myFunction()
...do stuff with foo1, foo2, foo3
end
Code: Select all
function widget:DrawWorldPreUnit()
local glTexture = gl.Texture
glTexture(blah)
end
Code: Select all
local function Blah()
local X = 0
...do arithmetic that might change X's value, but cannot operate if it's nil
X = final value
end
Code: Select all
local X = 0
local function Blah()
...do arithmetic that might change X's value, but cannot operate if it's nil
X = final value
end
Code: Select all
local function Blah()
local X
if X ~= nil then
...do arithmetic that might change X's value, but cannot operate if it's nil
else
X = 0
return
end
Code: Select all
local function Blah()
local myVar
myVar = functionCall()
-->use myVar to draw something
myVar = anotherFunctionCall()
-->use myVar to tell end-user that "42" is the number
end
Code: Select all
local function Blah()
local myVarOne, myVarTwo
myVarOne = functionCall()
-->use myVarOne to draw something
myVarTwo = anotherFunctionCall()
-->use myVarTwo to tell end-user that "42" is the number
end
[Unintended-Trolling]Argh wrote:@Jazcash: Erm, don't be silly. This isn't some auto-finder
Code: Select all
function widget:GetInfo()
return {
name = "Enemy Spotter v.2",
desc = "Draws smoothed octagon under enemy units",
author = "Argh,TradeMark,Trepan",
date = "December 17th, 2009",
license = "(C) WolfeGames, released under GNU GPL, v2 or later",
layer = 5,
enabled = false -- loaded by default?
}
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Automatically generated local definitions
local glBeginEnd = gl.BeginEnd
local glTexCoord = gl.TexCoord
local glTexture = gl.Texture
local GL_QUADS = GL.QUADS
local glColor = gl.Color
local glCreateList = gl.CreateList
local glDeleteList = gl.DeleteList
local glDepthTest = gl.DepthTest
local glDrawListAtUnit = gl.DrawListAtUnit
local glVertex = gl.Vertex
local GetVisibleUnits = Spring.GetVisibleUnits
local spGetUnitDefID = Spring.GetUnitDefID
local spGetUnitTeam = Spring.GetUnitTeam
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
local LocalTeam = Spring.GetLocalTeamID()
local ENEMY_UNITS = Spring.ENEMY_UNITS
local texture = "bitmaps/StaticCircle.tga"
local radiusDefs = {}
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
function widget:Initialize()
for uDefID, uDef in pairs(UnitDefs) do
radiusDefs[uDefID] = uDef.radius * 1.25
end
SimpleCircle = glCreateList(function()
glBeginEnd(GL_QUADS, function()
glTexCoord(0.04,0.04)
glVertex(-1,10,-1)
glTexCoord(0.96,0.04)
glVertex(1,10,-1)
glTexCoord(0.96,0.96)
glVertex(1,10,1)
glTexCoord(0.04,0.96)
glVertex(-1,10,1)
end)
end)
end
function widget:Shutdown()
glDeleteList(SimpleCircle)
end
function widget:DrawWorldPreUnit()
glDepthTest(true)
glTexture(texture)
glColor(1.0,0,0,1.0)
local teamID, ud
local visible = GetVisibleUnits(ENEMY_UNITS, nil, false)
for i = 1,#visible do
unitID = visible[i]
teamID = spGetUnitTeam(unitID)
if teamID ~= LocalTeam then
ud = spGetUnitDefID(unitID)
radius = radiusDefs[ud]
glDrawListAtUnit(unitID, SimpleCircle, false, radius, 1.0, radius, 0, 0, 0, 0)
end
end
glTexture(false)
end
Argh wrote: local visible = GetVisibleUnits(ENEMY_UNITS, nil, false)
for i = 1,#visible do
unitID = visible
teamID = spGetUnitTeam(unitID)
if teamID ~= LocalTeam then
jK wrote:Argh wrote: local visible = GetVisibleUnits(ENEMY_UNITS, nil, false)
for i = 1,#visible do
unitID = visible
teamID = spGetUnitTeam(unitID)
if teamID ~= LocalTeam then
Code: Select all
function widget:GetInfo()
return {
name = "Enemy Spotter v.2",
desc = "Draws smoothed octagon under enemy units",
author = "Argh,TradeMark,Trepan",
date = "December 17th, 2009",
license = "(C) WolfeGames, released under GNU GPL, v2 or later",
layer = 5,
enabled = false -- loaded by default?
}
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Automatically generated local definitions
local glBeginEnd = gl.BeginEnd
local glTexCoord = gl.TexCoord
local glTexture = gl.Texture
local GL_QUADS = GL.QUADS
local glColor = gl.Color
local glCreateList = gl.CreateList
local glDeleteList = gl.DeleteList
local glDepthTest = gl.DepthTest
local glDrawListAtUnit = gl.DrawListAtUnit
local glVertex = gl.Vertex
local GetVisibleUnits = Spring.GetVisibleUnits
local spGetUnitDefID = Spring.GetUnitDefID
local spGetUnitTeam = Spring.GetUnitTeam
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
local LocalTeam = Spring.GetLocalTeamID()
local ENEMY_UNITS = Spring.ENEMY_UNITS
local texture = "bitmaps/StaticCircle.tga"
local radiusDefs = {}
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
function widget:Initialize()
for uDefID, uDef in pairs(UnitDefs) do
radiusDefs[uDefID] = uDef.radius * 1.25
end
SimpleCircle = glCreateList(function()
glBeginEnd(GL_QUADS, function()
glTexCoord(0.04,0.04)
glVertex(-1,10,-1)
glTexCoord(0.96,0.04)
glVertex(1,10,-1)
glTexCoord(0.96,0.96)
glVertex(1,10,1)
glTexCoord(0.04,0.96)
glVertex(-1,10,1)
end)
end)
end
function widget:Shutdown()
glDeleteList(SimpleCircle)
end
function widget:DrawWorldPreUnit()
glDepthTest(true)
glTexture(texture)
glColor(1.0,0,0,1.0)
local teamID, ud
local visible = GetVisibleUnits(ENEMY_UNITS, nil, false)
for i = 1,#visible do
unitID = visible[i]
ud = spGetUnitDefID(unitID)
radius = radiusDefs[ud]
glDrawListAtUnit(unitID, SimpleCircle, false, radius, 1.0, radius, 0, 0, 0, 0)
end
glTexture(false)
end
i find it funny you guys are optimizing if's
Code: Select all
if bannana == true
eat pineapple
else
for( i=0; i < 100000000000; i++)
veryexpensiveoperation()
end for
end if
Code: Select all
local X = 0
function Blah()
--use X a little bit, so just leave it as an upvalue
end
Code: Select all
local X = 0
function Blah()
local X_ = X
--use X_ a *lot*, in a loop, needing a tiny performance tweak that makes the function two lines longer
X = X_
end
In Lua, as in any other programming language, we should always follow the two maxims of program optimization:
Rule #1: DonÔÇÖt do it.
Rule #2: DonÔÇÖt do it yet. (for experts only)
Yes. Also, OR and AND are both very, very cheap, so use that instead of arithmetic if you can.If you can avoid significant arithmetic with one, do so.
Well, if it's on GameFrame(), you should worry a bit, simply because it's competing with the rest of the gamecode that's running in that timeslot- over an entire game design, that gets to be an issue. But you can frequently space it out over multiple gameframes, etc.Don't worry about the speed of code that only runs once per frame, outside of a loop.
IDK about that one yet, I will have to test that. According to the document, there are specific size ranges where it might be optimal to build tables with default values at runtime, and do changes to the values, instead of table.insert / table.delete.Don't worry about table sizing. It's not going to come up. The impact of resizing a table isn't that big, and the cost of making huge tables and then not using them is just going to get in the way.
Where's that speedbump, though? 10? 100? 1000? Kinda curious as to how many iterations before the two extra operations + local speedup is actually faster. I have a few things where that would matter, but not much.--use X_ a *lot*, in a loop, needing a tiny performance tweak that makes the function
Yes, but it's usually before we've run a gameframe, assuming it's enabled at startup. IIRC, we're not allowed to begin the first gameframe until all of that has completed. Now, can that possibly cause a desync, if there's a massive disparity between two computers? IDK. I would think not, my experience with Gadgets is that it doesn't do so.very_bad_soldier wrote:Argh, one thing I noticed while testing:
When enabling your widget for the first time, I had a small freeze (maybe 300 ms). Probably while your widget builds the complete unit-radius-table.
Its not dramatic but imagine there were 10 or 20 widgets that would do stuff like that. It would sum up to a very noticable freeze of multiple seconds.
In fact I dont know how it is handled when loading the widgets at gamestart. Would it lead to a small "freeze"?
I think that's good advice.In Lua, as in any other programming language, we should always follow the two maxims of program optimization:
Rule #1: DonÔÇÖt do it.
Rule #2: DonÔÇÖt do it yet. (for experts only)