Skip to content

Commit

Permalink
Add Eluna documentation: features and getting started
Browse files Browse the repository at this point in the history
  • Loading branch information
Rochet2 committed Jul 31, 2015
1 parent f62c655 commit d57ca13
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 5 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ Special thanks to [MaNGOS](http://getmangos.eu/) for their continued support and

##Documentation

* [Installation](https://github.com/ElunaLuaEngine/Eluna/blob/master/docs/INSTALL.md)
* [__Installation__](https://github.com/ElunaLuaEngine/Eluna/blob/master/docs/INSTALL.md)
* [Getting started](https://github.com/ElunaLuaEngine/Eluna/blob/master/docs/USAGE.md)
* [Eluna features](https://github.com/ElunaLuaEngine/Eluna/blob/master/docs/IMPL_DETAILS.md)
* [Function documentation](http://eluna.emudevs.com/)
* [Hook documentation](https://github.com/ElunaLuaEngine/Eluna/blob/master/Hooks.h)
* [Lua reference manual](http://www.lua.org/manual/5.2/)

* [Contributing](docs/CONTRIBUTING.md)
* [Contributing](https://github.com/ElunaLuaEngine/Eluna/blob/master/docs/CONTRIBUTING.md)
* [Support forum](http://emudevs.com/forumdisplay.php/279-Eluna-Support)
* [Example scripts](https://github.com/ElunaLuaEngine/Scripts)
* [Guides, releases and news](http://emudevs.com/forumdisplay.php/15-Eluna-Lua-Engine-%C2%A9)
Expand Down
80 changes: 80 additions & 0 deletions docs/IMPL_DETAILS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#Eluna features
This article contains information about features and important notes regarding Eluna.

##Settings
Eluna has some settings in the server configuration file.
It is important that you use the new configuration file that you get from compiling after adding Eluna. If the new configuration file is not used you will not receive any error log or output to console.

The configuration file includes at least the following settings:
- enable and disable Eluna
- enable and disable traceback function - this adds extra debug information if you have the default Eluna extensions.
- configure script folder location
- configure Eluna logging settings

##Reloading
To make testing easier it is good to know that Eluna scripts can be reloaded by using the command `.reload eluna`.
However this command should be used for development purposes __ONLY__. If you are having issues getting something working __restart__ the server.

It is important to know that reloading does not trigger for example the login hook for players that are already logged in when reloading.

##Script loading
Eluna loads scripts from the `lua_scripts` folder by default. You can configure the folder name and location in the server configuration file.
Any hidden folders are not loaded. All script files must have an unique name, otherwise an error is printed and only the first file found is loaded.

The loading order is not guaranteed to be alphabetic.
Any file having `.ext` extension, for example `test.ext`, is loaded before normal lua files.

Instead of the ext special feature however it is recommended to use the basic lua `require` function.
The whole script folder structure is added automatically to the lua require path so using require is as simple as providing the file name without any extension for example `require("runfirst")` to require the file `runfirst.lua`.

##Automatic conversion
In C++ level code you have types like `Unit` and `Creature` and `Player`.
When in code you have an object of type `Unit` you need to convert it to a `Creature` or a `Player` object to be able to access the methods of the subclass.

In Eluna this is automatic. All objects are automatically converted to the correct type and you will always have full access to all member functions of an object.

##Storing userdata
Storing userdata objects over time that are memory managed by C++ is a bad idea.
For example you should never save a player to a global variable and then try access it in a timed event. The reason is that the player object in C++ is a pointer to an object that C++ can delete at any time. When time passes the player may have logged out and using the pointer after player object no longer exists can be catastrophic.

To prevent users from doing this objects that are memory managed by C++ are automatically turned into nil when they are no longer safe to be accessed - this means usually after the hooked function ends.
Instead of storing the object itself you can use store guids `player:GetGUID()` and fetch the object by the guid with `map:GetWorldObject(guid)`.

Any userdata object that is memory managed by lua is safe to store over time. These objects include but are not limited to: query results, worldpackets, uint64 and int64 numbers.

##Userdata metamethods
All userdata objects in Eluna have tostring metamethod implemented.
This allows you to print the player object for example.

##Database
Database is a great thing, but it has it's own issues.

###Querying
Database queries are slow. The whole server has to wait for the script to fetch the data from disk before continuing. Compared to reading cache or RAM reading from disk is the same as going to the moon to fetch the data (no pun intended).

Depending on what you need, prefer database Execute over Query when not selecting anything from the database. Database Executes are made asynchronously and they will not keep the server waiting.

Move all database queries possible to the script loading, server startup or similar one time event and use cache tables to manage the data in scripts.

###Types
__Database types should be followed strictly.__
Mysql does math in bigint and decimal formats which is why a simple select like `SELECT 1;` actually returns a bigint.
If you fetch a bigint or decimal using a function for a smaller type it is possible the value is read incorrectly.

For example the same code for fetching the result of `SELECT 1;` returned 1 on one machine and 0 on another. Using the correct function, in this case GetInt64, the right result was returned on both. https://github.com/ElunaLuaEngine/Eluna/issues/89#issuecomment-64121361

| base type | defined type | database type |
|---------------------------|--------------|-----------------------|
| char | int8 | tinyint(3) |
| short int | int16 | smallint(5) |
| (long int / int) | int32 | mediumint(8) |
| (long int / int) | int32 | int(10) |
| long long int | int64 | bigint(20) |
| unsigned char | uint8 | tinyint(3) unsigned |
| unsigned short int | uint16 | smallint(5) unsigned |
| unsigned (long int / int) | uint32 | mediumint(8) unsigned |
| unsigned (long int / int) | uint32 | int(10) unsigned |
| unsigned long long int | uint64 | bigint(20) unsigned |
| float | float | float |
| double | double | double and decimal |
| std::string | std::string | any text type |
13 changes: 10 additions & 3 deletions docs/INSTALL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#Installing and updating
This page will help you get a cMaNGOS and a TrinityCore source with Eluna.
To get a MaNGOS source with Eluna head over to [their forum](http://getmangos.eu/) for the core installation and updating instructions.
This page will help you get a cMaNGOS and a TrinityCore source with Eluna.

If you are looking to get MaNGOS source with Eluna head over to [MaNGOS forum](http://getmangos.eu/) for the installation and updating instructions - however read this page also as it contains important information.

If you are having trouble with the installation or updating the core source, head over to our [support forum](../README.md#documentation).
If you are looking for a way to merge eluna with a fork of the official repositories see [merging](MERGING.md).
Expand All @@ -25,9 +26,15 @@ For example `git clone https://github.com/ElunaLuaEngine/ElunaTrinityWotlk.git`
* [TrinityCore](http://collab.kpsn.org/display/tc/Installation+Guide)
* [cMaNGOS](https://github.com/cmangos/issues/wiki/Installation-Instructions)

__Important!__ After compiling use the new configuration files. They contain Eluna settings and without them Eluna may not function correctly. For example you do not get any error messages or error log.

After installing Eluna you should check out these:
- [Eluna getting started](USAGE.md)
- [Eluna features](IMPL_DETAILS.md)

###Updating
Updating is essentially handled in the same manner as you would normally update the core and database.
To get the newest core sourcecode open `git bash` and navigate to your local source folder.
To get the newest core source code open `git bash` and navigate to your local source folder.
Then execute use `git pull` followed by `git submodule init` and `git submodule update`.
After updating the source you need to recompile the core normally. Simply use `CMake` if needed and compile.
To update the databases refer to the core's or database's official updating documents:
Expand Down
116 changes: 116 additions & 0 deletions docs/USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#Using Eluna
Eluna is a lua engine implementation for world of warcraft emulators.
It can be used to create different kind of scripts from AI to events.
This article helps you to get started with Eluna. We go through adding a simple script, where to get information from and a few language basics.

This article assumes you have already installed Eluna successfully. If you have not, see [installation](INSTALL.md).

##Basic script
Here is a simple "Hello world" example.
Create a file named `hello world.lua` that contains the following code and place the file inside the scripts folder in your server folder. By default the scripts folder is called `lua_scripts`. The server folder is the folder which contains server executables.
```lua
local PLAYER_EVENT_ON_LOGIN = 3

local function OnLogin(event, player)
player:SendBroadcastMessage("Hello world")
end

RegisterPlayerEvent(PLAYER_EVENT_ON_LOGIN, OnLogin)
```
If you now restart your server and log in game you are greeted with "Hello world" in your chat.

###What happened
As you have witnessed here no core compiling was needed and your script runs from the file you just created.

The file is compiled and run by the lua engine when the server starts up or Eluna is reloaded.
The code in the file registers a function to be run when a player logs in and the function sends a message to the player that logged in.

##Lua basics
It is good to get to know a bit of lua to code lua scripts. In this article we do not go that much into explaining lua syntax. Here are some pointers to important sources of information and things to get to know about.

###Sources of information
- lua users wiki
- http://lua-users.org/wiki/LuaDirectory
- http://lua-users.org/wiki/TutorialDirectory
- http://lua-users.org/wiki/SampleCode
- programming in lua http://www.lua.org/pil/1.html
- lua reference manual http://www.lua.org/manual/5.2/

###some highlights
- Print function outputs to server console. Very useful for simple debugging `print("anything here")`.
- control structures - especially loops:
- http://lua-users.org/wiki/ControlStructureTutorial
- http://www.lua.org/manual/5.2/manual.html#3.3.5
- lua string library:
- http://lua-users.org/wiki/StringLibraryTutorial
- http://www.wowwiki.com/Pattern_matching
- Lua tables are the only container in lua and they are essential for good code. Lua tables can be compared to arrays and hash maps.
Table functions and tutorials:
- http://www.lua.org/manual/5.2/manual.html#6.5
- http://www.lua.org/manual/5.2/manual.html#4.3
- http://lua-users.org/wiki/TablesTutorial
- http://www.lua.org/pil/2.5.html
- prefer local variables over global. While global variables may work they can create issues with other scripts that use same variable names.
All local variables outside of functions in a script are shared by everything running the same script - the variables are locally global.

##Eluna basics
It is good to know where you can find information about Eluna and Eluna's API as well as the basic elements of a script. Here are links to the main sources of information:

- Eluna features [Eluna details](IMPL_DETAILS.md)
- Eluna documentation http://eluna.emudevs.com/

###Error messages
If Eluna is installed correctly, the default installation should make errors output to the console as well as a log file in the server folder. If you can not get your script to work, be sure to check the log file for any errors you might have missed.

Check out the configuration file for settings if you want to tweak the logging settings.

###Global functions
Global functions are functions you can run from anywhere in a script file and they do not require any object to be run.
In addition to normal global functions lua provides like `print` Eluna has it's own gobal functions. You can find them in the documentation under `global` class: [global functions](http://eluna.emudevs.com/Global/index.html).

```lua
-- print the return value of GetLuaEngine function
print(GetLuaEngine())
```

###Member functions
Member functions, also called methods, are functions that require an userdata object to run. There are several different classes of objects that have different member functions. You can find all the member functions and their documentations from the [Eluna documentation](http://eluna.emudevs.com/).

Classes in C++ inherit each other. In Eluna member functions are also inherited. For example objects of classes `Player` and `Creature` inherit all methods from `Unit` class.

Methods are called by using `:` notation on the object. For example to get the player name you can call the GetName methods like this: `player:GetName()`

```lua
local entry = 6
local on_combat = 1
local function OnCombat(event, creature, target)
-- creature is of type Creature
-- target is of type Creature or Player depending on who the creature is attacking
print(creature:GetLevel())
print(target:GetLevel())
end

RegisterCreatureEvent(entry, on_combat, OnCombat)
```

###Registering functions to events
Scripts register functions to events and the functions are executed when the event happens.
There are special global functions in Eluna API for registering functions for events.
You should be able to find all such functions from [Eluna documentation](http://eluna.emudevs.com/) by searching `register`.

Functions used to register other functions for events need the ID of the event you want the hook to be registered for passed to them. You can find these ID numbers from the registering function documentation page.

Eluna passes some arguments to the functions executed. The arguments are always in same order. You can name them in any way you want. In the above script example the event `PLAYER_EVENT_ON_LOGIN` passes the event id and the player who logs in to the registered function. This is why the registered function has these parameters defined: `(event, player)`.

Some events allow the registered function to return different values. Sometimes you can return more than one value. The possibility to return is documented on the registering function's documentation page. Simply using the `return` keyword returns normally as if the function would end.

For example in this script we register the function `OnCombat` to be run on event `1`, which triggers on combat, for the creature entry `6`. All needed information can be found here: http://eluna.emudevs.com/Global/RegisterCreatureEvent.html
```lua
local entry = 6
local on_combat = 1
local function OnCombat(event, creature, target)
creature:SendUnitYell("Yiee, me run!", 0)
end

RegisterCreatureEvent(entry, on_combat, OnCombat)
```

0 comments on commit d57ca13

Please sign in to comment.