Scripting::Lua

Experiment started.

Some details on my wiki page.

Bah, experiments started here

Before taking any other steps, condier the following:

  • Python language, which I strongly recommend
  • Game safety (Tow is obsessed about it). Who and under what conditions can execute script? How to ensure both players use legal scripts?
  • Network interaction. How to connect GUI interaction with client and game state change on server.
  • The actual way to embed scripts in objects (such as visiting adventure map object triggers script)

These topics were already discussed many times, but we didn’t reach conclusions - it’s mostly to early, not all the prerequsites are done.

It was too long time ago :slight_smile:

Im not strongly opposing python, but I wont implement it support myself.

In cheat proof mode scripts shall be on server side - this has been discussed. It can be done easily, implementation is indifferent of where it run on client or on server.

game state changes with net packs only. So synchronization is guarantied by engine.

Create packet -> set it up -> request callback to apply (here packet is sent to server if script runs on client side) -> packet applied in usual way

No embedding, only triggers.

  • smth like
objects.objectName.onVisit = ...

Just don’t put it in trunk… a few thoughts from recent discussions with Tow:

  1. Cheat-proof mode is essential. Responsiveness is important too. So:
  • no full gamestate on client
  • no mechanics-changing scripts on client (they are executed on server)
  • GUI events are not sent to server (but client-side script can catch them and communicate with server-side script)
  • as a result, ERM scripts will not be directly supported; possibility of automatic translation to new style could be investigated but most of ERM could be relatively easily rewritten anyway
  1. Scripting language
  • Python > Lua
  • SWIG could be a good idea

Anyway I think it’s still to early to write any code.

of course I`ll not commit such huge changes w|o approval.

completely agreed. Actually I`m developing exactly server-side scripting despite the fact that it runs on client side currently.

I think that it`s too difficult to design such large susbsystem w|o writing some code.

I do also think it is to early to start serious implementation of scripts support. (Well, I did it twice :P) I do also think that Python seems nicer than Lua. (though I don’t have significant experience with neither)
There are however some general things that can be useful for any scripting module.

Some things to consider:
Tear off the implementation of IGameEventCallback from CGameHandler to separate class. Have typical “event”<=>“netpack” translations in one class and move it to lib. Then scripting module won’t end reimplementing all these things all over again. CGameHandler implementation ends up calling sendAndApply usually — it is a virtual function that can either do its usual thing (on server, CGameHandler) or something else (eg. collect packages to send and output them via IGameEventRealizer::commitPackage when used by scripting module).

I’m not sure how sensible and feasible are these ideas but that’s what I’d start with if I were to implement server side scripts on client.

How does it relate to CScriptingModule? It should be exactly what you are looking for. At least as you describe it.
(server-side scripts running on client for testing convenience :stuck_out_tongue: )

There’s also an ERM module. It does not go much beyound “hello world” (and Boost.Spirit proved to be… not so nice to deal with, or expecially to compile) but it should be working proof of concept. And good base for work on alternative module.

How about keeping it versioned in a branch? I don’t want this in trunk but I like to know what I’m talking about. :wink:

Actually the scripting language I’m most familiar with is bash, despite the fact I mostly use Windows. SWIG supports both Lua and Python so we wouldn’t have to choose.

Boost.spirit is a great example of what’s wrong with templates in C++. They are not type-safe and even the best code looks obfuscated. Boost.spirit should never be used again.

Yes, I`ve started from ERM as example. CScriptingModule descendant + wrappers for NetPacks, use only commitPackage to do any changes in gamestate.

When I implement smth useful I`ll push it to github clone.

About SWIG I havent used it yet. But Im afraid much refactoring is needed before auto-wrapping can be done to not to export too much (private data f.e.). I`m using SLB (simple template based wrapper) for now.

I just hate Bash. For some reason I’m totally unable to accomplish anything with it unless wasting incredible amount of time. I learned it a few times to no avail. I have no idea why it so difficult for me.

As for SWIG… Someone should just check if it can actually work properly with our codebase. If we were able to automatically generate glue code, that’s great.
For Python there’s also Boost.Python as an alternative solution for interfacing. For Lua there was similar library but it was hardly usable. (or I was to green in 2007 to use it properly)

How are they not type-safe?

I disagree. There were two issues with ERM interpreter:

  • constant need of conversion between types that parser outputs (variants and so on) and types we want to use. This could’ve been neatly solved if not that stupid bug in Boost.Variant. Though… I still have a feeling that we missed some piece of Boost.Spirit that allows to easily output something more sensible. Anyway it is library issue, not C++ templates.
  • visitor pattern is ugly. Ugly, ugly, ugly. The try-cast style alternative is even worse though. C++ needs either:
    a) local classes that can capture scope (lambda classes?). The one useful thing in Java.
    b) type-switch. It seems there’s library for this parasol.tamu.edu/~yuriys/pm/

I still have a feeling that if I had enough time, I could refactor ERM module into really nice code.

My issues with templates are:

  • they are not part of type system. They generate types… but are not exactly types themselves.
  • syntactic issues with <>: ambiguity with comparison / bit shift operators, need of “template” and “typename” in various places, etc.
  • need of putting them into headers. Though it’s more that C++ lacks modules issue.
  • compile time and compiler memory usage (possibly connected to the previous one)
  • lack of static control structures (static if and possibly some more complex one). Template metaprogramming is truly nightmare’ish because of that.

They little more than macros. All typechecking happens after macros are instantiated. A lot of use cases of macros is parametric polymorphism which, in bounded or type-classed variation where well-typedness of ,instantiantion’’ follows from well-typedness of definition. That’s type safety.

You didn’t write the parser and therefore probably forgotten about totally incomprehensible error messages requiring voodoo programming-like changes. I looked into interiors of boost.spirit then and what I saw scared me.

That’s parially what I meant when I wrote about their type-safety.