CS2D: Basic Lua tutorial

Since beta, 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, 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.


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.


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 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

Leave a Reply

Your email address will not be published.