Plug-in scripting tutorial

From Vendetta Lua
Jump to: navigation, search


Introduction

This tutorial is designed for anyone new to writing Vendetta plug-ins that wants to jump in and get started. The format of the tutorial will be to introduce a couple of new ideas and then use those ideas in an example creating a small plug-in for the purposes of demonstration.

Hopefully, this approach will allow beginners to progress with careful study, but at the same time will not bore experienced programmers to tears.

Vendetta and the Lua Scripting Language

Many games today allow player created plug-ins and mods. Most games do this in the same basic way. First the core of the game (both server and client code) is written in a language such as C or C++, which is very efficient but takes a lot of experience and care to avoid subtle mistakes. The language is chosen to achieve the best possible performance at the cost of slower development time or more complicated code.

Then, to allow programmers to build upon this core rapidly, a second programming language is used. This second language is known as a scripting language. The principle benefit of a scripting language is that scripts are isolated from many low level, complex, details of the game core. This allow code written in scripts to be comparatively simple and easy to read (once you get the hang of it). As a result, development times using scripts can be very fast. As an added bonus, anyone, whether they are a member of the game development team, or regular a player, can use the scripting language to build upon the core game in creative new ways.

In Vendetta, that scripting language is Lua. All of the Vendetta Plug-in code you write will be written in Lua. Lua is a widely used language with free documentation and interpreters available on-line. So, the time you spend learning Lua while writing Vendetta plug-ins is a good investment, because you are free install Lua on your machine at any time and use the language however you see fit.

This tutorial will not spend much time covering the features of Lua itself, but will focus on using Lua in combination with Vendetta plug-ins. If you are new to Lua, you may benefit from spending an hour or two with some of the excellent Lua tutorials available on-line.

  • The Programming Language Lua[1]
  • Lua Tutorial Directory [2]

Getting Started with the Command Console

Getting started with Lua scripting in Vendetta is so easy, you don't even have to leave the game. That is because Lua is available to us via the in game command console.

First we'll open the command console. The default method of opening the command console is with the ` key (left of the '1' key). The command console can also be opened by typing /ConsoleToggle into any chat channel.

Then, we can access the Lua scripting language by starting the line with the command /lua. The output form Lua commands will appear in your message window. Let's do a couple of examples to get started.

/lua print("hello.");

One of the handy features you can start using right away is Lua's built in support for basic arithmetic. Suppose the station I'm docked at sells Synthetic Hydrocarbons at a price of 27c each. If I want to know the price for buying 117 Synthetic Hydrocarbons, the total cost can be quickly calculated in Lua.

/lua print(27 * 117);

The answer: 3159

For our last example of Lua in the Command Console, we'll use an API call to find out something about the state of the game. We'll get the id of the active chat channel.

/lua print(GetActiveChatChannel());

As you can see, lua script executed via the command console run immediately when you press ENTER. However, if you want to run the same command again in the future, you must retype it completely. As your scripts become more complex, you'll need to store the scripts in files so they can be executed again and again with minimal typing.

We do this by creating a plug-in, which is the topic of the next section.

"Hello, World!" Vendetta Plug-in

In this section we are going to get all the busy work of making a new plug-in out of the way. We'll cover where to put your files and how to load your plug-in without restarting the game. But we won't be too focused on what is actually going on in the code. For now, copy and paste to make it work. Later on we'll discuss the details of the code.

Let's get started.

Where to put your code:

In order for Vendetta to find your plug-in, it must be located in the correct place on your system. Our plug-in code will always be in a file named "main.lua". However the directory that main.lua belongs in is different for each of the three major operating systems supported by Vendetta, so we'll cover each in turn.

In general plug-ins reside in directory called 'plugins', and each plug-in needs to have it's own directory there.

VO tries to load a main.lua file from each directory inside plugins. What differes between OSes is where plugins directory is located.

The instructions here are brief, so if you need additional information see slime73's post on this topic in the forums[3]

Linux

In linux, each user has a hidden folder called .vendetta in his or her home directory. This directory contains customized settings, as well as all plug-ins.

first we'll make a directory for the HelloWorld plug-in:

mkdir -p ~/.vendetta/plugins/HelloWorld

then well create the main.lua file.

touch ~/.vendetta/plugins/HelloWorld/main.lua

Edit the file using your favorite text editor, such as vim.

Mac OSX

Right click(or command-click?) Vendetta package and click 'Select package contents'.

Create plugins directory there and then a directory for your plugin.

Windows

Plug-ins directory will need to be created in directory you installed VO to.

Usually it's c:\Program Files\Vendetta Online\

Create plugins directory there.

Hello, World! script

The code for the HelloWorld plug-in is as basic as possible. It prints the message "Hello, World!" to the message window when called from the command console by the user.

declare('HelloWorld', HelloWorld or {})
 
function HelloWorld.cmd(_,data)
  print ("Hello, World!");
end
 
RegisterUserCommand("say_hi",HelloWorld.cmd);

running the script

To reload all plug-ins without restarting Vendetta, you can use the following command:

/lua ReloadInterface()

Finally, to run the code, we execute the command we created in this plug-in:

/say_hi

The output should display in your message window.

The Basic Building Blocks of Plug-ins

Creating a namespace for your work

When writing a plug-in, we want to begin by working in an area that is all our own. We do not want to run the risk of getting function names or variable names mixed up with the resources of another plug-in.

To do this, we declare a namespace (technically, a table) with the same name as our plug-in and carefully keep all of our work inside that area.

  declare('MyPlugIn', MyPlugIn or {})

This namespace does much more than just protect us from name collisions, but additional features won't be covered just yet. Instead you'll learn more about it as you gain experience writing your own plug-ins.

Unterstanding Entry Points

'Entry point' is a term used to describe when and where your code will start running from. For example, in C, the most common entry point is the first line of code in the function 'main()'. In a Vendetta plug-in, there is no single common entry point. So, we are free to chose between a few possible entry points based on which best fit our needs. Also, we can use any number of entry points in combination with each other.

  1. Entry Point: Command Console
  2. The most basic entry point is to interact with the user via command console. The steps to do this are:

    In our plug-in's code:

    1) declare a function.

    function MyPlugIn.cmd(_,data)
      --code goes here.
    end

    2) Register the function with the vendetta command console.

    RegisterUserCommand('myplugin', MyPlugIn.cmd)

    The user :

    3) The user calls the function via command console by running the newly created command.

    /myplugin
  3. Entry Point: Events
  4. Another entry point available to us is to respond to events. Events inform us of what is going on in the game. There are a large number of events available to us, some examples include: getting hit in combat, docking with a station, joining a group, receiving a new inventory item, and so on. Our plug-in will not receive any events until we specify which, if any, we are interested in.

    There is more than one way to register for events, but for now, we'll just cover the steps for creating an OnEvent function (The other methods are covered here[4]). The steps are as follows:

    In our plug-in's code:

    1) Add an 'OnEvent' function to your plug-in.

    function MyPlugIn:OnEvent(event, data)
      --code goes here.
    end

    It's important to note, the function name must be exactly OnEvent, the name is case sensitive.

    2) Register to recieve the events you are interested in.

    RegisterEvent(MyPlugIn, "GROUP_MEMBER_DIED")

    Your Plug-in can register for as many events as you are interested in.

    The User:

    3) Later, during normal game play, every time an event that your plug-in registered for happens, the code in your OnEvent function will be run.

    In the example from step two above, our code would run every time a group member died.

    If your plug in needs to stop processing events you've registered for, it can unregister for the event to save processing time, as follows:

    UnregisterEvent(MyPlugIn, "GROUP_MEMBER_DIED")
  5. Entry Point: Custom GUI
  6. Custom GUI creation is beyond the scope of this tutorial, but keep in mind this is an option available to you using the Vendetta API.

Understanding entry points is important because it will help you plan the design of your code. It will also help you understand other people's plug-in code if you start by analyzing the entry points to determine: 1) what causes their code to run, and 2) what their code does each time it runs.

Vendetta Lua API calls

The final basic building block of Vendetta plug-ins is API calls[5]. Unlike events, that let us know when something is happening, api calls can be used at any time to find out the current status of our character, or another aspect of the game.

Browsing through the API is a great way to get ideas about what is possible in a plug-in or to discover new ways to do things.


Example Plug-in: StationReminder

This is a small example that shows the use of events together with calls to the Vendetta Lua API:

-- StationReminder
--
-- A plug-in that prints the sector of any station we leave to the message box.
 
declare("StationReminder", StationReminder or {})
 
function StationReminder:OnEvent(event, data)
  -- This function triggers when we receive a LEAVING_STATION event.
  -- It prints the sector name every time we leave a station in case we 
  -- need to look it up.
 
  print("Leaving station " .. AbbrLocationStr(GetCurrentSectorid()));
 
end                     
 
-- register to recieve the LEAVING_STATION event. 
RegisterEvent(StationReminder, "LEAVING_STATION")

Example Plug-in: MyPlugIn

This is a small example that shows one way to set up class-like function calls and member variables.

-- An example showing one approach to setting up function calls and "class" 
-- variables.
 
local MyPlugIn = {};
 
function MyPlugIn:init()
  -- set up some "class" variables. 
  self.message_three_text = "my_plugin: message three.";
end
 
function MyPlugIn:print_msg_one()
  -- demonstrate that functions work...
  print("my_plugin: message one.");
end
 
function MyPlugIn:print_msg_two()
  -- demonstrate that functions work...
  print("my_plugin: message two.");
end
 
function MyPlugIn:print_msg_three()
  -- demonstrate that functions work...
  print(self.message_three_text);
end
 
function MyPlugIn:command_console()
  self:init();
  self:print_msg_one();
  self:print_msg_two();
  self:print_msg_three();
end
 
RegisterUserCommand("my_plugin", MyPlugIn.command_console, MyPlugIn);

Summary

This tutorial was written by a beginner with other beginners in mind. I hope this tutorial has given you a quick and relatively painless introduction to Vendetta Plug-in scripting. If you have feedback, feel free to post it on the discussion page.

I look forward to using your plug-ins in the game.

Rubin427 16:53, 19 June 2009 (UTC)

Appendix A: Links and Resources

  • The Programming Language Lua[6]
  • Lua Tutorial Directory [7]
  • Vendetta Lua Interface Documentation Wiki [8]
  • Available Plug-ins [9]
  • VO Lua Question/Answer Thread [10]