This is the changelog since version 2025.01.6.
Caveats
These are the entries which may require special attention when migrating:
- network protocol: scribbling-related (draw, point, erase) messages now send coordinates as
uint32
instead ofint16
. This may break replay parsing. - uniform location 5 in vertex shaders for models extended from uvec2 (boneID, boneWeight) to uvec3 (boneID low byte, boneWeight, boneID high byte). Existing shaders should generally keep working.
- missiles now obey
myGravity
when expired. math.clamp
now errors if the lower bound is higher than the upper bound.- added minimap rotation API which can screw up the minimap (see below), set it to nil at LuaUI entry point if you don’t want to handle it.
- server no longer automatically forcestarts the game if there is nobody connected after 30s.
- fixed the
SPRING_LOG_SECTIONS
environment var, it no longer requires a comma in front. gl.GetAtmosphere("skyDir")
now returns nil. The skyDir was never actually used for anything.- updated Tracy to v0.11.1, see the changelog at https://github.com/wolfpld/tracy/releases
- archive cache was reworked. Should be much faster to process, but will take up more disk space and it’s not yet known how stable it is.
Deprecation notice
- the metal view automatically toggling when building a metal extractor is now deprecated. Disable it via
Spring.SetAutoShowMetal
(see below) and reimplement manually. A replacement example has been provided at(basecontent)/examples/Widgets/gui_autoshowmetal.lua
.
Features
Lua language server support
LDoc has been replaced by Lua Language Server compatible annotations. This allows for language server support when editing Lua code (namely autocompletion and type checking). Type definitions can be found in the Lua library repo. This is intended to be included as a submodule in projects that use the engine. Lua API docs are now generated from LLS definitions instead of LDoc. This has caused a regression in docs quality, with all docs on a single page and some docs missing information. Improvements to the docs are being considered. For more information see the Lua Language Server guide.
Unit groups
- units no longer removed from groups at the start of their death animation.
- added
Spring.SetUnitNoGroup(unitID, bool noGroup) → nil
, whether a unit can be added to groups. - added
Spring.GetUnitNoGroup(unitID) → bool noGroup
.
Infra-adjacent
- added
--calc-checksum "Archive Name"
CLI param, writes a single archive’s checksum to archive cache. Use from a lobby for preloading content, though be wary not to call it in paralllel. - added
--only-local
CLI param tospring.exe
, prevents a replay from opening a connection. Use for mass replay parsing. - fixed the
SPRING_LOG_SECTIONS
environment var, it no longer requires a comma in front. - server no longer automatically forcestarts the game if there is nobody connected after 30s.
More model pieces
- models now support 65534 pieces, up from 255.
- this tends to have terrible performance for even hundred-piece models, so consider it a crutch and avoid it if possible.
- add
Engine.FeatureSupport.maxPiecesPerModel
constant you can read to get the piece number. - uniform location 5 in vertex shaders for models extended from uvec2 (boneID, boneWeight) to uvec3 (boneID low byte, boneWeight, boneID high byte). Existing shaders should generally keep working.
Automatic metalmap view
- added
Spring.SetAutoShowMetal(bool) → nil
. If you set it to false then selecting a “build mex” command won’t automatically enable the metal view (use the widget from(basecontent)/examples/Widgets/gui_autoshowmetal.lua
to replicate it). If you leave it at true (default), engine will keep automatically enabling the metal view but also spam deprecation warnings. This function will be removed at some point in the future. - added
Engine.FeatureSupport.noAutoShowMetal
, false. At some point in the future this will change totrue
at which point the engine will stop automatically enabling the metal view for mexes (and removeSpring.SetAutoShowMetal
).
Minimap 90°/270° rotations
- minimap can now be rotated to 90° and 270°, and can be rotated manually.
- added
Spring.SetMiniMapRotation(number angle) → nil
, sets the minimap angle (in radians). Snaps to cardinal directions. Only works if the springsettingMiniMapCanFlip
is set to 0 (if it’s 1, engine automatically flips vertically as previously). Geometry is kept, so it may end up stretched - readjust it manually viagl.ConfigMiniMap
. Spring.GetMiniMapRotation() → number angle
handles the new rotations (i.e. can returnπ/2
and3π/2
).
Misc rendering
- add
Platform.glVersionNum
, 1/10th the version of glsl (e.g. GL 3.0 → 30). - added
gl.ClearAttachmentFBO(number? target = GL.FRAMEBUFFER, string|number attachment, clearValue0, cv1, cv2, cv3) → bool ok
. Clears the “attachment” of the currently bound FBO type “target” with “clearValues”. Attachment can be either string (“color0” .. “color15”, “depth”, or “stencil”) or the equivalentGL.COLOR_ATTACHMENT#
constant. - minimap is sharper with super-sampling anti-aliasing enabled
- added 3D noise to basecontent bitmaps archive, under
bitmaps/noise/recoil_noise_2025_p5_p3_w6_w4_64x64x64_RGBA.dds
andbitmaps/noise/recoil_noise_2025_p5_p3_w6_w4_128x128x128_RGBA.dds
. This allows for reliable generation of cheaper 3D noise in shaders.
Praise the sun!
- the shading texture (used by minimap, water, and grass) now tracks sun position changes immediately.
- the “modern” sky renderer now uses the actual sun color instead of hardcoded RGB 253/251/211.
Spinning skybox
- added new tag to
Spring.SetAtmosphere
,skyAxisAngle
, array of 4 numbers: X, Y, Z (defining an axis) and rotation around that axis. Lets the skybox be drawn at an angle and possibly spin. Complex rotations involve doing math yourself. - added
skyAxisAngle
togl.GetAtmosphere
, same format. - added
atmosphere.skyAxisAngle
to mapinfo, same format. - removed
atmosphere.skyDir
from mapinfo, it didn’t actually affect anything. gl.GetAtmosphere("skyDir")
now returns nil.
Debugging for rendering
- added
VBO:GetID() → number
, gets the internal OpenGL ID for use in debugging. - added a second return value to
gl.CreateShader
, now also returns the internal ID for use in debugging. - added
gl.ObjectLabel(objType, objID, string identifier) → nil
. Type is one of the new GL object type constants (GL.BUFFER
,GL.PROGRAM_PIPELINE
etc., see the list at the bottom). Adds a text label to an object for debugging tools. Conditionally available based on gfx drivers etc (do a nil check). - added
gl.PushDebugGroup(number ID, string message, bool isThirdParty) → nil
. Conditionally available. Puts a group (FIXME what exactly is a group? just a scope same as tracy? and how do I get its ID?) with given message onto the debug stack. Meant for debugging tools, seems to be specifically for “nVidia nSight 2024.04”. Apparently “does not seem to work” when FBOs are raw bound (FIXME is that a crash, corrupt data, just no-op?). - added
gl.PopDebugGroup() → nil
, conditionally available, pops a previously pushed debug group from the stack. - the engine now natively pushes some GL debug groups in relevant scopes, similar to tracy.
Unit rotations
Spring.GetUnitDirection
andSpring.GetFeatureDirection
now return 9 values (from 3). The initial three stay as the XYZ of the “front” direction in unit space, the new ones are XYZ of the “right” direction and the XYZ of the “up” direction. ```diff- local frontX, frontY, frontZ = Spring.GetUnitDirection(unitID)
- local frontX, frontY, frontZ, rightX, rightY, rightZ, upX, upY, upZ = Spring.GetUnitDirection(unitID) ```
Spring.SetUnitDirection
andSpring.SetFeatureDirection
now accept up to 6 args (from 3). The new ones are the XYZ for the “right” direction (since just the “front” is ambiguous) and are optional (same behaviour as previous, i.e. some direction based on ground). Note there is no way to specify the “up” dir (but given the “right” dir it is unambiguous; and if you have front+up dirs you can unambiguously find the right dir). ```diff Spring.SetUnitDirection(unitID, frontX, frontY, frontZ) – still works- Spring.SetUnitDirection(unitID, frontX, frontY, frontZ, rightX, rightY, rightZ) – new ```
Engine feature support tags
Added a bunch of feature support entries to the Engine.FeatureSupport
tags. These are for the future. Most likely you don’t need to worry about those since games will receive patches if there is a change.
- number
gunshipCruiseAltitudeMultiplier
, currently1.5
. Right now gunship cruise altitude is multiplied by this. - bool
noRefundForConstructionDecay
, currentlyfalse
. At some point refunds for construction decay will be handed over to Lua. - bool
noRefundForFactoryCancel
, currentlyfalse
. At some point refunds for factory cancel will be handed over to Lua. - bool
noOffsetForFeatureID
, currentlyfalse
. At some point featureIDs in mixed contexts (e.g. target ID for reclaim) won’t require to be offset.
Misc
- add
Spring.GetSoundDevices() → { { name = "...", }, { name = "...", }, ... }
. May be extended with more info than just name in the future. - add
wupget:ActiveCommandChanged(cmdID?, cmdType?) → nil
. - the
Spring.GiveOrder
family of functions now acceptnil
as params (same as{}
) and options (same as0
). - add
Spring.SetUnitStorage(unitID, "m"|"e", value) → nil
. - add
Spring.GetUnitStorage(unitID) → numbers metal, energy
. - added
Game.buildGridResolution
, number which is currently 2. This means that buildings created via native build orders are aligned to 2 squares. - add
Platform.totalRAM
, in megabytes. - added
Engine.gameSpeed
andEngine.textColorCodes
, same as the existing entries inGame.
. The practical effect is that the Engine table is available in some LuaParser environments that Game isn’t. - missiles now obey
myGravity
when expired. - NaN and infinity coming from Lua is now sometimes rejected. Coverage isn’t yet comprehensive.
socket.lua
moved from being a loosely distributed file under./socket.lua
to basecontent./LuaSocket/socket.lua
.- add
experience.experienceGrade
number modrule, same as calling Spring.SetExperienceGrade. - the
allowHoverUnitStrafing
modrule now defaults tofalse
. Previously it defaulted tofalse
for HAPFS andtrue
for QTPFS. - bumpmapped water (aka
/water 4
) now has a different default texture.
Fixes
- fix
Spring.SetUnitHealth(build < 1)
not reverting the unit into a nanoframe. - fix CPU pinning, no longer tries to pin itself to bad choices (efficiency cores, hyperthreads on the same physical core, performance cores on a dedicated server)
- fixed
Spring.ShareResources(teamID, "units", nil)
breaking due to the explicit nil. - fix scribblings and labels breaking on maps larger than 64xN.
- fix basecontent
actions.lua
providing an incorrectKeyAction
handler. - fix height of buildings under construction not updating properly.
- fix landed aircraft starting to levitate when EMPed.
- fix units being stuck if an overlapping push-resistant unit stops.
- fix the “modern” sky renderer not adjusting to changes via
Spring.SetAtmosphere
.
GL object type constants
For use with the new gl.ObjectLabel
(see above):
GL.BUFFER
GL.SHADER
GL.PROGRAM
GL.VERTEX_ARRAY
GL.QUERY
GL.PROGRAM_PIPELINE
GL.TRANSFORM_FEEDBACK
GL.RENDERBUFFER
GL.FRAMEBUFFER
Written by: sprunk