How GPython works¶
Let’s suppose we have a simpliest “Hello World” GPython addon:
addons\ ─┬─ example\ ─┬─ addon.json
... ├─ python\ ─── __autorun__\ ─── __init__.py
__init__.py:
from gmod import *
# Greeting the first player
print('Hello, ' + Player(1).nick + '!')
1. Lua Launcher¶
GPython’s Lua launcher is a regular Lua addon.
When it’s loaded by Garry’s Mod’s addon system, the launcher activates
gmcl_gpython_win32.dll and gmsv_gpython_win32.dll:
require 'gpython'
gmcl_gpython_win32.dll is for the client and gmsv_gpython_win32.dll is for the server.
2. Realms’ DLLs¶
These two DLLs call gpython_run() in gpython.dll.
3. Main GPython DLL: gpython.dll¶
gpython_run() does these preparation operations:
Server¶
- Adds
luastackmodule to the builtin initialization table. - Initializes Python interpreter.
- Appends
garrysmod\gpython\tosys.path. - Calls
setup()inluastackthus setting the global lua stack pointer and settingluastack.IN_GMODtoTrue. - Redirects I/O to Garry’s Mod console with
gmod.streams. - Adds Lua2Python interoperability functions (using Python from Lua).
- Scans
addons\directory for GPython addons and runs their code.
Client¶
Client’s routine is the same as server’s except the step 2.
Instead of initializing Python again, a subinterpreter is created and swapped to.
4. GPython wrappers¶
Player is just a wrapper over the corresponding Lua functions,
as much as many other GPython services.
In this example, Player(1) creates an object that wraps Player Lua class. nick is a property that
gets players’ nicknames using Player:Nick() function.
This property looks like this:
@property
def nick(self):
return str(self._player_luaobj['Nick']())
The Player internally uses gmod.lua.LuaObject to work with players.
5. gmod.lua module¶
gmod.lua module is itself a wrapper over luastack module. gmod.lua simplifies the interoperability
with Lua by providing LuaObject class and G singleton.
LuaObject internally uses the luastack module.
6. luastack module¶
luastack module manipulates the Lua stack. Lua stack pointer is previously set by the C++ module.
And that’s it, our GPython addon is initialized. For me, Hello, Protocs! will be printed to console.