Migrating from Remodel
If you have used Remodel before to manipulate place and/or model files, this migration guide will help you get started with accomplishing the same tasks in Lune.
Drop-in Compatibility
Section titled “Drop-in Compatibility”This guide provides a module which translates all of the relevant Lune APIs to their Remodel equivalents. For more details or manual migration steps, check out Differences Between Lune & Remodel below.
-
Copy the remodel module and place it in a file named
remodel.luau
.This module is quite large, but you will not need to read through it unless you want to know about the internal details of how Remodel used to work.
-
Next, create another script next to your
remodel.luau
. We will be naming itexample.luau
, but you can name it whatever you want. This example code is from one of the legacy Remodel-native example scripts, with only the top line added:remodel.luau local remodel = require("./remodel")-- One use for Remodel is to move the terrain of one place into another place.local inputGame = remodel.readPlaceFile("input-place.rbxlx")local outputGame = remodel.readPlaceFile("output-place.rbxlx")-- This isn't possible inside Roblox, but works just fine in Remodel!outputGame.Workspace.Terrain:Destroy()inputGame.Workspace.Terrain.Parent = outputGame.Workspaceremodel.writePlaceFile("output-place-updated.rbxlx", outputGame) -
Finally, run the script you’ve created by providing the script name to Lune, in our case
example
, without the luau file extension. Everything should work the same way it did when running natively in Remodel, now running in Lune 🚀Terminal lune run example
Differences Between Lune & Remodel
Section titled “Differences Between Lune & Remodel”Most APIs previously found in Remodel have direct equivalents in Lune, below are some direct links to APIs that are equivalent or very similar.
Places & Models
remodel.readPlaceFile
➡fs.readFile
&roblox.deserializePlace
remodel.readModelFile
➡fs.readFile
&roblox.deserializeModel
remodel.readPlaceAsset
➡net.request
&roblox.deserializePlace
remodel.readModelAsset
➡net.request
&roblox.deserializeModel
remodel.writePlaceFile
➡roblox.serializePlace
&fs.writeFile
remodel.writeModelFile
➡roblox.serializeModel
&fs.writeFile
remodel.writeExistingPlaceAsset
➡roblox.serializePlace
&net.request
remodel.writeExistingModelAsset
➡roblox.serializeModel
&net.request
remodel.getRawProperty
➡ no equivalent, you can get properties directly by indexingremodel.setRawProperty
➡ no equivalent, you can set properties directly by indexing
Files & Directories
remodel.readFile
➡fs.readFile
remodel.readDir
➡fs.readDir
remodel.writeFile
➡fs.writeFile
remodel.createDirAll
➡fs.writeDir
remodel.removeFile
➡fs.removeFile
remodel.removeDir
➡fs.removeDir
remodel.isFile
➡fs.isFile
remodel.isDir
➡fs.isDir
JSON
json.fromString
➡serde.decode
json.toString
➡serde.encode
json.toStringPretty
➡serde.encode
Since Lune is meant to be a general-purpose Luau runtime, there are also some more general differences, and Lune takes a different approach from Remodel in certain areas:
- Lune runs Luau instead of Lua 5.3.
- APIs are more loosely coupled, meaning that a task may require more steps using Lune. This also means that Lune is more flexible and supports more use cases.
- Standard libraries are not accessible from global variables, you have to explicitly import them
using
require("@lune/library-name")
. - Arguments given to scripts are not available in
...
, you have to useprocess.args
instead. - Lune generally supports all of the Roblox datatypes that are gettable/settable on instance properties. For a full list of available datatypes, check out the API Status page.
There may be more differences than are listed here, and the Lune-specific guides and examples may provide more info, but this should be all you need to know to migrate from Remodel. Good luck!