RBXLX → Directory Tree Exporter
Git-friendly file-system representation of .rbxlx places
xlx2tree is a command-line utility that parses .rbxlx XML place files and extracts them into a structured directory hierarchy. Each RbxInstance is represented as a directory or file, decoupling the monolithic XML structure into modular components suitable for version control systems like Git.
The tool operates strictly via the Python standard library (xml.etree, configparser, pathlib). It does not rely on external dependencies or third-party XML parsers.
- Parsing: The
.rbxlxfile is parsed into an in-memoryRbxInstancetree. Raw<Properties>XML nodes are preserved in memory to prevent data loss during extraction. - Filtering: Root-level services are filtered based on the declarative
config.inispecification. Internal engine services and unconfigured services are excluded from the extraction pool. - Extraction:
- Instances: Folders are generated using a
Name.ClassNameconvention to preserve type information. - Scripts:
<ProtectedString name="Source">nodes withinScript,LocalScript, andModuleScriptclasses are extracted and decoded into raw.luafiles (.server.lua,.client.lua,.module.lua). - Properties: Non-script data properties (e.g.,
Vector3,CoordinateFrame,BinaryString) are serialized into sidecar.properties.xmlfiles alongside their parent instance folder.
- Instances: Folders are generated using a
- Conflict Resolution: Sibling instances with identical
NameandClassNameattributes are disambiguated by appending an 8-character suffix derived from the instance's uniquereferentidentifier.
Note
The exporter operates in a unidirectional manner (read-only against the source file). It does not currently compile directory trees back into the .rbxlx format.
As xlx2tree requires no external Python packages, installation consists solely of cloning the repository.
git clone https://github.com/NonoNegative/xlx2tree.git
cd xlx2treeRequirements:
- Python 3.8 or higher.
The tool is invoked as a Python module.
python -m xlx2tree <input_file> <output_directory> [options]| Positional Argument | Description |
|---|---|
input |
Absolute or relative path to the source .rbxlx file. |
output |
Target directory path for the generated tree and metadata files. |
| Flag | Description |
|---|---|
--config <path> |
Specifies a custom configuration file path. If omitted, the tool searches the input directory and then the package directory for config.ini. |
--clean |
Recursively removes the output directory prior to beginning extraction. |
--tree-dir <subdir> |
Nests the generated instance tree within a subdirectory of the output root (e.g., --tree-dir src). Meta files (_export.log, _metadata.json, _tree.txt) remain in the output root. |
--dry-run |
Executes the parsing and conflict resolution logic without performing any filesystem I/O operations. |
--verbose, -v |
Emits detailed filesystem operation logs to stderr. |
--version |
Outputs the current application version and terminates. |
Standard Export
Extracts Place.rbxlx to the build/ directory using the default configuration.
python -m xlx2tree Place.rbxlx build/Clean Export with Nested Source Directory
Wipes the project/ directory, extracts instances into project/src/, and outputs metadata logs to the root of project/.
python -m xlx2tree Place.rbxlx project/ --clean --tree-dir srcTip
When integrating xlx2tree into CI/CD pipelines or shell scripts, use the --verbose flag and redirect stderr to capture execution logs without polluting standard output streams.
python -m xlx2tree Place.rbxlx output/ --verbose 2> execution.logThe extraction process is governed by config.ini. The configuration file utilizes standard INI formatting and supports inline comments prefixed with ; or #.
Defines the RbxInstance root classes permitted for extraction. Keys are evaluated against the class attribute of root XML nodes.
[Services]
Workspace = true
ServerScriptService = true
HttpService = falseDetermines structural promotion of critical player scripts. When true, these specific directories are hoisted from within StarterPlayer to the extraction root, optimizing file-system navigation and closely mirroring development workflows.
[StarterPlayerChildren]
StarterPlayerScripts = true
StarterCharacterScripts = trueControls secondary output artifacts and fallback behaviors.
[Export]
export_unlisted_services = false
generate_tree_manifest = true
generate_metadata = trueDepending on configuration, the output directory contains the extracted tree and up to three metadata artifacts.
project/
├── _export.log # Execution logs and diagnostic output
├── _metadata.json # Aggregated parsing statistics and provenance
├── _tree.txt # ASCII visualization of the generated structure
└── src/ # Instance tree root (when --tree-dir=src is used)
├── Workspace/
│ ├── Workspace.properties.xml
│ ├── Camera/
│ │ └── Camera.properties.xml
│ └── SpawnLocation.SpawnLocation/
│ └── SpawnLocation.SpawnLocation.properties.xml
├── ServerScriptService/
│ └── GameManager.server.lua
└── StarterGui/
└── MainMenu.ScreenGui/
└── Frame.Frame/
└── PlayButton.TextButton/
├── PlayButton.TextButton.properties.xml
└── OnClick.client.lua
Warning
Do not manually modify .properties.xml files unless you are familiar with the Roblox XML schema. Structural damage or malformed XML properties may corrupt the data representation.
In Roblox, it is valid for multiple sibling instances to possess identical Name and ClassName properties. To ensure deterministic filesystem representation and prevent data overwriting, xlx2tree employs a referent-based suffix mechanism.
If the parser detects a naming collision within the same parent context, the last 8 characters of the instance's referent UUID are appended to the directory name.
Workspace/
├── Zombie.Model/ # Primary instance
├── Zombie.Model_A1B2C3D4/ # Colliding instance 1
└── Zombie.Model_E5F6G7H8/ # Colliding instance 2
- Fork the repository
- Create a feature branch (
git checkout -b feature/component-enhancement) - Commit your modifications (
git commit -m 'Implement component enhancement') - Push to the branch (
git push origin feature/component-enhancement) - Open a Pull Request
This project is distributed under the MIT License. See LICENSE for further details.