Lua Beginners FAQ: Difference between revisions

From Spring
Jump to navigationJump to search
Quantum (talk | contribs)
No edit summary
 
(54 intermediate revisions by 12 users not shown)
Line 1: Line 1:
'''Q: I'm interested in learning to use Lua with Spring. Where should I start?'''
[[Engine_Development|Development]] < [[Lua_Scripting|Lua Scripting]] < {{FULLPAGENAME}}


A: You can start by reading the tutorial  [http://lua-users.org/wiki/TutorialDirectory here]. The "Introductory topics" and "Programming in Lua" sections should suffice, in the beginning. After that, you can try editing simple LuaUI widgets, like snd_chatterbox.


This page is an introduction to using Lua in Spring - it only tries to answer general questions, for more specific Questions please ask in the forum.


'''Q: Why should I learn Lua?'''


A: If you are a player, it can lets you you to make widgets that that automate tedious and mindless tasks, help you organize the information available to you in a a more effective way, or even allow you to overhaul the user interface. If you are a modder, it gives you the power to manipulate every aspect of the simluation except projectiles. Here are some of the things you can do:
==Where should I start?==


*Create or destroy units.
You can start by reading general Lua tutorials  [http://lua-users.org/wiki/LuaTutorial here].  
*Transform units in other units.
*Change game rules.
*Give orders to units.
*Add new buttons to the unit orders panel.
*Manipulate unit physics.
*Upgrade units.
*Create a research system.
*Write a new user interface.
*Directly access OpenGL calls.
*Use your own shaders written in GLSL.
*Write your custom model format.
*Use 3d textures, bump mapping, relief mapping, normal mapping, and more advanced graphic techniques.
*Use different levels of detail.
*Create single player missions.
*Implement a new resource system.
*Add fauna to a map.
*Create weather effects.
*Comminicate with cob scripts.


The possibilites are mostly limited by your creativity.
After that, you could look at the example widget [[Lua:Tutorial_GettingStarted|here]], and try to add some functionality of your own!


Once you're a pro, have a look at the game repos [https://springrts.com/wiki/Gamedev:PublicRepos here], especially their /luaui/Widgets and /luarules/gadgets dirs.


'''Q: How do I open ".lua" files?'''
==Where can I find help?==


A: Notepad or any text editor are enough.
You can find documentation of Springs Lua API on the [[Lua_Scripting|Lua_Scripting]] page. Discussion of lua coding takes place on the [https://springrts.com/wiki/Read_Me_First lobby] in #moddev and #lua, and there is also a [https://springrts.com/phpbb/viewforum.php?f=23 Lua sub-forum].




'''Q: Where can I find documentation?'''
==How do I open ".lua" files?==


A: There is incomplete documentation for LuaUI in "Spring/LuaUI/API.txt". "Spring/LuaUI/widgets.lua" and "<modname>/LuaRules/gadgets.lua" contain the call-ins and their arguments. You will have to read the Spring source to find the list of call-outs and their arguments. The source of the Lua API can be found [https://taspring.clan-sy.com/svn/spring/trunk/rts/Lua/ here]. LuaSyncedCtrl.cpp, LuaSyncedRead.cpp, LuaUnsyncedCtrl.cpp, LuaUnsyncedRead.cpp, LuaOpenGL.cpp and LuaSyncedMoveCtrl.cpp contain most call-outs. (L, 1) usually refers to the first argument, (L, 2) to the second, etc. If you don't know C++, understanding those files will require a little bit of guesswork, but it should'nt be hard. Note that not all calls are available to both LuaUI and LuaRules/LuaCob/LuaGaia.
Any text editor is enough. On Windows i.e. use [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++]. There are also IDEs able to work with Lua, such as Eclipse, if you look for them.


==What is a call-in? And a call-out?==


'''Q: What is a call-in? And a call-out?'''
Call-ins are functions defined in your script that Spring calls when a determined event takes place. For example, the widget:Initialize() call-in is run by Spring when the widget is loaded.
Call-outs are functions defined in Spring you can run at whichever moment you desire. For example, when you call Spring.GetUnitTeam(unitID), the engine returns the teamID of the unit identified by "unitID".
 
 
==What is the difference between unsynced and synced lua code?==
 
Synced code is code that runs, identically and at the same time, on every connected client. In practice, this means code which controls the game state. Unsynced code is code that will run differently (or maybe not at all) on each connected client. Typically, this means the user interface.
 
For example, lua code to make units explode if they fell down a cliff would need to be synced. But, code that warned a player when one of their own units was getting near a cliff edge, would need to be unsynced.
 
 
==What is the difference between LuaUI, LuaRules, widgets and gadgets?==


Call-ins are functions defined in your script that Spring calls when a determined event takes place. For example, the gadget:Initialize() call-in is run by Spring when the widget is loaded.
Spring allows various [[Lua:Environments|Lua Environments]], each with differing functionality. Inside each Lua environment, developers can write addons, which are self-contained pieces of code. There are:
Call-outs are functions defined in Spring you can run at whichever moment you desire. For example, when you call Spring.GetUnitTeam(unitID), the engine returns the teamID of the unit identified by "unitID".
* <b>LuaUI</b>: Used for unsynced GUI related code. Addons in here are often called widgets. Clients can (if the game permits it) control which widgets are running. Widgets contain only unsynced code. They can be bundled inside the game, or loaded from the users "Spring/LuaUI/Wigets" directory.
* <b>LuaRules</b>: Addons in here are often called gadgets. Clients cannot choose which gadgets run. Gadgets can include both synced and unsynced code, and must be bundled inside the game.


Intended for mappers, there is also LuaGaia, which behaves like LuaRules but is separated from it. To see which of the lua environoments has access to which data/functionality, see [[Lua:Environments#Interfaces]] and [[Lua:Callins]].


'''Q: What is the difference between a widget and a gadget?'''
==What can't Lua do in the current version of Spring?==


A: A widget is a Lua script that works with LuaUI. A gadget works with LuaRules, LuaCob or LuaGaia. Widgets allow you to customize your interface, and must be unsynced. They can be bundled with the mod or you can save them in your "Spring/LuaUI/Wigets" directory. Gadgets can be synced or unsynced. LuaRules and LuaCob gadgets are usually part of a mod. LuaGaia gadgets should be part of a map. Gadgets can contain both synced and unsynced code.
Springs Lua interface is very powerful. To work out if some idea is possible you need to ask
* When do I need the engine to tell me something has happened? Check against [[Lua:Callins|Callins]].
* What information will I need to know about the game state? Check against [[Lua_SyncedRead]] (synced) and [[Lua_UnsyncedRead]] (unsynced).
* What do I then need to do about it? Check against [[Lua_SyncedCtrl]] (synced) and[[Lua_UnsyncedCtrl]] (unsynced).
Sometimes you need special functionality, like disk access or OpenGL calls, in which case check against [[Lua_Scripting#Interfaces|Interfaces]].


For completeness, some examples of things you (currently) can't do:
*control the ground LOS - but you can set the los status of units!
*add custom parameters to CEG definitions.


'''Q: Where can I find examples?'''
==Complex Lifecycles==


A: The "Spring/LuaUI/Widgets" directory contains many examples. More can be found at [http://spring.unknown-files.net/category/19/Lua_Scripts/ Unknow Files] or in the [http://www.caspring.org/ Complete Annihilation] mod.
Due to the complexity of the simulation, spring scripts are burdened with the curse of complex lifecyles very similar to https://en.wikipedia.org/wiki/Object_lifetime in programing.


This means, you can not rely on any information about the simulation being valid after as little as 1 frame has passed. Units may have been captured, destroyed or created in this time. Terrain may have been altered.


'''Q: Why does the print function seem to do nothing?'''
People usually combat this by creating large amounts of  protective boiler plate, checking if a unit still exists, is still on the same team, etc. every time a unitscript, gadget or widget wakes up.


A: It's output is displayed in stdout. If you are a windows user, to see it, you need to first unzip [http://lcc-clan.com/quant/winpipe.zip this archive] in your Sprind directory, then open the command promt, navigate to your Spring directory, and run spring by typing "sprin.exe | winpipe.exe". The stdout will appear in the command prompt window.
==Where can I find/edit examples?==
You might want to run Spring in windowed mode so the command prompt is visible at all times.


You can find some easy example widgets [[Lua:Tutorial_GettingStarted|here]]. The best source of more complicated examples is inside games themselves, in the LuaUI/Widgets and Luarules/gadgets directories. See [[Gamedev:PublicRepos]] for a list of repositories.


'''Q: How do I print the "UnitDefs[unitDefID]" or "WeaponDefs[weaponDefID]" tables? "for k, v in ipairs(t) do print(k, v) end" doesn't behave as expected.'''
To make your own widgets, simply place individual .lua files into your Spring/LuaUI/Widgets dir (create the dir if it is not present. Case-sensitive!!!). Game repositories can be checked out into a folder named "SomeAwesomeGame.sdd", placed in your "/Spring/games" dir; this shoudl give a local copy of the game, recognized by Spring, where you can edit files. Make sure to check the licenses before doing this!


A: Use "for k,v in UnitDefs[48]:pairs() do print(k, v) end" instead.


==Can I reload a script without restarting Spring?==


'''Q: Where can I find help?'''
Yes, you can type "/luaui reload" to reload widgets, and if you have "cheats" enabled you can also "/luarules reload" to reload gadgets.


A: There is a [http://spring.clan-sy.com/phpbb/viewforum.php?f=23 Lua section] in the Spring forums. Probably the most effective way, though, is to join #lua on the lobby.
==Why does the print function seem to do nothing?==


Its output is displayed in stdout. If you have no easy way to see it, you can Spring.Echo("some text") which prints to the ingame chat and infolog.txt.


'''Q: Who implemented LuaUI, LuaRules, LuaCob and LuaGaia?'''


A: They were written by trepan.
[[Category: Lua]]

Latest revision as of 10:36, 12 December 2021

Development < Lua Scripting < Lua Beginners FAQ


This page is an introduction to using Lua in Spring - it only tries to answer general questions, for more specific Questions please ask in the forum.


Where should I start?

You can start by reading general Lua tutorials here.

After that, you could look at the example widget here, and try to add some functionality of your own!

Once you're a pro, have a look at the game repos here, especially their /luaui/Widgets and /luarules/gadgets dirs.

Where can I find help?

You can find documentation of Springs Lua API on the Lua_Scripting page. Discussion of lua coding takes place on the lobby in #moddev and #lua, and there is also a Lua sub-forum.


How do I open ".lua" files?

Any text editor is enough. On Windows i.e. use Notepad++. There are also IDEs able to work with Lua, such as Eclipse, if you look for them.

What is a call-in? And a call-out?

Call-ins are functions defined in your script that Spring calls when a determined event takes place. For example, the widget:Initialize() call-in is run by Spring when the widget is loaded. Call-outs are functions defined in Spring you can run at whichever moment you desire. For example, when you call Spring.GetUnitTeam(unitID), the engine returns the teamID of the unit identified by "unitID".


What is the difference between unsynced and synced lua code?

Synced code is code that runs, identically and at the same time, on every connected client. In practice, this means code which controls the game state. Unsynced code is code that will run differently (or maybe not at all) on each connected client. Typically, this means the user interface.

For example, lua code to make units explode if they fell down a cliff would need to be synced. But, code that warned a player when one of their own units was getting near a cliff edge, would need to be unsynced.


What is the difference between LuaUI, LuaRules, widgets and gadgets?

Spring allows various Lua Environments, each with differing functionality. Inside each Lua environment, developers can write addons, which are self-contained pieces of code. There are:

  • LuaUI: Used for unsynced GUI related code. Addons in here are often called widgets. Clients can (if the game permits it) control which widgets are running. Widgets contain only unsynced code. They can be bundled inside the game, or loaded from the users "Spring/LuaUI/Wigets" directory.
  • LuaRules: Addons in here are often called gadgets. Clients cannot choose which gadgets run. Gadgets can include both synced and unsynced code, and must be bundled inside the game.

Intended for mappers, there is also LuaGaia, which behaves like LuaRules but is separated from it. To see which of the lua environoments has access to which data/functionality, see Lua:Environments#Interfaces and Lua:Callins.

What can't Lua do in the current version of Spring?

Springs Lua interface is very powerful. To work out if some idea is possible you need to ask

Sometimes you need special functionality, like disk access or OpenGL calls, in which case check against Interfaces.

For completeness, some examples of things you (currently) can't do:

  • control the ground LOS - but you can set the los status of units!
  • add custom parameters to CEG definitions.

Complex Lifecycles

Due to the complexity of the simulation, spring scripts are burdened with the curse of complex lifecyles very similar to https://en.wikipedia.org/wiki/Object_lifetime in programing.

This means, you can not rely on any information about the simulation being valid after as little as 1 frame has passed. Units may have been captured, destroyed or created in this time. Terrain may have been altered.

People usually combat this by creating large amounts of protective boiler plate, checking if a unit still exists, is still on the same team, etc. every time a unitscript, gadget or widget wakes up.

Where can I find/edit examples?

You can find some easy example widgets here. The best source of more complicated examples is inside games themselves, in the LuaUI/Widgets and Luarules/gadgets directories. See Gamedev:PublicRepos for a list of repositories.

To make your own widgets, simply place individual .lua files into your Spring/LuaUI/Widgets dir (create the dir if it is not present. Case-sensitive!!!). Game repositories can be checked out into a folder named "SomeAwesomeGame.sdd", placed in your "/Spring/games" dir; this shoudl give a local copy of the game, recognized by Spring, where you can edit files. Make sure to check the licenses before doing this!


Can I reload a script without restarting Spring?

Yes, you can type "/luaui reload" to reload widgets, and if you have "cheats" enabled you can also "/luarules reload" to reload gadgets.

Why does the print function seem to do nothing?

Its output is displayed in stdout. If you have no easy way to see it, you can Spring.Echo("some text") which prints to the ingame chat and infolog.txt.