TappingKey¶
An input mashing prompt where the input can be one of the 4 main ones (Confirm, Cancel, Switch Party or Show HUD) or be a prompt where the player needs to alternate between the left and right input (with caveats, see the sections below for details). Each correct input press increases barfill
from 0.0 to 1.0. The goal of the command is to make barfill
reach 1.0 before the timer
expires.
NOTE: This action command will be overriden to SequentialKeys if MainManager.
mashcommandalt
is true (the game settings are configured for Sequential Keys commands instead of the mashing ones). Ifdata[9]
exists, the SequentialKeys command will have adata
of {data[9]
} which allows to configure the number of inputs (without hiding the future inputs) in case of override. Ifdata[9]
doesn't exist, the command will have adata
of {6.0} meaning a series of 6 inputs without hiding the future inputs.NOTE: This action command exceptionally sets
overridechallengeblock
to true which allows regular blocks to be processed in DoDamage when FRAMEONE is active. This only happens if the action command was not overriden to SequentialKeys.
timer
usage¶
This represents the amount of frames to give to the player before the command fails. A value of -1.0 means inifnite time where it is not possible to fail the command.
data
array¶
data[0]
: If after being truncated to int, it's -1, this is a left/right input mashing prompt. If it's between 0 and 3 inclusive after truncating to int, it's an input mashing prompt whose id corresponds to the value + 4. NOTE: any value of 4.0 or above is considered invalid and will cause an exception to be thrown. This is because only the 4 face buttons inputs (confirm, cancel, switch and show HUD) are supported which have ids from 4 to 7data[1]
: A multiplier that controls how muchbarfill
is incremented each correct input press. It changes the fraction of the game's frametime to use in the calculation formula meaning 1.0 will use the game's frametime directly. Additionally, ifdata[0]
is not -1 after being truncated to int,data[2]
will effectively be clamped from 0.005 to 0.0025 *data[1]
when calculating the decrease ofbarfill
every frame. The specific increase formula ofbarfill
on a correct input press depends on the game's settings:- With VSync off and the framerate set to 60 FPS, 1.0 means
barfill
increases by the game's frametime / 80.0 - With VSync off and the framerate set to 30 FPS, 1.0 means
barfill
increases by the game's frametime / 40.0 - With Vsync on, 1.0 means
barfill
increases by the game's frametime / 80.0 * (The monitor's refresh rate / 60.0). NOTE: This implies that the monitor's refresh rate acts as a multiplier on top ofdata[1]
's value if VSync is on
- With VSync off and the framerate set to 60 FPS, 1.0 means
data[2]
: Ifdata[0]
is not -1 after being truncated to int,barfill
will decrease every frame by a fraction of the game's frametime equal to 0.005 * this value. However, when calculating the decrease, it will be clamped from 0.005 to 0.0025 *data[1]
. Ifdata[0]
is -1 after being truncated to int, this does nothingdata[3]
: This value does nothing, but its existence in the array is mandatory because if it is not present, it becomes impossible for the command to succeed, even ifbarfill
reaches 1.0data[9]
: See the note above about the SequentialKeys override. This value only applies here and it does require to supply dummy values fromdata[4]
throughdata[8]
if its usage is desired, but it is optional and it won't apply if the override doesn't
High level explanation¶
Since the logic of this action command is complex, a high level explanation is provided. For the details, check the setup and execution phase's details.
There are 2 ways to operate this action command: either data[0]
after being truncated to int is -1 or it isn't (but still lands between 0 and 3 inclusive).
If it is -1, it's a left/right mashing prompt where barfill
only increments when left and right are pressed one after the other. The rate of increment is controlled by data[1]
(typical values used under normal gameplay are between 6.0 and 8.0). data[2]
is unused in this mode, but still must exist because data[3]
needs to exist in order for the command to function (otherwise, it's impossible to succeed the command).
If it's between 0 and 3 inclusive, it's a single input mashing prompt where the input whose id is 4 + data[0]
needs to be pressed in order for barfill
to increase (same usage of data[1]
here than in the left/right mashing prompt). However, this mode also makes barfill
decrease at a rate controlled by data[2]
, but that rate cannot exceed half of data[1]
. Typical values are similar than data[1]
's values.
Each mode features 2 commandsprites
: one for the bar's container and one for the bar itself. The bar's x scaling will get adjusted depending on barfill
which is itself clamped from 0.0 to 1.0 (0.0 being empty and 1.0 being fully filled). Additionally, as an additional audio feedback, as barfill
gets higher, so does the pitch of a looping Barfill
sound that will go from 1.0 to 2.0.
To succeed the command (assuming data[3]
exists), barfill
must reach 1.0 before the timer sent expires or the command is failed. There is no timer if it is -1.0 meaning the command cannot be failed in such a situation.
Left/right mashing prompt¶
This mode features:
presskey
starting at 2 (left) and its value swaps between 2 (left) and 3 (right) whenever an input is accepted- 2
buttons
which shows the left and right glyphs. They will periodically alternate between being white and gray every 8 frames, but this is only for visual indication purposes: it doesn't affect the logic in any way
The way this works is the starting value of presskey
is 2 (left) and it is the input that will always be accepted before moving on to the next one. In an ideal scenario, the player starts with left which increases barfill
and causes presskey
to become 3 (right) which the player can press and make presskey
become 2 (left) again. This continues until the bar is filled or timer expires.
However, the game allows for 1 input of tolerance as a grace input. It means for only a single time in a row, even if presskey
is 2 (left), the game will accept up to 1 right input and even count it towards increasing barfill
. The same happens for the reverse: if presskey
is 3 (right), up to 1 left input is allowed. This can only be granted once in a row: once a grace input is taken, the game will no longer accept any inputs except the presskey
one. This allows the player to completely skip one input, but still get back on track on the next one. It incidentally allows to double tap each input because the incorrect one is allowed each time.
There are some caveats with this mashing prompt however:
- Due to the tolerance logic on keyboard, it is possible to press both left and right input at the same time every time and still have it registered because the game will prioritise the correct input, but will still allow the incorrect one once before the next correct input press
- Due to an issue with MainManager's call to InputIO on controllers, if the player manages to swap the left/rights input to be pressed/released within a frame (such as flicking a D-pad), the game will not register the new inputs even if the correct one is being pressed. This is because the mash prompt only accept non holding inputs and MainManager does not distinguish on controllers (not keyboards) between left or right being held. It only signals to the game that either is held or neither are which isn't sufficient for this. This can lead to frequent inputs drops.
Single input mashing prompt¶
This mode features:
presskey
starting stays at 4 +data[0]
which is the input the prompt will be about and the only one that will be accepted to increasebarfill
- 4
buttons
, each corresponding to the Confirm, Cancel, Switch and Show HUD inputs glyphs. However, only thepresskey
one is enabled, the rest are disabled and thus, not shown. Each 3 frames, thebuttons
wll have their colors changed from gray to white and then back to gray, but this is only for visual indication purposes: it doesn't affect the logic in any way
This is a simpler mode: only the presskey
input is accepted, each increases barfill
, but on every frames (even those where presskey
isn't pressed), barfill
gets decreased by a slower amount. The player needs to mash fast enough to fight the decrease and fill the bar.
The only requirement for the input to be accepted is that it wasn't held meaning it is a fresh new press. It is however possible to bypass this restriction by alternating between a controller and a keyboard because their input holding are tracked separately.
DoCommand Setup phase¶
- The
Barfill
sound is played onsounds[4]
at 0.7 volume on loop presskey
is set todata[0]
(or to 2 if it was -1 meaning the left input is the starting one in left/right input prompt)buttons
is set to a new array of ButtonSrpites (length 2 ifdata[0]
is -1, length 4 if it's not). Each are initialised to be a new GameObject namedButtonX
whereX
is the index of the element. The GameObject is enabled ifdata[0]
is -1 or ifdata[0]
- 4 is the element's index (disabled otherwise). This means that if it's a left/right input prompt, bothbuttons
are enabled, but if it's a face button input prompt, only the concerned one is left enabled with the others left disabled. Each GameObject will have a ButtonSprite attached with SetUp called with the following:- buttonid: if
data[0]
is -1, it's 2 + the element's index (meaning 2 or 3 which are the left/right inputs) and if it's not -1, it's 4 + the element's index (meaning from 4 to 7 which are the face buttons inputs) - onlytype: -1
- description: empty
- position: (2.35, 1.5, 10.0)
- iconsise: (0.75, 0.75, 0.75)
- sortorder: 2
- parentobj:
GUICamera
- buttonid: if
commandsrpites
is set to a new array of 2 SpriteRenderer:commandsprites[0]
: The SpriteRenderer of a new UI object namedbarholder
childed to theGUICamera
with a local position of (-7.0, 1.5, 10.0), scale of Vector3.one using theguisprites[81]
sprite (an action command bar container) with a sortorder of 0commandsprites[1]
: The SpriteRenderer of a new UI object namedbar
childed tocommandsprites[0]
with a local position of Vector3.zero, scale of (0.0, 1.0, 1.0) using theguisprites[82]
sprite (a white bar) with a sortorder of 1 and a color of pure yellow
DoCommand Execution phase¶
There's 3 parts: before the while loop, the while loop itself and after it.
Pre while loop¶
overridechallengeblock
is set to true- A local tolerance int is initialised to 1
- A local altbutton int is initialised to 3
While loop¶
This loop is the main execution of the command and it runs while timer is above 0.0 meaning there's still time left (or we are operating in infinite mode where this goes on until barfill
is full).
This is what happens inside the loop:
sounds[4]
.pitch is set tobarfill
+ 1.0 clamped from 1.0 to 2.0 (meaning the pitch / speed goes higher and faster as the bar gets filled until doubled pitch / speed)commandsprites[1]
x scale is set to a lerp from the existing one tobarfill
with a factor of 1/5 of the game's frametime (this visually aligns the bar to thebarfill
value smoothly)- If the timer floored is divisible by 3 (or by 8 if
data[0]
is -1) and internaldata[0] is 0.0 or below:- The
buttons
'sbasesprite
.color is changed to pure white or 7F7F7F (gray) depending on conditions:- If
data[0]
is -1,buttons[0]
andbuttons[1]
have each their color set to white or gray if the first one'sbasesprite
isn't null. If the first one was gray, it becomes white with the other becoming gray and vice versa otherwise. Additionally,buttons[1]
local position is set to (3.5, 1.5, 10.0) - Otherwise, if
buttons[presskey - 4]
'sbasesprite
isn't null, its color gets set to white if it was grey or set to grey otherwise
- If
internaldata[0]
is set to 3.0
- The
- If
presskey
is pressed without hold OR (the altbutton is whiledata[0]
is -1 and tolerance is above 0):barfill
is incremented by a fraction of the game's frametime. This fraction isdata[1]
/ 80.0 * the framerate (or the refresh rate if MainManager.vsync
isn't 0) / 60.0. NOTE: This vsync logic is incorrect: it essentially means the monitor's refresh rate acts as a speed multiplier where the higher it is and away from 60.0, the faster each press will fill the bar- If
data[0]
is -1, then it depends ifpresskey
was pressed or not. If it wasn't, tolerance is decremented. If it was, tolerance is set to 1 and bothpresskey
and altbutton are set to flip flop between 2 or 3 (so if it was 2, it becomes 3 and vice versa)
- If
data[0]
isn't -1,barfill
is decremented by value that is a half of a fraction of the game's frametime. This fraction isdata[2]
clamped from 1.0 todata[1]
/ 2.0 and then the value is divided by 100.0 barfill
is clamped from 0.0 to 1.0- If
barfill
is at least 1.0 anddata
has more than 3 elements, the command succeed with the following:- The
ACReady
sound is played commandsuccess
is set to truecommandsprite[1]
.color is set to pure greencommandsprite[1]
scale is set to Vector3.one- The logic exits out of the loop
- The
- internaldata[0] is decreased by the game's frametime
- timer is decreased by the game's frametime
- A frame is yielded
Post while loop¶
sounds[4]
is faded out by 1/10 of the game's frametime every frame- All
buttons
elements are disabled - 0.35 seconds are yielded