Problem/Opportunity Space
Currently commands in an alias sequence are static strings. Users have no way to dynamically insert context-sensitive information such as their current job, character name, or active Penumbra collection into a command at execution time. This limits the usefulness of aliases for workflows that depend on the current game state, such as switching gear sets, toggling glamours, or sending contextual messages.
Acceptance Criteria
- Users can insert variables into command strings using a defined syntax (e.g.
{job}, {character}, {world})
- Variables are resolved at execution time, not at definition time
- Unresolved variables (e.g. unsupported or unavailable) are either left as-is or replaced with a configurable fallback
- Variable syntax is documented and discoverable in the UI
- Existing aliases without variables are completely unaffected
Suggested solution
At execution time in CommandHandler.ExecuteAsync, before firing each command, run it through a variable resolution pass. This pass checks for known variable tokens in the command string and replaces them with the current game state values fetched via Dalamud's service APIs.
Suggested design
- Define a
VariableResolver class in Services/ responsible for resolving all supported variables
- Variable syntax:
{variableName} - curly brace delimited, case insensitive
- Initial supported variables:
{job} - current job abbreviation (e.g. WHM, DRK)
{character} - current character name
{world} - current home world name
{level} - current character level
{collection} - active Penumbra collection name (if Penumbra is installed, via IPC)
CommandHandler.ExecuteAsync passes each command through VariableResolver.Resolve() before execution
- Add a variables reference tooltip or help text in
EditWindow listing available variables
- Penumbra collection variable should only resolve if Penumbra IPC is available, gracefully falling back if not installed
Would Like to Have
- User defined variables - allow users to define their own named variables with static values in the Settings window (e.g.
{myname} → Oreo). These would be stored in Configuration as a Dictionary<string, string> and resolved alongside the built-in variables. This would be useful for things like custom titles, linkshell names, or any repeated string the user wants to centralise and reuse across multiple aliases.
Testing Considerations
Happy path
Sad path
Problem/Opportunity Space
Currently commands in an alias sequence are static strings. Users have no way to dynamically insert context-sensitive information such as their current job, character name, or active Penumbra collection into a command at execution time. This limits the usefulness of aliases for workflows that depend on the current game state, such as switching gear sets, toggling glamours, or sending contextual messages.
Acceptance Criteria
{job},{character},{world})Suggested solution
At execution time in
CommandHandler.ExecuteAsync, before firing each command, run it through a variable resolution pass. This pass checks for known variable tokens in the command string and replaces them with the current game state values fetched via Dalamud's service APIs.Suggested design
VariableResolverclass inServices/responsible for resolving all supported variables{variableName}- curly brace delimited, case insensitive{job}- current job abbreviation (e.g.WHM,DRK){character}- current character name{world}- current home world name{level}- current character level{collection}- active Penumbra collection name (if Penumbra is installed, via IPC)CommandHandler.ExecuteAsyncpasses each command throughVariableResolver.Resolve()before executionEditWindowlisting available variablesWould Like to Have
{myname}→Oreo). These would be stored inConfigurationas aDictionary<string, string>and resolved alongside the built-in variables. This would be useful for things like custom titles, linkshell names, or any repeated string the user wants to centralise and reuse across multiple aliases.Testing Considerations
Happy path
{job}resolves to the correct job abbreviation at execution time{character}resolves to the correct character name{world}resolves to the correct home world{level}resolves to the correct character level{collection}resolves correctly when Penumbra is installedSad path
{collection}falls back gracefully when Penumbra is not installed{job) does not crash the resolver