Rogen

Linting

A lint rule that stops one feature from requiring another

Updated

Rogen doesn't check your requires. Because every path names its side and its feature, a linter can catch a require that crosses a boundary before the game runs.

Luau

Lute's linter runs rules written in Luau. The rule require_boundaries.luau reads the sourcemap to learn where each file lands, follows each require to the instance it names, and reports shared code that requires a side, a feature that requires another feature not listed in sharedFeatures, and a require of an instance that no file provides.

  1. Install Lute with rokit add luau-lang/lute, and save the rule:

    curl -o lints/require_boundaries.luau --create-dirs https://rogen-roblox.vercel.app/lint/require_boundaries.luau
  2. Add a .config.luau. featureRoots are the targets of your routes:

    .config.luau
    return {
    	lute = {
    		lint = {
    			rulepaths = { "lints" },
    			ruleconfigs = {
    				require_boundaries = {
    					options = {
    						sourcemap = "sourcemap.json",
    						featureRoots = {
    							"ServerScriptService",
    							"StarterPlayer.StarterPlayerScripts",
    							"ReplicatedStorage.Shared",
    						},
    						sharedFeatures = { "Util" },
    					},
    				},
    			},
    		},
    	},
    }
  3. Write the sourcemap, then lint:

    rogen sourcemap -o sourcemap.json
    lute lint --no-default-lints src

Each crossed boundary is an error, such as feature Inventory requires feature Shop: ServerScriptService.Shop.ShopService, and lute lint exits 1, so a CI job that runs it fails.

roblox-ts

An import names a file, so ESLint's import/no-restricted-paths does the same job: give each feature a zone, and each side a zone that keeps out the other side's folders.

On this page