LuaCallinReturn: Difference between revisions

From Spring
Jump to navigationJump to search
Argh (talk | contribs)
No edit summary
Maddox (talk | contribs)
m Added params and description to AllowFeatureBuildStep
 
(117 intermediate revisions by 24 users not shown)
Line 1: Line 1:
''Here are the known reserved parameter values for all Lua Call-Ins.  If you add new Call-Ins to Spring, please document them here.''
[[Engine_Development|Development]] < [[Lua_Scripting|Lua Scripting]] < {{FULLPAGENAME}}


<font style="font-size:80%">
==Engine Source==
If you can understand Lua code well and wish to get the most up to date info, you can refer to:
{{sourcelink|file=cont/base/springcontent/LuaGadgets/actions.lua}},
{{sourcelink|file=cont/LuaUI/widgets.lua}} and <br>
{{sourcelink|file=cont/base/springcontent/LuaGadgets/gadgets.lua}} <br>
to see how widget/gadget call-ins are distributed, find call-in and widgetHandler function definitions, see how they are processed and what values should be returned from some call ins
(are these the only files?)


Shutdown() --> none.
==What is a callin anyway?==
LayoutButtons() --> unknown, please document.
Call-ins are calls from the engine, into the gadget or widget script. In other words, these functions are called when a particular ''event'' happens.
ConfigureLayout() --> "command".
Some call-in functions can return values to the engine.
CommandNotify() --> "id, params, options", where id = the CommandID
===Blocking events with return values===
KeyPress() --> "key, mods, isRepeat", where key = keymap, mods = SHIFT, etc.
The call-in functions named '''''Allow'''''XXX can block their event by returning ''false''.<br>
KeyRelease() --> "key"
For example ''AllowUnitTransfer()''<br>
MouseMove() --> "x, y, dx, dy, button"
<code>return true</code> = allow transfer <br>
MousePress() --> "x, y, button"
<code>return false</code> = deny transfer
MouseRelease() --> "x, y, button"
IsAbove() --> "x, y" where x,y = screen coordinates.
GetTooltip() --> "x, y" where x,y = screen coordinates.  Returns WorldTooltip.
AddConsoleLine() --> "msg, priority"
GroupChanged() --> "groupID" where groupID is the value of Group whose table value changed.
WorldTooltip() --> "ttType, data1, data2, data3" special, should be documented in detail.


GameStart() --> unknown, but probably nil.
==Commands, general-purpose:==
GameOver() --> none.
TeamDied() --> "TeamID" where TeamID = the team that has been eliminated.


UnitCreated() --> "unitID, unitDefID, teamID" ... I hope that's self-explanatory
<font color=#55ee99>Initialize()</font> --> none.<br>
UnitFinished() --> "unitID, unitDefID, teamID"
called when widget/gadget gets (re-)loaded.
UnitFromFactory() --> "unitID, unitDefID, unitTeam, factID, factDefID, userOrders"
UnitDestroyed() --> "unitID, unitDefID, teamID"
UnitTaken() --> "unitID, unitDefID, unitTeam, newTeam"
UnitGiven() --> "unitID, unitDefID, unitTeam, oldTeam"
UnitIdle() --> "unitID, unitDefID, teamID"
UnitCommand() -->  unknown, please document.
UnitSeismicPing() --> "x, y, z, strength"
UnitEnteredRadar() --> "unitID, unitTeam"
UnitEnteredLos() --> "unitID, unitDefID, teamID"
UnitLeftRadar() --> "unitID, unitTeam"
UnitLeftLos() --> "unitID, unitDefID, teamID"
UnitLoaded() --> "unitID, unitDefID, unitTeam, transportID, transportTeam"
UnitUnloaded() --> "unitID, unitDefID, teamID, transportID"
UnitCloaked--> "unitID, unitDefID, teamID"
UnitDecloaked--> "unitID, unitDefID, teamID"
UnitMoveFailed--> "unitID, unitDefID, unitTeam"
StockpileChanged--> "unitID, unitDefID, unitTeam, weaponNum, oldCount, newCount"


UnitEnteredWater() --> "unitID, unitDefID, teamID"
<font color=#55ee99>Shutdown()</font> --> none.
UnitEnteredAir() --> "unitID, unitDefID, teamID"
UnitLeftWater() --> "unitID, unitDefID, teamID"
UnitLeftAir() --> "unitID, unitDefID, teamID"


FeatureCreated() --> "featureID, allyTeam"
<font color=#55ee99>PlayerChanged</font> --> (playerID).
FeatureDestroyed() --> "featureID, allyTeam"
gadget/widget: Use this to check whether a player has become spectator for instance.


DrawGenesis() --> none.
<font color=#55ee99>LayoutButtons()</font> --> unknown, please document.
DrawWorld() --> none.
DrawWorldPreUnit() --> none.
DrawWorldShadow() --> none.
DrawWorldReflection() --> none.
DrawWorldRefraction() --> none.
DrawScreenEffects() --> "vsx, vsy" where vsx, vsy are screen coords.
DrawScreen() --> none.
DrawInMiniMap() --> "sx, sy" where sx,sy are values relative to the minimap's position and scale.


Explosion() --> "weaponID, px, py, pz, ownerID"
<font color=#55ee99>ConfigureLayout()</font> --> "command".
ShockFront() --> "power, dx, dy, dz"


GameFrame() --> "frameNum"
<font color=#55ee99>CommandNotify()</font> --> "id, params, options", where id = the CommandID
CobCallback() --> unknown, marked FIXME.
 
AllowCommand() --> "unitID, unitDefID, unitTeam, cmdID, cmdParams, cmdOptions, cmdTag, synced"
<font color=#55ee99>KeyPress()</font> --> "key, mods, isRepeat", where key = keymap, mods = SHIFT, etc.
CommandFallback() --> "unitID, unitDefID, unitTeam, cmdID, cmdParams, cmdOptions, cmdTag"
 
AllowUnitCreation() --> "unitDefID, builderID, builderTeam, x, y, z"
<font color=#55ee99>KeyRelease()</font> --> "key"
AllowUnitTransfer() --> "unitID, unitDefID, oldTeam, newTeam, capture"
 
AllowUnitBuildStep() --> "builderID, builderTeam, unitID, unitDefID, part"
<font color=#55ee99>MouseMove()</font> --> "x, y, dx, dy, button"
AllowFeatureCreation() --> "featureDefID, teamID, x, y, z"
 
AllowFeatureBuildStep() --> unknown, please document.
<font color=#55ee99>MousePress()</font> --> "x, y, button"<br/>
AllowResourceLevel() --> "teamID, res, level"
<font color=#dd9944>button parameter values: left - 1, middle - 2, right - 3</font>
AllowResourceTransfer() --> "teamID, res, level"
 
{{new|>96.0}} buttom param removed  {{Sourcelinkhash|4c104344e92256e33d79820e9012c5e1178e212b}}
 
 
<font color=#55ee99>MouseRelease()</font> --> "x, y, button"<br/>
<font color=#dd9944>Please note that in order to have Spring call MouseRelease, you need to have a MousePress call-in in the same widget that returns true.</font>
 
<font color=#55ee99>MouseWheel()</font> --> "up, value"
 
<font color=#55ee99>IsAbove()</font> --> "x, y" where x,y = screen coordinates.
 
<font color=#55ee99>GetTooltip()</font> --> "x, y" where x,y = screen coordinates.  Returns WorldTooltip.
 
<font color=#55ee99>AddConsoleLine()</font> --> "msg, priority"
 
<font color=#55ee99>MapDrawCmd()</font> --> "playerID, cmdType, px, py, pz, labeltext"
 
<font color=#55ee99>AllowCommand()</font> --> "unitID, unitDefID, unitTeam, cmdID, cmdParams, cmdOptions, cmdTag, synced"<br />
<font color=#dd9944>Synced only.</font>
 
<font color=#55ee99>CommandFallback()</font> --> "unitID, unitDefID, unitTeam, cmdID, cmdParams, cmdOptions, cmdTag"
 
<font color=#55ee99>CommandsChanged()</font> --> unknown (none?)
 
<font color=#55ee99>AllowUnitCreation()</font> --> "unitDefID, builderID, builderTeam, x, y, z, facing"
 
<font color=#55ee99>AllowUnitTransfer()</font> --> "unitID, unitDefID, oldTeam, newTeam, capture"
 
<font color=#55ee99>AllowUnitBuildStep()</font> --> "builderID, builderTeam, unitID, unitDefID, part"
 
<font color=#55ee99>AllowFeatureCreation()</font> --> "featureDefID, teamID, x, y, z"
 
<font color=#55ee99>AllowFeatureBuildStep()</font> --> "builderID, builderTeam, featureID, featureDefID, part"</font><br>
<font color=#dd9944>Called just before a feature updates its build percentage. Returns a bool to allow the change.</font>
 
<font color=#55ee99>AllowResourceLevel()</font> --> "teamID, res, level"
 
<font color=#55ee99>AllowResourceTransfer()</font> --> "teamID, res, level"</font>
 
<font color=#55ee99>Update()</font> --> "dt"<br>
<font color=#dd9944>called every screenframe. dt is the time since the last screenframe</font>
 
<font color=#55ee99>DefaultCommand()</font> --> "type,id"<br>
<font color=#dd9944>can return an [[Lua_CMDs|CMD]] to change cursor and command. {{forumlink|topic=26438|title=example usage}}</font>
 
<font color=#55ee99>AllowDirectUnitControl(unitID, unitDefID, unitTeam, playerID)  </font> -> allowFpsControl<br>
''return true'' allows fps mode, ''return false'' blocks it.
 
==Unit-Specific:==
 
<font color=#55ee99>UnitPreDamaged()</font> --> "unitID, unitDefID, unitTeam, damage, paralyzer, weaponDefID, attackerID, attackerDefID, attackerTeam" <span class="warning">(prior to 94.0)</span>
 
<font color=#55ee99>UnitPreDamaged()</font> --> "unitID, unitDefID, unitTeam, damage, paralyzer, weaponDefID, projectileID, attackerID, attackerDefID, attackerTeam" <span class="warning">(as of 94.0)</span>
 
<font color=#55ee99>UnitDamaged()</font> --> "unitID, unitDefID, unitTeam, damage, paralyzer, weaponDefID, projectileID, attackerID, attackerDefID, attackerTeam" <span class="warning">(as of 95.0)</span> <br>
<font color=#dd9944>Can overwrite the taken damage by returning a new number value.<br>
 
As of 88.0 for both UnitDamaged and UnitPreDamaged:
    weaponDefID -1 --> debris collision
    weaponDefID -2 --> ground collision
    weaponDefID -3 --> object collision
    weaponDefID -4 --> fire damage
    weaponDefID -5 --> water damage
    weaponDefID -6 --> kill damage
    weaponDefID -7 --> crush damage
 
As of 96.0 {Unit,Feature}{Pre}Damaged events receive the 'attacker' ID when object is crushed</font>
 
<font color=#55ee99>UnitExperience()</font> --> "unitID, unitDefID, unitTeam, experience, oldExperience"<br>
<font color=#dd9944>Spring.SetExperienceGrade must be called first to determine how often it is called</font>
 
<font color=#55ee99>UnitCreated()</font> --> "unitID, unitDefID, teamID, builderID"<br>
<font color=#dd9944>Unit started being built (it's in wireframe mode)</font>
 
<font color=#55ee99>UnitFinished()</font> --> "unitID, unitDefID, teamID"
 
<font color=#55ee99>UnitFromFactory()</font> --> "unitID, unitDefID, unitTeam, factID, factDefID, userOrders"
 
<font color=#55ee99>UnitDestroyed()</font> --> "unitID, unitDefID, teamID, attackerID, attackerDefID, attackerTeamID"
 
<font color=#55ee99>UnitTaken()</font> --> "unitID, unitDefID, unitTeam, newTeam"<br>
<font color=#dd9944>Unit still belongs to old team</font>
 
<font color=#55ee99>UnitGiven()</font> --> "unitID, unitDefID, unitTeam, oldTeam"<br>
<font color=#dd9944>Unit now belongs to new team</font>
 
<font color=#55ee99>UnitIdle()</font> --> "unitID, unitDefID, teamID"<br>
<font color=#dd9944>No commands in this unit's queue. Beware, might be fired while 'guarding'.</font>
 
<font color=#55ee99>UnitCommand()</font> --> "unitID, unitDefID, unitTeam, cmdID, cmdOpts, cmdParams, cmdTag" <span class="warning">(cmdTag only available from version 95.0)</span>
 
 
<font color=#55ee99>UnitSeismicPing()</font> --> "x, y, z, strength"
 
<font color=#55ee99>UnitEnteredRadar()</font> --> "unitID, unitTeam"
 
<font color=#55ee99>UnitEnteredLos()</font> --> "unitID, teamID"
 
<font color=#55ee99>UnitLeftRadar()</font> --> "unitID, unitTeam"
 
<font color=#55ee99>UnitLeftLos()</font> --> "unitID, unitDefID, teamID"
 
<font color=#55ee99>UnitLoaded()</font> --> "unitID, unitDefID, unitTeam, transportID, transportTeam"
 
<font color=#55ee99>UnitUnloaded()</font> --> "unitID, unitDefID, teamID, transportID"
 
<font color=#55ee99>UnitCloaked()</font> --> "unitID, unitDefID, teamID"
 
<font color=#55ee99>UnitDecloaked)</font>--> "unitID, unitDefID, teamID"
 
<font color=#55ee99>UnitMoveFailed()</font> --> "unitID, unitDefID, unitTeam"
<br><font color=#dd9944>Only called for unitDefIDs registered via [[Lua_System#Synced|Script.SetWatchUnit]] since 85.0</font>
 
<font color=#55ee99>StockpileChanged()</font> --> "unitID, unitDefID, unitTeam, weaponNum, oldCount, newCount"
 
<font color=#55ee99>UnitEnteredWater()</font> --> "unitID, unitDefID, teamID"
<span class="warning">(as of 95.0)</span>
 
<font color=#55ee99>UnitEnteredAir()</font> --> "unitID, unitDefID, teamID"
<span class="warning">(as of 95.0)</span>
 
<font color=#55ee99>UnitLeftWater()</font> --> "unitID, unitDefID, teamID"
<span class="warning">(as of 95.0)</span>
 
<font color=#55ee99>UnitLeftAir()</font> --> "unitID, unitDefID, teamID"
<span class="warning">(as of 95.0)</span>
 
<font color=#55ee99>ShieldPreDamaged()</font> --> "proID, shieldEmitterWeaponNum, shieldCarrierUnitID, boolBounceProjectile, beamEmitterWaponNumber, beamCarrierUnitID, startx, starty, startz, hitx, hity, hitz"
 
<font color=#55ee99>UnitUnitCollision(colliderID, collideeID)</font> -- needs SetWatchUnit enabled for both parties
 
<font color=#55ee99>AllowWeaponTargetCheck(attackerID, attackerWeaponNum, attackerWeaponDefID)</font><br><font color=#dd9944>Only called for weaponDefIDs registered via [[Lua_System#Synced|Script.SetWatchWeapon]] since 92.0</font>
 
<font color=#55ee99>AllowWeaponTarget(attackerID, targetID, attackerWeaponNum, attackerWeaponDefID, defaultPriority)</font>
--> <code>return "targetAllowed, targetPriority"</code>
<span class="warning">defaultPriority new in 89.0</span><br>
 
<font color=#dd9944>Only called for weaponDefIDs registered via [[Lua_System#Synced|Script.SetWatchWeapon]] since 92.0</font>
 
<font color=#55ee99>DrawShield(number unitID, number weaponID)</font> --> boolean
 
''true'' (<-?) skips Spring's own drawing of shield <weaponID> owned by unit <unitID>
 
[https://github.com/spring/spring/commit/7bbfd9464d4f74c12163ea0740c8c60d1ba978f1 maybe new in 86.0+]
 
==Feature-Specific:==
 
<font color=#55ee99>FeatureCreated()</font> --> "featureID, allyTeam"
 
<font color=#55ee99>FeatureDestroyed()</font> --> "featureID, allyTeam"
 
<font color=#55ee99>TerraformComplete()</font> --> "unitID, unitDefID, unitTeam, buildUnitID, buildUnitDefID, buildUnitTeam"
 
<font color=#55ee99>UnitCmdDone()</font> --> "unitID, unitDefID, unitTeam, cmdID, cmdTag, cmdParams, cmdOptions" <span class="warning">cmdParams and cmdOptions are only available from version 95.0</span>
 
<font color=#55ee99>UnitFeatureCollision(colliderID, collideeID, crushKilled)</font> -- needs SetWatchUnit for first and SetWatchFeature for second party
 
{{new|95.0}} <font color=#55ee99>FeatureDamaged()</font> --> "featureID, featureDefID, featureTeam, damage, weaponDefID, projectileID, attackerID, attackerDefID, attackerTeam"
 
{{new|95.0}} <font color=#55ee99>FeaturePreDamaged()</font> --> "featureID, featureDefID, featureTeam, damage, weaponDefID, projectileID, attackerID, attackerDefID, attackerTeam"
 
<code>--> return newDamage, impulseMult (=0)</code>
 
==Drawing:==
Inside these functions, you can use the [[Lua_OpenGL_Api | Lua OpenGL Api]] to draw graphics.
 
* <font color=#55ee99>DrawGenesis()</font> --> none.  Don't render here.
 
Spring draws the sky, the map, some water types, and unit selection.
 
* <font color=#55ee99>DrawWorldPreUnit()</font> --> none.
 
Spring draws units, features, some water types, cloaked units, and the sun.
 
* <font color=#55ee99>DrawWorld()</font> --> none.
 
Spring draws command queues, 'map stuff', and map marks.
 
Each unit might also have a DrawUnit call, [[Lua_UnitRendering|enabled here.]]
 
<font color=#55ee99>DrawUnit(unitID,DrawMode)</font><br>
With enum DrawMode {<br>
notDrawing    = 0,<br>
normalDraw    = 1,<br>
shadowDraw    = 2,<br>
reflectionDraw = 3,<br>
refractionDraw = 4<br>
};
 
<font color=#55ee99>DrawFeature(featureID, DrawMode)</font><br>
 
<font color=#55ee99>DrawShield(unitID, weaponID, DrawMode)</font><br>
 
<font color=#55ee99>DrawProjectile(projectileID, DrawMode)</font><br>
 
<font color=#55ee99>DrawScreenEffects()</font> --> "vsx, vsy" where vsx, vsy are screen coords.
 
<font color=#55ee99>DrawScreen()</font> --> none.
 
<font color=#55ee99>DrawInMiniMap()</font> --> "sx, sy" where sx,sy are values relative to the minimap's position and scale.
 
<font color=#55ee99>DrawWorldShadow()</font> --> none.
 
<font color=#55ee99>DrawWorldReflection()</font> --> none.
 
<font color=#55ee99>DrawWorldRefraction()</font> --> none.
 
<font color=#55ee99>DrawLoadScreen()</font> --> none. {{new|95.0}}
 
Only available to LuaIntro, draws custom load screens.
 
==Game Events:==
 
<font color=#55ee99>GameID()</font> --> "gameID" {{new|89.0}}
 
<font color=#55ee99>Explosion()</font> --> "weaponID, px, py, pz, ownerID"
<br><font color=#dd9944>Only called for weaponDefIDs registered via Script.SetWatchWeapon</font>
<br>return true to hide the weapon's CEG
 
<font color=#55ee99>ShockFront()</font> --> "power, dx, dy, dz" <span class="warning">Not yet implemented!</span>
 
<font color=#55ee99>GameFrame()</font> --> "frameNum"
 
<font color=#55ee99>CobCallback()</font> --> unknown, marked FIXME.
 
<font color=#55ee99>GroupChanged()</font> --> "groupID" where groupID is the value of Group whose table value changed.
 
<font color=#55ee99>WorldTooltip()</font> --> "ttType, data1, data2, data3" special, should be documented in detail. <span class="warning">Not yet implemented!</span>
 
<font color=#55ee99>GamePreload()</font>  --> none.
 
<font color=#55ee99>GameStart()</font> --> none.
 
<font color=#55ee99>GameProgress()</font> --> "serverFrameNum" ( called every 60 frames, calculating delta between GameFrame and GameProgress can give an ETA about catching up with simulation )<span class="warning"> Not yet implemented!</span>
 
<font color=#55ee99>GameOver()</font> -->  "[ [1] = allyTeamID1, [2] = allyTeamID2, ... ]",  a list of winning allyteams, if empty the game result was undecided ( like when dropping from an host )<span class="warning">  Will return nil in pre 0.83.x</span>
 
<font color=#55ee99>TeamDied()</font> --> "TeamID" where TeamID = the team that has been eliminated.
 
<font color=#55ee99>AllowStartPosition()</font> -->
  number clampedPos.x, number clampedPos.y, number clampedPos.z,
  number playerID,
  number readyState,
  number rawPickPos.x, number rawPickPos.y, number rawPickPos.z
 
FIXME: apparently the above is incorrect and parameters are AllowStartPosition(playerID, teamID, readyState, cx, cy, cz, rx, ry, rz)
 
clampedPos = coordinates clamped into startbox, rawPickPos = where player tried to start
 
{{New|95.0}} the default 'failed to choose' start-position is now just (0,0,0), not (0,-500,0)
 
 
readyState can be any one of:
    PLAYER_RDYSTATE_UPDATED = 0 -- player picked a position
    PLAYER_RDYSTATE_READIED = 1 -- player clicked ready
    PLAYER_RDYSTATE_FORCED = 2 -- game was force-started (player did not click ready)
    PLAYER_RDYSTATE_FAILED = 3
 
 
<font color=#55ee99>GameSetup()</font> --> string "state", boolean "ready", table "playerStates"
<br>return success, newReady
 
<font color=#55ee99>GamePaused()</font> --> "playerID, paused"
 
<font color=#55ee99>PlayerAdded()</font> --> "playerID"
 
<font color=#55ee99>PlayerRemoved()</font> --> "playerID, reason"
 
==Projectiles:==
 
<font color=#55ee99>ProjectileCreated()</font> --> "proID, proOwnerID, weaponDefID"
<br><font color=#dd9944>Only called for weaponDefIDs registered via Script.SetWatchWeapon</font>
 
<font color=#55ee99>ProjectileDestroyed()</font> --> "proID"
<br><font color=#dd9944>Only called for weaponDefIDs registered via Script.SetWatchWeapon</font>
 
<font color=#55ee99>AllowWeaponInterceptTarget</font> --> "number interceptorUnitID, number interceptorWeaponID, number targetProjectileID"
returns boolean
<br><font color=#dd9944>Only called for weaponDefIDs registered via Script.SetWatchWeapon</font>
 
[[Category:Deprecated]]

Latest revision as of 20:52, 24 May 2022

Development < Lua Scripting < LuaCallinReturn

Engine Source

If you can understand Lua code well and wish to get the most up to date info, you can refer to: cont/base/springcontent/LuaGadgets/actions.lua , cont/LuaUI/widgets.lua and
cont/base/springcontent/LuaGadgets/gadgets.lua
to see how widget/gadget call-ins are distributed, find call-in and widgetHandler function definitions, see how they are processed and what values should be returned from some call ins (are these the only files?)

What is a callin anyway?

Call-ins are calls from the engine, into the gadget or widget script. In other words, these functions are called when a particular event happens. Some call-in functions can return values to the engine.

Blocking events with return values

The call-in functions named AllowXXX can block their event by returning false.
For example AllowUnitTransfer()
return true = allow transfer
return false = deny transfer

Commands, general-purpose:

Initialize() --> none.
called when widget/gadget gets (re-)loaded.

Shutdown() --> none.

PlayerChanged --> (playerID). gadget/widget: Use this to check whether a player has become spectator for instance.

LayoutButtons() --> unknown, please document.

ConfigureLayout() --> "command".

CommandNotify() --> "id, params, options", where id = the CommandID

KeyPress() --> "key, mods, isRepeat", where key = keymap, mods = SHIFT, etc.

KeyRelease() --> "key"

MouseMove() --> "x, y, dx, dy, button"

MousePress() --> "x, y, button"
button parameter values: left - 1, middle - 2, right - 3

New in version >96.0 buttom param removed 4c104344


MouseRelease() --> "x, y, button"
Please note that in order to have Spring call MouseRelease, you need to have a MousePress call-in in the same widget that returns true.

MouseWheel() --> "up, value"

IsAbove() --> "x, y" where x,y = screen coordinates.

GetTooltip() --> "x, y" where x,y = screen coordinates. Returns WorldTooltip.

AddConsoleLine() --> "msg, priority"

MapDrawCmd() --> "playerID, cmdType, px, py, pz, labeltext"

AllowCommand() --> "unitID, unitDefID, unitTeam, cmdID, cmdParams, cmdOptions, cmdTag, synced"
Synced only.

CommandFallback() --> "unitID, unitDefID, unitTeam, cmdID, cmdParams, cmdOptions, cmdTag"

CommandsChanged() --> unknown (none?)

AllowUnitCreation() --> "unitDefID, builderID, builderTeam, x, y, z, facing"

AllowUnitTransfer() --> "unitID, unitDefID, oldTeam, newTeam, capture"

AllowUnitBuildStep() --> "builderID, builderTeam, unitID, unitDefID, part"

AllowFeatureCreation() --> "featureDefID, teamID, x, y, z"

AllowFeatureBuildStep() --> "builderID, builderTeam, featureID, featureDefID, part"
Called just before a feature updates its build percentage. Returns a bool to allow the change.

AllowResourceLevel() --> "teamID, res, level"

AllowResourceTransfer() --> "teamID, res, level"

Update() --> "dt"
called every screenframe. dt is the time since the last screenframe

DefaultCommand() --> "type,id"
can return an CMD to change cursor and command. example usage

AllowDirectUnitControl(unitID, unitDefID, unitTeam, playerID) -> allowFpsControl
return true allows fps mode, return false blocks it.

Unit-Specific:

UnitPreDamaged() --> "unitID, unitDefID, unitTeam, damage, paralyzer, weaponDefID, attackerID, attackerDefID, attackerTeam" (prior to 94.0)

UnitPreDamaged() --> "unitID, unitDefID, unitTeam, damage, paralyzer, weaponDefID, projectileID, attackerID, attackerDefID, attackerTeam" (as of 94.0)

UnitDamaged() --> "unitID, unitDefID, unitTeam, damage, paralyzer, weaponDefID, projectileID, attackerID, attackerDefID, attackerTeam" (as of 95.0)
Can overwrite the taken damage by returning a new number value.

As of 88.0 for both UnitDamaged and UnitPreDamaged:

    weaponDefID -1 --> debris collision
    weaponDefID -2 --> ground collision
    weaponDefID -3 --> object collision
    weaponDefID -4 --> fire damage
    weaponDefID -5 --> water damage
    weaponDefID -6 --> kill damage
    weaponDefID -7 --> crush damage

As of 96.0 {Unit,Feature}{Pre}Damaged events receive the 'attacker' ID when object is crushed

UnitExperience() --> "unitID, unitDefID, unitTeam, experience, oldExperience"
Spring.SetExperienceGrade must be called first to determine how often it is called

UnitCreated() --> "unitID, unitDefID, teamID, builderID"
Unit started being built (it's in wireframe mode)

UnitFinished() --> "unitID, unitDefID, teamID"

UnitFromFactory() --> "unitID, unitDefID, unitTeam, factID, factDefID, userOrders"

UnitDestroyed() --> "unitID, unitDefID, teamID, attackerID, attackerDefID, attackerTeamID"

UnitTaken() --> "unitID, unitDefID, unitTeam, newTeam"
Unit still belongs to old team

UnitGiven() --> "unitID, unitDefID, unitTeam, oldTeam"
Unit now belongs to new team

UnitIdle() --> "unitID, unitDefID, teamID"
No commands in this unit's queue. Beware, might be fired while 'guarding'.

UnitCommand() --> "unitID, unitDefID, unitTeam, cmdID, cmdOpts, cmdParams, cmdTag" (cmdTag only available from version 95.0)


UnitSeismicPing() --> "x, y, z, strength"

UnitEnteredRadar() --> "unitID, unitTeam"

UnitEnteredLos() --> "unitID, teamID"

UnitLeftRadar() --> "unitID, unitTeam"

UnitLeftLos() --> "unitID, unitDefID, teamID"

UnitLoaded() --> "unitID, unitDefID, unitTeam, transportID, transportTeam"

UnitUnloaded() --> "unitID, unitDefID, teamID, transportID"

UnitCloaked() --> "unitID, unitDefID, teamID"

UnitDecloaked)--> "unitID, unitDefID, teamID"

UnitMoveFailed() --> "unitID, unitDefID, unitTeam"
Only called for unitDefIDs registered via Script.SetWatchUnit since 85.0

StockpileChanged() --> "unitID, unitDefID, unitTeam, weaponNum, oldCount, newCount"

UnitEnteredWater() --> "unitID, unitDefID, teamID" (as of 95.0)

UnitEnteredAir() --> "unitID, unitDefID, teamID" (as of 95.0)

UnitLeftWater() --> "unitID, unitDefID, teamID" (as of 95.0)

UnitLeftAir() --> "unitID, unitDefID, teamID" (as of 95.0)

ShieldPreDamaged() --> "proID, shieldEmitterWeaponNum, shieldCarrierUnitID, boolBounceProjectile, beamEmitterWaponNumber, beamCarrierUnitID, startx, starty, startz, hitx, hity, hitz"

UnitUnitCollision(colliderID, collideeID) -- needs SetWatchUnit enabled for both parties

AllowWeaponTargetCheck(attackerID, attackerWeaponNum, attackerWeaponDefID)
Only called for weaponDefIDs registered via Script.SetWatchWeapon since 92.0

AllowWeaponTarget(attackerID, targetID, attackerWeaponNum, attackerWeaponDefID, defaultPriority)

--> return "targetAllowed, targetPriority"

defaultPriority new in 89.0

Only called for weaponDefIDs registered via Script.SetWatchWeapon since 92.0

DrawShield(number unitID, number weaponID) --> boolean

true (<-?) skips Spring's own drawing of shield <weaponID> owned by unit <unitID>

maybe new in 86.0+

Feature-Specific:

FeatureCreated() --> "featureID, allyTeam"

FeatureDestroyed() --> "featureID, allyTeam"

TerraformComplete() --> "unitID, unitDefID, unitTeam, buildUnitID, buildUnitDefID, buildUnitTeam"

UnitCmdDone() --> "unitID, unitDefID, unitTeam, cmdID, cmdTag, cmdParams, cmdOptions" cmdParams and cmdOptions are only available from version 95.0

UnitFeatureCollision(colliderID, collideeID, crushKilled) -- needs SetWatchUnit for first and SetWatchFeature for second party

New in version 95.0 FeatureDamaged() --> "featureID, featureDefID, featureTeam, damage, weaponDefID, projectileID, attackerID, attackerDefID, attackerTeam"

New in version 95.0 FeaturePreDamaged() --> "featureID, featureDefID, featureTeam, damage, weaponDefID, projectileID, attackerID, attackerDefID, attackerTeam"

--> return newDamage, impulseMult (=0)

Drawing:

Inside these functions, you can use the Lua OpenGL Api to draw graphics.

  • DrawGenesis() --> none. Don't render here.
Spring draws the sky, the map, some water types, and unit selection.
  • DrawWorldPreUnit() --> none.
Spring draws units, features, some water types, cloaked units, and the sun.
  • DrawWorld() --> none.
Spring draws command queues, 'map stuff', and map marks.

Each unit might also have a DrawUnit call, enabled here.

DrawUnit(unitID,DrawMode)
With enum DrawMode {
notDrawing = 0,
normalDraw = 1,
shadowDraw = 2,
reflectionDraw = 3,
refractionDraw = 4
};

DrawFeature(featureID, DrawMode)

DrawShield(unitID, weaponID, DrawMode)

DrawProjectile(projectileID, DrawMode)

DrawScreenEffects() --> "vsx, vsy" where vsx, vsy are screen coords.

DrawScreen() --> none.

DrawInMiniMap() --> "sx, sy" where sx,sy are values relative to the minimap's position and scale.

DrawWorldShadow() --> none.

DrawWorldReflection() --> none.

DrawWorldRefraction() --> none.

DrawLoadScreen() --> none. New in version 95.0

Only available to LuaIntro, draws custom load screens.

Game Events:

GameID() --> "gameID" New in version 89.0

Explosion() --> "weaponID, px, py, pz, ownerID"
Only called for weaponDefIDs registered via Script.SetWatchWeapon
return true to hide the weapon's CEG

ShockFront() --> "power, dx, dy, dz" Not yet implemented!

GameFrame() --> "frameNum"

CobCallback() --> unknown, marked FIXME.

GroupChanged() --> "groupID" where groupID is the value of Group whose table value changed.

WorldTooltip() --> "ttType, data1, data2, data3" special, should be documented in detail. Not yet implemented!

GamePreload() --> none.

GameStart() --> none.

GameProgress() --> "serverFrameNum" ( called every 60 frames, calculating delta between GameFrame and GameProgress can give an ETA about catching up with simulation ) Not yet implemented!

GameOver() --> "[ [1] = allyTeamID1, [2] = allyTeamID2, ... ]", a list of winning allyteams, if empty the game result was undecided ( like when dropping from an host ) Will return nil in pre 0.83.x

TeamDied() --> "TeamID" where TeamID = the team that has been eliminated.

AllowStartPosition() -->

  number clampedPos.x, number clampedPos.y, number clampedPos.z,
  number playerID,
  number readyState,
  number rawPickPos.x, number rawPickPos.y, number rawPickPos.z

FIXME: apparently the above is incorrect and parameters are AllowStartPosition(playerID, teamID, readyState, cx, cy, cz, rx, ry, rz)

clampedPos = coordinates clamped into startbox, rawPickPos = where player tried to start

New in version 95.0 the default 'failed to choose' start-position is now just (0,0,0), not (0,-500,0)


readyState can be any one of:

   PLAYER_RDYSTATE_UPDATED = 0 -- player picked a position
   PLAYER_RDYSTATE_READIED = 1 -- player clicked ready
   PLAYER_RDYSTATE_FORCED = 2 -- game was force-started (player did not click ready)
   PLAYER_RDYSTATE_FAILED = 3


GameSetup() --> string "state", boolean "ready", table "playerStates"
return success, newReady

GamePaused() --> "playerID, paused"

PlayerAdded() --> "playerID"

PlayerRemoved() --> "playerID, reason"

Projectiles:

ProjectileCreated() --> "proID, proOwnerID, weaponDefID"
Only called for weaponDefIDs registered via Script.SetWatchWeapon

ProjectileDestroyed() --> "proID"
Only called for weaponDefIDs registered via Script.SetWatchWeapon

AllowWeaponInterceptTarget --> "number interceptorUnitID, number interceptorWeaponID, number targetProjectileID" returns boolean
Only called for weaponDefIDs registered via Script.SetWatchWeapon