RPy — Python to Luau Compiler for Roblox
Write Python. Ship to Roblox.
RPy is a production-grade Python-to-Luau transpiler that combines the elegance and power of Python with native Luau performance. Compile, type-check, and sync your code directly into Roblox Studio while taking advantage of advanced compiler optimizations, SSA analysis, and full Roblox API awareness.
Target Audience: Intermediate to Advanced Roblox developers (and engineering teams) who want to leverage the Python ecosystem, rigorous static analysis, and expressive syntax without sacrificing raw Luau VM performance.
Compatibility: Fully compatible with Roblox Studio 2026+ and Luau versions supported by the Roblox client. Works for client, server, and replicated scripts.
Overview
RPy is not just a translator—it is a multi-stage compiler designed for production use. Python syntax is parsed, semantically analyzed, optimized, and output as idiomatic, high-performance Luau code. No heavy Python runtime is shipped; RPy maps Python semantics directly to Luau structures.
Pipeline:
Python AST → Lexical Scope Resolution → Middle-end IR → Dependency Graph → Optimization Passes → Target-specific Luau generation
Key Features:
- SSA-based optimizer (Constant Folding, Dead Code Elimination, Peephole Optimization, Escape Analysis, SRA)
- Strict type mapping: Python type hints → Luau types
--!strictheaders for all modules- Flow-sensitive semantic analysis
- Classes, inheritance, properties, static methods
- Lists, dictionaries, sets, comprehensions
- Module imports resolved to Roblox
require() - Minimal runtime shims for Python-only features
- Built-in code syncing with Roblox Studio via
rpy watch - Full Roblox API metadata baked into the compiler
- CLI tools (
rpy build,rpy watch,rpy doctor,rpy setup) - Custom VSCode extension with LSP features (diagnostics, completion, go-to-definition)
Installation / Quick Start
Get RPy up and running on your machine in under three minutes.
Prerequisites
- Python 3.10+ — required for modern syntax and type hints
- Roblox Studio — target environment for compiled code
Step-by-Step Setup
- Install the Transpiler
pip install rpy-roblox
- Initialize Your Project
rpy init my-awesome-game
cd my-awesome-game
- Deploy the Studio Companion
rpy install
The companion plugin handles automatic syncing between your filesystem and Roblox Studio.
Example: Advanced Object-Oriented Transpilation
Python (src/managers/PlayerManager.py):
from roblox import game, Instance
from typing import List
class PlayerManager:
def __init__(self, start_pos: "Vector3"):
self.start_pos = start_pos
self.players: List["Instance"] = []
def spawn_hero(self, name: str) -> "Instance":
hero = Instance.new("Part")
hero.Name = name
hero.Position = self.start_pos
hero.Parent = game.Workspace
self.players.append(hero)
return hero
RPy Output (.rpy/out/managers/PlayerManager.lua):
-- Generated by RPy — do not edit manually
--!strict
local PlayerManager = {}
PlayerManager._method_types = {}
PlayerManager.__index = PlayerManager
PlayerManager.__call__ = function(self, ...)
return self:__call__(...)
end
function PlayerManager.new(...)
local self = setmetatable({}, PlayerManager)
if self.__init__ then
self:__init__(...)
end
return self
end
function PlayerManager.__init__(self, start_pos)
self.start_pos = start_pos
self.players = {}
end
function PlayerManager.spawn_hero(self, name)
local hero = Instance.new("Part")
hero.Name = name
hero.Position = self.start_pos
hero.Parent = game.Workspace
self.players:append(hero)
return hero
end
return PlayerManager
Common Questions / FAQ
Q: Can I use standard Python libraries like os, json, or requests?
A: No. RPy transpiles to Luau, which runs in Roblox’s sandbox. Use HttpService for HTTP, JSONEncode for JSON, etc. RPy includes shims for common stdlib APIs like re, json.dumps, and math.
Q: Why do f-strings become tostring() chains instead of Luau backticks?
A: RPy targets maximum Luau version compatibility. Backticks are not guaranteed in all Roblox environments. tostring() chains ensure correctness everywhere.
Q: Does RPy use 0-based or 1-based indexing?
A: Python is 0-based, Luau is 1-based. RPy does not automatically offset indexes. Use my_list[1] for the first element in Luau.
Q: Does Python’s is keyword work correctly?
A: No. is checks object identity in Python; RPy maps it to == in Luau, which tests value equality for primitives and reference equality for tables.
Q: What happens to docstrings?
A: Docstrings are converted into Luau multi-line comments (--[[ ]]) and preserved above functions/classes.
Q: Can I use try/except?
A: Not yet. Use Roblox pcall() patterns as a workaround.
Q: Can I define Python classes and use inheritance?
A: Yes, with single inheritance. RPy emits Luau tables with metatables. Multiple inheritance and full super() semantics are partially supported.
Limitations
- No
eval()or deep__dunder__runtime hacking - Python generators (
yield) have limitations - Metaclasses are not supported to guarantee native Luau performance
Links & Community
- Documentation: https://rpy.vercel.app/
- VSCode Extension: RPy for Roblox
- Discord: https://discord.gg/2wAEnyXA
Why RPy?
Scale demands professional tooling. Writing raw Luau abandons one of the world’s most powerful ecosystems. With RPy:
- Use Python tooling (Black, Ruff/Flake8, Pytest) before Roblox Studio
- Write expressive, maintainable Python code with full type safety
- Compile directly to optimized, native Luau
- Scale complex game architectures predictably
RPy gives you the power of standard Python engineering with the exact runtime speed of native Luau.

