Code frameworks
Limits and errors
The limits of a project, and the messages you may see with their fixes.
Limits
| Limit | Value |
|---|---|
| Source size | 8 MiB |
| Compiled game size | 16 MiB |
| Files | 1000 |
| Frameworks | 64 |
| Scenario files | 512 |
| Content presets per Framework | 512 |
| Content presets per Game | 2048 |
| Actions per Framework | 96 |
| Actions per Game | 192 |
| Ledger functions per Framework | 64 |
| Frames per Framework | 1 to 16 |
| Frames per Game | 128 |
| Sections per Framework | 64 |
| Input options | 2 to 128 |
| Authored action steps per project | 512 |
| Steps per action | 64 |
| Steps per scenario | 32 |
| Ledger checks per scenario | 32 |
| Expected writes per step | 64 |
The rows above limit your source. Fabled also compiles your source into one game, and that compiled game must stay under 16 MiB before it can be prepared.
The server checks the same limits again when you prepare a game, and its verdict is final.
Errors and fixes
Each row quotes part of a message. The message in The Forge may add the file, the line or the names involved.
| Message | Cause | Fix |
|---|---|---|
| Project contains undeclared source files: rules/extra.ts. | Unreferenced files exist. The message lists up to five paths and counts any remaining files. | Compare the files of the tree with the manifest and the schemas. Deleting a ledger function leaves its rules file behind, so delete that file too. |
| Missing or misplaced project source. | A listed path has no file, or the file is in the wrong folder. | Fix the path or add the file. |
| Unrecognized key(s) in object | A JSON file uses a field the format does not have. | Remove the field or correct its spelling. |
| Input name is hidden, so it must declare a defaultValue. | A hidden input has no default. | Add a defaultValue, or show the input. |
| must be one of its options | A default is not in the options list. | Use one of the options as the default. |
| Parameter max_hp 99 is not between 1 and 40. | A scenario or preset breaks an input's bounds. | Change the value or the bounds. |
| is not assigned to any section | Sections exist, but an input is in none. | Add the input to a section. |
| Duplicate semantic identity or source path. | Two items share an id or a source file. | Give each its own id and file. |
| Invalid child Framework constraint | A child slot points at a Framework outside the game. | Use the id of a Framework in this game. |
| Ledger function must target an existing scalar field. | The field is not one the constructor returns. | Return the field from the constructor, or fix the name. |
| must define the required 'name' value | A constructor does not return a name. | Return a string field called name. |
| The entry framework must be a character constructor. | The manifest's entry Framework is not a character. | Point entryFramework at a character Framework. |
| while loops are not allowed | A rule uses a loop that may not end. | Use for of. |
| is a host global and not part of the TypeScript subset | A rule uses Math or another global. | Use the host calls, such as math.min. |
| import is not allowed | A rule imports code. | Put the logic in the rule file itself. |
| must return a value on every reachable path | A function with a return type has a path with no return. | Return a value on every path, or declare void. |
| is not declared on this schema | An action writes a field the constructor does not return. | Return the field from the constructor, or fix the name. |
| FRAME_BINDING_UNKNOWN | A Frame binds a field that does not exist. | Bind a declared field. |
| ACTION_MISSING | A button names an action alias that does not exist. | Declare the alias, or fix the name. |
| Expected ordered writes | An action wrote something different from expectedWrites. | Fix the rule or the expected writes. |
| Constructor output does not match its scenario. | expectedValues differs from what the constructor returns. | Fix the scenario or the constructor. |
| SCENARIO_COVERAGE_MISSING | An action has no scenario step. | Add at least one step for the action. |
| is a non-writable state field | An action writes a value that a ledger function derives. | Write a stored field, and let the ledger function derive the rest. |
| Action accesses require literal keys on self. | An action names a field with a value instead of a string written in the code. | Write the field name between quotes. Use one action for each field. |
| functions but only the action | An action file exports two functions. | Export one function per action file, or share the file between actions. Keep helpers without export. |
| the step expects it to be refused with | A step expects a refusal, but the action was not refused. | Remove expectedRefusal, or fix the offer so it refuses. |
| Add expectedRefusal | A list step was refused, but it does not say so. | Add expectedRefusal with the code, and no writes. |
| Every ledger function needs an executable scenario. | A ledger function has no entry in the ledger list of any scenario. | Add a ledger entry with the function id, a currentValue and the expected result. |
| effectful action helpers are not supported | A helper function writes with ledger.set or ledger.add. | Let the helper return the value, and write it in the action. |
| is not a writable state field | A fields list names a field that is not stored, such as one a ledger function derives. | List only stored fields that the constructor returns. |
| is not satisfied: roll.missing | A scenario uses the roll method without recorded rolls, or a preset uses it, and only the server can roll. | In a scenario, add poolRolls with one slot per score. A preset cannot use roll, so give the pool another method for presets. |
| The roll dice must be one group such as | The roll dice are not one group like "3d6", for example 3d6x5. | Write one group of dice, and put a multiplier in the multiplier key. |
| outside the min/max of input | The dice can give a total that an input does not allow. | Widen the min and max of the inputs, or change the dice. |
| give exactly one roll per input. | The count of the roll differs from the number of inputs in the pool. | Set count to the number of inputs. |
| must offer exactly the methods of pool | The options of the input that picks the method differ from the methods of the pool. | Make the options the method names, no more and no fewer. |
| Required | A key that the format needs is missing. The Problems panel shows a JSON list. | Read the path in the list. It names the missing key. Add that key. |
| Expected number, received string | A schema key has the wrong type. The Problems panel shows a JSON list. | Read the path in the list. It names the key, such as inputs, max_hp, min. Fix that value. |
The Forge lists problems for each file under Problems. A rule problem also names the line and column. A constructor mismatch lists its first differences and ends with how many more were omitted. Fix the listed ones and check again.

