FlavioFS / ParsecSoda

Parsec Soda is a custom open-source game streaming app that integrates with Parsec API and is focused in Host experience.
MIT License
203 stars 52 forks source link

[Bug] !one causes button spamming with multiple controllers. #27

Open CollinCodez opened 2 years ago

CollinCodez commented 2 years ago

Whenever a parsec client actually has multiple controllers, and !one is active, it causes button spamming rather than holding a button, alternating through the different gamepads the client has. If you hold the buttons on multiple of the controllers, the press does become more solid and less spam.

Each individual controller does work regardless of index, but they are spamming rather than holding buttons or stick directions.

FlavioFS commented 2 years ago

That's intended. It is Parsec design to identify controllers through deviceID. When !one is enabled, every input device can compete for the same controller. You should not use !one with multiple controllers plugged as a client.

What you're experiencing is probably a controller with drift higher than deadzone, and it is spamming lots of axis inputs that are concurrent with your second controllers' inputs.

CollinCodez commented 2 years ago

I know for sure this is not drift as it happens with multiple different controllers I have, and work fine with !one disabled.

If I have a Mayflash GameCube controller adapter connected on the client (which is officially supported by parsec, though it always appears as 4 dinput controllers regardless of if you actually have controllers connected in each slot), this issue can become apparent, even when only having one controller connected. If I hold a stick in one direction with !one enabled (which is now on by default), the host sees that hold as flashing in that direction (not actually smoothly moving from the direction to the center, actually flashing and alternating between the two positions). The same happens for holding a button down.

If you should not use !one with multiple controllers connected, then what is the point of it?

Rather than having the controllers compete for control of the input, why not share control between them, so for buttons it could be something along the lines of: if((Controller1 is pressing A) || (Controller2 is pressing A)).

For Sticks, it could be an average of the position of sticks on all controllers outside a deadzone.

FlavioFS commented 2 years ago

One is a workaround for people with controller issues. Some guests have defective controllers that plug in and out constantly, then the deviceID keeps changing. Most players only use 1 controlller and deviceID should be ignored.

If your gamepad is blinking with one, than it is sending inputs constantly, period. Like analog state or something. Due to Parsec SDK design (and to avoid numerical errors or "delta shifting" errors), Soda just overwrites the controller state with the new one. You have multiple controllers trying to write the whole controller state at all times.

Soda does not support multiple concurrent controllers on the same client. If you want to have 4 plugged controllers and keep shifting through them still mapped to the same Puppet, that is not a feature.

FlavioFS commented 2 years ago

Well, it does support multiple controllers on the same client. Without !one. When there are 2 or more people using each controller in the same guest machine.

CollinCodez commented 2 years ago

That's not mapped to the same controller though

FlavioFS commented 2 years ago

I just remembered there is no deadzone in the low level stuff, since it could be a problem and that is usually for the game to handle.

There is no "controller 1 is pressing" or "controller 2 is pressing", there are just lots of gamepad state packets travelling through the network, that's what your Parsec client sends. And there are no 2 controllers pressing at same time, it is just 1 device per packet.

If you are using a multipad adapter and your OS flags that as multiple controllers. They should not be sending input states as they are just empty slots, but somehow they are. In that case you should just disable !one and let the deviceID's be handled normally, assuming your adapter isn't going to connect and disconnect constantly.

Parsec has no !one, there is always a deviceID. And if your controller connection fails guess what... You lose control and Parsec just assigns you a different controller (deviceID). That is the official behaviour which !one just negates in case you don't want it.

CollinCodez commented 2 years ago

Though (If I remember correctly), when hosting with the official app, if one controller comes disconnected on the client and gets reconnected, while the client's controller gets a new device ID on their end, the same gamepad is continued to be emulated until the host stops hosting, and the client gamepad simply takes that slot. (this is after the controller has pressed a button on the client side to initially connect it).

Also, I just looked at my adapter in parsec. It shows no movement on the slots where there is no controller connected, With the sticks actually centering at 0.

Disabling !one does in fact make it behave correctly, but of course most people won't know about this, and since !one is now generally enabled by default, people who connect to streams and unknowingly have multiple gamepads connected can have issues with this.

I may look into setting up this other !one behavior I described above with "Shared control", perhaps as another option to the current "Fight for control" behavior