Parse commannds from players and invoke corresponding GameEvents to drive emotes, help systems and macro systems and more.
The Command System works with System Core's GameEvents to enable an easy to use and flexible command system for your next project. Commands can be parsed from string input and used to invoke game events on demand with or without arguments. This can be used for simply player commands such as emotes, chat whisper, help commands, etc. or used to drive more complex systems such as macros and end user scripting.
Create your commands as GameEvents in your asset database, the name of the event will be used as its command text. You can use String Game Event to pass the arguments of a command along with it or you can use the Command Director to parse arguments ahead of time and use more complex or even custom Game Events with detailed parameters.
Once you have your GameEvents defined you link them to a Command Library this represents the set of commands the system will listen for and defines how the commands will be identified. The Command Library can be used to parse through any text searching for matching commands and optionally invoke any command found. You can also use tools such as the Command Director to pass command data into your own systems where you can perform additional logic such as parsing arguments for more complex commands.
Step 1 is always to define your commands. A command is simply a GameEvent and you can use any type of GameEvent you want even custom GameEvents. To learn more about what a GameEvent is please read the Knowedge Base articles on System Core's GameEvents.
Once you have defined your commands your next step is to reference them in your Command Library. A command library is Scriptable Object that lists all the valid commands and how they should be parsed. You can create a new Command Library in your asset folders by right clicking and selecting Create > UX > Commands > Library.
With your library populated your ready to use the system as is, additional tools such as the Command Director are described below.
This object acts as a collection of valid commands and provides the basic logic for parsing text and matching commands.
You can create a new Command Library by right clicking in your asset folder and seleting Create > UX > Commands > Library.
Command Library's fields are
As the name suggests if this is true the system will require the case of the input string to match the name of the GameEvents used as commands.
This is the string that is tested for at the start of input to determine if a command follows. It must be the start of the input string or the input will be ignored e.g.
"echo this is my message"
" /echo this is my message"
"Hi /echo this is my message"
None of the above strings would not result in the echo command being invoked however
"/echo this is my message"
The above text shown here however will match a command named Echo or echo and will pass "this is my message" as the argument.
The command system can be useful for developers, moders and other cases where perhaps the regular end user shouldn't have unrestricted access to the commands. When parsing for commands you can enable or disable checking for all or user only commands this simply means the parse will or will not check the Developer Commands as well as the User Commands. Note if a command matches in both the Developer Command will be taken first if enabled.
This object is simple helper tool that can help you direct input text to the Command Parser and raise an event containing the results of the parse. The main feature of this object is the Evt Command Found event this will be invoked with each successful parse and contains details about the command and arguments found, useful for more complex command uses where you need to apply your own logic before the command is invoked.
A typical use case is to use the OnEndEdit of a standard InputField and connect it to the Command Director's
The fields of the director include
This is a reference to the library that should be used for command parsing
This indicates rather or not the director should test for user only or both user and developer commands
This is an event which is raised when a valid command is parsed
Command data is the object sent when the Command Directory raises its Evt Command Found. Put more simply its the type of data sent in the parameter of that event.
Command Data has the following fields
Indicates rather or not the command is a valid command
A reference to the GameEvent the command matched with
The string following the command text e.g. its arguments. Its up to you to parse this if you want to extract more specific information such as converting it to numbers, splitting multiple parameters out, etc.
The string that was parsed to find this information
You can enable nested commands by handling the results of the Command Director and calling it again on the argument string. Depending on your needs you may want to parse the arguments manually e.g. search for occurrences of where a space is followed by the command start string e.g. something similar to
var commandList = input.Split(", ");
/macro /targetPet, /e pet
This suggests a macro system that is able to take as input multiple commands. You can imagine this might let a user create a button that lets the target there own pet and then perform the pet emote. Macro systems typically work by giving the users a set of modular commands such as targeting commands, emotes, etc that they can string together to perform more complex actions. In this case macro is a command your system is using to understand that the arguments is such a set of modular commands which are them selves commands the Command Directory can parse for ... once you split them apart as desired.
You have multiple ways to parse commands, the most basic is to use the Command Library directly
out GameEvent command,
out string arguments))
//If we get here then command is the game event
//arguments is the string that follows it
The library can also call commands directly e.g. it will parse it as seen above and if found it will go ahead and invoke it if it can.
out string errorMessage))
//If we get here then we called a command
//If we get here we did not call a command ... check errorMessage for details
The TryCallCommand feature is "smart" that is if it finds a command it will check the command type and if the type is something other than void it will attempt to parse the arguments accordingly. Supported types include
- GameEvent This is the void game event type e.g. ignores the arguments
- StringGameEvent This will pass the arguments in to the event as a string
- IntGameEvent This will attempt to parse the arguments to an int
- FloatGameEvent This will attempt to parse the arguments to a float
- BoolGameEvent This will attempt to parse the arguments to a bool
- DoubleGameEvent This will attempt to parse the arguments to a double
Finally you can use the ParseCommand option available on both the Command Library and on the Command Director ... or optionally directly from the CommandData object as a constructor.
var commandData = library.ParseCommand(inputString, userOnly);
var commandData = director.ParseCommand(inputString);
var commandData = new CommandData(library, inputString, userOnly);
Command Data is the object passed by the Command Director's Evt Command Raised event and can be constructed directly by your own logic with a simple single line call as shown the Parsing Commands example above.
Once you have a Command Data object you can use it to invoke the GameEvent represented by the command and to handle any arguments the command might have included.
//Is this command valid?
Debug.Log("Yes it is");
Debug.Log("No it is not");
//What game event does this command use
var gameEvent = data.command;
//What arguments came with the command
var arguments = data.arguments;
//What was the source of the command (its input string)
var source = data.sourceText;
Invoking command data will depend on what kind of command it is. Knowing what type of command it is, is best done by you at development time e.g.
Debug.Log("I know I created this as a GameEvent ... no need to cast here");
Debug.Log("I know I created this as a StringGameEvent");
Debug.Log("I know I created this as something :)");
... etc ...