6

Folks, is there a way to clone a Lua state?

In my game application the initialization procedure of the Lua virtual machine is pretty heavy(about 1 sec, since many scripts are loaded at once). I have a separate Lua VM for each autonomous agent and once the agent is created its Lua initialization affects FPS pretty badly.

I'm thinking about the following schema: what about keeping "preforked" Lua state which is then simply cloned for each agent? Is it possible?

RBerteig
  • 41,948
  • 7
  • 88
  • 128
pachanga
  • 3,003
  • 4
  • 30
  • 45
  • 2
    Many people write Lua wrong, it's not an acronym. Would you kindly modify the above so that it follows the standard naming. We don't write PYTHON either. Lua just happens to be a three-letter name. See: http://www.lua.org/about.html – akauppi Sep 06 '09 at 08:18
  • 3
    Oh, sorry for that. Thanks for head's up. – pachanga Sep 07 '09 at 05:52
  • did you ever find a way to do this? – DShook Jan 10 '10 at 18:31

4 Answers4

4

You want to consider using Lua's coroutines for each autonomous agent, instead of a completely separate VM. Coroutines are a more lightweight solution, but may or may not be suitable for your application.

If you can't change the architecture, you might try LuaJIT. It might make the initialization fast enough for your purposes.

More options:

  1. Rings: "Rings is a library which provides a way to create new Lua states from within Lua. It also offers a simple way to communicate between the creator (master) and the created (slave) states."

  2. Pluto: "Pluto is a library which allows users to write arbitrarily large portions of the "Lua universe" into a flat file, and later read them back into the same or a different Lua universe."

ijprest
  • 4,208
  • 1
  • 19
  • 12
  • I was thinking about using coroutines however I'm afraid a fatal error in one coroutine will affect others that's why it's not option atm. Thanks for the links! I'm currently looking at LuaJIT and Rings. Rings seems to be a possible solution for my problem. – pachanga Sep 05 '09 at 18:05
  • 3
    Fatal error in one coroutine would not affect others in any way. As long as we're talking about Lua code -- user supplied stuff may do any damage it is programmed for of course. – Alexander Gladysh Sep 06 '09 at 09:14
  • I actually need to clone an state. It is for a POS framework that I am doing, and I dont want that the guy writing the script to be able to steal credit card passwords. The EMV library allows that the user customize the screens via callbacks, and each callback triggers a lua coroutine that loads the screens. But coroutines share variables, and I want all modifications to the variable environment during the password call rolled back... Should I create a new question for this? – Luiz Menezes Jan 09 '17 at 17:43
1

There's also Lanes (download, docs) and within the comparison to all similar products I know.

About Rings the comparison sheet says:

Rings offers separate Lua states, but no multithreading. This makes it simple, but it won't use more than one CPU core.

Note: The comparison sheet says Lanes would only marshal 'non-cyclic tables'. It does do cycles, and does marshall functions, upvalues etc. And it does the copies between Lua states as direct copies, not needing to stringify the contents in the middle. This makes it fast.

akauppi
  • 17,018
  • 15
  • 95
  • 120
1

If you're on Linux, you may try lper, LPSM-based experimental library by one of Lua authors.

Alexander Gladysh
  • 39,865
  • 32
  • 103
  • 160
1

Notice, works with Lua 5.2 and above

You can just restrict access to this VM. Create one instance with all functions required, that will not depend on _G (global Lua state) and then create separate table for each client. That they will use as their global namespace. Setting a table as current _G is possible via _ENV. That's quite difficult topic to explain in one post. In short you prepare "virtual" _G for your new client and then just replace _G for the client's code. There is where I advice you to start.

Here's the point.

local _ENV = t -- change the environment. without the local, this would change the environment for the entire chunk

Just remove local and you'll change _ENV for all further code. Good luck with experiments!

P. S. don't forget that you may set metatable for _ENV and _G tables and forbid changing that metatable. Lua is really flexible here.