beyond-all-reason / beyond-all-reason/RecoilEngine
Optimise basecontent LUS gadget
- Dominant language
- C++
- Stars
- 683
- Forks
- 293
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 40
Description
Here are some ways the LUS gadget could be optimized (without touching engine).
* pre-process constants like `math.rad(123)`, `SFX.EXPLODE` or `z_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-L594
* pre-process piece names (since they are also essentially numerical constants). The caveat is that pieces tend to have names that look like normal variables (`wheel`, `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 a `PIECE(foo)` macro and then the gadget would just do `text = test:gsub("PIECE%((%w+)%)", Spring.GetModelPieceMap("model.s3o"))` which wouldn't force anything onto existing scripts.
* the environment could be shared where possible, for example right now each unit gets a copy of functions like `script.QueryWeapon`. Note that animation functions do not require a `unitID` (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 have `script.Foo` and `staticScript.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:
* get rid of functions where possible. Most units have just a single query point for example, so it ends up being a function that just immediately returns an upvalue that is (unknowingly to Lua) a constant. I'd replace the `function script.QueryWeapon() return flare end` with a `script.QueryWeapon = flare`. Or, perhaps, `Spring.SetQueryPiece(unitID, piece[, weaponNum])` which would reflect how `script.QueryNanoPiece` has been obsoleted by `Spring.SetUnitNanoPieces`.
* ~~reduce the number of Turn/Move etc calls by introducing a multi-arg call (possibly just extending the existing one), it would just take 4N args.~~ **Done** #1527
Contributor guide
Research direction
Start with LuaRules/Gadgets/unit_script.lua around the referenced lines 587-594, then inspect the LUS gadget handling of constants, piece names, environments, and animation functions. The issue contains several alternative optimizations rather than one defined change; work is not complete until a specific proposal and its acceptance criteria are selected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- lua
- Domain
- game-dev, performance
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100