Skip to content

Add texture atlas skins to the virtual gamepad - #1840

Merged
obiot merged 1 commit into
melonjs:masterfrom
snowyukitty:feat/gamepad-skins
Nov 7, 2026
Merged

obiot merged 1 commit into
melonjs:masterfrom
snowyukitty:feat/gamepad-skins

Conversation

@snowyukitty

Copy link
Copy Markdown
Contributor

Description

Adds optional TextureAtlas skins to the gamepad plugin. Sticks can name base and thumb regions, and buttons can name resting region and pressed regions. Each omitted part keeps its existing shapes, so games can skin controls gradually.

The skin uses the existing control positions, radii and hit areas. Cached sprites handle packed atlas rotation and trimming, while the controls retain their opacity, held highlight, dimming, visibility, labels and floating behavior. Invalid region names are rejected before a virtual gamepad slot is claimed; destroying the plugin releases its sprites without destroying the game's atlas.

The visual page now has a skin toggle with a small generated atlas. The README, option documentation, changelog and input skill describe the API.

Type of change

  • Bug fix
  • New feature
  • Documentation update
  • Performance improvement
  • Refactoring (no functional changes)

Validation

  • pnpm lint, pnpm biome check and pnpm build pass.
  • pnpm test: 10,439 engine tests pass; 11 are skipped.
  • Matter adapter: 226 tests; Planck adapter: 221; debug plugin: 23; gamepad plugin: 93, all passing.
  • The 28 new Canvas/WebGL tests exercise rendered pixels and control behavior, including partial skins, pressed/dimmed/hidden states, labels, floating controls, atlas lifetime, invalid regions, trimmed frames and rotated frames. Against the unchanged base, 24 of these tests fail as expected.
  • Browser smoke checks cover the visual page in Canvas, WebGL and WebGPU. A separate WebGPU pixel readback checks sticks, button states, trimmed/rotated atlas frames and floating buttons.

The plugin also builds and passes all 93 tests with melonJS 20.12.0, its declared minimum version.

Checklist

  • I have read the Contributing Guide
  • My code follows the existing code style (pnpm lint passes)
  • I have tested my changes locally (pnpm test passes)
  • I have added tests that cover my changes (if applicable)
  • The build succeeds (pnpm build)

Related issues

Fixes #1802

@snowyukitty

Copy link
Copy Markdown
Contributor Author

The test job lost its Vitest browser connection while importing tests/hdr-adversarial.spec.js: Browser connection was closed. It reported 6,376 passing tests and one failed suite import, then stopped before the gamepad plugin suite.

I checked the controls:

  • The upstream base run passed both its test and Windows jobs at f11f5e3.
  • From the repository root, pnpm -F melonjs exec vitest run tests/hdr-adversarial.spec.js passes all 29 tests on both the unchanged base and this PR's head in Linux with Playwright 1.62.1. The full local suite also passes on this PR head.
  • This PR changes no engine runtime or engine test files; its only file under packages/melonjs is the input skill documentation. The PR's Windows job is skipped by the existing workflow, so that is not a Windows result for this head.

This matches the browser disconnect already documented in the workflow. The failed suite import also matches its “Test Files … failed” guard, so the existing automatic retry did not run. Could you re-run the failed test job?

@obiot
obiot merged commit 22e844a into melonjs:master Nov 7, 2026
5 of 6 checks passed
obiot pushed a commit that referenced this pull request Nov 7, 2026

obiot commented Nov 7, 2026

Copy link
Copy Markdown
Member

Thank you @snowyukitty, this is a great addition! Clean code, thorough Canvas/WebGL pixel tests (including trimmed and rotated frames), and it stays fully backward compatible: without a skin the controls draw exactly as before.

Two small follow-ups landed in #1841:

  • the plugin is now at 1.2.0, with the changelog entry under that version
  • a skinned button without a pressed region now draws at 90% of its size while held, so a press is visible even at full opacity (doubling the opacity alone showed no change at 0.5 or more)

It will ship with the next gamepad-plugin release. Thanks again!


Generated by Claude Code

@obiot obiot mentioned this pull request Nov 7, 2026
5 of 10 tasks
@obiot

obiot commented Nov 7, 2026

Copy link
Copy Markdown
Member

The test job lost its Vitest browser connection while importing tests/hdr-adversarial.spec.js: Browser connection was closed. It reported 6,376 passing tests and one failed suite import, then stopped before the gamepad plugin suite.

I checked the controls:

  • The upstream base run passed both its test and Windows jobs at f11f5e3.
  • From the repository root, pnpm -F melonjs exec vitest run tests/hdr-adversarial.spec.js passes all 29 tests on both the unchanged base and this PR's head in Linux with Playwright 1.62.1. The full local suite also passes on this PR head.
  • This PR changes no engine runtime or engine test files; its only file under packages/melonjs is the input skill documentation. The PR's Windows job is skipped by the existing workflow, so that is not a Windows result for this head.

This matches the browser disconnect already documented in the workflow. The failed suite import also matches its “Test Files … failed” guard, so the existing automatic retry did not run. Could you re-run the failed test job?

No worries, i'll look into it, thanks for the contribution !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gamepad plugin: add custom skin

2 participants