LizardByte / LizardByte/Sunshine
[Windows][DS4] PS4 DualShock lightbar/LED flickers distractingly like it's broken (possibly same with rumble motors)
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 41.3k
- Forks
- 2.1k
- Avg merge
- 23h 47m
- Merged PRs (30d)
- 124
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### Is your issue described in the documentation?
- [x] I have read the documentation
### Is your issue present in the latest beta/pre-release?
This issue is present in the latest pre-release
### Describe the Bug
### Summary
During gameplay with some games such as Lego Star Wars The Skywalker Saga, the PS4 DualShock Gamepad lightbar/LED quickly flickers between the colour selected by the game and black/off.
Because the lightbar is big and bright, it's _horridly distracting_ .
And because of the fast and stochastic flickering, it _looks like a failing light, as if it's a hardware fault_ (which I first suspected) but it's not:
**Sunshine seems to be rapidly sending (wrong?) instructions to turn the LED on/off (and probably the rumble motors too) using values that are theoretically undefined.**
This can also mean that the lightbar is left black after finishing a game, _leaving the gamepad ON but looking like it's OFF_, which caused me no end of confusion.
I'm seeing this with both the stable _and_ pre-release version of Sunlight running on Windows 10 with both Moonlight on Android _and_ on a hardware Steam Link, using both V1 _and_ V2 PS4 DS4s.
There's been [reports on Reddit of others experiencing likely the same issue](https://www.reddit.com/r/MoonlightStreaming/comments/1knf09h/my_playstation_controllers_led_are_flickering/).
### Suspected Cause
I think this occurs because a game's instructions to the DS4 controller are supposed to come with feature flags indicating which feature value fields should be sent to the controller (e.g. set the rumble motors to 11) and which features should be left untouched (e.g. don't touch the LED) -- but Sunshine currently doesn't get these feature flags, and so sets ALL the features to the supplied values, including the ones it shouldn't.
So if a game says-
`SET LED TO BLUE (Colour 0x00,0x00,0x40) + DON'T CHANGE RUMBLE MOTORS`
Sunshine sends-
`SET LED TO BLUE (Colour 0x00,0x00,0x40) [Correct] + SET RUMBLE MOTORS TO (0,0) [Wrong]`
And conversely if the game sends-
`DON'T CHANGE LED - SET RUMBLE MOTORS TO (27,11)`
Sunshine actually sends-
`SET LED TO BLACK (Colour 0x00,0x00,0x00) [Wrong] - SET RUMBLE MOTORS TO (27,11) [Correct]`
In the case of Lego Star Wars The Skywalker Saga, instructions to turn the LED on and then off again seem to about once per frame / output-update cycle, which the the controller seems to struggle with, hence the worrying-looking random flickering.
https://github.com/nefarius/ViGEmBus/issues/80 describes this problem and support for accessing the feature flags was implemented in 2022 (>= v1.19)
### Expected Behavior
Sunshine should **only** set the LEDs and motors on the DS4 gamepad if the relevant feature flag received from ViGEmBus says they should be set.
Unfortunately a fix for this this would only appear to only be possible for _ViGEmBus version >=1.19_ (when https://github.com/nefarius/ViGEmBus/issues/80 was addressed.)
So, in order to retain backwards compatibility with older versions, it would seem to require conditional use of the newer `vigem_target_ds4_await_output_report_timeout()` etc interface (which I gather allows access to the feature flags) vs the older `vigem_target_ds4_register_notification()` / `ds4_notify()` (which doesn't) depending on ViGEmBus version.
### Additional Context
Excerpts from log (with rumble enabled in Lego Star Wars The Skywalker Saga):
```
[2026-08-09 16:19:32.809]: Debug: largeMotor: 21 smallMotor: 0 LED: 00 00 00
[2026-08-09 16:19:32.809]: Debug: largeMotor: 0 smallMotor: 0 LED: 00 00 40
[2026-08-09 16:19:32.825]: Debug: largeMotor: 19 smallMotor: 0 LED: 00 00 00
[2026-08-09 16:19:32.825]: Debug: largeMotor: 0 smallMotor: 0 LED: 00 00 40
```
**Note the apparent pattern and timing:** For each frame, one instruction presumably intended to ONLY control the rumble motors (that wrongly also turns the LED off), and one instruction to intended to set the LED colour (that wrongly turns the motors off!)
(Full log attached via gist, more info and versions etc available if needed.)
### Host Operating System
Windows
### Operating System Version
Windows 10 19045.7548
### Architecture
amd64/x86_64
### Package
Windows - msi installer (recommended)
### GPU Type
Intel
### GPU Model
RTX 3060 Ti
### GPU Driver/Mesa Version
591.74
### Capture Method
Desktop Duplication API (Windows)
### Apps
```json
```
### Log output
```shell
```
### Online logs
https://gist.github.com/geekycow/907accbd0f5d05e886bb9e446d673b79
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the DS4 output-report sequence from the supplied log, then trace Sunshine's Windows ViGEmBus handling around the DS4 notification and await-output-report interfaces. Compare the feature flags available in ViGEmBus versions before and from 1.19; done means LED and rumble updates occur only when their corresponding flags request them while older versions remain supported.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100