Lua is a world-famous scripting language. It is a lightweight multi-paradigm programming language designed as a scripting language with extensible semantics as a primary goal. A typical usage of Lua is to
serve as an embedded script tool in a large application developed using C, C++, Java, C#, etc. In this article, we are to explore how to integrate Lua into C# applications, especially WPF games.
The test environments we'll utilize in the sample applications include:
1. Windows 7;
2. .NET 4.0;
3. Visual Studio 2010;
4. LuaForWindows (version 5.1.4-45 at
http://code.google.com/p/luaforwindows/), the famous Lua integration development tools on Windows;
5. LuaInterface (http://luaforge.net/projects/luainterface/).
Introducing Lua and LuaInterface
Lua was created in 1993 in Brazil. As a small scripting language, Lua is designed to be embedded inside applications in order to provide flexible expansion and customization. The most famous applications
based upon Lua should be the online game "World of Warcraft" and the AngryBirds game release on the iOS platform.
Lua scripts can be easily called in C/C++ code. Lua can in turn call functions written
using C/C++, which makes Lua widely used in applications. Lua can not only be used as an extension script but can be used as an ordinary configuration file, instead of XML, .ini, and other file formats,
easier to understand and maintain.
Download and rebuild LuaInterface
LuaInterface is a library for integration between the Lua language and Microsoft .NET platform's Common Language Runtime (CLR). Lua
scripts can use it to instantiate CLR objects, access properties, call methods, and even handle events with Lua functions. As of this writing, the latest version of LuaInterface is 2.0.3 compiled against
lower version of .NET.
To use LuaInterface in the latest .NET 4.0, we have to rebuild the source code project. To do this, we can download the source project from here running the following command at the MS-DOS command line:
To successfully rebuild LuaInterface under .NET 4.0, you should remain the two files, App.config under the project LuaInterface.net35, and App.config under the project LuaRunner. If you
remove these two files, you are sure to meet some error during the course of the build. The related reason and solution is simply given at somewhere at MSDN. I forgot taking it down; if you meet such an
error, please search MSDN or leave message at the end of this file. To use LuaInterface more securely, you are suggested to use the assemble LuaInterface.dll and its buddy .dll.
A good news is within
the project LuaInterface.Test, there is a file LuaTests.cs. In this file, there are a lot of test examples (based on XUnit and Mock) related to using LuaInterface in .NET CLR.
Now that the preconditions have been prepared, it is time to build some examples to illustrate how to combine LuaInterface with .NET projects.
Build the Console Sample project - LuaForCSharpTest
First off, create a new C# Console program and name it LuaForCSharpTest. For readers more clearly see the relations between the interested stuff, I create a folder LuaInterfaceStuff which holds the two
file LuaInterface.dll and lua51.dll.
Now, add reference to LuaInterface.dll in the sample project, the other DLL should be automatically copied to the output folder with it.
As usual, let's add
reference to the namespace defined in the assemble:
Let's next introduce the related tiny samples one by one.
Sample 1 - access global variables
To interact with Lua, we should first create an instance of the Lua virtual machine. And then we create the following .NET code to access the global variables defined in the .NET side (you can of course
access those defined in Lua files - to be shown later).
There are only eight basic types defined in Lua, i.e.
table. The table type is like a magic, with which you can achieve more flexible and stronger data structures, and other fantastic features. Here, we defined some global
variables, use the method
NewTable to define a table and use the related method
GetTable to access the table. As you may have guessed, all the global variables are held inside the
property Globals of the Lua virtual machine. As for the method
DoString, we'll discuss it in particular later on.
The running-time snapshot is shown in Figure 1.
Figure 1: The running-time snapshot for Sample 1
Sample 2 - access functions and tables defined in Lua
In Lua, functions can be stored in variables, passed as arguments to other functions, and returned as results. With this definition, you can easily redefine a function to add new functionality, or simply
erase a function to create a secure environment when running a piece of untrusted code. Moreover, Lua offers good support for functional programming. And also, functions play a key role in Lua's object-
On the other hand, table is similar to the associative array in C# and Java, but with more flexibility and efficiency. An associative array is an array that can be indexed not
only with numbers, but also with strings or any other value of the language, except nil. By digging further, you will easily find that tables are virtually the only data structuring mechanism in Lua, with
which you can represent ordinary arrays, symbol tables, sets, records, queues, and other data structures, in a simple, uniform, and efficient way.
Detailing into function and table is beyond the scope
of this short article. Let's see a simple example concerning accessing Lua function and table via CLR.
First, we define a .lua file named LuaAdd.lua using SCiTE.
In the above script file, we defined two functions, three tables (named mytable1, color, and tree respectively), three global variables -
Please don't define the .lua file content with Visual Studio because the .lua file is not the simplest text file format as you image. So you are suggested to create .lua files using
special .lua editor like SciTE (together with the Lua for windows package). If you create .lua file using Visual Studio you are sure to meet some error when running the application.
Now, let's see the CLR code dealing with the above Lua script.
DoFile method loads and executes the Lua script. By digging into the anti-compiled code using ILSpy.exe (a
good open-source .NET assembly browser and decompiler with which you can remove your .NET Reflector since it will become a commercial tool), I find
GetFunction is just a simple helper method of
the Lua class. The real work is finished in another class LuaFunction, which has a
Call method to execute the target function, with two arguments (in this case), and return the function's
return values inside an array.
GetTable method of class Lua and another class LuaTable, we can easily retrieve all the table related info defined in the Lua side as shown above.
Figure 2 illustrates the related running-time screenshot.
Figure 2: The running-time snapshot for Sample 2
Sample 3 - the DoString method
There is a Lua function called
loadstring which is similar to another Lua function
loadfile, except that it reads its chunk from a string, not from a file. As you image, the
DoFile method and another method
DoString are just the correspondents of the Lua function
loadstring. Every time the method
DoString is called, the compilation is executed, so although
DoString is stronger it may result in huge overhead. Before using it please make sure that you cannot find simpler one
to tackle your immediate problem.
Now, let's look at a related example.
As you've seen, we can within the method
DoString do common Lua things. The corresponding running-time snapshot is given in Figure 3.
Figure 3: The running-time snapshot for Sample 3
Sample 4 - calling of a function inside a table
As is mentioned previously, you can easily extend the current function of Lua using table. The following example gives a simple example, in which we define an empty object and also define a method for it.
In fact, with this approach, we can achieve object-oriented programming support in Lua. Though, this is only a simple case; the real thing is associated with more details.
Let's look at the related CLR
The corresponding running-time snapshot is given in Figure 4.
Figure 4: The running-time snapshot for Sample 4
Sample 5 - calling of a global function that returns two values
In this sample, we are going to use
DoString method to construct a Lua function, and then call it using the Lua virtual machine. Through this example, you will further have an idea of the
powerful feature of the
The related running-time snapshot is shown in Figure 5.
Figure 5: The running-time snapshot for Sample 5
Sample 6 - Test the RegisterFunction method
In this example, we will explore another powerful feature of LuaInterface. Via the
RegisterFunction method of the Lua virtual machine class, we can register a CLR function to Lua, so that
the Lua script can invoke the function as if it is an internal function. And at last, we will use the above means to test it.
First of all, let's define a simple C# method named
outside the method Main.
This method simple sets the fore color of the Console and then output the incoming string.
Now, let's look at the first case in which we will register the above function within the Lua
virtual machine and then invoke this method from the CLR side.
The running-time snapshot for Sample 6 case 1 is given below.
Figure 6: The running-time snapshot for Sample 6 case 1
second case, we will invoke the above registered CLR function inside Lua script. Let's first look at the Lua script (named outStringTest.lua), as shown below.
Finally, we start to test in the C# side with the following code.
In this case, we invoke the method
DoFile of the Lua virtual machine to execute the above Lua script, so that the method
outString1 gets invoked inside Lua. The
second case related snapshot is shown in Figure 7 below.
Figure 7: The running-time snapshot for Sample 6 case 2
above samples, you've seen how we can invoke Lua scripts from inside C# applications. In fact, as a high-efficiency embedded language, Lua can do far more than that. In the next section, you will see more
complex samples where lua files can invoke other .lua files, components defined inside .NET assembles and even more...
Sample 7 - Invoking other .lua files, .NET assembles and more…
The following sample is adapted from the online LuaInterface samples (http://penlight.luaforge.net/packages/LuaInterface/).
In most of the online samples, you would see Lua scripts inside C# application can easily interact with .NET libraries and related data structures. Now, let's take a look at a related example.
let's build up a Lua script file named Prompting.wlua which looks like this.
First note that
require command is the generally-used higher-level function to load and run libraries in Lua. Roughly,
require does the same job as
dofile, but with two important differences. First, require searches for the file in a path; second,
require controls whether a file has already been run to avoid duplicating the
work. Because of these features,
require is the preferred function in Lua for loading libraries.
Second, CLRForm.lua is a lua script file shipped together with LuaForWindows_v5.1.4-
45.exe, which is located under \Program Files\Lua\5.1\lua. The CLRForm module contains some very useful utilities for doing Windows Forms programming in Lua. In fact, by opening CLRForm.lua, you will notice
it further call another module using
require "CLRPackage". CLRPackage.lua is a helper script to simplify the explicit invocation of all the required types, which is also located under \Program
PromptForString is a function defined in the file CLRForm.lua. In this case, we use the method
PromptForString to prompt the user to enter some
content and then call the delegate MessageBox to show a CLR dialog.
Finally, according to the online LuaInterface samples, the .wlua extension is associated with the GUI version wlua.exe while .lua is
associated with the console version lua.exe. Though, in our self-built samples we can also use the .wlua files.
To make our sample normally run, we copy the two files CLRForm.lua, and CLRPackage.lua at the project root folder while put the other .lua script files under the sub folder named
scripts, all of whose "Build Action" property should be set to "Content" and the "Copy to Output Directory" to "Copy if newer".
Next, let's look at the .NET side programming.
There is only a simple
DoFile method call; most of the work has been done in the Lua side.
The running-time snapshot is shown in Figure 8 and 9.
Figure 8: One of the running-time snapshots for Sample 7
this case, I input a simple string "Hi" at the textbox, and then you will see a related modal dialog like Figure 9.
Figure 9: The other running-time snapshot for Sample 7
will notice in the downloadable source project, there are still more samples in the file Program1.cs, which are nearly corresponding to the ones in the online samples. Nearly all of them have been passed in
this sample project.
Integrate Lua into WPF Games
Embedded scripting language can give our application system more powerful flexibility and scalability. Take the world-famous network game World of Warcraft for example. This application used a bit more
than 200K of Lua volume but gained a very fast computation speed. Nowadays, in Microsoft .NET platform, Lua can be widely applied to applications (such as WinForm, WebForm, WPF, etc.) which allow unsafe
code. The good features of ease of use (no needing to consider the core module of complex logic, just using the simple script to complete the task can be specified), cross-platform (once compiled by the
right script language can be free to migrate to other systems), and expansion of demand (in the function of the complement system and upgrade in the same play a pivotal role) makes Lua applicable over a wide
variety of development areas.
Starting from this section, let's explore how to make WPF games interact with Lua.
First, start up Visual Studio 2010 and create a general WPF application named
LuaInWPFGame based upon .NET 4.0.
Second, add a reference to LuaInterface in our WPF project. In our case, we use the afore-mentioned ready-made assemble LuaInterface.dll (together with the related
Next, let's take the popular chat scene in a WPF game as an example to introduce how to embed Lua inside a WPF application.
Set up Lua script
The first thing to do is to create a Lua script file (named Talk.lua). The script is responsible for storing the chat content, as well as making corresponding process according to the income parameters.
And especially, the script will invoke a C# method, return the data to the code-behind .cs file, and eventually the contents are reflected to the UI interface. The complete script code is as
The first variable content is a table, which is used to store all kinds of chat contents. Here I defined three sets of contents. As is shown, the method
ShowTalk called another
RandomTalk that's defined in the C# site to achieve the target of displaying conversation contents onto the screen. Apparently, the
RandomTalk method does not belong as
part of the Lua script file. In this case, we illustrate to you how Lua calls C# method within a WPF application. Of course, we also need to register this method for the script in the background WPF C# code,
so that the method can ultimately play the role.
The Build Action of the script file Talk.lua should be set as "Embedded Resource" in the Properties dialog.
WPF C# programming
As the preceding C# Console samples, to use Lua inside WPF, we should first add necessary namespace reference.
Next, we define a Lua virtual machine class (as well as define other related variables used in the sample game):
Also note that we defined a Sprite array to represent the sprites to be rendered in the game scene. In this case, we will simple draw five game characters and let them chatter around a fire.
Each character is described using the Sprite class (refer to the source code yourself).
Now, set up the C# method to be invoked with the Lua script.
Here, we randomly select a sprite and assign the passed in argument as his topic.
Now, we should register the above C# method to make Lua know it and all related info.
Since all the related details concerning registering the method have been covered previously, we are no more to delve into it. You've also seen after the registration we invoked the method
DoFile of the lua virtual machine to load and run the script.
Till now, the core of the mechanism of embedding Lua script inside a WPF application has been introduced. Figure 10 gives one
of the running-time snapshots.
Figure 10: One of the running-time snapshots of the WPF game
In this article you learned the fundamental means of integrating Lua into C# based Console and WPF applications. Lua is a high-efficient embedded language based upon ANSI C. Lua offers many advanced
features based upon the two components table and function; we cannot delve into all the interesting stuffs, but you can refer to other detailed Lua materials together with this tutorial to do further
I'm a college teacher and also a freelance developer and writer from WeiFang China, with more than fourteen years of experience in design, and development of various kinds of products and applications on Windows platform. My expertise is in Visual C++/Basic/C#, SQL Server 2000/2005/2008, PHP+MyS...
This author has published 81 articles on DotNetSlackers. View other articles or the complete profile here.
You might also be interested in the following related blog posts
InfoStrat releases a Virtual Earth control for both WPF and Surface to CodePlex
Expression Products Added to MSDN
Host WPF Controls in Windows Forms
Using WPF, Virtual Earth, and WPF/E together...
More WPFE, Virtual Earth, and AJAX goodness!
Windows Forms Additions in the Next Version of .NET
WPF/E and Script#
ASPInsiders Public Notes - Scott Guthrie
You gotta love SeeWindowsVista
Please login to rate or to leave a comment.