![]() |
| [[ Home | Forums | 3D Engines Database | Wiki | Articles/Tutorials | Game Dev Jobs | IRC Chat Network | Contact Us ]] |
|
|
#1 |
|
New Member
Join Date: Apr 2003
Posts: 6
|
<html><p align="center"><font size="5">Lua Scripting 101: The Basics</font></p><p align="center">By: Arsenio Costa</p>
1. Introduction In this article, I will try to cover the Lua syntax and also try to give an explanation of what scripting is all about. Since scripting these days is an indispensable part of any game, this should at least be interesting to anyone who wants to make a game. Scripting was used in games like Unreal Tournament, Half-Life, Neverwinter Nights, Quake III, Unreal II, and other games. Scripting will give you the power to code your game's A.I., game dialogs, game events, game history and so on, while also providing the power to the end users of the game to add mods (modifications), A.I scripts, and even game plots (like in Neverwinter Nights). Scripting is what the mod community has been using to allow them to make new levels and other fun stuff. </p> Also who is this guy writing this article, you might ask? First, I need to say I'm neither an expert nor a guru and I do not master all knowledge. I started this adventure called "game programming" about a year and a half; I started with the basics of OpenGL with the powerful assistance of a book called "OpenGL Game Programming", and in the past months I started the journey of scripting with another very powerful book called "Game Scripting Mastery" which is a great book that I recommend seriously to anyone who wants to be a scripting guru. I'm not also a god so you might find mistakes. If any mistakes are found, please email-me at arsenio_costa@hotmail.com so I can rewrite the tutorial and send a new version to DevMaster.net. So with that said let's start...Happy coding and happy scripting </p><p align="left">2. Why Scripting?</p>Imagine you already have your game engine ready and want to take the next step: making a full game.</p> Most might think "well the hard part is done (the engine) so now it will be a piece of cake to complete the game". Imagine you want to make an RPG with your engine, and already have sounds, levels, models and so on. You can put it all in the screen and you can even allow them to interact each with another (the models I mean). You can also play sounds. However, something is missing. The most important part of any game is Game Content; without it there will be no game. Can you imagine yourself writing thousands of code lines to code the game's AI, items descriptions, and associate with them actions like for a potion the ability to cure MP or HP. and interactivity of your players and the NPC's all together with the game engine?. And when do you find you have something wrong? Can you imagine yourself searching for that specific dialog in thousands of lines? Worst yet: compiling, why do you need to compile the entire engine together with the game content just to change one dialog? Not to mention the few good minutes you loose just sitting watching your compiler compile.</p> Well I can't imagine that because I know scripting exists and can help. Game content, like sound or art don't have anything to do with the game engine. With audio and art you don't need to compile the entire game if you want to change a sound, the sound artist just do is work changes the file with the new audio file he wants and runs the game EXE and see if that was the intended result. This is because the game engine code and the sound files are kept apart one from each other like you can see in Figure 1.</p><p align="center"><span style="font-size: 12.0pt; font-family: Times New Roman"> </span></p>What we need is to be able to do something with the Game Content and that what scripting gives us. With scripting, you can separate your game content from the engine.</p> I believe the best way to make someone understand what is scripting is to give you an example:</p> Imagine you (and maybe your team) decide to make an RPG game. You start your design paper, write the history of the games, the items the game should have, make some scary sounds, ambient sounds etc.., you also have an engine which allows for the player to walk in a world, play sounds, load levels, animate models, etc.. Next you sit on the computer and start coding. Let's assume that you start with the item: 'potion' and you write some structure like this:</p> <font face="Courier New" size="2"><font color="#0000FF">struct</font> _potion { *** <font color="#0000FF">char</font> *name; <font color="#008000">//the name that should appear in the player inventory, stores etc.</font> *** <font color="#0000FF">int</font> price;****<font color="#008000">//how much this item cost in a shop?</font> *** <font color="#0000FF">int</font> power;****<font color="#008000">//how much effect this does in a player </font>*** <font color="#0000FF">int</font> type;****<font color="#008000">*//what does this potion heals ? HP/M </font>} potion;</font> </p> The name might be "Healing Potion LV 1" or " "Magic Potion LV 2". 'price' is the price for which the player might buy the potion in a store. 'Power' is how much effect the potion has on the player. And 'type' is what does the potion do it can heal mp, hp, restore a player life etc.. After the potion structure suites your need, you can start doing something with it like this:</p> <font face="Courier New" size="2"><font color="#0000FF">const</font> MAX_POTIONS = 20;* <font color="#008000">//the max of different potions you might have. 20 is more than enough for this example</font>************************<font color="#008000">//! just kidding I will only write a few </font></font></p><font face="Courier New" size="2"><font color="#0000FF">const</font> HEALING = 0; <font color="#0000FF">const</font> MAGIC_RESTORE = 1; <font color="#0000FF">const</font> LIFE_RESTORING = 2; potion potions[MAX_POTIONS];</font></p> <font face="Courier New" size="2">potions[0].name = "Magic Potion LV 2"; potion [0].price = 200; potion [0].type = HEALING; potion [0].power = 40;</font></p> <font face="Courier New" size="2">potions[1].name = "Fenix the bringer of life LV 1"; potion [1].price = 1500; potion [1].type = LIFE; potion [1].power = 20;**** <font color="#008000">//power in this case might be the amount of life</font></font></p> <font face="Courier New" size="2" color="#008000">//the player would have after is return from dead</font><font face="Courier New" size="2">potions[2].name = "HP potion LV 1"; potion [2].price = 150; potion [2].type = HEALING; potion [2].power = 20;</font></p> upon recompiling the game you would have 3 new brand potions available to your player now its time to make a little play test you start playing the game to make and realize that the "Magic potion LV 2" is a little expensive and the player is a little poor to survive so you stop running the game and just go and change one line right? Right no problem:</p> <font size="2" face="Courier New">potions[0].price = 150;</font></p> now everything is ok you start the game. Oops, did I say start ? No I mean recompile the game and the start the game. After a few minutes, you are able to start the game. You start it and guess what? Bad luck; now the problem is "HP potion LV 1" which isn't ok because it heals too little HP so you stop the game again! So you go to change it.</p> potion [2].power = 40;</p> and then you will have to recompile.</p> Conclusion: hardcoding is not efficient (hardcoding basically is what we've done above: mixing the game engine with the Game Content). In a game like an RPG, tweaking the items is a very important step since RPG games have a lot of Game Content like items, weapons, plot's, etc. Now that we've defined the problem how can we solve it to make the Game Content like sound or art?. The answer is SCRIPTING, like most of you should already guess.</p> 3. Overview of Scripting</p> When you write a script, you write just like you would write a normal program with the exception of some of the programming scripting language syntax (which I'm going to cover one of the most popular: LUA) you open your text editor or IDE.</p> The difference begins with the compilation step. You can choose either to compile the script or leave it the script in the original form (text). Leaving the code uncompiled means you can have to make your engine load and interpret the scripts in a "pure" code form instead of a compiled form. Most of the times, you will have to compile the script because it will make its loading quicker and also protects your game from hacks. Another difference exists between coding a script and normal coding like c++, which is how the code will be run. I talked about a compiling step but I didn't mean compiling to real machine code like asm, since the script won't be run by the CPU. Rather, it will be run by something called a VM (Virtual Machine). While the programs you code runs on the CPU the scripts run on the VM which in turn will be run by your program (the "host"). A VM alone is nothing. It's like a "module" you build into other programs like your RPG. That program is called the "host application" and with the scripts you load and run you are "scripting the host application". The game engine is the engine that makes the script able to communicate with your RPG and give it orders. The script might ask the RPG how much life the players has, or reduce it to half if it was a cursed potion for example. When your program calls a script function, this is called intra-language calls. It is possible because you "give" to the abstraction layer (which might be seen as an intermediate between c and your scripting language also know as interface) access to the program function. It is this abstraction layer which allow for two distinct languages to "speak" with each other. For instance, if I need to talk with a Japanese person, we to would communicate through a translator.</p> Now that I tried to explain what scripting is, I hope you understand it now. It is now time to start work and we will go to clear one of the available free scripting languages Lua. Go quick to the next topic what are, you waiting for?</p> 4. Lau and its Syntax</p> Lua is one of the simplest scripting languages available. But don't be a fool to think it is a poor scripting language. Lua was used in a lot of commercial games like MDK2, Baldurs Gate, and I believe (almost sure) Impossible Creatures used it (I have the game and saw there some .lua files Lua is a clean and easy to use scripting language. You can also get more information from the official web site www.lua.org. If you want to become a game scripting guru you, you got to go and make a stop there since I will only cover some of the basics. Lua comes packaged in a very organized way with the include files and libraries needed to link Lua into your host application as well with other few utilities.</p>4.1 The Lau Library</p> Lua library is mainly composed of two files: lua-lib and lua.h. The library provides a clean API, which allows loading scripts, running scripts and, most importantly, initializes Lua and shut it down.</p> 4.2 The Lau Compiler</p> Lua also comes with a command line compiler called lua. Typing 'luac' in the command prompt will display the program's usage info. In order to compile a script you need to type luac <FILENAME> which you should get used to. Lua doesn't require a compiler in order to use lua since lua can load your script directly and compile it on-the-fly, saving you time. Uncompiled form will have three disadvantages: That your script will load slower than the compiled scripts. Another one is that you won't be able to get compile time error information. The final reason, and maybe the most important, is that your script code won't be "available" to those hackers. In other words, you don't need to use the Lua compiler but you should!. The choice is yours.</p> 4.3 Lua's interactive interpreter</p> One also useful utility that comes with lua package is the lua interactive interpreter. This little program allows you to test blocks of lua code and see its results in real time. Although I haven't explained the lua syntax, start it and try this:</p> <font face="Courier New" size="2">*** > player_life = 500 *** > player_life = player_life - 200 *** > print(player_life)</font></p> lua's interactive interpreter should show the following output</p> <font face="Courier New" size="2">*** 300</font></p> 'print' should be self-explanatory like <font size="2" face="Courier New">printf</font> in c++ and it is used to print values into the screen. The interactive interpreter also allows you to run scripts without the need to embed the lua.lib into a C program. Simply type '<font face="Courier New" size="2">lua my_script_filename.lua</font>' and it will attempt to run the script and print the output of the script.</p> 4.3 Journey begins: Lua syntax</p> The Lua syntax is a very simple and clean scripting language. Lua is like a cousin of c, Pascal, and BASIC. If someone is familiar with the c syntax switching to Lua won't be too hard..</p> Variables: like most part of scripting languages, variable in Lua are typeless, which means that one variable can hold any value of any type at any time. Unlike C in which you declare a variable of one type (int for example) and that variable can't hold any different type, (int can't hold a string and you should not even try). Also unlike C, the variables you use don't need to be declared, when you assigne them. As in C, valid variable names are a sequence of letters, numbers, and underscore that start with a non numeric character (a letter or underscore). Lua is also case sensitive in the use of variables so mycar is different than Mycar. Therefore, in Lua when you assign a variable to a number, you are also declaring the variable like this:</p> <font face="Courier New" size="2">my_car = "alfa romeu" my_car = 128</font></p> as you can see my_car can hold any type of value at any time. You should also note the lack of semicolons at the end of the statement. Including semicolons is also valid, however. People who are used with C++ usually include semicolons.</p> Use the interactive interpreter and try writing the following:</p> <font size="2" face="Courier New">my_car = "ferrari" print(my_car) my_car = 200 print(my_car)</font></p> Lua will not complain and you should see the following output:</p> <font size="2" face="Courier New">ferrari 200</font></p> Another thing about Lua's variables is that Lua supports multiple assignment. Multiple assignment works like this: You put all of the variables on the left of the equal sign. Than on the right of the equal sign, you put the values you want those varibles to be assigned respectively. For example:</p> <font size="2" face="Courier New">x,b = 2, 8</font></p> After this line is executed, x will equal 2 and b will equal 8. Multiple assignments work with any type of data. But what about when you don't provide an equal number of variables and values on both sides? Lua will happily solve the problem for you if you don't provide enough values on the right side by assigning the extra variables to nil (i.e. null):</p> <font size="2" face="Courier New">*** x = 2 *** b,a,x = 12,4</font></p> x will be assigned to nil even if it already had a value before. What about the other case if you have more values on the right than variables on the left? As you might have guessed, Lua will ignore those values </p> <font face="Courier New" size="2">*** x, y = 12, 4, 5, 6, 7</font></p> x will equal 12, y will equal 4 and 5, 6,7 will be ignored. By the way, you can and you should be typing these examples in the Lua interactive interpreter. Use multiple assignments with careful care since it cans make your code hard to read. One good use of it is swapping values:<font face="Courier New" size="2">*** a, b = 2, 4 *** a,b = b, a</font></p> this will swap the two values.</p> Comments: Lua's suports comments and can be used by typing: -- which corresponds to // in C. Lua provides no support for multi-line commenting</p> Data Types: Lua supports numeric values, strings, functions, tables, userdata and the nil. In this tuturial I will cover numeric, tables, functions and the nil. I won't cover userdata simply because I'm not that familiar with it. If you want more information I recommend referring to www.lua.org. This is because the tutorial is intended as a beginner's tutorial.</p><blockquote> Numeric: In Lua, floats and ints are the same data type because of Lua being a type-less language</p></blockquote><blockquote> String: A string of characters almost like char in C, but it supports a few features char doesn't. I'm going to elaborate more on that in a few minutes</p> Function: Just like in C, you have the ability to call a declared function or create one.</p></blockquote> </p><blockquote> Table: Lua's more complex data type and powerful. A Table can be seen as arrays but its also more complex. It is similar to linked list.</p> nil: just like Alex Varaness says in my book are a more sofisticated version of c's NULL. For example, in Lua variables before being assigned are set to nil. Trying to use them results in a run-time error. For example:</p></blockquote> <font size="2" face="Courier New">*** a, b = 2 , 4; *** print ( a + b ); *** print ( a + b + c );</font></p> Will result in an error like this:</p> <font face="Courier New" size="2">*** error: attempt to perform arithmetic on global 'c' ( a nil value)</font></p> nil is also the only concept of "false-hood" lua supports. We've seen this in the upper example. It's also good to remind that nil is false but not equal to 0 in a numeric sense. This was why</p> <font face="Courier New" size="2">*** print(a + b + c)</font></p> c being a nil "value" will result in a runtime error</p> Now I'm going to cover strings in more detail before you can try the examples in the interpreter and also try this:</p> <font face="Courier New" size="2">*** print ( type (2333) ); \ *** print ( type (2.45) ); \ *** print ( type ("Lua rulez") )</font></p> The back slash is to make the interactive interpreter not run the code after pressing enter. Upon pressing Enter you should see</p> <font size="2" face="Courier New">*** number *** number *** string</font></p> As you can see float and int are the same to Lua, 'type' is just a Lua keyword which will return the type of the variable.</p><blockquote> Strings: Lua supports one feature called "coercion" which happens when one data type is forced into another. For example, numeric and strings are two distinct data types but can be used in expressions like this:</p></blockquote> <font size="2" face="Courier New">*** print ( "20" + 4);</font></p> This will print <font face="Courier New" size="2">24</font>. This is because Lua recognizes strings that can be converted in numbers like the previous examples. But expressions like:</p> <font size="2" face="Courier New">*** print ( 20 + "Arsenio");</font></p> will result in an error. This is because "20" makes sense, but "arsenio" doesn't. It will show:</p> <font size="2" face="Courier New">*** error: attempt to perform arithmetic on a string value</font></p> This is the first of part of articles, I will post about Lua, I hope you enjoy it, in the next tutorial I will start with some real examples and maybe applications in which we will be using some Lua scripts!! Feedback is welcome.</p> arsenio_costa@hotmail.com</p></html> |
|
|
|
|
|
#2 |
|
DevMaster Staff
Join Date: Jan 2003
Posts: 1,201
|
This article (and more importantly the other more advanced parts that will come soon hopefully) will definitely be useful for the game project. Nice job Force_of_Will.
|
|
|
|
|
|
#3 |
|
DevMaster Staff
Join Date: Apr 2003
Location: Germany
Posts: 2,328
|
nice !!!
i hope there is more to come. this is definetly the content this site needs. LUA material is very very rare on the net.
___________________________________________
If Prolog is the answer, what is the question ? |
|
|
|
|
|
#4 |
|
DevMaster Staff
Join Date: Jan 2003
Location: Mars
Posts: 1,141
|
unfortunate that the title is misspelled. Any chance of fixing that?
___________________________________________
baldurk He who knows not and knows that he knows not is ignorant. Teach him. He who knows not and knows not that he knows not is a fool. Shun him. |
|
|
|
|
|
#5 |
|
Senior Member
Join Date: Jan 2003
Location: ON, Canada
Posts: 524
|
Force_Of_Will: Very nice article, thank you very much....
___________________________________________
"What ever happened to happily ever after?" |
|
|
|
|
|
#6 |
|
DevMaster Staff
Join Date: Jan 2003
Posts: 1,201
|
oops...probably my fault...I fixed the title.
|
|
|
|
|
|
#7 | ||
|
Valued Member
Join Date: May 2003
Location: Canada
Posts: 111
|
Quote:
*cough* you misspelt Lua in several places. Quote:
Should be "alfa romeo"
___________________________________________
http://stodge.blogspot.com |
||
|
|
|
|
|
#8 |
|
Member
Join Date: May 2003
Posts: 44
|
Needs some more depth to it I think you missed out the other lua libs can't remember.
BTW Homeworld 2 will be using a slightly modified LUA for scripting. Also being smug I mentioned that LUA should be used on teh game project a while back :P |
|
|
|
|
|
#9 |
|
New Member
Join Date: Apr 2003
Posts: 6
|
I intend to cover it more this was the first of a series i will post more when they are done right now id on't have the time maybe in a couple of weeks.
i also intend to present some demos |
|
|
|
|
|
#10 |
|
Senior Member
Join Date: Jan 2003
Location: East Coast, USA
Posts: 370
|
cool - keep up the good work! I hope to learn exclusively from your article and demo's.
moomin: I. LOVE. HOMEWORLD. ![]()
___________________________________________
Imagine. |
|
|
|
|
|
#11 |
|
New Member
Join Date: Jun 2003
Posts: 1
|
nice article,
but I think you could have choosen a better exmaple, it would be much easier to solve your example with datadriven-design than with scripting. rapso->greets(); |
|
|
|
|
|
#12 |
|
New Member
Join Date: Sep 2003
Posts: 1
|
great article, i can hardly wait for the other articles!
|
|
|
|
|
|
#13 |
|
DevMaster Staff
Join Date: Apr 2003
Location: Germany
Posts: 2,328
|
a shame that he never wrote that second article...
i'm sure baldurk will wildly accuse me of necromancing here but i just needed to express my pity ![]()
___________________________________________
If Prolog is the answer, what is the question ? |
|
|
|
|
|
#14 |
|
DevMaster Staff
Join Date: Jan 2003
Location: Mars
Posts: 1,141
|
NECROMANCY!
seriously, this should have been in a seperate topic :|.
___________________________________________
baldurk He who knows not and knows that he knows not is ignorant. Teach him. He who knows not and knows not that he knows not is a fool. Shun him. |
|
|
|
|
|
#15 |
|
New Member
Join Date: Nov 2007
Location: Finland
Posts: 1
|
Great article, im looking forward for next articles of Lua!
|
|
|
|
|
|
#16 |
|
Senior Member
Join Date: Oct 2005
Location: Pensacola, FL
Posts: 1,028
|
Good luck with that! This article was written over four years ago and the two posts above yours remove the necessity of your comment and my rebuke regarding thread necromancy.
![]() Perhaps you can find more information here: http://lua-users.org/wiki/ |
|
|
|
|
|
#17 |
|
Member
Join Date: Dec 2007
Posts: 47
|
This is a pretty bad explanation of Lua.
Multi-line comments are done with --[[ and --]] There are five levels of long strings, here's level one: [[ ]] Level two: [=[ ]=] Level three: [==[ ]==] Level four: [===[ ]===] Level five: [====[ ]====] You must end a long string with the same level you started it with. |
|
|
|
|
|
#18 |
|
Member
Join Date: Dec 2007
Posts: 47
|
World of Warcraft also uses Lua.
|
|
|
|
![]() |
| Thread Tools | Search this Thread |
| Display Modes | |
|