Simultaneous opposite direction behavior

This is the main shmups forum. Chat about shmups in here - keep it on-topic please!
Post Reply
User avatar
Lethe
Posts: 368
Joined: Tue Mar 03, 2020 9:49 am

Simultaneous opposite direction behavior

Post by Lethe »

Typically, simultaneous digital opposites cancel each other out and make the player stand still. However, there are some games where one direction will take priority over the other. For curiosity's sake I've recorded some PC games that behave in this way. At the bottom is a list of games that have the expected simultaneous opposite behavior.

When it comes to arcade games, some developers had a consistent approach to this and others didn't seem to care. Why would they? It's impossible to do simultaneous opposites with standard arcade controls. Therefore I'm not going to bother listing arcade games unless there's some exploit or other noteworthy consequence. I don't know much about such exploits (only remember the DonPachi Type B one) so if anyone has anything to add on that front, arcade or not, it'd be welcome.

Code: Select all

                        Directions with priority
Game                    Down    Up     Right   Left
Alltynex Second                 y      *       *    (L+R is Up)
Blue Revolver                   y              y
Crimzon Clover WEX              y              y
DNH/danmakufu games     ?       ?      ?       ?    (could be anything)
Eschatos                y              y
IKUSAAAAAAAN!           y              y
Klorets                 *       *      *       *    (most recent direction)
Leiria -Stargazer-      y                      y
Len'en games                    y      y
Noiz2sa                         y              y
Parsec47                        y      y
rRootage                        y              y
SideLine                y              y
Sisters Royale          y                      y
Sophstar                y              y
STG Builder games       y              y
Suwapyon                        y              y
Tumiki Fighters                 y      y
x.x games up to BWR     y              y
Touhou "logic":
TH02: Opposing directions cancel each other, but pressing a diagonal while arrested will override it.
TH03/04/05: Most recent direction takes priority, including cardinals overriding diagonals. (Unironically the best control scheme of all?)
TH06/07: Up and Right take priority. Opposing diagonals produce Up-Right.
TH08 onward: Down and Left take priority, except during diagonals, where Up takes priority. Opposing diagonals produce Up-Left. (?????)

Confirmed games where simultaneous opposites cancel each other out:

Code: Select all

Aero Chimera
Blue Wish Desire (3 or more directions produces Up-Left > Down-Left)
CAVE CV1K ports (via xinput d-pad emulation, opposites arrest ALL movement)
Cho Ren Sha 68k
Dead End City
Eden's Aegis  (3 or more directions produces Up-Left > Down-Left)
Fire Lancer
Flame Zapper Kotsujin
G-Darius HD
G-wangeDash (opposites arrest ALL movement)
Gunvein
Hazelnut Hex
Hellsinker
Judgement Silversword
Kamui
Psyvariar Delta
RefleX
ring^-27
Shikigami no Shiro 2
Shmup Creator games
StellaVanity (opposites arrest ALL movement)
Torus Trooper
TranscendPang (pseudo-Right, undetermined if it's only visual or not)
Xeno Fighters R
ZeroRanger
Last edited by Lethe on Thu Dec 01, 2022 4:06 pm, edited 2 times in total.
User avatar
Lander
Posts: 848
Joined: Tue Oct 18, 2022 11:15 pm
Location: Area 1 Mostly

Re: Simultaneous opposite direction behavior

Post by Lander »

Interesting idea for a topic.

From a software design standpoint, Most Recent Direction speaks to a well implemented event-based input system that only changes memory when something happens, rather than creating an implicity priority chain by periodically polling inputs in a fixed order. Thus making it the best on multiple levels 8)

And slightly off-topic from shmups, but simultaneous opposite directional inputs are quite interesting in the general sense. In the most extreme cases, they violate manufacturer assumptions hard enough to cause memory overflows, which can make all manner of wacky things happen.
I forget exactly which years it was, but the TASbot block at Games Done Quick did some amazing stuff on a stock SNES by using padhacks and input overflow exploits to live-rewrite Super Mario World's RAM into a passable Snake clone and a functional Twitch chat client, among other things.
User avatar
To Far Away Times
Posts: 1661
Joined: Tue Sep 11, 2012 12:42 am

Re: Simultaneous opposite direction behavior

Post by To Far Away Times »

In the fighting game world, this matters a whole heck of a lot with those newer hitbox arcade sticks.

Depending on the game, you might be able to charge two directions at once and stand still. Throwing neutral Sonic Booms and such. Or just piano rolling a 1 frame 360 grab. Scary stuff in games that weren't designed for it.

For shmups, I guess this matters more for keyboard players or those that play on hitboxes. Do people play shmups on hitboxes?
User avatar
copy-paster
Posts: 1683
Joined: Thu Apr 30, 2015 7:33 pm
Location: Indonesia

Re: Simultaneous opposite direction behavior

Post by copy-paster »

In LiveWire's Cave PC ports pressing 3 arrow keys at the same time will make your ship movement stop completely, this is quite annoying if you wanna do quick changing diagonal movement unless you're used with 2-button only manuever.
Steven
Posts: 2870
Joined: Tue May 11, 2021 5:24 am
Location: Tokyo

Re: Simultaneous opposite direction behavior

Post by Steven »

Aside from everything on PC, test Switch games using the Joy-Crap controllers, provided you didn't throw them in the garbage where they belong, as those let you press all 4 directions simultaneously. I doubt anything with an official Switch release will crash or have any super weird glitching, or at least I hope not given that the default Switch controller lets you press any/all opposing directions at once, but you might get some interesting results on older games.
User avatar
Lander
Posts: 848
Joined: Tue Oct 18, 2022 11:15 pm
Location: Area 1 Mostly

Re: Simultaneous opposite direction behavior

Post by Lander »

I'd hope Switch releases would catch and prevent any undefined behaviour in emulation, since the classic ENGAGE RIDLEY MOTHER FUCKER password in NES Metroid early-outs with an error instead of hardlocking or causing permanent damage.

I guess you never know though. Perhaps City Connection will surprise us at some point :P
User avatar
Lethe
Posts: 368
Joined: Tue Mar 03, 2020 9:49 am

Re: Simultaneous opposite direction behavior

Post by Lethe »

To Far Away Times wrote:In the fighting game world, this matters a whole heck of a lot with those newer hitbox arcade sticks.

Depending on the game, you might be able to charge two directions at once and stand still. Throwing neutral Sonic Booms and such. Or just piano rolling a 1 frame 360 grab. Scary stuff in games that weren't designed for it.
Yeah, not so severe a problem here. It's not like shmups need to handle input buffering. Wait! I just remembered Akashicverse exists. Anyone want to give that one a spin and see if it breaks? (I've not yet bothered playing it)
copy-paster wrote:In LiveWire's Cave PC ports pressing 3 arrow keys at the same time will make your ship movement stop completely, this is quite annoying if you wanna do quick changing diagonal movement unless you're used with 2-button only manuever.
Good catch. Seems the arcade versions behave like that too so at least it's accurate. Maybe it's their way of preempting any bugs? :lol:
User avatar
copy-paster
Posts: 1683
Joined: Thu Apr 30, 2015 7:33 pm
Location: Indonesia

Re: Simultaneous opposite direction behavior

Post by copy-paster »

Lethe wrote:Good catch. Seems the arcade versions behave like that too so at least it's accurate. Maybe it's their way of preempting any bugs? :lol:
I don't know seems like a glitch or something since the ports are using xinput emulator, and the dpads are simulated by the arrow keys. I got the same issue while emulating SDOJ too but with analog control the issue doesn't exist, best solution is use the analog keys for movement if you're keyboard player (use xinput to keyboard emulator for KB players).

The 3-button issue also doesn't exist in the arcade versions too, atleast from what I tried in MAME.
User avatar
Lethe
Posts: 368
Joined: Tue Mar 03, 2020 9:49 am

Re: Simultaneous opposite direction behavior

Post by Lethe »

Yeah, you're right. Tried stock MAME without xinput support and it didn't lock up, so I guess it could be an xinput bug. Why these games only though? Weird.
Steven
Posts: 2870
Joined: Tue May 11, 2021 5:24 am
Location: Tokyo

Re: Simultaneous opposite direction behavior

Post by Steven »

Today I played Tatsujin Ou with a keyboard on MiSTer for the first time and I accidentally hit left and right at the same time. It teleported me above the top of the screen outside of the play area, but I was able to return by pressing down, and naturally I backed up into an enemy and died because I couldn't see where I was due to being off screen. I also tried it with up/down + left + right and it has various effects ranging from teleporting you to just killing you for some reason. Up + down seems to just make you go up. I also was able to successfully teleport myself off screen to see if it's possible to clear the game off screen, but enemies can still ram into you and kill you when off screen, so not going to happen.

I tried various combinations in MAME and all it did was make my ship not move, so it's probably a problem with the emulation on MiSTer, as it's still in development. I wonder if anyone has a PCB and a way to test what happens there.
User avatar
Shatterhand
Posts: 4039
Joined: Wed Jan 26, 2005 3:01 am
Location: Rio de Janeiro - Brazil
Contact:

Re: Simultaneous opposite direction behavior

Post by Shatterhand »

For Sophstar, the direction that gets the "Priority" is the last one I check if its being pressed on code, which is completely arbitrary. The game will check if you pressed "up" and change the variable for vertical movement to "up". Then it checks if you pressed "down" and change the variable for vertical movement to "down", replacing the previous value. Same thing for the horizontal axis. Then it checks if both axis have a value, which means you're moving diagonally so you move on each axis with proper speed (so you don't move faster when moving diagonally)

I don't know if anyone is interested on this kind of stuff, but as I never thought anyone would also be interested to know what direction a game prioritizes.. there it is.
For shmups, I guess this matters more for keyboard players or those that play on hitboxes. Do people play shmups on hitboxes?
I've seen at least 2 videos of people playing shmups on a hitbox the last few months... so, yeah, it may become a trend.
Image
Steven
Posts: 2870
Joined: Tue May 11, 2021 5:24 am
Location: Tokyo

Re: Simultaneous opposite direction behavior

Post by Steven »

Shatterhand wrote:I don't know if anyone is interested on this kind of stuff, but as I never thought anyone would also be interested to know what direction a game prioritizes.. there it is.
I've been wondering about and interested in this subject for my entire life.

While I am here, it seems that many Toaplan games exhibit this sort of behaviour. With the older single player Toaplan games set to upright mode in the DIP switches, both P1 side and P2 side can control the ship, allowing you to test on PCB on a cabinet without any modifications at all (provided you have both 1P and 2P controls installed on the cabinet, anyway). I forget what most of my games did, but if anyone cares I can test them again. I only have Slap Fight, Hishouzame, Dash Yarou, and Out Zone, and Out Zone won't let you do this, but the others will.
User avatar
Lander
Posts: 848
Joined: Tue Oct 18, 2022 11:15 pm
Location: Area 1 Mostly

Re: Simultaneous opposite direction behavior

Post by Lander »

Steven wrote:I've been wondering about and interested in this subject for my entire life.
In which case, let's do some more demystifying :)

In pseudocode, Shatterhand's approach would look something like this:

Code: Select all

// First, calculate the horizontal axis

// Number representing the left-right component of our move input
variable direction_x starts at 0

// direction_x will be 0 or -1 after this runs
if left is pressed, set direction_x to -1

// Applies regardless of direction_x's value, thus introducing priority due to overwrite
if right is pressed, set direction_x to 1 

// Now we do it again for the vertical axis...

 // Number representing the up-down component of our move input
variable direction_y starts at 0

// direction_y will be 0 or -1 after this runs
if up is pressed, set direction_y to -1

 // Applies regardless of direction_y's value, thus introducing priority due to overwrite
if down is pressed, set direction_y to 1
Which results in the following output:

R=left&right&direction_x R=False&False&0 R=True&False&-1 R=False&True&1 R=True&True&1

R=up&down&direction_y R=False&False&0 R=True&False&-1 R=False&True&1 R=True&True&1


To avoid priority, you can take advantage of signed addition to represent each direction as the sum of -1, 0 and 1. Showing just one axis for brevity:

Code: Select all

// Start at neutral
variable direction_x starts at 0

// Effectively a "set to -1" operation since direction_x can only ever be 0 here
if left is pressed, subtract 1 from direction_x

// Will set to 1 if direction_x is 0, or cancel out a -1 from the line above and result in 0
if right is pressed, add 1 to direction_x
R=left&right&direction_x R=False&False&0 R=True&False&-1 R=False&True&1 R=True&True&0


The golden solution of "last pressed direction" is a bit more complex, since you need to cache a copy of each input so the next frame can compare it with up-to-date state and decide if a change has happened.

If it has, and that change is a button-down (i.e. last frame input = not pressed, this frame input = pressed), you overwrite the appropriate direction variable with -1 or 1, otherwise do nothing. After that, you check each axis to see if both its inputs are non-pressed, and if so overwrite the respective direction variable with 0 to account for returning to neutral.

Modern engines have high-level abstractions like event systems that discretize time-based state changes into simple "if i receive a button-down event, overwrite the direction variable" setups, but the above is - in abstract - how you'd do it in a low-level way using basic number variables and conditional logic, as you might in closer-to-the-metal contexts like C or ASM.
Post Reply