• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Fix/Patch Shared Lua States

Eventide

Member
Joined
Sep 16, 2008
Messages
79
Reaction score
6
Location
Brasil
i didn't tested yet, when i test i'll post the result here, and if you find any kind of error, post it. =)~

luascript.cpp
Code:
bool LuaScriptInterface::initSharedState()
{
    lua_State* shared_lua_state = getSharerState();

    if(!shared_lua_state)
        return false;

    lua_newtable(shared_lua_state);
	lua_setfield(shared_lua_state, LUA_REGISTRYINDEX, "EVENTS");

	m_runningEventId = EVENT_ID_USER;

    newSharerState(shared_lua_state);
    registerFunctions();
    return true;
}

void LuaScriptInterface::newSharerState(lua_State* L)
{
    m_luaState = L;
}

lua_State* LuaScriptInterface::getSharerState()
{
    static lua_State* sharer;
    if(!sharer)
    {
        sharer = luaL_newstate();
#ifndef __USE_LUALIBRARIES__
        //Here you load only the "safe" libraries
        luaopen_base(sharer);
        luaopen_table(sharer);
        luaopen_os(sharer);
        luaopen_string(sharer);
        luaopen_math(sharer);
        // Unsafe, but immensely useful
        luaopen_debug(sharer);
#else
        //And here you load both "safe" and "unsafe" libraries
        luaL_openlibs(sharer);
#endif
        std::string datadir = g_config.getString(ConfigManager::DATA_DIRECTORY);

        if(loadFile(std::string(datadir + "global.lua")) == -1)
        {
            std::cout << "Warning: [LuaScriptInterface::initSharedState] Can not load " << datadir << "global.lua." << std::endl;
        }
    }
    return sharer;
}

luascript.h on public slot
Code:
	bool initSharedState();

luascript.h on private or protected slot:
Code:
	void newSharerState(lua_State* L);
	static lua_State* getSharerState();

on the Events you want to share, go to the cpp code and find the constructor, then re-write this:
Code:
	m_scriptInterface.initState();

to this:

Code:
#ifndef __SHARED_LUASTATES__
	m_scriptInterface.initState();
#else
    m_scriptInterface.initSharedState();
#endif

to use a shared state, define __SHARED_LUASTATES__ on luascript.h(will compile faster) or on definitions.h
 
Its a simple code to make one Lua state to be shared between all scripting interfaces.
Basicaly it could be done much easier, by adding one static state and removing initState from interfaces calling it, but its more files to edit.

Bah, current otserv/TFS Lua support is an epic fail.
 
@mindrage
2 or more scripts kind can have a bridge state to share functions, vars, arrays, metatables etc

@elf
with this code you can choose what to share and what to don't share, it's the difference.
 
Yeah... 13 years later.
Anyway, this thing would be really helpful (today it has affected me 2nd time in 2 unrelated situations, because while I have 2 ways of writing some script without shared lua states I am forced to choose what I believe - the worse one in both cases that occured to me).

So, has anyone on otland used it or something similar and came across any problems? (I mean whatever... e.g. crashes at any point or other issues)
 
Yeah... 13 years later.
Anyway, this thing would be really helpful (today it has affected me 2nd time in 2 unrelated situations, because while I have 2 ways of writing some script without shared lua states I am forced to choose what I believe - the worse one in both cases that occured to me).

So, has anyone on otland used it or something similar and came across any problems? (I mean whatever... e.g. crashes at any point or other issues)
TFS has shared lua state since 1.x (even 0.4 had it, as far as I can recall) you are either running some really old ass sources or whatever you are trying to do is not the intended way on how to do it.
Feel free to show a use case of what you're trying to do and I'm pretty sure we can solve that problem pretty quick
 
TFS has shared lua state since 1.x (even 0.4 had it, as far as I can recall) you are either running some really old ass sources or whatever you are trying to do is not the intended way on how to do it.
Feel free to show a use case of what you're trying to do and I'm pretty sure we can solve that problem pretty quick
I'm using 0.4. I've tested that global variables from 000-const.lua if changed in e.g. creaturescript will still be unchanged in e.g. talkaction.
Lets say I have a set of 1-10 missions. If a player had 4th one and wanted to check with talkaction what other players online have this 4th mission as well I guess the way would be to loop through getPlayersOnline() and if(storageValue). The way I wanted to do that was to cache it at onLogin so I wouldnt have to loop through online players (the more players the higher cost of such operation).

The second case was when I wanted a spell to know accumulated dmg to the caster (creaturescript and spells would have to be "connected"). Well, I had to do all in creaturescript which I think as worse way too (limiting me).

As you can see, I know solutions, but I also believe that I would implement better ones with shared lua.
 
So, has anyone on otland used it or something similar and came across any problems?
0. On 1.x you cannot write scripts 'without shared Lua states'. All Lua states are shared. If you got 'old 0.x scripts', rewrite them. Often using local on some events make them 'safe'. Anyway, you need to understand context and 'scope' of script.
1. You cannot use /reload on server that keeps any state in Lua on 1.x. It's fine for test-server, but if it crashes, just restart server and make sure it does not crash 'without reload'. Never use /reload on server with real players - it's command just for fast debug of Lua scripts, not real 'reload' of Lua state/scripts.
2. You have to not use scripts that violate basic shared-state and 'delayed execution' principles: [TFS 1.x+] How to NOT write LUA scripts or how to crash server by LUA script – HALP! (https://halp.skalski.pro/2020/06/05/tfs-1-x-how-to-not-write-lua-scripts-or-how-to-crash-server-by-lua-script/)

Yes. It limits some weird scripts (you need to rewrite them), but it optimizes common OTS (real tibia) scenarios. That's why TFS 1.x focused on these changes, not 'do anything you want without crash' 0.X style - these scripts also failed making some players stay in invalid location, it just did not crash whole engine.

In case on really custom OTSes (ex. dragon ball/pokemon). I would say it's easier to program things on 1.x. You just need to spend few hours to understand new logic. New 'object-oriented logic with shared scope' is not against old scripts/logic, it will just make crash much faster, if your Lua script breaks OTS (C++) logic.

I'm using 0.4
Shared Lua states are C++ thing, not "Lua" thing. No matter what you do in .lua (const.lua, whatever) on 0.4 it will still create new Lua instance for each OTS system (actions, creaturescripts, npcs, movements..).
Only way to do 'shared states' on 0.x is to use 'global storages', which are kept in C++ and shared among Lua 'states' and even Lua `/reload`s - which make them better than 1.x scripts.
 
Back
Top