Scripting Extension: Difference between revisions

From OpenMW Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
(One intermediate revision by the same user not shown)
Line 3: Line 3:


== Current Status ==
== Current 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).
Python and Lua 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> or <pre>StartExternalScript, "scriptname.lua"</pre> This way you get access to all the locals and globals as if your script is a normal script. The Python/Lua script has to be in the same directory that other morrowind data/addons are in (one of the data directories).


== How to use ==
== How to use ==
=== Get the modified openmw binary ===
=== Get the modified openmw binary ===
==== Ubuntu PPA ====
Utopic PPA is available <pre>$ sudo apt-add-repository ppa:showard314/openmw-scripting
$ sudo apt-get update
$ sudo apt-get install openmw</pre>
It will install the highest version of openmw in all the repositories you have enabled, so if you have the openmw PPA, the daily PPA, and this PPA turned on, it may download versions from unwanted PPAs as each gets updated. Therefore, to be safe, only enable one PPA in the Software Center Sources at a time. This version also comes with "testing.py" as seen in the Example below.
==== github ====
==== github ====
<pre>$ sudo apt-get install python3-dev swig
<pre>$ sudo apt-get install python3-dev swig liblua5.1-0-dev
$ git clone https://github.com/maqifrnswa/openmw/tree/python-scripting  
$ git clone https://github.com/maqifrnswa/openmw/tree/python-scripting  
$ cd openmw/
$ cd openmw/
Line 16: Line 23:
$ ./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, "testing.py"</pre>, or write a script/addon that calls StartExternalScript.
then in game, hit "~" to get the console, and run your script with the new command <pre>StartExternalScript, "testing.py"</pre> or <pre>StartExternalScript, "testing.lua"</pre> or write a script/addon that calls StartExternalScript.


==== Ubuntu PPA ====
coming soon


=== Writing Python Script ===
=== Writing Python Script ===
Line 25: Line 30:
==== Example ====
==== Example ====
Example script, make sure you have a "run()" method, that is what will be called by openmw:
Example script, make sure you have a "run()" method, that is what will be called by openmw:
<pre>#SomethingScript in morrowind_testing.omwaddon has a short variable named hello you can use
<pre>#example file "testing.py"
#SomethingScript is a script in a .omwaddon files that you create that has a short variable named hello you can use for testing
# it's just a demonsrtation of setting a local variable, you can comment it out if it causes problems.
from openmw import *
from openmw import *


Line 64: Line 71:
===== Non-extension functions/instructions =====
===== Non-extension functions/instructions =====
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.
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.
=== Writing Python Script ===
OpenMW will import your lua script as a module and run the "run()" method when you use the morrowind command "StartExternalScript"
==== Example ====
Example script, make sure you have a "run()" method, that is what will be called by openmw:
<pre>#example file "testing.lua"
#SomethingScript is a script in a .omwaddon files that you create that has a short variable named hello you can use for testing
# it's just a demonsrtation of setting a local variable, you can comment it out if it causes problems.
local testing = {}
function testing.run()
    print("health: "..omw.gethealth("player"))
    print("hello i'm a criminal")
    omw.setpccrimelevel(100000000)
    print("flying: "..omw.getflying("player"))
    omw.setflying("player",1)
    print("flying: "..omw.getflying("player"))
    print("random100: "..omw.omwget("random100"))
    omw.omwset("random100",42)
    print("random100: "..omw.omwget("random100"))
    print("SomethingScript.hello: "..omw.omwget("SomethingScript.hello"))
    omw.omwset("SomethingScript.hello",42.0)
    print("SomethingScript.hello: "..omw.omwget("SomethingScript.hello"))
    omw.omwcall("MessageBox, \"This is a simple message\"")
end
return testing
</pre>
==== How to Write Python Scripts ====
All commands are in the "omw" namespace, 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:
<pre>player->AddItem, "Gold_001", 200 </pre> is now <pre>omw.additem("player","Gold_001",200)</pre>
Example 2:
<pre>AIWander, 0, 0, 0 </pre> is now <pre>omw.aiwander("self",0,0,0)</pre>
Example 3:
<pre>"urzul gra-agum"->AIWander, 128, 0, 0, 60, 30, 10, 0, 0, 0, 0, 0, 0</pre> is now <pre>omw.aiwander("urzul gra-agum", 128, 0, 0, 60, 30, 10, 0, 0, 0, 0, 0, 0)</pre>
===== Getting and setting variables =====
<pre>omw.omwset("localvariablename", value)
omw.omwset("globalvariablename", value)
omw.omwset("objectID.variablename", value)
omw.owmset("globalID.variablename", value)
omw.omwget("localvariablename")
etc.</pre>
===== Non-extension functions/instructions =====
All extensions are directly available for use, but interpreter commands (like message box) can be accessed with "omw.omwcall()"<pre>omw.omwcall("MessageBox, \"This is a simple message\"")</pre> the argument to omwcall will be parsed as if it was a normal Morrowind script.


=== Debugging output ===
=== Debugging output ===
Line 72: Line 128:


== To do ==
== To do ==
sandboxed and secure lua scripting, coming very soon!
sandboxing Lua, options to enable/disable compile and runtime availabillity of scripts, code clean up, script signing/trust

Revision as of 17:12, 10 February 2015

Overview

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

Current Status

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

StartExternalScript, "scriptname.py"

or

StartExternalScript, "scriptname.lua"

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

How to use

Get the modified openmw binary

Ubuntu PPA

Utopic PPA is available

$ sudo apt-add-repository ppa:showard314/openmw-scripting
$ sudo apt-get update
$ sudo apt-get install openmw

It will install the highest version of openmw in all the repositories you have enabled, so if you have the openmw PPA, the daily PPA, and this PPA turned on, it may download versions from unwanted PPAs as each gets updated. Therefore, to be safe, only enable one PPA in the Software Center Sources at a time. This version also comes with "testing.py" as seen in the Example below.

github

$ sudo apt-get install python3-dev swig liblua5.1-0-dev
$ 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

StartExternalScript, "testing.lua"

or write a script/addon that calls StartExternalScript.


Writing Python Script

OpenMW will import your python script as a module and run the "run()" method when you use the morrowind command "StartExternalScript"

Example

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

#example file "testing.py"
#SomethingScript is a script in a .omwaddon files that you create that has a short variable named hello you can use for testing
# it's just a demonsrtation of setting a local variable, you can comment it out if it causes problems.
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 Python 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/instructions

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.

Writing Python Script

OpenMW will import your lua script as a module and run the "run()" method when you use the morrowind command "StartExternalScript"

Example

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

#example file "testing.lua"
#SomethingScript is a script in a .omwaddon files that you create that has a short variable named hello you can use for testing
# it's just a demonsrtation of setting a local variable, you can comment it out if it causes problems.

local testing = {}

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

return testing

How to Write Python Scripts

All commands are in the "omw" namespace, 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

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

Example 2:

AIWander, 0, 0, 0 

is now

omw.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

omw.aiwander("urzul gra-agum", 128, 0, 0, 60, 30, 10, 0, 0, 0, 0, 0, 0)
Getting and setting variables
omw.omwset("localvariablename", value)
omw.omwset("globalvariablename", value)
omw.omwset("objectID.variablename", value)
omw.owmset("globalID.variablename", value)

omw.omwget("localvariablename")
etc.
Non-extension functions/instructions

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

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

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

Debugging output

There's still a bunch of debugging output that will show up in the terminal, bear with it for the moment. Normal python debugging output will go to the terminal.

Security

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

sandboxing Lua, options to enable/disable compile and runtime availabillity of scripts, code clean up, script signing/trust