Changelog
What changed in each release of Rogen
Updated
All notable changes to Rogen are listed here.
The format is based on Keep a Changelog, and Rogen adheres to Semantic Versioning from 2.0.0 on.
Unreleased
Changed
rogen initnow writes a*route by default, so a file that matches no route goes to the shared route. Only the files that run on one side need marking, such as with@Server. To leave such files out with a warning instead, remove*fromroutesin the config.rogen initlifts a Rojo project whose code Darklua writes to a folder of its own, such asbuild, into adefault.rogen.jsonthat reads the source and adist.rogen.jsonwith that folder as itscompiledPath, and its next steps servedist. It looks for a.darklua.jsonor.darklua.json5and for mounts that repeat the source path. Before, the lifted config kept the mounts of that folder, so Rojo synced each script twice.- In
rogen init --json, eachdecidedentry names the flag that changes the choice, as the agent skill reads it:--no-samplefor the sample init writes,--placesfor one place. Before, it named the flag that keeps the choice. The text line names each choice with the same flag: "Took the defaults, each with the flag that changes it: a place (--kind), luau (--language), one place (--places), …". rogen initadds the agent hook only when--agent-hookis given, or when it is chosen under Customise. Before, pressing Create in a terminal added it where a coding agent was in use, while-ydidn't. Where one is in use, a note says thatrogen init --agent-hookadds it, and running it where the hook is registered already says so.rogen syncbackruns on a project with acompiledPath. It writes the changes outside the compiled path, such as the folders the tree mounts, and lists each changed, removed or new instance that the project compiles as asyncback.compiledPathwarning, for you to make in the source files. Before, it stopped withsyncback.compiledPathand wrote nothing. In a terminal, the warnings about what syncback leaves out now come before it asks to write the rest.
Removed
rogen initno longer has flags or questions for what is one line in the config.--route,--unmatched,--package,--source-path,--project-file,--darkluaand--compiled-pathare gone, and so are their questions. Edit the config instead.--sampleand--no-agent-hookare gone too, as they only repeated a default; each is now a usage error that names the flag that changes it. The entries below say what each one did and what init does now.rogen initno longer asks which routes, packages or unmatched files to start with (--route,--packageand--unmatched). It writes the server, client, shared and*routes, or the routes a lifteddefault.project.jsonmounts, and mounts the package folders that are installed or that awally.tomlorpesde.tomlsays are coming. Its next steps say to changeroutesand thetreein the config, or in each.rogen.jsonwhere there are several. In--json,decidedno longer listsroutes,unmatchedorpackages, and avalueis never a list.rogen initno longer asks for the source path (--source-path): it finds it. When it lifts a Luau project, the source path is the closest folder that holds every folder of code the project file mounts, socode/serverandcode/clientgivecode. A folder named after a route, such assrc/serveralone, gives its parentsrcwhen the routes put the code where the project file did. Folders mounted from the top of the project, such asserver/andshared/, stay mounted in the tree, with a note. Package folders,"."and a compiler's output are never source paths. Code that no source path holds and the tree doesn't mount gets aninit.codeOutsideSourcePathswarning, also in--jsonwarnings. Before, a lifted project whose code wasn't insrcgot an emptysrc, and Rogen placed nothing, with no warning.rogen initno longer asks whether to lift a hand-writtendefault.project.jsonor start a new tree (--project-file): it always lifts it intodefault.rogen.json. Starting a new tree replaced the file and lost its tree with no warning. To start a new one, movedefault.project.jsonaway first. Beside it,--places, and--kind modelor--kind pluginwhen the file is a place's, are a usage error that says so.rogen initno longer sets up Darklua for a new project (--darkluaand--compiled-path): it writes no.darklua.json, Darklua pin,dist.rogen.jsonor.gitignoreentry for Darklua's output, and its next steps run nodarklua process.rogen writestill knows Darklua's output in acompiledPath, and warns about it as before. Using Darklua sets it up by hand.
Fixed
rogen inittakes a roblox-ts project's source path from therootDirintsconfig.json, which roblox-ts compiles. Before, it read asourcePaththere, which roblox-ts doesn't use.- The Baseplate that
rogen initwrites gives its color as whole numbers (Color3uint8), which a place keeps exactly, so the firstrogen syncbackno longer rewrites it when nothing changed in Studio. - With a
compiledPath, code compiled after the project file was written now syncs into a running Rojo. Rojo never watches a mounted path that is missing when it loads the project, so before it writes, Rogen creates each folder the project file mounts in the compiled path and roblox-ts'sinclude, and a placeholder script for each Luau file mounted there, which the compiler replaces. This happened on a fresh checkout when Rojo started before the first compile, and to each new feature folder while serving. - When
rogen initlifts a project file, files that it mounts through a compiled folder (roblox-ts'sout, Darklua's) or through a folder above the source path (such as".") no longer count as files Rojo ignored (init.unmountedFiles). rogen writeno longer warns thatrbxts.copyfiles.json, which sloptor writes in the compiled path for itself, is acompiled.orphan.- In a project that has a config,
rogen init --agent-rulesand--agent-hookadd the agent files also with--skip-git,-y,-nor--json. Before,--skip-gitmade them stop withinit.configExists. With a flag that shapes a config, such as--language, they now stop with a usage error that names the flag. - In the README that
rogen initwrites for one place, the paragraph on which folders decide where code runs now follows the one about the feature it means.
2.0.0-beta.1 - 2026-10-26
Added
default.rogen.json, a Rojo project file with Rogen's keysroutes,sourcePathsandcompiledPath. Rogen writesdefault.project.jsonfrom it.- Routing by folder (
Server/), by name (Save@Server.luau) or by marker file (@Server). - The
*fallback route, for files that no other route covers. - Rojo's commands through Rogen:
serve,build,upload,sourcemap,syncback,fmt-projectandplugin. They take Rojo's flags and write the project file first. - In a folder with a plain
default.project.jsonand no config, Rojo's commands run on that file as Rojo would. rogen write, which writes the project file, and with--watchwrites it on every change.rogen check, which reports each problem with a code and its fix.rogen where, which prints where a file lands in the game and how to require it.rogen help, which prints a command's flags or what a diagnostic code means, androgen doc, which opens the docs or prints a topic offline.rogen initadds Rogen's rules for coding agents toAGENTS.md, and can add a hook that checks the files an agent changed before it ends its turn.--jsonon every command, for one JSON document instead of text.- A new docs site at rogen-roblox.vercel.app.
Changed
- Breaking: Rogen needs Rojo 7.5.0 or newer.
- Breaking: The outermost route wins. In 1.x the deepest rule won.
- Breaking: Only
@routes a name. Prefixes and suffixes such asserver_Combat.luauandCombat_Server.luauno longer route, and Rojo's.serverand.clientkeep their meaning. - Breaking: Only the routes you declare exist. A file that no route covers is left out with a warning, instead of going to
ReplicatedStorage. - Breaking: A
^file goes to the root of its route's target, not of the service. - Breaking:
rogen build -obuilds a place, as Rojo's does. - Breaking: Every command stops with
legacy.configwhile a v1.rogen.jsonis in the folder. See Migrating from v1 to move a project.
Removed
- Breaking: The 1.x config keys and flags.
sourceis nowsourcePaths,aliasesand the built-in keywords are nowroutes, a mode'sbuildis nowcompiledPath, andprojectis now the config'stree.casing,unwrap,verbatim, tags and modes are gone; Migrating from v1 says what replaces each. - Breaking: The
.structure,.sync,.verbatimand.unwrapmarker files. - Breaking: Several places from one config. Each place has a config of its own.
- Breaking:
rogen watchand-w. Userogen write --watch, orrogen serve, which writes the project file on every change.
1.4.4 - 2026-08-20
Fixed
- Custom aliases for nested services (
StarterCharacterScriptsorStarterPlayerScripts) generate the correct nodes in the project file again. This broke in 1.4.2.
1.4.3 - 2026-08-15
Fixed
- Folders with a version in their name, such as
sleitnick_signal@2.0.3, were taken for data files and removed from the build. Rogen now only takes the data file extensions that Rojo and Argon support.
1.4.2 - 2026-08-10
Added
- A log line for the first run, even when nothing changed.
Changed
- Generated entries use Rojo's optional path form (
{ "optional": path }), so deleting a file or folder duringrojo serveno longer crashes Rojo. - Watching polls for changes on Windows, so editors such as VS Code no longer show "folder in use" prompts.
- Generated folders set
$ignoreUnknownInstances: false. - The project file is written atomically, so a watcher never reads a half-written file.
- A better project tree when you use
globIgnorePaths.
Fixed
*.d.tsfiles were not ignored. This broke in 1.4.0.- Undefined service containers went out of sync.
- In Luau projects, the watcher fired in the middle of a deletion and rebuilt deleted paths as empty stubs. Placeholder stubs are now made only for compiled projects (TypeScript or Darklua).
1.4.1 - 2026-08-01
Changed
- An unmapped data file no longer stops the build. Rogen leaves it out of the tree, finishes the build, and warns you to use
globIgnorePathsor to wrap it in a folder.
Fixed
- Folder collapsing overwrote a parent node's own
$path. Rogen now skips folder collapsing on nodes with a$path.
1.4.0 - 2026-07-31
Added
- Tags, which leave files out of a build, such as tests and mock data. Define tags in your config and apply them to files or folders.
- The
unwrapconfig option, which removes the global wrapper folders. - The
globIgnorePathsconfig option, which ignores files by pattern. - The
casingconfig option, which sets folder names to"camelCase"or"PascalCase"(contributed by @bo-rges). - Invisible folders: a folder name in parentheses, like
(inventory), keeps its files together on disk but leaves the folder out of Roblox Studio. - File hoisting: a
^at the start of a file name places it at the root of a service. - The
.structure,.sync,.verbatimand.unwrapmarker files, which change how Rogen reads a folder. - The plus sign (
+) as a routing delimiter in file names, beside dots, hyphens and underscores. - Support for data files such as
.jsonand.yml. - Full support for Argon.
- Warnings for colliding file paths, and for an old configuration, saying what to change.
- The
watchandinitcommands. The-w,--watch,-iand--initflags still work. - The
-vand--versionflags. - The npm package:
npm i @ldgerrits/rogen. - A documentation website.
Changed
- Breaking: Paths in the config are resolved from the
.rogen.jsonfile, not from your terminal's folder, so Rogen runs from any folder. Paths given as flags still use your terminal's folder. - Breaking: The
projectconfig option replacestemplatefor the base tree. - Breaking: The
verbatimconfig option replaceskeepRouteNames. - Breaking: The
-tflag activates tags. It no longer sets the template. - Breaking: The
-pand--projectflags set the project file, which-tused to do. - A file name that is exactly a routing keyword is now its name, not a routing affix.
- The generated Rojo tree crashes Rojo far less when you delete files or folders.
- Clearer log messages.
1.3.1 - 2026-06-30
Changed
- Rogen's code moved to TypeScript. Nothing changes in how you use it.
1.3.0 - 2026-06-27
Added
- Marker files: an empty
.server,.clientor.sharedfile routes the folder it is in, and the folder keeps its name. - Routing prefixes: a keyword can start a file name as well as end it, as in
server.data.tsorserverData.ts.
Changed
- Breaking: A file's prefix or suffix overrides its folder and its marker file. Before, the folder won.
- Breaking:
keepSuffixesand-k, --keepSuffixesare renamed tokeepRouteNamesand-k, --keepRouteNames.
1.2.2 - 2026-06-15
Fixed
- Watching on Linux, which now uses chokidar instead of
fs.watch.
1.2.1 - 2026-06-01
Fixed
- A bug in watching introduced in 1.2.0.
1.2.0 - 2026-06-01
Added
- Several sources:
sourcetakes a list of folders, and-scan be given more than once. Folders with the same route merge, and when two sources hold the same file, the one listed last wins.
1.1.1 - 2026-05-22
Added
- The
-iand--initflags, which write a default.rogen.json. - The
aliasesconfig option, which routes your own keywords or folders to a service, such as"Controller": "ReplicatedStorage", and can override the default routing. - The
keepSuffixesconfig option and the-kflag, which keep routing suffixes in script names.
1.1.0 - 2026-05-21
Changed
- Rogen reads
.rogen.json, or else the first*.rogen.jsonin the folder.
Fixed
- The
-hand-bflags, which the help listed but Rogen didn't read. - The built-in config Rogen uses when there is no
.rogen.json.
1.0.2 - 2026-05-20
Changed
- Compiled files that are not there yet get an empty placeholder right away, so Rojo doesn't fail and the compiler has the tree it needs. Before, Rogen waited up to 5 seconds and then dropped them.
1.0.1 - 2026-05-19
Added
- The
-wand--watchflags, which regenerate the project file when your files change, so you no longer need chokidar-cli. - The
--helpflag.
Changed
- Rogen waits for compiled output, such as roblox-ts's, before it writes the project file.
1.0.0 - 2026-05-19
Added
- Routing files to Roblox services by folder name (
server,client,sharedor a service name) or by file-name suffix, and generating the Rojo project file from them. - Support for Luau, roblox-ts and Darklua.