CLI dataclass conventions
Schola training and utility CLIs use cyclopts with dataclasses. Follow these
rules when adding or renaming CLI-bound types in schola.scripts.
Type suffixes
-
*Config— Dataclass definesmake()(and optional helpers such asmake_n_async) that construct a runtime object (simulator, gRPC protocol, etc.). -
*Settings— Nomake(); holds only CLI-visible values (hyperparameters, paths, nested aggregates).
Root command dataclasses use the suffix ScriptSettings (e.g.
Sb3ScriptSettings, RllibScriptSettings, MinariScriptSettings).
Field names
Nested fields on *ScriptSettings and on aggregates such as
EnvironmentSettings use only the pattern <area>_settings (snake_case
_settings), even when the annotated type is*Config. Example:simulator_settings: UnrealExecutableSimulatorConfig,protocol_settings: GrpcProtocolConfig.
Do not use *_config as an attribute name for CLI fields; Config vs
Settings is expressed in the class name, not the field name.
Renaming fields can change CLI flags; treat that as a breaking change unless you add cyclopts aliases.
Cyclopts: Parameter(name=”*”)
-
name="*"(withgroup=where applicable) is the default for user-facing nested dataclass fields on script commands. Inner options appear flat within the same help group, without an extra prefix from the Python field name. -
Omit
name="*"only when you intentionally want nested / longer flag names; document the exception next to the field. -
Meta commands (e.g.
command_template.py) may usename="*"on synthetic parameters so a single token list parses before values are copied intohidden_script_args. -
Explicit
name="something"(not*) is rare: stable CLI after Python renames, disambiguation, or shorter public tokens. Re-check--helpand document.
Rule of thumb: group= selects the help section; name="*" merges inner
fields into that scope. Prefer name="*" + group= consistently across
SB3, RLlib, and Minari training entrypoints.
On the CLI this produces single-level kebab-case flags (for example
--timesteps, --save-final-policy), not dotted paths such as
--training-settings.timesteps. Use schola … --help to confirm spellings
when copying examples from older posts or drafts.
Other
-
Shared hidden nested fields:
IgnoreParameter = Parameter(show=False, parse=False)inschola.scripts.common.settings(e.g.simulator_settingsuntil a subcommand selects the simulator variant). -
Help text: use the string literal immediately after each field (cyclopts convention); keep long prose in class docstrings or Sphinx guides.
-
Sub-apps:
App(name="...", help="...")with kebab-case command names where applicable.