Skip to content

Run game commands from standard input outside headless mode - #670

Merged
stanoddly merged 1 commit into
mainfrom
stdin-commands-non-headless
Oct 27, 2026
Merged

stanoddly merged 1 commit into
mainfrom
stdin-commands-non-headless

Conversation

@botoddly

Copy link
Copy Markdown
Collaborator

A game's AutomationCommands ran only in headless mode. This lets a game run them, for example cheats, from standard input while it runs normally: windows shown, physical input, real clock.

#if DEBUG
bool enableCommandConsole = true;
builder.AddSingleton<AutomationCommand, GodModeCommand>();
#else
bool enableCommandConsole = false;
#endif
builder.AddSingleton(new PixelyConfig(EnableCommandConsole: enableCommandConsole));

Typing god and Enter in the terminal of dotnet run then runs the command in the next frame.

API

  • PixelyConfig.EnableCommandConsole, the last constructor parameter, false by default.
  • PIXELY_COMMAND_CONSOLE overrides it, with the same values as the other boolean PIXELY_* variables.

Behavior

AutomationCommandConsole runs at UpdateOrders.Input, like the headless console.

  • A background thread reads standard input, so a frame never waits for it. Each frame runs the commands read since the frame before.
  • A newline ends a command as well as ;.
  • Only game commands, with an optional @<n>, and quit run. The built-in input, screenshot and wait commands are unknown here.
  • An unknown command, an invalid @<n>, or a FormatException from Execute is written to standard error and the app goes on. Any other exception ends the app, as in headless mode.
  • The end of the input ends only the console; the app keeps running.
  • With PixelyConfig.Headless the setting does nothing, because headless mode has its own console. In the browser it does nothing either: the console is not registered there, and the setting raises no error.

The @<n> parsing and game command dispatch moved from InputAutomationCommandInterpreter to AutomationCommandRegistry, so both consoles share them. Headless behavior is unchanged.

Not included

The reading thread is not stopped when the app is disposed. A read blocked on a terminal cannot be cancelled, and the thread is a background thread, so it does not keep the process alive. It matters only for a process that runs a second app with the console on.

…lyConfig.EnableCommandConsole or PIXELY_COMMAND_CONSOLE
@stanoddly
stanoddly merged commit fb0cbe6 into main Oct 27, 2026
3 checks passed
@stanoddly
stanoddly deleted the stdin-commands-non-headless branch October 27, 2026 09:40
@github-actions

Copy link
Copy Markdown

📦 Development package Pixely 0.0.147 is available.

Workflow run (attempt 1)

@github-actions

Copy link
Copy Markdown

✅ Development package validation passed on all platforms.

Workflow run (attempt 1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants