User:Knorke/Sandbox1

From Spring
Revision as of 00:08, 23 April 2014 by Knorke (talk | contribs) (1)
Jump to navigationJump to search

Lua tut

Requirements

  • played a spring game
  • texteditor
  • copy of SpringTutorialGame
  • some small map because those load faster
  • Spring set to windowed mode for easier switchting between editor/game
  • a very bit familiar with programing (variables, functions, loops, arrays = enough)


Wupget and friends

In Spring games there are 3 kinds of Lua scripts. Crude and simple explaination:

  1. gadgets: these are the "gameplay code" and do all kind of things.
  2. widgets: these are for interface.
  3. unit scripts: animate units & controll their weapons. also have some gadget power.

Making those 3 is not very different but widgets are the easiest to test.

There is also 4) functionality provided by the engine.

Also look at this:

Gadgets_widgets_and_friends.png

All 4 are in a constant fight against each other.

My first wupdget

The SpringTutorialGame is simple and good for testing: You can use any other game but some block player widgets or are very confusing.

1) Create a txt file like this and there: Spring\LuaUI\Widgets\myfirstwidget.lua

and copypaste this text into it:


function widget:GetInfo()
  return {
    name      = "my first widget",
    desc      = "this is so awesome",
    author    = "horse 3000",
    date      = "2009",
    license   = "GNU GPL, v2 or later",
    layer     = -10,
    enabled   = true
  }
end

Nobody cares what excactly this does, but here you can put informations about your widget. What matters is that without such GetInfo() function Spring will not load the widget correctly. Since it takes up screen-space it will be left out when code is posted (but it must still be there.)

Start spring.exe and press F11. The "widget menu" opens:

Widget_F11menu.png

It is likely already filled with some other widgets contained in the game. Find your new widget in the list. Click on it to turn it on and off: The name in list should go green or red accordingly.

If that works - congratulation: You made a new widget that does excactly nothing.

"Hello unit" wupdget

Add the following at the end of myfirstwidget.lua:

<code>
function widget:UnitFinished(unitID, unitDefID, teamID)
	Spring.Echo ("a new unit was finished! It belongs to team " .. teamID)	
end

UnitFinished(...) is a callin function: Those are functions that the engine calls when

certain events happen. Captain Obvious has already figured out: This function gets called when a new unit is

finished.

Spring.Echo is used to output text to the chat/console. So this widget should tell when a new unit is made.

4) Open the widget menu and disable then re-enable your widget: This will reload the

widget. Now build some units to test it.

For lolz add an error like this: Spring.Echo (100 + nil) and reload the widget. The widgets name is green but turns yellow as soon a unit is build because "nil" can not

be used in math like that. The error is also displayed in chat and infolog.txt Fix the error, reload the widget and it is green again. Oha.

5) Even if there is a bot/other player building stuff, the widget will not notify on all

their new units. That is because widgets are limited in what they can "see", to prevent cheating. The widget only sees what what the player who is running the widget can see, too. This

is to prevent cheating.

6) change the widget to this and guess what it does?

<code>
function widget:UnitFinished(unitID, unitDefID, teamID)
	local x,y,z = Spring.GetUnitPosition (unitID)
	Spring.MarkerAddPoint (x,y,z, "a new unit! id=" .. unitID)
end

It adds a marker point on every new unit! Note how the unitID parameter from UnitFinished() is passed to GetUnitPosition()

Every unit, feature or weapon projectile in spring has an ID number:

Units_features_projectiles.png

There are never two units with the same unitID at the same time. #YOLO? No YOLO: when a unit is destroyed its unitID might be reused later for a different unit.

6) A counter that is increased when units are made:


local counter = 0 function widget:UnitFinished (unitID, unitDefID, teamID) counter = counter +1 Spring.Echo ("now there are " .. counter .. " units") if counter > 10 then Spring.Echo ("wow, more than 10 units!") end end


Reload the widget and note how the counter gets reseted. That is how widgets roll: Their variables get cleared on reload.

7) A counter that stores for each factory how many units it has already produced. One variable will not be enought here but an array can store multiple things. Arrays in Lua are tables. Read about tables: FIXME LINK


local buildCount = {} function widget:UnitFromFactory(unitID, unitDefID, unitTeam, factoryID, factoryDefID,

userOrders) local n = buildCount[factoryID] --read from table how many units this

factory already built if n == nil then --was the entry empty? n = 0 --if yes, start

counting from 0 end n = n +1 --increase n by

1. (best comment ever) Spring.Echo ("This was unit number " .. n .. " from factory " .. factoryID) buildCount[factoryID] = n --store new buildCount for this

factory end


UnitFromFactory is basically the same as UnitFinished, but has the usefull factoryID

parameter. Why the if n == nil? In Lua everything not initialized is nil (=nothing) and nil can not be used in any math.

(n = n +1 is a math) Btw shorter version: buildCount[factoryID] = (buildCount[factoryID] or 0) + 1

8)



Concatenating a nil is what breaks. Do it like this: Spring.Echo("text", param1, "text",

param2, param3)