Controls: Difference between revisions
No edit summary |
|||
| (31 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
== Introduction == | == Introduction == | ||
OpenBOR’s native control scheme is designed to be intuitive as possible and conform to established standards for side scrolling action games. Through various native options and scripting techniques (see below), creators can map these controls to perform any desired action. You can even rename or remove commands entirely to create a unique control scheme specific to your game. In turn, players may map available commands to desired keys or buttons via Control Options in the main menu. | OpenBOR’s native control scheme is designed to be as intuitive as possible and conform to established standards for side scrolling action games. Through various native options and scripting techniques (see below), creators can map these controls to perform any desired action. You can even rename or remove commands entirely to create a unique control scheme specific to your game. In turn, players may map available commands to desired keys or buttons via Control Options in the main menu. | ||
== Default Keys == | == Default Keys == | ||
| Line 98: | Line 98: | ||
disablekey attack4 | disablekey attack4 | ||
</syntaxhighlight> | </syntaxhighlight> | ||
[[File:Controls menu.webp|center|frame|Renaming keys | [[File:Controls menu.webp|center|frame|Renaming keys to match their function in your projects adds a professional touch.]] | ||
== Alternate Command Functions == | == Alternate Command Functions == | ||
| Line 106: | Line 106: | ||
<syntaxhighlight lang="text"> | <syntaxhighlight lang="text"> | ||
com {sequence} {freespecial#} | com {sequence} {freespecial#} | ||
</syntaxhighlight>Enables mapping single button or command sequences to trigger a desired | </syntaxhighlight>Enables mapping single button or command sequences to trigger a desired Freespecial animation. Place <code>com</code> into a model’s text header. You may add multiple commands to a model with no practical limits other than hardware resources. | ||
* '''Sequence''' is the input or sequence of inputs to trigger the command. Each sequence may contain up to sixty-four | * '''Sequence''' is the input or sequence of inputs to trigger the command. Each sequence may contain up to sixty-four steps from the following list. Default in game leeway for command sequences is 50 [[Time#Elapsed Time 2|elapsed time]] ticks, or <code>0.25</code> seconds allowed between each new step: | ||
** <code>f</code> - Left/right (same direction character is facing). | ** <code>f</code> - Left/right (same direction character is facing). | ||
** <code>b</code> - Left/Right (opposite direction character is facing). | ** <code>b</code> - Left/Right (opposite direction character is facing). | ||
| Line 122: | Line 122: | ||
** <code>s</code> - Special. | ** <code>s</code> - Special. | ||
** <code>st</code> - Start. | ** <code>st</code> - Start. | ||
** <code> | ** <code>sc</code> - Screenshot. | ||
** <code>+</code> - Chord input. Ex. <code>a + s</code> means press Attack and Special together. Each chord counts as one sequence | ** <code>+</code> - Chord input. Ex. <code>a + s</code> means press Attack and Special together. Each chord counts as one sequence step, regardless of how many inputs it may encompass. | ||
*** <code>+[int grace time (default 0)]</code> - Optional grace period to press all buttons in a chord. Ex. <code>a + s +[100]</code> allows up to 100 ticks to press <code>a</code> and <code>s</code>. Longer grace periods make commands easier, but may also result in overly delayed activation if players are slow with their fingers and give the game an unresponsive, laggy feeling. Adjust to suit your game needs. | *** <code>+[int grace time (default 0)]</code> - Optional grace period to press all buttons in a chord. Ex. <code>a + s +[100]</code> allows up to 100 ticks to press <code>a</code> and <code>s</code>. Longer grace periods make commands easier, but may also result in overly delayed activation if players are slow with their fingers and give the game an unresponsive, laggy feeling. Adjust to suit your game needs. | ||
** <code>~</code> - Release key. Ex. <code>~a</code> means release Attack. | ** <code>~</code> - Release key. Ex. <code>~a</code> means release Attack. | ||
** <code>[min time (default 0)][max time (default 0)]</code> - Time constraints for holding key. | ** <code>[min time (default 0)][max time (default 0)]</code> - Time constraints for holding a key. Held requirements must share their sequence step with a press, release, or automatic trigger. Maximum time is optional. | ||
*** <code>a[50]</code> - Hold <code>a</code> for at least 50 ticks. | *** <code>a[50]</code> - Hold <code>a</code> for at least 50 ticks. | ||
*** <code>a[50][200]</code> - Hold <code>a</code> for at least 50 ticks, but no more than 200 ticks. | *** <code>a[50][200]</code> - Hold <code>a</code> for at least 50 ticks, but no more than 200 ticks. | ||
*** <code>a[0][200]</code> - Hold <code>a</code> with no minimum hold time, but no more than 200 ticks. | *** <code>a[0][200]</code> - Hold <code>a</code> with no minimum hold time, but no more than 200 ticks. | ||
*** <code>a[0]</code> - Hold <code>a</code> without any time constraints. | *** <code>a[0]</code> - Hold <code>a</code> without any time constraints. | ||
** <code>*[int time]</code> - Auto trigger if held to time. Ex. <code>a*[50]</code> means action triggers automatically after holding a for 50 ticks. | ** <code>*[int time]</code> - Auto trigger if held to time. Ex. <code>a*[50]</code> means action triggers automatically after holding <code>a</code> for 50 ticks. | ||
** <code>:[int time]</code> - Time allowed between sequence | ** <code>:[int time]</code> - Time allowed between sequence steps. Ex. <code>d -> f -> a -> :[100]</code> means you have 100 ticks to enter <code>d</code>, then 100 ticks to enter <code>f</code>, and another 100 to enter <code>a</code>. If not used, the global default applies instead. <code>:[time]</code> may appear once anywhere outside an unfinished <code>+</code> expression and requires at least two sequence steps. Does not count as a sequence step. | ||
** <code>-></code> - Delimiter. Optional, | ** <code>-></code> - Delimiter. Optional, but highly recommended for readability. Does not count as a sequence step. | ||
* '''Freespecial#''' is the animation that plays in response to the command, assuming other conditions are met (i.e. having enough energy if the animation has an energy cost). | * '''Freespecial#''' is the animation that plays in response to the command, assuming other conditions are met (i.e. having enough energy if the animation has an energy cost). | ||
| Line 191: | Line 191: | ||
===== Tips ===== | ===== Tips ===== | ||
Don’t let the name “freespecial” confuse you. | Don’t let the name “freespecial” confuse you. Freespecials are not inherently “special”. You can use them to create any sort of animation you like, from a simple punch or kick, evasive movement, taunt, or whatever else. | ||
Overly exact commands in a side scrolling environment are not necessary and may make your game more spastic to control instead of more precise. For example, to create the classic Hadouken input you should use <code>d -> f -> a</code> rather than <code>d -> d + f -> f -> a</code>. | Overly exact commands in a side scrolling environment are not necessary and may make your game more spastic to control instead of more precise. For example, to create the classic Hadouken input you should use <code>d -> f -> a</code> rather than <code>d -> d + f -> f -> a</code>. | ||
If two or more sequences overlap, the more complex input from the player “wins”. This is the same command scheme seen in most fighting games. Again using the | If two or more sequences overlap, the more complex input from the player “wins”. This is the same command scheme seen in most fighting games. Again using the Hadouken example, you could create a command for the normal Hadouken <code>d -> f -> a</code>, and another for Shinku Hadouken as <code>d -> f -> d -> f -> a</code>. OpenBOR will recognize if a player uses the Shinku Hadouken input even though the last portion of it is identical to the Hadouken input. | ||
=== Cancel === | === Cancel === | ||
<syntaxhighlight lang="text"> | <syntaxhighlight lang="text"> | ||
cancel {int start frame} {int end frame} {int hits} {sequence} {freespecial#} | cancel {int start frame} {int end frame} {int hits} {sequence} {freespecial#} | ||
</syntaxhighlight>Cancel is similar to Command, in that it maps command sequences to activate a | </syntaxhighlight>Cancel is similar to Command, in that it maps command sequences to activate a Freespecial. However, cancels are unique to a single animation and can interrupt the animation on a successful input. This allows “canceling” from one animation to another for customized chains and combos. | ||
Place cancels into the animation header of any Jump, Attack, Freespecial, or Follow animation. You may add as many cancels as you like to an animation to give it multiple cancel options. The animation you cancel into may also have its own cancels to create an entire series of combo branch points. | Place cancels into the animation header of any Jump, Attack, Freespecial, or Follow animation. You may add as many cancels as you like to an animation to give it multiple cancel options. The animation you cancel into may also have its own cancels to create an entire series of combo branch points. | ||
| Line 208: | Line 208: | ||
* '''Hits -''' Required number of combo hits, if any, before cancel is available. | * '''Hits -''' Required number of combo hits, if any, before cancel is available. | ||
* '''Sequence -''' Identical to [[Controls#Command|command]] sequence parameter. | * '''Sequence -''' Identical to [[Controls#Command|command]] sequence parameter. | ||
* ''' | * '''Freespecial# -''' Identical to [[Controls#Command|command]] Freespecial# parameter. | ||
Cancel is otherwise identical to Command and follows the same rules (input sequence, energy cost, etc.). | Cancel is otherwise identical to Command and follows the same rules (input sequence, energy cost, etc.). | ||
=== Script API === | |||
Command sequences defined by <code>com</code> and <code>cancel</code> are stored in each model structure’s command collection. See [[Controls#Command Input Sequence|Command Input Sequence]] below for access details. The command history used to match player inputs against these sequences is stored in the player structure. See [[Player Property#Command Buffer|Command Buffer]] in [[Player Property]] for access details. | |||
== Maximum Freespecials == | == Maximum Freespecials == | ||
| Line 260: | Line 263: | ||
== Key Control Constants == | == Key Control Constants == | ||
=== Key Constants === | === Key ID Constants === | ||
Each key press sent from the control reading layer maps to one of the following constants. These are usually not used by creators unless you are capturing and manipulating the detected keys with InputAll (see below). | Each key press sent from the control reading layer maps to one of the following constants. These are usually not used by creators unless you are capturing and manipulating the detected keys with InputAll (see below). | ||
| Line 277: | Line 280: | ||
* <code>openborconstant("SDID_START")</code> - Start key. | * <code>openborconstant("SDID_START")</code> - Start key. | ||
=== | === Key Flag Constants === | ||
Once OpenBOR has detected a physical key press, it is mapped and stored using the following event constants. These are then used to execute the appropriate in game action. You may in turn use these constants to evaluate and even manipulate detected events (see below). | Once OpenBOR has detected a physical key press, it is mapped and stored using the following event constants. These are then used to execute the appropriate in game action. You may in turn use these constants to evaluate and even manipulate detected events (see below). Note these constants are actually bit masks. | ||
* <code>openborconstant("FLAG_ATTACK")</code> - Attack key. | * <code>openborconstant("FLAG_ATTACK")</code> - Attack key. | ||
| Line 299: | Line 302: | ||
== Key Events == | == Key Events == | ||
OpenBOR provides layered script hooks for intercepting and responding to player input. These include the global InputAll preprocessor, level and model <code>keyscript</code>, per-player <code>key#.c</code> files, and global <code>keyall.c</code>. Each layer executes before native gameplay input handling, allowing creators to observe, supplement, redirect, or replace default control behavior. | |||
OpenBOR | |||
Player input is represented by bit masks for held, newly pressed, newly released, pending native play, and disabled controls. Scripts may inspect these values with <code>playerkeys()</code> or player properties, and may alter the masks when input must be transformed or consumed. | |||
See [[Key Scripts]] for the complete reference, including execution order, scope, event data, key states, <code>keyscriptrate</code>, input cancellation, and examples. | |||
== Command | == Command Input Sequence == | ||
Command sequences are part of a model structure and define the sequences recognized while an entity spawned from the model is under player control. Each <code>com</code> or <code>cancel</code> mapping stores its input sequence as an array containing up to sixty-four command input steps. Each step describes the input edges, held-key requirements, and timing restrictions that must be satisfied together. | |||
Inputs joined with <code>+</code> occupy the same sequence step. For example, <code>a + j</code> stores the Attack and Jump flags together in the step's Press property. Sequence steps are stored in chronological order, with index <code>0</code> representing the first step. | |||
Sequence syntax is represented internally as follows: | |||
* Ordinary key input - Press property. | |||
* <code>~key</code> - Release property. | |||
* <code>key[min][max]</code> - Hold, Hold Time, and Hold Time Maximum properties. | |||
* <code>key*[time]</code> - Hold Trigger and Hold Time properties. | |||
* <code>+[time]</code> - Chord Time property. | |||
* <code>+</code> - Combines input flags into the same step. | |||
* <code>-></code> - Readability delimiter only. It is not stored. | |||
* <code>:[time]</code> - Applies to the complete command and is stored by the parent <code>com</code>/<code>cancel</code> structure rather than an individual step. | |||
=== Get Sequence Step === | |||
Once you have obtained the input-sequence pointer from a <code>com</code> or <code>cancel</code> structure, supply an index from <code>0</code> through <code>63</code> to obtain an individual step pointer. | |||
Unlike the command buffer, the sequence array is not a ring. Indexes follow the command's chronological input order. Only indexes below the parent command's step count belong to the loaded sequence. | |||
<syntaxhighlight lang="c" line="1"> | |||
int index = 2; // 0 - 63 | |||
int index = 2; // 0 - | |||
void | void sequence_step = get_command_input_step_object(command_sequence, index); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== | === Sequence Step Properties === | ||
Once you have obtained a | Once you have obtained a sequence-step pointer, use <code>get_command_input_step_property()</code> and <code>set_command_input_step_property()</code> to read or modify its members. Key flags and timing properties use unsigned 64-bit integer values. | ||
<syntaxhighlight lang="c" line="1"> | |||
// Get the required press flags. | |||
// Get | int step_press = get_command_input_step_property(sequence_step, openborconstant("COMMAND_INPUT_STEP_PROPERTY_PRESS")); | ||
int | |||
// | // Require Attack and Jump in the same step. | ||
int | int new_step_press = openborconstant("FLAG_ATTACK") | openborconstant("FLAG_JUMP"); | ||
// Set the required press flags. | |||
set_command_input_step_property(sequence_step, openborconstant("COMMAND_INPUT_STEP_PROPERTY_PRESS"), new_step_press); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
= | {| class="wikitable sortable" | ||
|+Sequence Step Properties | |||
!Property | |||
!Description | |||
|- | |||
|<code>COMMAND_INPUT_STEP_PROPERTY_PRESS</code> | |||
|Key flags requiring a positive edge. Multiple flags form a press chord. | |||
|- | |||
|<code>COMMAND_INPUT_STEP_PROPERTY_HOLD</code> | |||
|Key flags that must be held when the step's triggering edge occurs. This is a passive requirement and cannot trigger a step by itself. | |||
|- | |||
|<code>COMMAND_INPUT_STEP_PROPERTY_HOLD_TRIGGER</code> | |||
|Key flags that automatically produce an input edge upon reaching Hold Time. | |||
|- | |||
|<code>COMMAND_INPUT_STEP_PROPERTY_RELEASE</code> | |||
|Key flags requiring a negative edge. | |||
|- | |||
|<code>COMMAND_INPUT_STEP_PROPERTY_HOLD_TIME</code> | |||
|Inclusive minimum held duration in elapsed-time ticks. For Hold Trigger flags, this is the exact automatic-trigger threshold. | |||
|- | |||
|<code>COMMAND_INPUT_STEP_PROPERTY_HOLD_TIME_MAXIMUM</code> | |||
|Inclusive maximum duration for passive Hold flags. Zero removes the maximum. | |||
|- | |||
|<code>COMMAND_INPUT_STEP_PROPERTY_CHORD_TIME</code> | |||
|Maximum elapsed-time span allowed among the Press flags forming a chord. Zero requires the presses to occur on the same logical tick. | |||
|} | |||
[[Category:Openbor]] | [[Category:Openbor]] | ||
[[Category:Script]] | |||
Latest revision as of 14:32, 20 August 2026
Introduction
OpenBOR’s native control scheme is designed to be as intuitive as possible and conform to established standards for side scrolling action games. Through various native options and scripting techniques (see below), creators can map these controls to perform any desired action. You can even rename or remove commands entirely to create a unique control scheme specific to your game. In turn, players may map available commands to desired keys or buttons via Control Options in the main menu.
Default Keys
OpenBOR allots each player the following inputs and default mappings.
Left
- Move player left on screen.
- Cycle to previous column or option on current row in menus.
- Cycle to previous character during player select.
Right
- Move player right on screen.
- Cycle to next column or option on current row in menus.
- Cycle to next character during player select.
Up
- Moves player up on screen (along Z axis) in pseudo 3D stages.
- Cycle upward through rows in menus.
- Cycle to previous color palette during player select.
Down
- Moves player down on screen (along Z axis) in pseudo 3D stages.
- Crouch/Duck in 2D stages.
- Cycle downward through rows in menus.
- Cycle to next color palette during player select.
Special
- Player Special.
- Blocking if enabled (see ajspecial below).
Jump
- Player Jumping.
Attack 1
- Basic attack.
- Confirm a selection.
- Pick up items.
Attack 2 - Unused.
Attack 3 - Unused.
Attack 4 - Unused.
Start
- Begin or continue a game.
- Join multiplayer game in progress (if not an active player).
- Pause/resume game in progress (if an active player).
Screenshot
- Send a screen capture to Screenshots folder.
- Access main menu during game pause.
In addition, there is a universal Escape key:
- Cycle to previous page in menu.
- Exit player select and return to main menu.
- Shut down engine when not in game or in a menu.
- Resume a paused game.
Renaming Keys
You can rename keys by adding a file to the data folder named menu.txt. Use the following commands in the menu.txt file to customize or remove keys.
renamekey {target command} {new name}disablekey {target command}
Accepted keys for rename or removal:
moveupmovedownmoverightmoveleftattackattack2attack3attack4jumpspecialstartscreenshot
In this example, menu.txt renames Special to Defend and Attack 2 to Magic, while removing unused commands Attack 3 and Attack 4. This presents the player with a more polished set of controls that match actual in game functionality.
renamekey attack Attack
renamekey attack2 Magic
renamekey special Defend
disablekey attack3
disablekey attack4

Alternate Command Functions
You can add to or change the existing functionality of commands entirely. Common examples include adding additional attacks mapped to the normally unused Attack 2+ commands, remapping the player special, or special move sequences.
Command
com {sequence} {freespecial#}
Enables mapping single button or command sequences to trigger a desired Freespecial animation. Place com into a model’s text header. You may add multiple commands to a model with no practical limits other than hardware resources.
- Sequence is the input or sequence of inputs to trigger the command. Each sequence may contain up to sixty-four steps from the following list. Default in game leeway for command sequences is 50 elapsed time ticks, or
0.25seconds allowed between each new step:f- Left/right (same direction character is facing).b- Left/Right (opposite direction character is facing).l- Left.r- Right.u- Up.d- Down.a- Attack 1.a2- Attack 2.a3- Attack 3.a4- Attack 4.j- Jump.s- Special.st- Start.sc- Screenshot.+- Chord input. Ex.a + smeans press Attack and Special together. Each chord counts as one sequence step, regardless of how many inputs it may encompass.+[int grace time (default 0)]- Optional grace period to press all buttons in a chord. Ex.a + s +[100]allows up to 100 ticks to pressaands. Longer grace periods make commands easier, but may also result in overly delayed activation if players are slow with their fingers and give the game an unresponsive, laggy feeling. Adjust to suit your game needs.
~- Release key. Ex.~ameans release Attack.[min time (default 0)][max time (default 0)]- Time constraints for holding a key. Held requirements must share their sequence step with a press, release, or automatic trigger. Maximum time is optional.a[50]- Holdafor at least 50 ticks.a[50][200]- Holdafor at least 50 ticks, but no more than 200 ticks.a[0][200]- Holdawith no minimum hold time, but no more than 200 ticks.a[0]- Holdawithout any time constraints.
*[int time]- Auto trigger if held to time. Ex.a*[50]means action triggers automatically after holdingafor 50 ticks.:[int time]- Time allowed between sequence steps. Ex.d -> f -> a -> :[100]means you have 100 ticks to enterd, then 100 ticks to enterf, and another 100 to entera. If not used, the global default applies instead.:[time]may appear once anywhere outside an unfinished+expression and requires at least two sequence steps. Does not count as a sequence step.->- Delimiter. Optional, but highly recommended for readability. Does not count as a sequence step.
- Freespecial# is the animation that plays in response to the command, assuming other conditions are met (i.e. having enough energy if the animation has an energy cost).
Example Sequences
| Command | Result |
|---|---|
com a2 freespecial1
|
Press Attack 2. |
com d -> f -> a freespecial1
|
Press Down, then Forward, then Attack. |
com a + j freespecial1
|
Press Attack and Jump on the same tick. |
com a + j +[100] freespecial1
|
Press Attack and Jump within 100 ticks of each other. |
com ~a freespecial1
|
Release Attack. |
com f[0] + a freespecial1
|
Hold Forward and press Attack. |
com f[50] + a freespecial1
|
Hold Forward for at least 50 ticks, then press Attack while still holding Forward. |
com a[0] + j freespecial1
|
Hold Attack for any duration and press Jump. |
com a[0][200] + j freespecial1
|
Press Jump while Attack has been held for no more than 200 ticks. |
com a[50][200] + j freespecial1
|
Press Jump while Attack has been held for 50 through 200 ticks. |
com a[50] + ~a freespecial1
|
Hold Attack for at least 50 ticks, then release it. |
com a[50][200] + ~a freespecial1
|
Release Attack after holding it for 50 through 200 ticks. |
com a*[50] freespecial1
|
Trigger automatically when Attack has been held for 50 ticks. |
com f -> ~f freespecial1
|
Press Forward, then release Forward. |
com b[60][180] + ~b -> f + a freespecial1
|
Hold Back for 60 through 180 ticks, release it, then press Forward and Attack together. |
com b[60][180] + ~b -> f + a +[20] freespecial1
|
Perform the same charge command with a 20-tick grace period for the Forward and Attack chord. |
Tips
Don’t let the name “freespecial” confuse you. Freespecials are not inherently “special”. You can use them to create any sort of animation you like, from a simple punch or kick, evasive movement, taunt, or whatever else.
Overly exact commands in a side scrolling environment are not necessary and may make your game more spastic to control instead of more precise. For example, to create the classic Hadouken input you should use d -> f -> a rather than d -> d + f -> f -> a.
If two or more sequences overlap, the more complex input from the player “wins”. This is the same command scheme seen in most fighting games. Again using the Hadouken example, you could create a command for the normal Hadouken d -> f -> a, and another for Shinku Hadouken as d -> f -> d -> f -> a. OpenBOR will recognize if a player uses the Shinku Hadouken input even though the last portion of it is identical to the Hadouken input.
Cancel
cancel {int start frame} {int end frame} {int hits} {sequence} {freespecial#}
Cancel is similar to Command, in that it maps command sequences to activate a Freespecial. However, cancels are unique to a single animation and can interrupt the animation on a successful input. This allows “canceling” from one animation to another for customized chains and combos.
Place cancels into the animation header of any Jump, Attack, Freespecial, or Follow animation. You may add as many cancels as you like to an animation to give it multiple cancel options. The animation you cancel into may also have its own cancels to create an entire series of combo branch points.
- Start Frame - The first frame in animation when cancel is available - Remember that frames are 0 indexed.
- End Frame - The last frame in animation when cancel is available.
- Hits - Required number of combo hits, if any, before cancel is available.
- Sequence - Identical to command sequence parameter.
- Freespecial# - Identical to command Freespecial# parameter.
Cancel is otherwise identical to Command and follows the same rules (input sequence, energy cost, etc.).
Script API
Command sequences defined by com and cancel are stored in each model structure’s command collection. See Command Input Sequence below for access details. The command history used to match player inputs against these sequences is stored in the player structure. See Command Buffer in Player Property for access details.
Maximum Freespecials
maxfreespecials {int}
#default
maxfreespecials 8
Models.txt command that sets the highest numbered freespecial animation available globally. The default and minimum value is 8. For example, maxfreespecials 12 enables animation identifiers freespecial1 through freespecial12.
Tip: You may allocate any number, but don't set some silly amount like 100 when you only need a few more freespecial animations. This wastes memory. Figure out what you actually need and allocate accordingly.
Attack and Jump Special
ajspecial {flags}
#default
ajspecial special
Controls mapping of the native breakaway special attack and enables blocking for players. Accepts one of the following:
special(default) – Special attack mapped to Special key.double– Special attacks mapped to Attack + Jump. Blocking enabled (if entity has a Block animation) and mapped to Special key.attack2– Special attack mapped to Attack 2 key.attack3– Special attack mapped to Attack 3 key.attack4– Special attack mapped to Attack 4 key.
Ajspecial is exposed to script as a global_config property. Use the following constants:
openborconstant("AJSPECIAL_KEY_SPECIAL")openborconstant("AJSPECIAL_KEY_DOUBLE")openborconstant("AJSPECIAL_KEY_ATTACK2")openborconstant("AJSPECIAL_KEY_ATTACK3")openborconstant("AJSPECIAL_KEY_ATTACK4")
void config = openborvariant("global_config");
int value = get_global_config(config, "ajspecial");
value = openborconstant("AJSPECIAL_KEY_ATTACK3");
set_global_config(config, "ajspecial", value);
Legacy
Prior to OpenBOR 4.0, ajspecial accepted only the following:
0(default) – Special attack mapped to Special key.1– Special attacks mapped to Attack + Jump. Blocking enabled (if entity has a Block animation) and mapped to Special key.
Key Control Constants
Key ID Constants
Each key press sent from the control reading layer maps to one of the following constants. These are usually not used by creators unless you are capturing and manipulating the detected keys with InputAll (see below).
openborconstant("SDID_ATTACK")- Attack key.openborconstant("SDID_ATTACK2")- Attack 2 key.openborconstant("SDID_ATTACK3")- Attack 3 key.openborconstant("SDID_ATTACK4")- Attack 4 key.openborconstant("SDID_ESC")- Escape key.openborconstant("SDID_JUMP")- Jump key.openborconstant("SDID_MOVEDOWN")- Move down key.openborconstant("SDID_MOVELEFT")- Move left key.openborconstant("SDID_MOVERIGHT")- Move right key.openborconstant("SDID_MOVEUP")- Move up key.openborconstant("SDID_SCREENSHOT")- Screenshot key.openborconstant("SDID_SPECIAL")- Special key.openborconstant("SDID_START")- Start key.
Key Flag Constants
Once OpenBOR has detected a physical key press, it is mapped and stored using the following event constants. These are then used to execute the appropriate in game action. You may in turn use these constants to evaluate and even manipulate detected events (see below). Note these constants are actually bit masks.
openborconstant("FLAG_ATTACK")- Attack key.openborconstant("FLAG_ATTACK2")- Attack 2 key.openborconstant("FLAG_ATTACK3")- Attack 3 key.openborconstant("FLAG_ATTACK4")- Attack 4 key.openborconstant("FLAG_ANYBUTTON")- Shortcut for any action key (jump, special, any attack).openborconstant("FLAG_BACKWARD")- Left or right key in opposite direction player's controlled entity faces.openborconstant("FLAG_CONTROLKEYS")- Shortcut for any game control (anything other than Start, Screenshot, or Escape).openborconstant("FLAG_ESC")- Escape key.openborconstant("FLAG_FORWARD")- Left or right key in same direction player's controlled entity faces.openborconstant("FLAG_JUMP")- Jump key.openborconstant("FLAG_MOVEDOWN")- Down key.openborconstant("FLAG_MOVELEFT")- Left key.openborconstant("FLAG_MOVERIGHT")- Right key.openborconstant("FLAG_MOVEUP")- Up key.openborconstant("FLAG_SCREENSHOT")- Screenshot key.openborconstant("FLAG_SPECIAL")- Special key.openborconstant("FLAG_START")- Start key.
Key Events
OpenBOR provides layered script hooks for intercepting and responding to player input. These include the global InputAll preprocessor, level and model keyscript, per-player key#.c files, and global keyall.c. Each layer executes before native gameplay input handling, allowing creators to observe, supplement, redirect, or replace default control behavior.
Player input is represented by bit masks for held, newly pressed, newly released, pending native play, and disabled controls. Scripts may inspect these values with playerkeys() or player properties, and may alter the masks when input must be transformed or consumed.
See Key Scripts for the complete reference, including execution order, scope, event data, key states, keyscriptrate, input cancellation, and examples.
Command Input Sequence
Command sequences are part of a model structure and define the sequences recognized while an entity spawned from the model is under player control. Each com or cancel mapping stores its input sequence as an array containing up to sixty-four command input steps. Each step describes the input edges, held-key requirements, and timing restrictions that must be satisfied together.
Inputs joined with + occupy the same sequence step. For example, a + j stores the Attack and Jump flags together in the step's Press property. Sequence steps are stored in chronological order, with index 0 representing the first step.
Sequence syntax is represented internally as follows:
- Ordinary key input - Press property.
~key- Release property.key[min][max]- Hold, Hold Time, and Hold Time Maximum properties.key*[time]- Hold Trigger and Hold Time properties.+[time]- Chord Time property.+- Combines input flags into the same step.->- Readability delimiter only. It is not stored.:[time]- Applies to the complete command and is stored by the parentcom/cancelstructure rather than an individual step.
Get Sequence Step
Once you have obtained the input-sequence pointer from a com or cancel structure, supply an index from 0 through 63 to obtain an individual step pointer.
Unlike the command buffer, the sequence array is not a ring. Indexes follow the command's chronological input order. Only indexes below the parent command's step count belong to the loaded sequence.
int index = 2; // 0 - 63
void sequence_step = get_command_input_step_object(command_sequence, index);
Sequence Step Properties
Once you have obtained a sequence-step pointer, use get_command_input_step_property() and set_command_input_step_property() to read or modify its members. Key flags and timing properties use unsigned 64-bit integer values.
// Get the required press flags.
int step_press = get_command_input_step_property(sequence_step, openborconstant("COMMAND_INPUT_STEP_PROPERTY_PRESS"));
// Require Attack and Jump in the same step.
int new_step_press = openborconstant("FLAG_ATTACK") | openborconstant("FLAG_JUMP");
// Set the required press flags.
set_command_input_step_property(sequence_step, openborconstant("COMMAND_INPUT_STEP_PROPERTY_PRESS"), new_step_press);
| Property | Description |
|---|---|
COMMAND_INPUT_STEP_PROPERTY_PRESS
|
Key flags requiring a positive edge. Multiple flags form a press chord. |
COMMAND_INPUT_STEP_PROPERTY_HOLD
|
Key flags that must be held when the step's triggering edge occurs. This is a passive requirement and cannot trigger a step by itself. |
COMMAND_INPUT_STEP_PROPERTY_HOLD_TRIGGER
|
Key flags that automatically produce an input edge upon reaching Hold Time. |
COMMAND_INPUT_STEP_PROPERTY_RELEASE
|
Key flags requiring a negative edge. |
COMMAND_INPUT_STEP_PROPERTY_HOLD_TIME
|
Inclusive minimum held duration in elapsed-time ticks. For Hold Trigger flags, this is the exact automatic-trigger threshold. |
COMMAND_INPUT_STEP_PROPERTY_HOLD_TIME_MAXIMUM
|
Inclusive maximum duration for passive Hold flags. Zero removes the maximum. |
COMMAND_INPUT_STEP_PROPERTY_CHORD_TIME
|
Maximum elapsed-time span allowed among the Press flags forming a chord. Zero requires the presses to occur on the same logical tick. |