LLFS Command Execution Specification - wwestlake/Labyrinth GitHub Wiki
LLFS commands will be executed within the context of both the user (authenticated player) and the character (in-game avatar). We will manage these contexts through the following components:
The user context includes:
- Identity: The authenticated user's ID (from the authentication system).
- Claims: The user's claims, such as permissions, roles, etc.
- Session: Information about the current user session, such as active connections.
The User Context will be passed along with each command as:
{
"userId": "user-12345",
"userClaims": {
"roles": ["Admin", "Player"],
"permissions": ["can_move", "can_attack"]
}
}
The character context includes:
- Character ID: The in-game avatar's ID.
- Character Attributes: Properties such as health, strength, inventory, etc.
- Character Status: Current status (e.g., "alive", "stunned").
The Character Context is represented as:
{
"characterId": "char-67890",
"attributes": {
"health": 100,
"strength": 15,
"inventory": ["sword", "shield"]
},
"status": "alive"
}
The LLFS command execution involves the following steps:
When a command is compiled, it will output an executable function with any variable or expression resolved. The compiled command needs to be associated with both the user and character contexts for execution.
To execute a compiled command, the system should:
- Validate the user and character contexts.
- Check the user's permissions to ensure they are allowed to execute the command.
- Execute the command with the relevant character state.
Each compiled command is passed to an executor along with the contexts:
executeCommand(compiledCommand, userContext, characterContext)
Before execution, the command must be validated:
- User Role and Claims Check: Ensure the user has sufficient rights to perform the action.
- Character Status Check: Ensure the character is able to perform the action (e.g., not stunned or dead).
Validation logic:
function validateCommand(userContext, characterContext, compiledCommand) {
if (!userContext.userClaims.permissions.includes(compiledCommand.requiredPermission)) {
throw new Error("Permission Denied");
}
if (characterContext.status !== "alive") {
throw new Error("Character cannot act in current state");
}
}
After validation, the compiled command is executed within the character's context. This may include modifying character attributes, interacting with other game objects, or sending responses to the user.
Example execution flow:
function executeCommand(compiledCommand, userContext, characterContext) {
// Validate command first
validateCommand(userContext, characterContext, compiledCommand);
// Execute the compiled command logic
const result = compiledCommand.execute(characterContext);
// Update character state or handle results
updateCharacterState(characterContext, result);
return result;
}
The result of executing a command may include:
- Updating the game world.
- Sending feedback to the user (e.g., "You successfully moved north").
- Triggering other events in the game.
Example output handling:
function handleCommandOutput(result, userContext) {
// Send the result back to the user
sendFeedbackToUser(userContext.userId, result.message);
// Broadcast changes to the game world if applicable
if (result.worldChanges) {
broadcastToGameWorld(result.worldChanges);
}
}
The compiled form of the go <direction>
command will include logic to move the character and any conditions that need to be checked before the move is executed.
const compiledGoCommand = {
name: "go",
requiredPermission: "can_move",
execute: function(characterContext) {
if (characterContext.attributes.health <= 0) {
return { success: false, message: "You are too weak to move!" };
}
// Perform the move logic
const newPosition = moveCharacter(characterContext, "north");
return { success: true, message: "You move north.", worldChanges: { position: newPosition } };
}
};
When the player types go north
, the following steps occur:
- The command is parsed and compiled into
compiledGoCommand
. - The
executeCommand
function is invoked with the compiled command, user context, and character context. - The system checks if the user has the "can_move" permission and if the character is alive.
- If valid, the command is executed, and the character's position is updated.
- The result of the command is returned to the user and optionally broadcast to other players.
const result = executeCommand(compiledGoCommand, userContext, characterContext);
handleCommandOutput(result, userContext);
Any errors during command validation or execution should be caught and logged for auditing or debugging purposes.
function executeCommandWithErrorHandling(compiledCommand, userContext, characterContext) {
try {
return executeCommand(compiledCommand, userContext, characterContext);
} catch (error) {
logError(error, userContext, characterContext);
return { success: false, message: "An error occurred while executing the command." };
}
}
Logs will capture the user's identity, character context, and the specific error encountered.
function logError(error, userContext, characterContext) {
console.error(`Error for user ${userContext.userId} on character ${characterContext.characterId}:`, error);
}
- User and Character Contexts: Commands are executed in the context of both the authenticated user and their in-game character.
- Command Validation: Commands are validated for permissions and character status before execution.
- Execution Workflow: Commands are compiled, executed, and the results are handled, including feedback to the user and updates to the game world.
- Error Handling: Errors during execution are logged, and the user is informed.