CS2D: Basic Lua tutorial

[:en]

Since beta 0.1.1.4, Lua has come to be an integral part of Counter-Strike 2D. It has added a whole new level of customization to the game, and sparked the initiative in many players, both old and new, to create wonderful modifications to the game, and make whatever they wanted possible. Now, at beta 0.1.2.5, Counter-Strike 2D Lua has grown and now offers tools to customize the game in new unique ways.

But, the more sophisticated a system becomes, the more difficult it is for newbies to get into. This article is made to help them in that process.

Notes in red boxes are warnings. They usually tell you how to avoid common mistakes or notify you about the disadvantages of some approach, and should be read.
Notes in blue boxes are information. They usually tell you additional info about an approach or a feature. Although they may be skipped it’s recommended that you read them for general education and future reference.
Notes in green boxes are newbie information. They usually offer friendly explanations for newbies in programming. If you haven’t had experience in programming you should read them.

More in-depth explanations of all the topics discussed here are available in the official Programming in Lua manual online.

Quick Start

Since this is a tutorial to get you started with Lua in Counter-Strike 2D, let’s jump right into action and make a script. With it, whenever a player writes !announce [MESSAGE] in the chat, the message will be displayed to all players in the centre of their screens.

Pure Lua

The Basics

On the whole, Lua as a language is easier to learn than, for example, C or Java. It has a number of features that make it simpler for newbies to pick up, especially in the beginning, so learning its basics really won’t be that difficult.

Before we begin learning the actual language, there are a few programming terms you should familiarise yourself with:

  • Variable – a “container” that holds a value
  • Argument – data given to a function or an operator that they then operate on
  • Function – a piece of code that performs some action
  • Operator – a word or a symbol that performs an action and returns a result depending on its arguments
Caution: Some of the examples provided here might misbehave when executed in a CS2D environment! To check their validity, execute them in a pure Lua 5.1 environment, built from unmodified Lua source files.

Variables

Let’s start with variables. In Lua, a value can be any one of these 8 types: nil, boolean, number, string, table, function, userdata and thread.

Unlike in some other languages, variable types don’t have to be explicitly declared. Thus, variables are dynamically typed:

The “absence” of a meaningful value is represented by nil. Although nil isn’t inherently bad, it can raise some problems if not handled correctly. More on that in later paragraphs.

nil is largely synonymous to null in Java, None in Python and nil in Ruby. The data type of nil is nil. Unlike some other languages, however, any undeclared variable has the type and value nil, and printing or referencing an undeclared variable will not raise an error per se.

Variables of type boolean can represent only two values: true or false. Boolean variables are usually used to indicate the state of something that can only have two states, a metaphorical switch of sorts. They can be used to indicate whether a player is alive or not, whether a process is running or not, and so on.

The number data type is used to store numbers of (almost) arbitrary size.

Lua does not differentiate between different types of numbers; bytes, chars, integers, longs, as well as single- and double-precision numbers are all represented by the number data type. Internally, Lua uses double-precision floating-point numbers for its number type.

The string data type is used to store strings – collections of characters – of arbitrary sizes.

The table data type is truly the feature that distinguishes Lua from other scripting languages. In short, a table can contain any reasonable amount of values of any data type. Entries in a table are stored in key-value pairs – one value corresponds to one key. Keys can be any type except for nil, values can be any type including nil (and are nil by default). Tables are a very important topic in Lua and will be discussed separately (see 2.1.X).

The function data type is used to store functions (see 2.1.3).

Unlike in some other languages, functions in Lua are first-class values; that means that they can be manipulated in the same way as other variables.

The userdata data type is used by Lua internally. Values of the userdata type cannot be modified by Lua directly. You will rarely, if ever, encounter this data type in working environments.

userdata values are used by the C API to store C data and are simple memory blocks.

The thread data type is used by Lua in its coroutine implementation.

Operators

The assignment and comparison operators are the big three in Lua, as with any programming language.

The first among them is the = (assignment) operator. It is used to assign values to variables or table entries.

The second is the == (equals) operator. It compares two values and returns true if the values are the same and false if they are not.

Caution: Take care not to confuse the operators = and ==! Though they may be very similar visually, their functions are very different!

The ~= (not equal) operator is the opposite to == and equivalent to != in other languages. It returns false if the values are the same and true if they are different.

There are also four arithmetic comparison operators: < for less than, > for greater than, <= for less than or equal and >= for greater than or equal.

The basic arithmetic operators in Lua are + for addition, - for subtraction, * for multiplication and / for division.

The unary minus is the - operator which operates on only one value. 0-2 and -2, despite being two different operations, are equivalent in Lua.

Lua uses the ^ operator for exponentiation (2^2 is equivalent to 22).

Lua also has the % operator, called the modulo operator. It is used to return the remainder of a division; 5%2 would equal 1, because 5/2 = 2*2 + 1.

Arithmetic operators will try to convert string arguments into numbers. Thus, "2"+2, 2+"2" and "2"+"2" are all equivalent to 2+2.

The logical operators in Lua are and, or and not.

nil and false are considered false in logical expressions, whereas all other values are considered true.

The and operator returns true if both values are true.

The or operator returns true if at least one of the values is true.

The not operator is an unary operator that returns the opposite of the given value. As such, (not false) == true and (not true) == false. not nil also evaluates to true.

Another operator in Lua is the .. operator, which performs concatenation. When two values are concatenated, they are put together and transformed into a string:

Functions

Functions in Lua are declared using the reserved word function. Because functions are first-class values, they can be declared in two different ways:

The two syntax constructions are equivalent.

A function in Lua can have an arbitrary amount of arguments. Arguments are specified between brackets in the function declaration. A function declaration must always be terminated with the word end.

A sample function that prints its argument to the console:

Flow control

Flow control is control over code execution. Flow control basically lets you execute different code under different circumstances.

Basic flow control in Lua is represented by three keywords: if, else, elseif. The general structure is:

CS2D Lua

[:ru]

Since beta 0.1.1.4, Lua has come to be an integral part of Counter-Strike 2D. It has added a whole new level of customization to the game, and sparked the initiative in many players, both old and new, to create wonderful modifications to the game, and make whatever they wanted possible.

Now, at beta 0.1.2.2, Counter-Strike 2D Lua has grown and now offers tools to customize the game in unique ways never possible earlier.

But, the more sophisticated a system becomes, the more difficult it is for newcomers to take on. This article is made to help beginners in that process.

Be warned that this tutorial uses some sophisticated English words and constructions, as well as technical terms; have a translator or a dictionary by your side if you're not sure in your language skills.

Notes in red boxes are warnings. They usually tell you how to avoid common mistakes or notify you about the disadvantages of some approach, and should be read.
Notes in blue boxes are information. They usually tell you additional info about an approach or a feature. Although they may be skipped it's recommended that you read them for general education and future reference.
Notes in green boxes are newbie information. They usually offer friendly explanations for newbies in programming. If you haven't had experience in programming you should read them.

 

A Quick Start

Since this is a tutorial to get you started with Lua in Counter-Strike 2D, let's leap into action and make a script right away. It shall be a true classic in the CS2D community - a script that colours your chat, randomly in our edition.

[lua]
function randomColour()
local r, g, b = math.random(0,255), math.random(0,255), math.random(0,255) -- Make up a random RGB colour (pseudorandom number generator from 0 to 255 as per RGB specifications)
r, g, b = string.rep("0",3-#r)..r, string.rep("0",3-#g)..g, string.rep("0",3-#b)..b -- Format the colour according to the CS2D format (preceding zeroes if a colour value is less than three digits long)
return string.char(169)..r..g..b -- Add a colour mark and we're done (the copyright sign, Unicode point U+00A9)
end

function teamColour(team)
local colours = {[0]=string.char(169).."255220000",string.char(169).."255000000",string.char(169).."050150255"} -- Team colours assigned to team numbers (0 for spectators, 1 for Terrorists, 2 for Counter-Terrorists)
return colours[team] -- Return the colour that corresponds to the given team
end

addhook("say","colouredChat",1) -- Make a function that runs whenever someone says something and give it the top priority
function colouredChat(id,txt) -- Initialise the function (two arguments are passed to it when it is called - the ID of the player who spoke and his message)
msg(teamColour(player(id,"team"))..player(id,"name")..": "..randomColour()..txt) -- Send a coloured message into the chat!
end
[/lua]

SECTION INCOMPLETE

The Basics

Before we begin learning the actual language, there are a few programming terms you should familiarise yourself with:

  • Variable - a "container" that holds a value
  • Argument - data given to a function or an operator that they then operate on
  • Function - a piece of code that performs some action
  • Operator - a word or a symbol that performs an action and gives a result depending on its arguments

The Lua language is in many places easier to learn than, for example, C or Java. It has a number of features that make it simpler for newbies to pick up, especially in the beginning, so learning its basics really won't be that difficult.

Variables

Let's start with variables. There are 8 data types: nil, boolean, number, string, table, function, userdata and thread. Unlike in some other languages, variable types don't have to be explicitly declared:

[lua]
-- Instead of how you would do it in C or Java:
int n = 0;

-- This is how you would do it in Lua:
n = 0
[/lua]

The "absence" of a meaningful value is represented by nil. Although nil in itself isn't bad, it can raise some problems if not handled correctly. More on that in later paragraphs.

nil is synonymous to nil in C, nil in Java and nil in Python. The data type of nil is nil. By default, any variable has the type and value nil.

[lua]
print(a) -- Print a non-declared variable - prints "nil"
print(type(a)) -- Print its type - prints "nil"
[/lua]

Variables of type boolean can represent only two values: true or false. Boolean variables are usually used to indicate the state of something that can only have two states, a metaphorical switch of sorts. They can be used to indicate whether a player is alive or not, whether a process is running or not, and so on.

nil and false are considered false in expressions, whereas all other values are considered true.

The number data type is used to store numbers of (almost) arbitrary size.

Lua does not differentiate between different types of numbers; bytes, chars, integers, longs, as well as single- and double-precision numbers are all represented by the number data type. Internally, Lua uses double-precision floating-point numbers for its number type, and as such only supports numbers up to 21023.

The string data type is used to store strings - collections of characters - of arbitrary sizes.

The table data type is, by far, the feature that distinguishes Lua from other scripting languages. In short, a table can contain any reasonable amount of values of any data type. Entries in a table are stored in key-value pairs - one value corresponds to one key. Keys can be any type except for nil, values can be any type including nil (and are nil by default). Tables are a large and important topic in Lua and will be discussed separately.

The function data type is used to store functions.

Unlike in some other languages, functions in Lua are first-class values; that means that they can be manipulated in the same way as other variables.

The userdata data type is used by Lua internally. Values of the userdata type cannot be modified by Lua directly.

userdata values are used by the C API to store C data and are simple memory blocks.

The thread data type is used by Lua in its coroutine implementation.

Operators

One of the most important operators is the = operator. It is used to assign values to variables or table entries.

Another important operator in lua is the == operator. It is a comparison operator, and as such it compares two values. It returns true if the values are the same or false if they are not.

Do not confuse the = and == operators! Even though they are very similar visually, their functions are drastically different!

 
Lua has the ~= operator, which is the equivalent of != in other languages and is the opposite to ==. It returns false if the values are the same or true if they are different.

The basic arithmetic operators in Lua are +, -, * and / for addition, subtraction, multiplication and division, respectively. The unary minus is the - operator which operates on only one value. 0-2 and -2, despite being two different operations, are equivalent in Lua.

Lua uses the ^ operator for exponentiation (2^2 is equivalent to 22).

Lua also has the % operator, called the modulo operator. It is used to return the remainder of a division; 5%2 would equal 1, because 5/2 == 2*2 + 1.

The logical operators in Lua are and, or and not. As has been stated before, in logical expressions nil and false are considered false, whereas all other values are considered true.

The and operator returns true if both values are true.

The or operator returns true if at least one of the values is true.

Lua does not have built-in operators for NAND (a nand b is equivalent to not (a and b)), NOR (a nor b is equivalent to not (a or b)), XOR and XNOR.

The not operator is an unary operator that returns the opposite of the given value. As such, not false == true, and not true == false.

Another operator in Lua is the .. operator, which performs concatenation. More on concatenation will follow in later paragraphs.

Functions

Functions in Lua are declared using the reserved word function. Because functions are values like any others, they can be declared in two different ways:

[lua]
function test()

end

test = function()

end
[/lua]

The two syntax constructions are equivalent.

A function in Lua can have an arbitrary amount of arguments. Arguments are specified between brackets in the function declaration. A function declaration must always be terminated with the word end.

A sample function that prints its argument to the console:
[lua]
function test(a)
print(a)
end
[/lua]

Flow control

Flow control is control over code execution. Flow control basically lets you execute different code in different cases.

Basic flow control in Lua is represented by three keywords: if, else, elseif. The general structure is:

[lua]
if (a==1) then -- if a is 1
-- do something
elseif (a==2) then -- if a is 2
-- do something else
else -- if a is neither 1 nor 2, but something different
-- do something different
end
[/lua]

[:de]

Since beta 0.1.1.4, Lua has come to be an integral part of Counter-Strike 2D. It has added a whole new level of customization to the game, and sparked the initiative in many players, both old and new, to create wonderful modifications to the game, and make whatever they wanted possible.

Now, at beta 0.1.2.2, Counter-Strike 2D Lua has grown and now offers tools to customize the game in unique ways never possible earlier.

But, the more sophisticated a system becomes, the more difficult it is for newcomers to take on. This article is made to help beginners in that process.

Be warned that this tutorial uses some sophisticated English words and constructions, as well as technical terms; have a translator or a dictionary by your side if you're not sure in your language skills.

Notes in red boxes are warnings. They usually tell you how to avoid common mistakes or notify you about the disadvantages of some approach, and should be read.
Notes in blue boxes are information. They usually tell you additional info about an approach or a feature. Although they may be skipped it's recommended that you read them for general education and future reference.
Notes in green boxes are newbie information. They usually offer friendly explanations for newbies in programming. If you haven't had experience in programming you should read them.

 

A Quick Start

Since this is a tutorial to get you started with Lua in Counter-Strike 2D, let's leap into action and make a script right away. It shall be a true classic in the CS2D community - a script that colours your chat, randomly in our edition.

[lua]
function randomColour()
local r, g, b = math.random(0,255), math.random(0,255), math.random(0,255) -- Make up a random RGB colour (pseudorandom number generator from 0 to 255 as per RGB specifications)
r, g, b = string.rep("0",3-#r)..r, string.rep("0",3-#g)..g, string.rep("0",3-#b)..b -- Format the colour according to the CS2D format (preceding zeroes if a colour value is less than three digits long)
return string.char(169)..r..g..b -- Add a colour mark and we're done (the copyright sign, Unicode point U+00A9)
end

function teamColour(team)
local colours = {[0]=string.char(169).."255220000",string.char(169).."255000000",string.char(169).."050150255"} -- Team colours assigned to team numbers (0 for spectators, 1 for Terrorists, 2 for Counter-Terrorists)
return colours[team] -- Return the colour that corresponds to the given team
end

addhook("say","colouredChat",1) -- Make a function that runs whenever someone says something and give it the top priority
function colouredChat(id,txt) -- Initialise the function (two arguments are passed to it when it is called - the ID of the player who spoke and his message)
msg(teamColour(player(id,"team"))..player(id,"name")..": "..randomColour()..txt) -- Send a coloured message into the chat!
end
[/lua]

SECTION INCOMPLETE

The Basics

Before we begin learning the actual language, there are a few programming terms you should familiarise yourself with:

  • Variable - a "container" that holds a value
  • Argument - data given to a function or an operator that they then operate on
  • Function - a piece of code that performs some action
  • Operator - a word or a symbol that performs an action and gives a result depending on its arguments

The Lua language is in many places easier to learn than, for example, C or Java. It has a number of features that make it simpler for newbies to pick up, especially in the beginning, so learning its basics really won't be that difficult.

Variables

Let's start with variables. There are 8 data types: nil, boolean, number, string, table, function, userdata and thread. Unlike in some other languages, variable types don't have to be explicitly declared:

[lua]
-- Instead of how you would do it in C or Java:
int n = 0;

-- This is how you would do it in Lua:
n = 0
[/lua]

The "absence" of a meaningful value is represented by nil. Although nil in itself isn't bad, it can raise some problems if not handled correctly. More on that in later paragraphs.

nil is synonymous to nil in C, nil in Java and nil in Python. The data type of nil is nil. By default, any variable has the type and value nil.

[lua]
print(a) -- Print a non-declared variable - prints "nil"
print(type(a)) -- Print its type - prints "nil"
[/lua]

Variables of type boolean can represent only two values: true or false. Boolean variables are usually used to indicate the state of something that can only have two states, a metaphorical switch of sorts. They can be used to indicate whether a player is alive or not, whether a process is running or not, and so on.

nil and false are considered false in expressions, whereas all other values are considered true.

The number data type is used to store numbers of (almost) arbitrary size.

Lua does not differentiate between different types of numbers; bytes, chars, integers, longs, as well as single- and double-precision numbers are all represented by the number data type. Internally, Lua uses double-precision floating-point numbers for its number type, and as such only supports numbers up to 21023.

The string data type is used to store strings - collections of characters - of arbitrary sizes.

The table data type is, by far, the feature that distinguishes Lua from other scripting languages. In short, a table can contain any reasonable amount of values of any data type. Entries in a table are stored in key-value pairs - one value corresponds to one key. Keys can be any type except for nil, values can be any type including nil (and are nil by default). Tables are a large and important topic in Lua and will be discussed separately.

The function data type is used to store functions.

Unlike in some other languages, functions in Lua are first-class values; that means that they can be manipulated in the same way as other variables.

The userdata data type is used by Lua internally. Values of the userdata type cannot be modified by Lua directly.

userdata values are used by the C API to store C data and are simple memory blocks.

The thread data type is used by Lua in its coroutine implementation.

Operators

One of the most important operators is the = operator. It is used to assign values to variables or table entries.

Another important operator in lua is the == operator. It is a comparison operator, and as such it compares two values. It returns true if the values are the same or false if they are not.

Do not confuse the = and == operators! Even though they are very similar visually, their functions are drastically different!

 
Lua has the ~= operator, which is the equivalent of != in other languages and is the opposite to ==. It returns false if the values are the same or true if they are different.

The basic arithmetic operators in Lua are +, -, * and / for addition, subtraction, multiplication and division, respectively. The unary minus is the - operator which operates on only one value. 0-2 and -2, despite being two different operations, are equivalent in Lua.

Lua uses the ^ operator for exponentiation (2^2 is equivalent to 22).

Lua also has the % operator, called the modulo operator. It is used to return the remainder of a division; 5%2 would equal 1, because 5/2 == 2*2 + 1.

The logical operators in Lua are and, or and not. As has been stated before, in logical expressions nil and false are considered false, whereas all other values are considered true.

The and operator returns true if both values are true.

The or operator returns true if at least one of the values is true.

Lua does not have built-in operators for NAND (a nand b is equivalent to not (a and b)), NOR (a nor b is equivalent to not (a or b)), XOR and XNOR.

The not operator is an unary operator that returns the opposite of the given value. As such, not false == true, and not true == false.

Another operator in Lua is the .. operator, which performs concatenation. More on concatenation will follow in later paragraphs.

Functions

Functions in Lua are declared using the reserved word function. Because functions are values like any others, they can be declared in two different ways:

[lua]
function test()

end

test = function()

end
[/lua]

The two syntax constructions are equivalent.

A function in Lua can have an arbitrary amount of arguments. Arguments are specified between brackets in the function declaration. A function declaration must always be terminated with the word end.

A sample function that prints its argument to the console:
[lua]
function test(a)
print(a)
end
[/lua]

Flow control

Flow control is control over code execution. Flow control basically lets you execute different code in different cases.

Basic flow control in Lua is represented by three keywords: if, else, elseif. The general structure is:

[lua]
if (a==1) then -- if a is 1
-- do something
elseif (a==2) then -- if a is 2
-- do something else
else -- if a is neither 1 nor 2, but something different
-- do something different
end
[/lua]

[:]

Leave a Reply

Your email address will not be published. Required fields are marked *