PyLua - Python Interpreter in Luau

PyLua - Running Python Code Inside Roblox

So I’ve been working on this silly little project called PyLua and thought I’d share it with you all. It’s basically a Python interpreter that runs entirely inside Roblox using Luau. You can check the Github here

Important note: This isn’t a Python-to-Luau compiler or anything fancy like that - it actually parses and executes Python code in real-time while your game is running

What it does

You can literally write Python code as a string and execute it inside your Roblox scripts:

local PyLua = require("PyLua Module")

-- Create a Python runtime
local python = PyLua.new()

-- Execute multi-line Python code (statements)
python:execute([[ 
x = 10
y = 32
print("sum:", x + y)
]])

-- Evaluate a Python expression and get the result in Luau
local value = python:eval("1 + 2 * 3")
print("eval result:", value) -- 7

-- Share values via the globals table
python:execute("z = 5")
local globals = python:globals()
print("z from python globals:", globals.z) -- 5

Why did I make this?

Honestly? Just for the fun of it! I wanted to see if I could build a working interpreter in Luau, and it turned out to be a pretty awesome learning experience. Its easy to add new features, so I might keep expanding it whenever I’m bored.

Now go and check the Github maybe even download it? You chose, bye :3

55 Likes

Would be cool to be used as a programming language for modding inside the expirience maybe.

5 Likes

could be cool yeah, like other programs use lua for plugins. I just need to make it good enough for it to be considered good to use :slight_smile:

I’ve always wanted to make an OS with programmable apps. This’ll defo help me to understand how to make a custom programming language and run it in roblox. Awesome work :slight_smile:

1 Like

Thanks! Feel free to use some of the code, its under the MIT license so go for it.

1 Like

You could gain a lot of performance here by targetting .pyc and running off that. Theres some interesting stuff out there with bytecode virtual machines, especially pyc. If you ever want to dip your hands into full on compilation, give it a try. CPython Internals is a good starting point imo.

You’d also allow scripts compiled from the outside world to run in your interpreter (not including library support) if your virtual machine correctly maps to each operation in the bytecode format.

Other than that, cool library.

This is actually very interesting, I’ll take a look at pyc and decided if its worth the try, thanks!

Okay so, I actually looked into the idea of running raw .pyc files directly and dove deep into CPython’s internals. While it’s a cool concept, I decided not to fully replicate Python’s bytecode for a few key reasons:

  • Most games do not want to support dynamic code loading (like loadstring) and roblox luau does not support file access, and its memory model is tightly controlled.
  • Python bytecode (.pyc) is deeply tied to CPython’s internals (like its C-based memory management and stack frames), which don’t map cleanly to Luau’s VM.
  • Supporting full .pyc would introduce a ton of complexity for limited benefit — especially since the target environment is so different.

Instead, I’m taking inspiration from the concept and designing a simplified bytecode format for which allows:

  • Faster loading (compiled once, run multiple times),
  • Better performance than interpreting raw strings every time,
  • Safer and more controlled execution for in-game scripts and mods.

This also opens up AOT workflows (compile on PC, run on Roblox) while still supporting direct string-based execution for development.

In short: I’m taking .pyc, but optimizing it for Roblox and Luau’s limitations — and I think it is a good balance between them. Thanks again for the suggestion!

2 Likes

Bytecode executor has mostly all core features, have around 80% of opcodes defined and working, more inside PyLua/src/PyLua0.2/vm, going to start working on finalizing it and then moving on to the Bytecode Compiler. I’m open for feedback on the opcodes before I start on it :3

1 Like

PyLua 0.2

Took me some time to make it work but the base is done :slight_smile:

Features

  • Bytecode Compilation: Compile Python code once, execute multiple times
  • Python Syntax: Almost full support for all Python variables, operators, control flow, and data structures
  • Data Structures: Lists, dictionaries, tuples, sets with proper Python semantics
  • Control Flow: if/elif/else, for loops, while loops with nested support
  • Built-ins: print(), len(), type(), range(), int(), float(), str(), bool()
  • Optimized VM: Stack-based virtual machine for efficient bytecode execution

All features detailed here

Basic Usage

local python = require('path.to.PyLua0.2.python')
-- Simple one-line execution
python.execute('print("Hello, PyLua 0.2!")')

Compile Once, Execute Multiple Times

For better performance when running the same code repeatedly:

local python = require('path.to.PyLua0.2.python')

-- Compile Python code to bytecode
local bytecode, error = python.compile([[
x = 10
y = 20
result = x + y
print("Result:", result)
]])

if error then
    print("Compilation error:", error)
    return
end

-- Execute the bytecode multiple times
for i = 1, 5 do
    print("Execution", i)
    local success, variables = python.runBytecode(bytecode)
    if success then
        print("Variables:", variables)
    end
end

Check out the demo file with all features, download PyLuaV0.2 or just check the Github repository.

1 Like

I created a playground ROBLOX experience using your Python Interpeter!

I use Ode Script Editor for the IDE
Ode Script Editor: A simple embedded script editor entirely in Roblox - Resources / Community Resources - Developer Forum | Roblox

Here’s the link if you want to try it!
PyLua Playground - Roblox

Thanks!

3 Likes

This is pretty amazing and I like how it’s readable and modular so thats a big plus, but there is something that bothers me. I kno that the interpreter isn’t meant to be extremly fast and beat Luau in raw performance but there are some stuff especially in the built-in functions that could be improved and tuned for better performance. Also I wanted to point out that the len() function is not accurate for strings since I see that you are using string.len() which returns the number of bytes and not the number of characters in a string, this isn’t that big of a problem but just wanted to point it out. I recommend using utf8.len() instead to replicate the exact behaviour. I’m not saying any of this to be rude or anything, this resource is indeed amazing I’m just pointing out stuff that could be improved.

2 Likes

I forgot to mention that the string.len() function only becomes a problem with multi-byte characters like emojis where Python normally would return 1 for a single multi-byte character and Luau with string.len() would return the amount of bytes it takes that could be 2, 4 or even more.

2 Likes

This will be fixed in the next version, thanks for pointing it out. Next time feel free to open a github issue GitHub · Where software is built.

It’d be cool if it was able to retrieve and modify instance properties through built-in functions, but generally besides that, this looks pretty awesome and I could see it bringing new creators on Roblox within the near future.

1 Like

I’m planning on adding special roblox objects, its one of my main points to the future of developing this. thanks for suggesting tho!

1 Like

Awesome, looking forward to seeing this implemented. Keep developing!

2 Likes

Hi, I wanted to share an update about PyLua’s v0.3 and its new API

What’s New in v0.3? (Still in development)

Runtime-Based Architecture


-- OLD v0.2 approach (static/global)

local result = PyLua.execute("print('Hello')")

-- NEW v0.3 approach (runtime instances)

local python = PyLua.new()

local result = python:eval("2 + 3") -- Returns 5

python:execute("message = 'Hello from Python!'")

Multiple Isolated Runtimes


-- Game modding example: Each mod gets its own Python environment

local mod1_runtime = PyLua.new()

local mod2_runtime = PyLua.new()

mod1_runtime:globals().mod_name = "Custom ducks"

mod2_runtime:globals().mod_name = "New animated ducks"

-- Completely isolated - no interference between mods

Custom Function Injection


local python = PyLua.new()

-- Inject Luau functions into Python environment

python:globals().roblox_raycast = function(origin, direction)

   return workspace:Raycast(origin, direction)

end

-- Use in Python code

python:execute([[

result = roblox_raycast(Vector3.new(0, 10, 0), Vector3.new(0, -1, 0))

if result:
   print("Hit:", result.Instance.Name)

]])

Proper eval() vs execute() Distinction


-- eval() - returns expression values (like Python's eval())

local math_result = python:eval("10 * 5 + 2") -- Returns 52

-- execute() - for statements/side effects (like Python's exec())

python:execute("items = [1, 2, 3, 4, 5]") -- Creates variable, returns nothing

What’s Next?

With the solid v0.3 foundation in place, upcoming features will be much easier to implement:

  • Enhanced error handling with stack traces
  • Performance optimizations
  • More Standard Methods
  • More Python built-ins
  • Better Roblox API integration

Well, I guess that’s it and I’m going to keep working on it :+1:

4 Likes

Some quick updates since this has been taking a bit longer than expected :3

I’m currently on section 4.3 of internalDocs/REWRITE_PLAN.md. Right now the focus is implementing for loops and the break / continue control-flow logic.

Major changes vs v0.2

I guess that’s it, feel free to open an issue for feature requests or even star the repo :slight_smile:

2 Likes

Hi, first dev preview of 0.3.0 is out @ Release 0.3.0-dev · OMouta/PyLua · GitHub

Expect rough edges and behavior may change before a stable release :slight_smile:

1 Like