Open sprunk opened 10 months ago
Regarding unitID per unit with shared script. Could units still have their unitID but share functions?
Also, do you think that the sharing of functions can only be done with an engine update, and cannot be done with a gadget update only?
Regarding unitID per unit with shared script. Could units still have their unitID but share functions?
I see three basic ways to share functions:
1) call setfenv
so the global being referenced is correct. Sounds like it would ruin perf though because not only it is an extra function call that you'd have to call on all functions (since you can't tell which use the global and which don't) and would also force you to use globals (as opposed to being upvalues local to the chunk scope). Note that this also applies to other upvalues that aren't necessarily unitID
(think all the static-vars in cob), these would have to turn from local upvalues into globals as well. I don't think this option is viable.
2) pass the environment table as the parameter. This should be better than setfenv
but changes the interface.
3) make people explicitly put functions in a "static" portion (for example via staticScript.Foo
instead of script.Foo
) and keep the rest (who use per-unit upvalues) as-is. Note that in this approach unitID
can still be in a static function because of Spring.UnitScript.GetActiveUnitID()
. This is IMO the best approach.
do you think that the sharing of functions can only be done with an engine update, and cannot be done with a gadget update only?
This ticket is in the engine repo because that's where basecontent gadgets live but some improvements are gadgetside. This includes the shared functions stuff (note that the engine doesn't even have a concept of unit script environment per se).
Could a metatable not be used for sharing functions?
Possibly! Worth investigating.
Does the order of these calls matter?
Turn(turret, x_axis, math.rad(12), math.rad(34))
Turn(gun, y_axis, math.rad(5), math.rad(6))
Turn(screws, z_axis, math.rad(78), math.rad(90))
If it's literally those 3 lines like that then no, it's not distinguishable. But you could have
Turn(turret, x_axis, math.rad(12), math.rad(34))
if Spring.UnitScript.IsInTurn(turret, x_axis) then
-- stuff
end
Turn(gun, y_axis, math.rad(5), math.rad(6))
Turn(screws, z_axis, math.rad(78), math.rad(90))
and now it matters.
Here are some ways the LUS gadget could be optimized (without touching engine).
math.rad(123)
,SFX.EXPLODE
orz_axis
. The caveat is that Lua lets you redefine these values which the preprocessor won't necessarily know about. This seems like not a real problem though. A basic implementation: https://github.com/ZeroK-RTS/Zero-K/blob/11db6c586a8bd49cbf2a3bc4daec60cf7082023b/LuaRules/Gadgets/unit_script.lua#L587-L594wheel
,gun
etc) so I don't think it's good for newbies to make them work like magic constants seemingly not defined anywhere. I've been thinking about making aPIECE(foo)
macro and then the gadget would just dotext = test:gsub("PIECE%((%w+)%)", Spring.GetModelPieceMap("model.s3o"))
which wouldn't force anything onto existing scripts.script.QueryWeapon
. Note that animation functions do not require aunitID
(animation works on stack principles and these functions just apply to the unit on top of the stack) which is why pure-animation functions could be shared. On the other hand, one of the major points of LUS is to be able to call other Lua interfaces and wrangle the power of the language, which means using upvalues. Perhaps havescript.Foo
andstaticScript.Foo
? Sounds easy to shoot yourself in the foot though. Also perhaps many of them don't even need to be functions which would reduce the pressure to share them, see below.And here are some ways to do more with engine support:
function script.QueryWeapon() return flare end
with ascript.QueryWeapon = flare
. Or, perhaps,Spring.SetQueryPiece(unitID, piece[, weaponNum])
which would reflect howscript.QueryNanoPiece
has been obsoleted bySpring.SetUnitNanoPieces
.