Scripting Extension: Difference between revisions

From OpenMW Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
These are notes and current status of extending openmw scripting through SWIG.
These are notes and current status of extending openmw scripting through SWIG.


STATUS: All extensions can be called from python scripts (both instructions and functions). Python scripts can be run in the console or attached to objections. Local/global variables do not work yet.
STATUS: Python scripting is fully functional. You can call from the console, or can attach to objects/global scripts with the command <pre>StartExternalScript, "scriptname.py"</pre>. This way you get access to all the locals and globals as if your python script is a normal script. The Python script has to be in the same directory that other morrowind data/addons are in (one of the data directories).


These are notes on the scripting extension work, see:
How to use (development release):
First described for python (SWIG):
 
https://forum.openmw.org/viewtopic.php?f=6&t=617&start=60#p29966
 
LUA implementation:
 
https://forum.openmw.org/viewtopic.php?f=6&t=617&start=70#p30090
 
https://forum.openmw.org/viewtopic.php?f=6&t=617&start=70#p30093
 
How to use:
<pre>$ sudo apt-get install python3-dev swig
<pre>$ sudo apt-get install python3-dev swig
$ git clone https://github.com/maqifrnswa/openmw/tree/python-scripting  
$ git clone https://github.com/maqifrnswa/openmw/tree/python-scripting  
Line 21: Line 10:
$ make -j
$ make -j
$ [make your python script, see example below]
$ [make your python script, see example below]
$ PYTHONPATH=. ./openmw --start="Seyda Neen" --skip-menu
$ ./openmw --start="Seyda Neen" --skip-menu
</pre>
</pre>
then in game, hit "~" to get the console, and run your script with the new command <pre>StartExternalScript, "test.py"</pre>
then in game, hit "~" to get the console, and run your script with the new command <pre>StartExternalScript, "testing.py"</pre>, or write a script/addon that calls StartExternalScript.
 
Example script (no need to import openmw, it will do it automatically):
<pre>
print("health: " + str((gethealth("player"))))


print("hello i'm a criminal")
Example script, make sure you have a "run()" method, that is what will be called by openmw:
setpccrimelevel(100000000)
<pre>#SomethingScript in morrowind_testing.omwaddon has a short variable named hello you can use
from openmw import *


print("flying: " + str(getflying("player")))
def run():
setflying("player",1)
    print("health: " + str((gethealth("player"))))
print("flying: " + str(getflying("player")))
    print("hello i'm a criminal")
    setpccrimelevel(100000000)
    print("flying: " + str(getflying("player")))
    setflying("player",1)
    print("flying: " + str(getflying("player")))
    print("random100: " + str(omwget("random100")))
    omwset("random100",42)
    print("random100: " + str(omwget("random100")))
    print("SomethingScript.hello: " + str(omwget("SomethingScript.hello")))
    omwset("SomethingScript.hello",42.0)
    print("SomethingScript.hello: " + str(omwget("SomethingScript.hello")))
    omwcall("MessageBox, \"This is a simple message\"")
</pre>
</pre>


Line 45: Line 42:
<pre>"urzul gra-agum"->AIWander, 128, 0, 0, 60, 30, 10, 0, 0, 0, 0, 0, 0</pre> is now <pre>aiwander("urzul gra-agum", 128, 0, 0, 60, 30, 10, 0, 0, 0, 0, 0, 0)</pre>
<pre>"urzul gra-agum"->AIWander, 128, 0, 0, 60, 30, 10, 0, 0, 0, 0, 0, 0</pre> is now <pre>aiwander("urzul gra-agum", 128, 0, 0, 60, 30, 10, 0, 0, 0, 0, 0, 0)</pre>


Also, use
Getting and setting variables:
<pre>omwset("localvariablename", value)
<pre>omwset("localvariablename", value)
omwset("globalvariablename", value)
omwset("globalvariablename", value)
Line 54: Line 51:
etc.</pre>
etc.</pre>
instead of set and get to avoid name collisions with functions in python.
instead of set and get to avoid name collisions with functions in python.
Non-extension functions:
All extensions are directly available for use, but interpreter commands (like message box) can be accessed with "omwcall()"<pre>omwcall("MessageBox, \"This is a simple message\"")</pre> the argument to omwcall will be parsed as if it was a normal Morrowind script.


there's still a bunch of debugging output that will show up in the terminal, bear with it for the moment.
there's still a bunch of debugging output that will show up in the terminal, bear with it for the moment.


Overview:
Overview:
* I think a post-1.0 goal, of mine at least, will still be to see if I can get an easy generic scripting interface.
* It will be a seperate fork from openmw, as I think a unified scripting language and zini's enhancements to the existing implementation would be best for the community. It's generally better to improve one implementation rather than create several new ones. If, in the future, such extension of scripting is found desireable, then there is no problem incorporating it into openmw.
* There are some things that python/other languages can do better and can be implemented faster than writing a new scripting engine from scratch. For example, you can use all of python's existing modules and capabillities that could enable things like dynamic web content/interaction in games. Some people are already used to lua and python scripting, they could potentially write more complicated scripts or more easily integrate scripts. For discussion on python versus lua, I found this very helpful:http://lua-users.org/wiki/LuaVersusPython -- I think both could be usefull in different cases.
* Existing scripting IDEs can be used, most scripting language already has built-in verbose debugging. It's possible to generate embedded consoles for testing scripts on the fly. Scripts can be edited and recompiled on the fly, in game.
* Security will be an issue (running untrusted scripts), but it something people already deal with in the modding community (e.g, [http://wiki.blender.org/index.php/Doc:2.6/Manual/Extensions/Python/Security Blender Python Scripting)Security]. Concerns can be addressed at a minimum by making users opt in to using python, and can be extended to only allow running scripts signed by a trusted certificate/key.
* Security will be an issue (running untrusted scripts), but it something people already deal with in the modding community (e.g, [http://wiki.blender.org/index.php/Doc:2.6/Manual/Extensions/Python/Security Blender Python Scripting)Security]. Concerns can be addressed at a minimum by making users opt in to using python, and can be extended to only allow running scripts signed by a trusted certificate/key.


Implementation:
To do:
https://github.com/maqifrnswa/openmw/tree/python-scripting
* sandboxed and secure lua scripting, coming very soon!
* a new executable, extensionstool, generates bindings. A header and cpp file are generated containing that creates compiled code for every extension based on the arguments passed to the function, then sends the compiled code to an interpreter. The interpreter is declared by the console or by the new opcode, the bindings just have a pointer to the interpreter that is owned by whomever created it.
* SWIG compiles the bindings and creates a module _openmw.so and python module openmw.py.
* Right now, the console intercepts all *.py files so the console command "filename.py" will run the python script filename.py
* All commands are lowercase and take the same arguments as before. Commands that can take a reference (commands with ->) now have a first argument which is the reference. For example:
<pre> player->AddItem, "Gold_001", 200 </pre> is now <pre> additem("player","Gold_001",200)</pre>

Revision as of 23:59, 8 February 2015

These are notes and current status of extending openmw scripting through SWIG.

STATUS: Python scripting is fully functional. You can call from the console, or can attach to objects/global scripts with the command

StartExternalScript, "scriptname.py"

. This way you get access to all the locals and globals as if your python script is a normal script. The Python script has to be in the same directory that other morrowind data/addons are in (one of the data directories).

How to use (development release):

$ sudo apt-get install python3-dev swig
$ git clone https://github.com/maqifrnswa/openmw/tree/python-scripting 
$ cd openmw/
$ mkdir build && cd build
$ make -j
$ [make your python script, see example below]
$ ./openmw --start="Seyda Neen" --skip-menu

then in game, hit "~" to get the console, and run your script with the new command

StartExternalScript, "testing.py"

, or write a script/addon that calls StartExternalScript.

Example script, make sure you have a "run()" method, that is what will be called by openmw:

#SomethingScript in morrowind_testing.omwaddon has a short variable named hello you can use
from openmw import *

def run():
    print("health: " + str((gethealth("player"))))
    print("hello i'm a criminal")
    setpccrimelevel(100000000)
    print("flying: " + str(getflying("player")))
    setflying("player",1)
    print("flying: " + str(getflying("player")))
    print("random100: " + str(omwget("random100")))
    omwset("random100",42)
    print("random100: " + str(omwget("random100")))
    print("SomethingScript.hello: " + str(omwget("SomethingScript.hello")))
    omwset("SomethingScript.hello",42.0)
    print("SomethingScript.hello: " + str(omwget("SomethingScript.hello")))
    omwcall("MessageBox, \"This is a simple message\"")

how to write scripts: All commands are lowercase and take the same arguments as before, even optional ones. Commands that can take a reference (commands with ->) now have a first argument which is the reference. That first argument is required. If it is an implicit reference, use "self". Example 1:

player->AddItem, "Gold_001", 200 

is now

additem("player","Gold_001",200)

Example 2:

AIWander, 0, 0, 0 

is now

aiwander("self",0,0,0)

Example 3:

"urzul gra-agum"->AIWander, 128, 0, 0, 60, 30, 10, 0, 0, 0, 0, 0, 0

is now

aiwander("urzul gra-agum", 128, 0, 0, 60, 30, 10, 0, 0, 0, 0, 0, 0)

Getting and setting variables:

omwset("localvariablename", value)
omwset("globalvariablename", value)
omwset("objectID.variablename", value)
owmset("globalID.variablename", value)

omwget("localvariablename")
etc.

instead of set and get to avoid name collisions with functions in python.

Non-extension functions:

All extensions are directly available for use, but interpreter commands (like message box) can be accessed with "omwcall()"

omwcall("MessageBox, \"This is a simple message\"")

the argument to omwcall will be parsed as if it was a normal Morrowind script.


there's still a bunch of debugging output that will show up in the terminal, bear with it for the moment.

Overview:

  • Security will be an issue (running untrusted scripts), but it something people already deal with in the modding community (e.g, Blender Python Scripting)Security. Concerns can be addressed at a minimum by making users opt in to using python, and can be extended to only allow running scripts signed by a trusted certificate/key.

To do:

  • sandboxed and secure lua scripting, coming very soon!