RobloxFileService
Open, change and save Roblox places and Models as files, with no Studio running: .rbxl, .rbxlx, .rbxm or .rbxmx, binary or XML.
OpenAsync reads a file into a PlaceFile, FromBuffer reads bytes and New starts an empty place or Model. Each open file is a child of this service until you close it. A failure of the world, such as a missing or broken file, comes back as nil and why; a mistake in your code, such as a wrong kind, is an error.
A service: write use RobloxFileService.
Example
--!strict
-- A new place made in memory, a Model read from XML text, the two put together and read back from bytes.
local RobloxFileService = require("@shotsystem/RobloxFileService")
-- an XML CFrame at x, y, z with no rotation
local function at(x : number, y : number, z : number) : string
return `<CoordinateFrame name="CFrame"><X>{x}</X><Y>{y}</Y><Z>{z}</Z><R00>1</R00><R01>0</R01><R02>0</R02>`
.. `<R10>0</R10><R11>1</R11><R12>0</R12><R20>0</R20><R21>0</R21><R22>1</R22></CoordinateFrame>`
end
local xml = `<roblox version="4"><Item class="Folder" referent="A"><Properties><string name="Name">Shop</string></Properties>`
.. `<Item class="Part" referent="B"><Properties><string name="Name">Stand</string>{at(10, 2, 0)}</Properties>`
.. `<Item class="Attachment" referent="C"><Properties><string name="Name">Sign</string>{at(0, 3, 0)}</Properties>`
.. `</Item></Item></Item></roblox>`
local kit = assert(RobloxFileService:FromBuffer(xml, "Model"))
print("kit:", kit.Kind, kit.Format, #kit.Instances, kit.Instances[1].Name)
local sign = RobloxFileService:GetWorldCFrame(assert(kit:FindInstance("Shop.Stand.Sign"))).Position
print("the sign in the world:", sign.X, sign.Y, sign.Z)
local place = RobloxFileService:New("Place")
kit.Instances[1]:Clone().Parent = assert(place.DataModel):GetService("Workspace")
local back = assert(RobloxFileService:FromBuffer(place:ToBuffer(), "Place"))
print("read back:", back.Kind, back.Format, assert(back:FindInstance("Workspace.Shop.Stand")).ClassName)
print("open files:", #RobloxFileService:GetChildren())
for _, file in { kit, place, back } do
file:Close()
end
print("open files after Close:", #RobloxFileService:GetChildren())kit: Model Xml 1 Shop the sign in the world: 10 5 0 read back: Place Binary Part open files: 3 open files after Close: 0
Methods
| Name | Arguments | Returns | Description |
|---|---|---|---|
| OpenAsync yields | (path: string, options: { ReadOnly: boolean? }?) | (PlaceFile?, string?) | Waits to read the file and gives a PlaceFile under this service, or nil and why; { ReadOnly = true } refuses every save. |
| FromBuffer | (bytes: buffer | string, kind: "Place" | "Model") | (PlaceFile?, string?) | A PlaceFile from a file's bytes, with no Path and its Format read from the bytes; broken bytes give nil and why. |
| New | (kind: "Place" | "Model") | PlaceFile | An empty place or Model in Binary format with no Path, so its first SaveAsync must be given one. |
| GetWorldCFrame | (attachment: RobloxInstance) | CFrame | An Attachment's WorldCFrame, since reading that property inside a file errors; passing anything but an Attachment is an error. |
From ShotInstance 33
ClassNameNameParentAncestryChangedAttributeChangedChangedChildAddedChildRemovedDestroyingAddTagClearAllChildrenCloneDestroyFindFirstAncestorFindFirstAncestorOfClassFindFirstAncestorWhichIsAFindFirstChildFindFirstChildOfClassFindFirstChildWhichIsAGetAttributeGetAttributeChangedSignalGetAttributesGetChildrenGetDescendantsGetFullNameGetPropertyChangedSignalGetTagsHasTagIsAIsAncestorOfIsDescendantOfRemoveTagSetAttribute
