Lua:Callins

From Spring

Lua Callins

This page is future looking to unified widget/gadget (aka "addon") handler, which may yet be some way off, c.f. the changelog.

Related Sourcecode : https://github.com/spring/spring/rts/Lua/LuaHandle.cpp

For now, to use these addons in a widget, replace addon with widget and, for a gadget, replace addon with gadget. For example,

    function widget:UnitCreated(unitID, unitDefID, unitTeam, builderID)
        ...  
    end

Some functions may differ between (synced) gadget and widgets; those are in the #Synced_-_Unsynced_Shared section. Essentially the reason is that all information should be available to synced (game logic controlling) gadgets, but restricted to unsynced gadget/widget (e.g. information about an enemy unit only detected via radar and not yet in LOS). In such cases the full (synced) param list is documented.

Attention: some callins will only work on the unsynced portion of the gadget. Due to the type-unsafe nature of lua parsing, those callins not firing up might be hard to trace. This document will be continuously updated to properly alert about those situations.

Common

addon.Initialize()

Called when the addon is (re)loaded.


addon.Shutdown()

Called when the addon or the game is shutdown.


Unsynced Only

addon.DefaultCommand(type, id)
return: number cmdID

Used to set the default command when a unit is selected. First parameter is the type of the object pointed at (either "unit or "feature") and the second is its unitID or featureID respectively.


addon.CommandNotify(cmdID, cmdParams, cmdOptions)
return: bool removeCmd

Called when a command is issued. Returning true deletes the command and does not send it through the network.


addon.CommandsChanged(None)
return: ?

Called when the command descriptions changed, e.g. when selecting or deselecting a unit.


addon.WorldTooltip(ttType, data1, data2, data3)
return: string newTooltip

The parameters can be "unit", unitID; "feature", featureID; "ground", posX, posY, posZ or "selection".


addon.UnsyncedHeightMapUpdate(???)

Called when the unsynced copy of the height-map is altered.


addon.GameProgress(serverFrameNum)

Called every 60 frames, calculating delta between GameFrame and GameProgress. Can give an ETA about catching up with simulation for mid-game join players.


addon.GameSetup(state, ready, playerStates)
return: bool success, bool newReady

???


addon.SunChanged(???)

???


addon.AddConsoleLine(msg, priority)

Called when text is entered into the console (e.g. Spring.Echo).


addon.RecvSkirmishAIMessage(aiTeam, dataStr)
return: ???

???


addon.RecvFromSynced(...)

Receives data sent via SendToUnsynced callout.


addon.Save(zip)

Called when a chat command '/save' or '/savegame' is received. The single argument is a userdatum representing the savegame zip file. See Lua_SaveLoad.


addon.LoadProgress(message, replaceLastLine)

Only available to LuaIntro.


addon.GroupChanged(groupID)

Called when a unit is added to or removed from a control group. Currently implemented for widgets only.


addon.ConfigureLayout(???)
return: ???

???


Input

addon.IsAbove(x, y)
return: bool isAbove

Called every Update. Must return true for Mouse* events and GetToolTip to be called.


addon.GetTooltip(x, y)
return: string tooltip

Called when IsAbove returns true.


addon.KeyPress(key, mods, isRepeat)
return: bool becomeOwner

Called repeatedly when a key is pressed down. If you want an action to occur only once check for isRepeat == false. The mods parameter is a table, with keys "alt", "ctrl", "meta" and "shift" each having a boolean value. Return true if you don't want other callins or the engine to also receive this keypress. A list of key codes can be seen at the SDL wiki.


addon.KeyRelease(key)
return: bool

Called when the key is released.


addon.TextInput(utf8char)

Called whenever a key press results in text input. Introduced in 97.0.


addon.JoystickEvent(???)

???


addon.MousePress(x, y, button)
return: bool becomeMouseOwner

Called when a mouse button is pressed. The button parameter supports up to 7 buttons. Must return true for MouseRelease and other functions to be called.


addon.MouseRelease(x, y, button)
return: bool becomeMouseOwner

Called when a mouse button is released. Please note that in order to have Spring call MouseRelease, you need to have a MousePress call-in in the same addon that returns true.


addon.MouseWheel(up, value)

Called when the mouse wheel is moved. The parameters indicate the direction and amount of travel.


addon.MouseMove(x, y, dx, dy, button)

Called when the mouse is moved. The dx and dy parameters indicate the distance travelled, whereas the first two indicate the final position.


Players

addon.PlayerChanged(playerID)

Called whenever a player's status changes e.g. becoming a spectator.


addon.PlayerAdded(playerID)

Called whenever a new player joins the game.


addon.PlayerRemoved(playerID, reason)

Called whenever a player is removed from the game.


Downloads

addon.DownloadStarted(id)

Called when a Pr-downloader download is started via VFS.DownloadArchive.


addon.DownloadFinished(id)

Called when a Pr-downloader download finishes successfully.


addon.DownloadFailed(id, errorID)

Called when a Pr-downloader download fails to complete.


addon.DownloadProgress(id, downloaded, total)

Called incrementally during a Pr-downloader download.


Drawing

addon.ViewResize(viewSizeX, viewSizeY)

Called whenever the window is resized.


addon.Update(dt)

Called for every draw frame (including when the game is paused) and at least once per sim frame except when catching up. The parameter is the time since the last update.


Draw* Functions

Inside the Draw* functions, you can use the Lua OpenGL Api to draw graphics.
Avoid doing heavy calculations inside these callins; ideally, do the calculations elsewhere and use Draw callins only for drawing.

addon.DrawGenesis()

Doesn't render to screen! Use this callin to update textures, shaders, etc. Also available to LuaMenu.


addon.DrawWorldPreParticles()

??? New in version 104.0


addon.DrawWorldPreUnit()

Spring draws units, features, some water types, cloaked units, and the sun.


addon.DrawWorld()

Spring draws command queues, 'map stuff', and map marks.


addon.DrawWorldShadow()

???


addon.DrawWorldReflection()

???


addon.DrawWorldRefraction()

???


addon.DrawGroundPreForward()

Runs at the start of the forward pass when a custom map shader has been assigned via Spring.SetMapShader (convenient for setting uniforms).


addon.DrawGroundPreDeferred()

Runs at the start of the deferred pass when a custom map shader has been assigned via Spring.SetMapShader (convenient for setting uniforms).


addon.DrawGroundPostDeferred()

This runs at the end of its respective deferred pass and allows proper frame compositing (with ground flashes/decals/foliage/etc, which are drawn between it and DrawWorldPreUnit) via gl.CopyToTexture.


addon.DrawUnitsPostDeferred()

Runs at the end of the unit deferred pass to inform Lua code it should make use of the $model_gbuffer_* textures before another pass overwrites them (and to allow proper blending with e.g. cloaked objects which are drawn between these events and DrawWorld via gl.CopyToTexture). N.B. The *PostDeferred events are only sent (and only have a real purpose) if forward drawing is disabled.


addon.DrawFeaturesPostDeferred()

Runs at the end of the feature deferred pass to inform Lua code it should make use of the $model_gbuffer_* textures before another pass overwrites them (and to allow proper blending with e.g. cloaked objects which are drawn between these events and DrawWorld via gl.CopyToTexture). N.B. The *PostDeferred events are only sent (and only have a real purpose) if forward drawing is disabled.


addon.DrawScreen(vsx, vsy)

??? Also available to LuaMenu.


addon.DrawScreenEffects(vsx, vsy)

Where vsx, vsy are screen coordinates.


addon.DrawScreenPost(vsx, vsy)

New in version 104.0 Similar to DrawScreenEffects, this can be used to alter the contents of a frame after it has been completely rendered (i.e. World, MiniMap, Menu, UI).


addon.DrawLoadScreen()

New in version 95.0 Only available to LuaIntro, draws custom load screens.


addon.DrawInMinimap(sx, sy)

Where sx, sy are values relative to the minimap's position and scale.


addon.DrawInMinimapBackground(sx, sy)

Where sx, sy are values relative to the minimap's position and scale.


Custom Object Rendering

For the following calls drawMode can be one of the following, notDrawing = 0, normalDraw = 1, shadowDraw = 2, reflectionDraw = 3, refractionDraw = 4, and finally gameDeferredDraw = 5 which was added in 102.0.

addon.DrawUnit(unitID, drawMode)
return: bool suppressEngineDraw

For custom rendering of units, enabled here.


addon.DrawFeature(unitID, drawMode)
return: bool suppressEngineDraw

For custom rendering of features, enabled here.


addon.DrawShield(unitID, weaponID, drawMode)
return: bool suppressEngineDraw

For custom rendering of shields.


addon.DrawProjectile(projectileID, drawMode)
return: bool suppressEngineDraw

For custom rendering of weapon (& other) projectiles.


Unsynced Menu Only

addon.AllowDraw()
return: bool allowDraw

Enables Draw{Genesis,Screen,ScreenPost} callins if true is returned, otherwise they are called once every 30 seconds. Only active when a game isn't running.


addon.ActivateMenu()

Called whenever LuaMenu is on with no game loaded.


addon.ActivateGame()

Called whenever LuaMenu is on with a game loaded.


Synced - Unsynced Shared

addon.GotChatMsg(msg, player)

Called when a player issues a UI command e.g. types /foo or /luarules foo.


Game

addon.GameID(gameID)

Called once to deliver the gameID. As of 101.0+ the string is encoded in hex.


addon.GamePaused()

Called when the game is paused.


addon.GameOver(winningAllyTeams)

The parameter is a table list of winning allyTeams, if empty the game result was undecided (like when dropping from an host).


addon.GameFrame(frame)

Called for every game simulation frame (30 per second). Starts at frame 0 in 101.0+ and 1 in previous versions.


addon.GamePreload()

Called before the 0 gameframe. From 104.0 onwards, will not be called when a saved game is loaded.


addon.GameStart()

Called upon the start of the game. From 104.0 onwards, will not be called when a saved game is loaded.


Teams

addon.TeamChanged(teamID)

???


addon.TeamDied(teamID)

Called when a team dies (see Spring.KillTeam).


Units

addon.UnitCreated(unitID, unitDefID, unitTeam, builderID)

Called at the moment the unit is created.


addon.UnitFinished(unitID, unitDefID, unitTeam)

Called at the moment the unit is completed.


addon.UnitFromFactory(unitID, unitDefID, unitTeam, factID, factDefID, userOrders)

Called when a factory finishes construction of a unit.


addon.UnitReverseBuilt(unitID, unitDefID, unitTeam)

Called when a living unit becomes a nanoframe again.


addon.UnitGiven(unitID, unitDefID, newTeam, oldTeam)

Called when a unit is transferred between teams. This is called after UnitTaken and in that moment unit is assigned to the newTeam.


addon.UnitTaken(unitID, unitDefID, oldTeam, newTeam)

Called when a unit is transferred between teams. This is called before UnitGiven and in that moment unit is still assigned to the oldTeam.


addon.UnitDamaged(unitID, unitDefID, unitTeam, damage, paralyzer, weaponDefID, projectileID, attackerID, attackerDefID, attackerTeam)

Called when a unit is damaged (after UnitPreDamaged).


addon.UnitDestroyed(unitID, unitDefID, unitTeam, attackerID, attackerDefID, attackerTeam)

Called when a unit is destroyed.


addon.RenderUnitDestroyed(unitID, unitDefID, unitTeam)

Called just before a unit is invalid, after it finishes its death animation. New in version 101.0


addon.UnitStunned(unitID, unitDefID, unitTeam, stunned)

Called when a unit changes its stun status. New in version 99.0


addon.UnitUnitCollision(colliderID, collideeID)

Called when two units collide. Both units must be registered with Script.SetWatchUnit.


addon.UnitFeatureCollision(colliderID, collideeID)

Called when a unit collides with a feature. The unit must be registered with Script.SetWatchUnit and the feature registered with Script.SetWatchFeature.


addon.UnitCommand(unitID, unitDefID, unitTeam, cmdID, cmdParams, cmdOpts, cmdTag)

Called after when a unit accepts a command, after AllowCommand returns true.


addon.UnitCmdDone(unitID, unitDefID, unitTeam, cmdID, cmdParams, cmdOpts, cmdTag)

Called when a unit completes a command.


addon.UnitLoaded(unitID, unitDefID, unitTeam, transportID, transportTeam)

Called when a unit is loaded by a transport.


addon.UnitUnloaded(unitID, unitDefID, unitTeam, transportID, transportTeam)

Called when a unit is unloaded by a transport.


addon.UnitExperience(unitID, unitDefID, unitTeam, experience, oldExperience)

Called when a unit gains experience greater or equal to the minimum limit set by calling Spring.SetExperienceGrade. Should be called more reliably with small values of experience grade in 104.0+.


addon.UnitIdle(unitID, unitDefID, unitTeam)

Called when a unit is idle (empty command queue).


addon.UnitCloaked(unitID, unitDefID, unitTeam)

Called when a unit cloaks.


addon.UnitDecloaked(unitID, unitDefID, unitTeam)

Called when a unit decloaks.


addon.UnitMoved(???)

??? Not implemented in base handler


addon.UnitMoveFailed(???)

??? Not implemented in base handler


addon.StockpileChanged(unitID, unitDefID, unitTeam, weaponNum, oldCount, newCount)

Called when a units stockpile of weapons increases or decreases. See stockpile.


addon.UnitEnteredLos(unitID, unitTeam, allyTeam, unitDefID)

Called when a unit enters LOS of an allyteam.


addon.UnitLeftLos(unitID, unitTeam, allyTeam, unitDefID)

Called when a unit leaves LOS of an allyteam.


addon.UnitEnteredRadar(unitID, unitTeam, allyTeam, unitDefID)

Called when a unit enters radar of an allyteam.


addon.UnitLeftRadar(unitID, unitTeam, allyTeam, unitDefID)

Called when a unit leaves radar of an allyteam.


addon.UnitEnteredAir(???)

??? Not implemented by base handler


addon.UnitLeftAir(???)

??? Not implemented by base handler


addon.UnitEnteredWater(???)

??? Not implemented by base handler


addon.UnitLeftWater(???)

??? Not implemented by base handler


addon.UnitSeismicPing(x, y, z, strength, allyTeam, unitID, unitDefID)

Called when a unit emits a seismic ping. See seismicSignature.


Features

addon.FeatureCreated(featureID, allyTeamID)

Called when a feature is created.


addon.FeatureDamaged(featureID, featureDefID, featureTeam, damage, weaponDefID, projectileID, attackerID, attackerDefID, attackerTeam)

Called when a feature is damaged.


addon.FeatureDestroyed(featureID, allyTeamID)

Called when a feature is destroyed.


addon.FeatureMoved(???)

???


Projectiles

The following Callins are only called for weaponDefIDs registered via Script.SetWatchWeapon.

addon.ProjectileCreated(proID, proOwnerID, weaponDefID)

Called when the projectile is created. Note that weaponDefID is missing if the projectile is spawned as part of a burst, but Spring.GetProjectileDefID and Spring.GetProjectileName still work in callin scope using proID.


addon.ProjectileDestroyed(proID)

Called when the projectile is destroyed.


Synced Only

addon.CommandFallback(unitID, unitDefID, unitTeam, cmdID, cmdParams, cmdOptions, cmdTag)
return: bool used, bool finished

Called when the unit reaches an unknown command in its queue (i.e. one not handled by the engine). If no addon returns used as true the command is dropped, if an addon returns true, true the command is removed because it's done, with true, false it's kept in the queue and CommandFallback gets called again on the next slowupdate.


addon.AllowCommand(unitID, unitDefID, unitTeam, cmdID, cmdParams, cmdOptions, cmdTag, synced)
return: bool allow

Called when the command is given, before the unit's queue is altered. The return value is whether it should be let into the queue. The queue remains untouched when a command is blocked, whether it would be queued or replace the queue.


addon.AllowUnitCreation(unitDefID, builderID, builderTeam, x, y, z, facing)
return: bool allow

Called just before unit is created, the boolean return value determines whether or not the creation is permitted.


addon.AllowUnitTransfer(unitID, unitDefID, oldTeam, newTeam, capture)
return: bool allow

Called just before a unit is transferred to a different team, the boolean return value determines whether or not the transfer is permitted.


addon.AllowUnitBuildStep(builderID, builderTeam, unitID, unitDefID, part)
return: bool allow

Called just before a unit progresses its build percentage, the boolean return value determines whether or not the build makes progress.


addon.AllowFeatureCreation(featureDefID, teamID, x, y, z)
return: bool allow

Called just before feature is created, the boolean return value determines whether or not the creation is permitted.


addon.AllowFeatureBuildStep(builderID, builderTeam, featureID, featureDefID, part)
return: bool allow

Called just before a feature progresses its build percentage, the boolean return value determines whether or not the progress change is permitted.


addon.AllowResourceLevel(teamID, res, level)
return: bool allow

Called when a team sets the sharing level of a resource, the boolean return value determines whether or not the sharing level is permitted.


addon.AllowResourceTransfer(oldTeamID, newTeamID, res, amount)
return: bool allow

Called just before resources are transferred between players, the boolean return value determines whether or not the transfer is permitted.


addon.AllowStartPosition(playerID, teamID, readyState, clampedX, clampedY, clampedZ, rawX, rawY, rawZ)
return: bool allow

clamped{X,Y,Z} are the coordinates clamped into start-boxes, raw is where player tried to place their marker. The readyState can be any one of
  • 0 - player picked a position,
  • 1 - player clicked ready,
  • 2 - player pressed ready OR the game was force-started (player did not click ready, but is now forcibly readied) or
  • 3 - the player failed to load.
  • New in version 95.0 the default 'failed to choose' start-position is the north-west point of their startbox, or (0,0,0) if they do not have a startbox.

NB: The order of the parameters changed with the addition of teamID in 104.0. Previouly it was: clampedX, clampedY, clampedZ, playerID, readyState, rawX, rawY, rawZ


addon.AllowDirectUnitControl(unitID, unitDefID, unitTeam, playerID)
return: bool allow

Determines if this unit can be controlled directly in FPS view.


addon.AllowWeaponTargetCheck(attackerID, attackerWeaponNum, attackerWeaponDefID)
return: bool allowCheck, bool ignoreCheck

Determines if this weapon can automatically generate targets itself. See also commandFire weaponDef tag. The ignoreCheck return value was added in 99.0 to allow ignoring the callin i.e. running normal engine check for this weapon.


addon.AllowWeaponTarget(attackerID, targetID, attackerWeaponNum, attackerWeaponDefID, defPriority)
return: bool allowed, number newPriority

Controls blocking of a specific target from being considered during a weapon's periodic auto-targeting sweep. The second return value is the new priority for this target (if you don't want to change it, return defPriority). Lower priority targets are targeted first.


addon.AllowWeaponInterceptTarget(interceptorUnitID, interceptorWeaponID, targetProjectileID)
return: bool allowed

Controls blocking of a specific intercept target from being considered during an interceptor weapon's periodic auto-targeting sweep. Only called for weaponDefIDs registered via Script.SetWatchWeapon.


addon.AllowBuilderHoldFire(unitID, unitDefID, action)
return: bool actionAllowed

New in version 98.0 5a82d750 Called when a construction unit wants to "use his nano beams".
action is one of following:
  • -1 Build
  • CMD.REPAIR Repair
  • CMD.RECLAIM Reclaim
  • CMD.RESTORE Restore
  • CMD.RESURRECT Resurrect
  • CMD.CAPTURE Capture


addon.Explosion(weaponDefID, px, py, pz, AttackerID, ProjectileID)
return: bool noGfx

Called when an explosion occurs. If it returns true then no graphical effects are drawn by the engine for this explosion.


addon.TerraformComplete(unitID, unitDefID, unitTeam, buildUnitID, buildUnitDefID, buildUnitTeam)
return: bool stop

Called when pre-building terrain levelling terraforms are completed (c.f. levelGround). If the return value is true the current build order is terminated.


addon.MoveCtrlNotify(unitID, unitDefID, unitTeam, data)
return: bool moveCtrlComplete

Enable both Spring.MoveCtrl.SetCollideStop and Spring.MoveCtrl.SetTrackGround to enable this call-in, data was supposed to indicate the type of notification but currently never has a value other than 1 ("unit hit the ground"). The return value determines whether or not the unit should remain script-controlled (false) or return to engine controlled movement (true).


addon.RecvLuaMsg(msg, playerID)

Receives messages from unsynced sent via Spring.SendLuaRulesMsg.


addon.Load(zip)

Called after GamePreload and before GameStart. See Lua_SaveLoad.


Damage Controllers

For the following callins, in addition to being a regular weapon, weaponDefID may be one of the following:

  • -1 - debris collision, also default of Spring.AddUnitDamage
  • -2 - ground collision
  • -3 - object collision
  • -4 - fire damage
  • -5 - water damage
  • -6 - kill damage
  • -7 - crush damage

addon.UnitPreDamaged(unitID, unitDefID, unitTeam, damage, paralyzer, weaponDefID, projectileID, attackerID, attackerDefID, attackerTeam)
return: number newDamage, number impulseMult

Called before damage is applied to the unit, allows fine control over how much damage and impulse is applied.


addon.ShieldPreDamaged(proID, shieldCarrier, boolBounceProjectile, beamEmitterWeaponNum, beamEmitterUnitID, startX, startY, startZ, hitX, hitY, hitZ)
return: bool handleCollision

Called before any engine shield-vs-projectile logic executes. If the return value is true the gadget handles the collision event and the engine does not remove the projectile. If the weapon is a hitscan type (BeamLaser or LightningCanon) then proID is nil and beamEmitterWeaponNum and beamEmitterUnitID are populated instead. The start and hit position arguments are provided from 104.0 onwards.


addon.FeaturePreDamaged(featureID, featureDefID, featureTeam, damage, weaponDefID, projectileID, attackerID, attackerDefID, attackerTeam)
return: number newDamage, number impulseMult

Called before damage is applied to the feature, allows fine control over how much damage and impulse is applied.