#!/usr/bin/env python3 """Push MapBuilder.luau source into a LIVE (Play-mode) Studio via the MCP bridge. Rojo cannot reach the running server datamodel in Play mode, so the source is shipped as ~9000-char chunks into named StringValue children (p0, p1, ...) under ReplicatedStorage, then concatenated and assigned to the ModuleScript's .Source. Named children matter: a retried chunk overwrites its slot instead of appending a duplicate. Bridge calls fail intermittently ("Unable to find an active Studio instance") even while Studio is up, so every call is retried. """ import sys, time sys.path.insert(0, "/tmp") import rbx SRC_PATH = "/home/jesse/roblox/tokyo-wangan-racing/src/server/MapBuilder.luau" MODULE = 'game:GetService("ServerScriptService"):FindFirstChild("Server", true)' CHUNK = 9000 def call(code, tries=4): last = None for a in range(tries): try: r = rbx.call( "execute_luau", {"code": code, "datamodel_type": "Server"}, warmup=6, wait=45, timeout=300, ) if r and "Unable to find an active Studio" not in str(r): return r last = r except Exception as e: # noqa: BLE001 last = e time.sleep(5) raise RuntimeError(f"bridge failed after {tries} tries: {last}") src = open(SRC_PATH, encoding="utf-8").read() nbytes = len(src.encode()) print(f"source: {len(src)} chars, {nbytes} utf-8 bytes") # Pick a long-bracket level that does not occur in the source. lvl = 0 while ("]" + "=" * lvl + "]") in src or ("[" + "=" * lvl + "[") in src: lvl += 1 eq = "=" * lvl print(f"long-bracket level: {lvl}") chunks = [src[i : i + CHUNK] for i in range(0, len(src), CHUNK)] print(f"chunks: {len(chunks)}") print(call('local rs=game:GetService("ReplicatedStorage")\n' 'local b=rs:FindFirstChild("MBBuf") if b then b:Destroy() end\n' 'b=Instance.new("Folder") b.Name="MBBuf" b.Parent=rs\n' 'return "buffer reset"')) for i, c in enumerate(chunks): code = ( 'local rs=game:GetService("ReplicatedStorage")\n' 'local b=rs:WaitForChild("MBBuf")\n' f'local n="p{i}"\n' "local sv=b:FindFirstChild(n) or Instance.new(\"StringValue\")\n" "sv.Name=n sv.Parent=b\n" f"sv.Value=[{eq}[{c}]{eq}]\n" f'return "p{i} "..#sv.Value' ) print(f" chunk {i+1}/{len(chunks)}: {call(code)}") assemble = f""" local rs=game:GetService("ReplicatedStorage") local b=rs:WaitForChild("MBBuf") local parts={{}} for i=0,{len(chunks)-1} do local sv=b:FindFirstChild("p"..i) if not sv then return "MISSING CHUNK p"..i end parts[#parts+1]=sv.Value end local s=table.concat(parts) local sss=game:GetService("ServerScriptService") local m=sss:FindFirstChild("MapBuilder", true) if not m then return "MapBuilder ModuleScript NOT FOUND" end m.Source=s return ("assembled=%d expected={nbytes} match=%s class=%s path=%s"):format( #s, tostring(#s=={nbytes}), m.ClassName, m:GetFullName()) """ print(call(assemble))