Uloop Simulate Mouse Input
CyberAgentGameEntertainment/NovaShader
Simulate Mouse.current input in PlayMode through Unity Input System.
A skill your agent uses when handling user input in Phaser 4.
$ npx skills add autonomous-ai/openharness --skill input-keyboard-mouse-touch -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install autonomous-ai/openharness input-keyboard-mouse-touch --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/autonomous-ai/openharness.git skills-src && mkdir -p .claude/skills && cp -r skills-src/store/agents/phaser/skills/input-keyboard-mouse-touch .claude/skills/input-keyboard-mouse-touch && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "input-keyboard-mouse-touch" agent skill from https://github.com/autonomous-ai/openharness/tree/main/store/agents/phaser/skills/input-keyboard-mouse-touch into .claude/skills/input-keyboard-mouse-touch/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "input-keyboard-mouse-touch", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/autonomous-ai/openharness/tree/main/store/agents/phaser/skills/input-keyboard-mouse-touchType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add autonomous-ai/openharness --skill input-keyboard-mouse-touch -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install autonomous-ai/openharness input-keyboard-mouse-touch --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/autonomous-ai/openharness.git skills-src && mkdir -p .agents/skills && cp -r skills-src/store/agents/phaser/skills/input-keyboard-mouse-touch .agents/skills/input-keyboard-mouse-touch && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "input-keyboard-mouse-touch" agent skill from https://github.com/autonomous-ai/openharness/tree/main/store/agents/phaser/skills/input-keyboard-mouse-touch into .agents/skills/input-keyboard-mouse-touch/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "input-keyboard-mouse-touch", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add autonomous-ai/openharness --skill input-keyboard-mouse-touch -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install autonomous-ai/openharness input-keyboard-mouse-touch --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/autonomous-ai/openharness.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/store/agents/phaser/skills/input-keyboard-mouse-touch .cursor/skills/input-keyboard-mouse-touch && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "input-keyboard-mouse-touch" agent skill from https://github.com/autonomous-ai/openharness/tree/main/store/agents/phaser/skills/input-keyboard-mouse-touch into .cursor/skills/input-keyboard-mouse-touch/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "input-keyboard-mouse-touch", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/autonomous-ai/openharness.git --path store/agents/phaser/skills/input-keyboard-mouse-touch--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add autonomous-ai/openharness --skill input-keyboard-mouse-touch -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install autonomous-ai/openharness input-keyboard-mouse-touch --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/autonomous-ai/openharness.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/store/agents/phaser/skills/input-keyboard-mouse-touch .gemini/skills/input-keyboard-mouse-touch && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "input-keyboard-mouse-touch" agent skill from https://github.com/autonomous-ai/openharness/tree/main/store/agents/phaser/skills/input-keyboard-mouse-touch into .gemini/skills/input-keyboard-mouse-touch/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "input-keyboard-mouse-touch", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install autonomous-ai/openharness input-keyboard-mouse-touchInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add autonomous-ai/openharness --skill input-keyboard-mouse-touch -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/autonomous-ai/openharness.git skills-src && mkdir -p .github/skills && cp -r skills-src/store/agents/phaser/skills/input-keyboard-mouse-touch .github/skills/input-keyboard-mouse-touch && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "input-keyboard-mouse-touch" agent skill from https://github.com/autonomous-ai/openharness/tree/main/store/agents/phaser/skills/input-keyboard-mouse-touch into .github/skills/input-keyboard-mouse-touch/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "input-keyboard-mouse-touch", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add autonomous-ai/openharness --skill input-keyboard-mouse-touch -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install autonomous-ai/openharness input-keyboard-mouse-touch --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/autonomous-ai/openharness.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/store/agents/phaser/skills/input-keyboard-mouse-touch .opencode/skills/input-keyboard-mouse-touch && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "input-keyboard-mouse-touch" agent skill from https://github.com/autonomous-ai/openharness/tree/main/store/agents/phaser/skills/input-keyboard-mouse-touch into .opencode/skills/input-keyboard-mouse-touch/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "input-keyboard-mouse-touch", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
input-keyboard-mouse-touchA skill your agent uses when handling user input in Phaser 4.
Input Keyboard Mouse Touch is an agent skill from autonomous-ai/openharness. Use this skill when handling user input in Phaser 4. Covers keyboard keys, mouse clicks and movement, touch events, pointer handling, drag and drop, hit areas, interactive objects, and gamepad support. Triggers on: keyboard, mouse, touch, pointer, drag, drop, click, input, gamepad, cursor keys.
Its SKILL.md is about 4.6k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files, including reference files (for example `references/REFERENCE.md`).
The repository describes itself as: The ultimate harness for coding agents and beyond. All your agents. All your machines. One command center. Start with code, then follow your curiosity and build across… The licence is MIT.
3 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 50da5db. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are javascript).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Input Keyboard Mouse Touch loads about 4.6k tokens when it runs, and up to ~8.9k if it reads all its reference files. Until then it costs about 81 tokens; SKILL.md has 838 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from autonomous-ai/openharness at commit 50da5db, republished under its MIT licence (© autonomous-ai). 838 words, ~4,590 tokens.
.claude/skills/input-keyboard-mouse-touch/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.Phaser provides a unified input system accessed via
this.inputin any Scene. It supports keyboard polling and events, mouse/pointer interaction with Game Objects (click, hover, drag), multi-touch, mouse wheel, and gamepad input. Input can be handled through event listeners or by polling state each frame.
Key source paths: src/input/InputPlugin.js, src/input/Pointer.js, src/input/keyboard/KeyboardPlugin.js, src/input/keyboard/keys/Key.js, src/input/keyboard/keys/KeyCodes.js, src/input/keyboard/combo/KeyCombo.js, src/input/gamepad/GamepadPlugin.js, src/input/gamepad/Gamepad.js, src/input/events/, src/input/keyboard/events/
Related skills: ../sprites-and-images/SKILL.md, ../events-system/SKILL.md, ../scenes/SKILL.md
class MyScene extends Phaser.Scene {
create() {
// Keyboard: create cursor keys (up, down, left, right, space, shift)
this.cursors = this.input.keyboard.createCursorKeys();
// Keyboard: listen for a specific key event
this.input.keyboard.on('keydown-SPACE', (event) => {
console.log('Space pressed');
});
// Pointer: listen for click/tap anywhere on the game canvas
this.input.on('pointerdown', (pointer) => {
console.log('Clicked at', pointer.x, pointer.y);
});
// Pointer: make a Game Object interactive and clickable
const sprite = this.add.sprite(400, 300, 'player');
sprite.setInteractive();
sprite.on('pointerdown', (pointer, localX, localY, event) => {
console.log('Sprite clicked at local', localX, localY);
});
}
update() {
// Poll cursor keys each frame
if (this.cursors.left.isDown) {
// move left
}
if (this.cursors.right.isDown) {
// move right
}
if (Phaser.Input.Keyboard.JustDown(this.cursors.space)) {
// fire once per press
}
}
}Accessed via this.input in any Scene. It is an EventEmitter that handles all input for that Scene.
Key properties:
this.input.enabled (boolean) - toggle input processing for the Scenethis.input.topOnly (boolean, default true) - only emit events from the top-most Game Object under the pointerthis.input.keyboard - the KeyboardPlugin instancethis.input.gamepad - the GamepadPlugin instancethis.input.mouse - the MouseManager referencethis.input.activePointer - the most recently active Pointerthis.input.mousePointer - the mouse Pointer (pointers[0], distinct from pointer1 which is the first touch)this.input.pointer1 through this.input.pointer10 - individual pointer referencesthis.input.dragDistanceThreshold (number, default 0) - pixels a pointer must move before drag startsthis.input.dragTimeThreshold (number, default 0) - ms a pointer must be held before drag startsthis.input.pollRate (number, default -1) - how often pointers are polled; 0 = every frame, -1 = only on movementKey methods:
addPointer(quantity) - add extra pointers for multi-touch (default is 2; max 10)setHitArea(gameObjects, hitArea, hitAreaCallback) - set custom hit area on Game ObjectssetHitAreaCircle(gameObjects, x, y, radius, callback)setHitAreaEllipse(gameObjects, x, y, width, height, callback)setHitAreaRectangle(gameObjects, x, y, width, height, callback)setHitAreaTriangle(gameObjects, x1, y1, x2, y2, x3, y3, callback)setHitAreaFromTexture(gameObjects, callback) - use the texture frame dimensionssetDraggable(gameObjects, value) - enable or disable draggingmakePixelPerfect(alphaTolerance) - returns a callback for pixel-perfect hit testingA Pointer object encapsulates both mouse and touch input. By default Phaser creates 2 pointers. Use this.input.addPointer(quantity) for more (up to 10 total).
Key properties:
x, y - position in screen space (read from position.x, position.y)worldX, worldY - position translated through the most recent CameradownX, downY - position when button was pressedupX, upY - position when button was releasedisDown (boolean) - true if any button is heldprimaryDown (boolean) - true if primary button (left click / touch) is heldbutton (number) - which button was pressed/released (0=left, 1=middle, 2=right)buttons (number) - bitmask of currently held buttons (1=left, 2=right, 4=middle, 8=back, 16=forward)wasTouch (boolean) - true if input came from touchvelocity (Vector2) - smoothed velocity of pointer movementangle (number) - angle of movement in radiansdistance (number) - smoothed distance moved per framemovementX, movementY - relative movement when pointer is lockeddeltaX, deltaY, deltaZ - mouse wheel scroll amountslocked (boolean) - whether pointer lock is activecamera - the Camera this Pointer last interacted withKey methods:
leftButtonDown(), rightButtonDown(), middleButtonDown(), backButtonDown(), forwardButtonDown() - check specific buttonsleftButtonReleased(), rightButtonReleased(), middleButtonReleased() - check recent releasegetDistance() - distance between down position and current/up positiongetDistanceX(), getDistanceY() - horizontal/vertical distancegetDuration() - ms between down and current time or up timegetAngle() - angle between down and current/up positionupdateWorldPoint(camera) - recalculate worldX/worldY for a given camerapositionToCamera(camera, output) - translate pointer position through a cameraCall gameObject.setInteractive() to enable input on a Game Object. This uses the texture frame as the hit area by default.
// Default hit area from texture
sprite.setInteractive();
// Custom shape hit areas (Rectangle, Circle, Ellipse, Triangle, Polygon)
sprite.setInteractive(new Phaser.Geom.Circle(32, 32, 32), Phaser.Geom.Circle.Contains);
sprite.setInteractive(new Phaser.Geom.Ellipse(50, 50, 100, 60), Phaser.Geom.Ellipse.Contains);
sprite.setInteractive(new Phaser.Geom.Triangle(0,64,32,0,64,64), Phaser.Geom.Triangle.Contains);
sprite.setInteractive(new Phaser.Geom.Polygon(points), Phaser.Geom.Polygon.Contains);
// Pixel-perfect hit testing (expensive — use sparingly)
sprite.setInteractive({ pixelPerfect: true, alphaTolerance: 1 });
sprite.setInteractive(this.input.makePixelPerfect());
// With alpha tolerance (default 1):
sprite.setInteractive(this.input.makePixelPerfect(150));
// Config object with multiple options
sprite.setInteractive({
draggable: true,
dropZone: false,
useHandCursor: true,
cursor: 'pointer',
pixelPerfect: true,
alphaTolerance: 1
});
// Containers must specify a shape or call setSize first
container.setSize(200, 200);
container.setInteractive();Cursor keys return an object with up, down, left, right, space, shift Key objects:
this.cursors = this.input.keyboard.createCursorKeys();
// In update():
if (this.cursors.up.isDown) { /* held */ }
if (this.cursors.space.isDown) { /* held */ }addKey creates a Key object for any key:
// By string name
const keyW = this.input.keyboard.addKey('W');
// By key code
const keySpace = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE);
// With options: addKey(key, enableCapture, emitOnRepeat)
const keyA = this.input.keyboard.addKey('A', true, false);addKeys creates multiple keys at once:
// Comma-separated string returns { W, S, A, D } Key objects
const keys = this.input.keyboard.addKeys('W,S,A,D');
if (keys.W.isDown) { /* ... */ }
// Object form with custom names
const keys = this.input.keyboard.addKeys({
up: Phaser.Input.Keyboard.KeyCodes.W,
down: Phaser.Input.Keyboard.KeyCodes.S,
left: Phaser.Input.Keyboard.KeyCodes.A,
right: Phaser.Input.Keyboard.KeyCodes.D
});Polling vs events:
// Polling in update() - check every frame
if (keyW.isDown) { /* key is currently held */ }
if (keyW.isUp) { /* key is currently released */ }
// JustDown - returns true only once per press, resets after check
if (Phaser.Input.Keyboard.JustDown(keyW)) { /* fire once */ }
if (Phaser.Input.Keyboard.JustUp(keyW)) { /* released once */ }
// checkDown with duration - throttled polling
if (this.input.keyboard.checkDown(keySpace, 250)) {
// true at most once every 250ms while held
}
// Event-driven: listen for specific key
this.input.keyboard.on('keydown-SPACE', (event) => { /* ... */ });
this.input.keyboard.on('keyup-SPACE', (event) => { /* ... */ });
// Event-driven: listen for any key
this.input.keyboard.on('keydown', (event) => {
console.log(event.key); // native DOM KeyboardEvent
});
// Event on a Key object itself
const spaceBar = this.input.keyboard.addKey('SPACE');
spaceBar.on('down', (key, event) => { /* Key object + native event */ });
spaceBar.on('up', (key, event) => { /* ... */ });Key object properties:
isDown / isUp (boolean)keyCode (number)altKey, ctrlKey, shiftKey, metaKey (boolean) - modifier state when pressedduration (number) - ms held in previous down-up cycletimeDown, timeUp (number) - timestampsrepeats (number) - repeat count while heldemitOnRepeat (boolean) - if true, fires 'down' event on each repeatenabled (boolean) - can this key be processedPrevent browser default behavior:
// Capture specific keys to prevent browser scrolling etc.
this.input.keyboard.addCapture('SPACE,UP,DOWN,LEFT,RIGHT');
this.input.keyboard.addCapture([ 32, 37, 38, 39, 40 ]);
this.input.keyboard.removeCapture('SPACE');
// Note: captures are global across all ScenesCommon KeyCodes: BACKSPACE(8), TAB(9), ENTER(13), SHIFT(16), CTRL(17), ALT(18), ESC(27), SPACE(32), LEFT(37), UP(38), RIGHT(39), DOWN(40), A-Z(65-90), ZERO-NINE(48-57), F1-F12(112-123). Access via Phaser.Input.Keyboard.KeyCodes.SPACE etc.
Scene-level pointer events (fire anywhere on the canvas):
this.input.on('pointerdown', (pointer, currentlyOver) => {
// pointer: Pointer object, currentlyOver: array of interactive Game Objects under pointer
});
this.input.on('pointerup', (pointer, currentlyOver) => { /* ... */ });
this.input.on('pointermove', (pointer, currentlyOver) => { /* ... */ });
this.input.on('wheel', (pointer, currentlyOver, deltaX, deltaY, deltaZ) => { /* ... */ });Game Object pointer events (require setInteractive):
sprite.setInteractive();
// pointerdown on this specific object
sprite.on('pointerdown', (pointer, localX, localY, event) => {
// localX/localY are relative to the Game Object's top-left
// event.stopPropagation() prevents the event from going further
});
sprite.on('pointerup', (pointer, localX, localY, event) => { /* ... */ });
sprite.on('pointermove', (pointer, localX, localY, event) => { /* ... */ });
sprite.on('pointerover', (pointer, localX, localY, event) => { /* ... */ });
sprite.on('pointerout', (pointer, event) => { /* ... */ });
sprite.on('wheel', (pointer, deltaX, deltaY, deltaZ, event) => { /* ... */ });Right-click handling:
this.input.on('pointerdown', (pointer) => {
if (pointer.rightButtonDown()) {
// right-click
}
});
// Disable context menu
this.input.mouse.disableContextMenu();Pointer lock (FPS-style mouse capture):
// Request lock on click
this.input.on('pointerdown', () => {
this.input.mouse.requestPointerLock();
});
this.input.on('pointerlockchange', (event, locked) => {
// locked: boolean
});
// Read relative movement while locked
// pointer.movementX, pointer.movementYconst sprite = this.add.sprite(400, 300, 'item');
sprite.setInteractive();
this.input.setDraggable(sprite);
// Or use config:
// sprite.setInteractive({ draggable: true });
// Drag events on the Scene input
this.input.on('dragstart', (pointer, gameObject) => {
gameObject.setTint(0xff0000);
});
this.input.on('drag', (pointer, gameObject, dragX, dragY) => {
gameObject.x = dragX;
gameObject.y = dragY;
});
this.input.on('dragend', (pointer, gameObject) => {
gameObject.clearTint();
});
// Drop zones
const zone = this.add.zone(600, 300, 200, 200).setRectangleDropZone(200, 200);
this.input.on('drop', (pointer, gameObject, dropZone) => {
gameObject.x = dropZone.x;
gameObject.y = dropZone.y;
});
this.input.on('dragenter', (pointer, gameObject, dropZone) => { /* ... */ });
this.input.on('dragleave', (pointer, gameObject, dropZone) => { /* ... */ });
this.input.on('dragover', (pointer, gameObject, dropZone) => { /* ... */ });Game Object-level drag events are also available:
sprite.on('drag', (pointer, dragX, dragY) => {
sprite.x = dragX;
sprite.y = dragY;
});
sprite.on('dragstart', (pointer, dragX, dragY) => { /* ... */ });
sprite.on('dragend', (pointer, dragX, dragY) => { /* ... */ });
sprite.on('drop', (pointer, dropZone) => { /* ... */ });Drag thresholds:
this.input.dragDistanceThreshold = 16; // must move 16px before drag starts
this.input.dragTimeThreshold = 200; // must hold 200ms before drag startsPointer events fire at three levels (see reference for details):
gameObject.on('pointerdown', (pointer, localX, localY, event) => {})this.input.on('gameobjectdown', (pointer, gameObject, event) => {})this.input.on('pointerdown', (pointer, currentlyOver) => {})// Debug visualize hit areas
this.input.enableDebug(gameObject);
this.input.enableDebug(gameObject, 0xff00ff);
this.input.removeDebug(gameObject);
// Let all objects under pointer receive events (not just top-most)
this.input.topOnly = false;
this.input.setTopOnly(false);Multi-touch: set config.input.activePointers to reserve pointer slots at startup, or call this.input.addPointer(num) at runtime. Access via this.input.pointer1 through pointer10.
Enable gamepads in the game config:
const config = {
input: {
gamepad: true
}
};Access via this.input.gamepad. Gamepads are available as pad1 through pad4:
// Wait for connection
this.input.gamepad.once('connected', (pad) => {
console.log('Gamepad connected:', pad.id);
});
// If already connected, check total
if (this.input.gamepad.total > 0) {
const pad = this.input.gamepad.pad1;
}Polling gamepad state in update():
update() {
const pad = this.input.gamepad.pad1;
if (!pad) return;
// D-pad (boolean properties)
if (pad.up) { /* d-pad up */ }
if (pad.down) { /* d-pad down */ }
if (pad.left) { /* d-pad left */ }
if (pad.right) { /* d-pad right */ }
// Face buttons (boolean) - Xbox naming convention
if (pad.A) { /* bottom button (Xbox A / PS X) */ }
if (pad.B) { /* right button (Xbox B / PS Circle) */ }
if (pad.X) { /* left button (Xbox X / PS Square) */ }
if (pad.Y) { /* top button (Xbox Y / PS Triangle) */ }
// Shoulder buttons (float 0-1)
if (pad.L1 > 0) { /* left shoulder top (LB) */ }
if (pad.L2 > 0) { /* left shoulder bottom / trigger (LT) */ }
if (pad.R1 > 0) { /* right shoulder top (RB) */ }
if (pad.R2 > 0) { /* right shoulder bottom / trigger (RT) */ }
// Analog sticks (Vector2, values -1 to 1)
const lx = pad.leftStick.x; // left stick horizontal
const ly = pad.leftStick.y; // left stick vertical
const rx = pad.rightStick.x;
const ry = pad.rightStick.y;
// Raw axis/button access
pad.getAxisValue(0); // float
pad.getButtonValue(0); // float 0-1
pad.isButtonDown(0); // boolean
pad.setAxisThreshold(0.1); // ignore values below threshold
}Gamepad events:
// Plugin-level events (any gamepad)
this.input.gamepad.on('connected', (pad, event) => { /* ... */ });
this.input.gamepad.on('disconnected', (pad, event) => { /* ... */ });
this.input.gamepad.on('down', (pad, button, value) => { /* any button on any pad */ });
this.input.gamepad.on('up', (pad, button, value) => { /* ... */ });
// Gamepad-instance events
pad.on('down', (index, value, button) => { /* button on this specific pad */ });
pad.on('up', (index, value, button) => { /* ... */ });Vibration (experimental, hardware/browser dependent):
if (pad.vibration) {
pad.vibration.playEffect('dual-rumble', {
duration: 200,
strongMagnitude: 1.0,
weakMagnitude: 0.5
});
}Listen for a sequence of keys:
// String-based combo
this.input.keyboard.createCombo('PHASER');
// Array of key codes (Konami code)
this.input.keyboard.createCombo(
[ 38, 38, 40, 40, 37, 39, 37, 39, 66, 65, 13 ],
{ resetOnMatch: true }
);
// Listen for match
this.input.keyboard.on('keycombomatch', (keyCombo, event) => {
console.log('Combo matched!');
});createCombo(keys, config):
keys: a string (each character is a key) or an array of key codes / Key objectsconfig.resetOnWrongKey (boolean, default true) - reset progress if wrong key is pressedconfig.maxKeyDelay (number, default 0) - max ms between key presses; 0 = no limitconfig.resetOnMatch (boolean, default false) - reset combo after a successful matchconfig.deleteOnMatch (boolean, default false) - remove combo after first matchFor detailed configuration options, API reference tables, and source file maps, see the reference guide.
© autonomous-ai, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 1 other file (references) in store/agents/phaser/skills/input-keyboard-mouse-touch of autonomous-ai/openharness.
Open the folder on GitHubat commit 50da5db
Input Keyboard Mouse Touch next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Input Keyboard Mouse Touch this skillautonomous-ai/openharness | 1.1k | — | ~4.6k | Automated safety check: Pass | MIT | |
| Uloop Simulate Mouse InputCyberAgentGameEntertainment/NovaShader | 1.6k | 1 repos | ~2k | Automated safety check: Pass | MIT | |
| Search Inputthedaviddias/Front-End-Checklist | 74k | — | ~402 | Automated safety check: Pass | MIT | |
| Input Typesthedaviddias/Front-End-Checklist | 74k | — | ~487 | Automated safety check: Pass | MIT | |
| Keyboard Navigationthedaviddias/Front-End-Checklist | 74k | — | ~567 | Automated safety check: Pass | MIT | |
| Paste Inputsthedaviddias/Front-End-Checklist | 74k | — | ~443 | Automated safety check: Pass | MIT |
CyberAgentGameEntertainment/NovaShader
Simulate Mouse.current input in PlayMode through Unity Input System.
thedaviddias/Front-End-Checklist
A skill your agent uses when reviewing templates, rendered HTML, or shared components related to Make search inputs accessible.
thedaviddias/Front-End-Checklist
A skill your agent uses when reviewing templates, rendered HTML, or shared components related to Use semantic input type attributes.
thedaviddias/Front-End-Checklist
A skill your agent uses when reviewing rendered HTML, interactive components, or design-system patterns related to Enable keyboard navigation for all elements.
thedaviddias/Front-End-Checklist
A skill your agent uses when reviewing rendered HTML, interactive components, or design-system patterns related to Allow pasting into form inputs.
thedaviddias/Front-End-Checklist
A skill your agent uses when applies to all interactive elements on touchscreen interfaces: buttons, links, checkboxes, radio buttons, form inputs, icon buttons, and menu items.
autonomous-ai/openharness
Slices 3D mesh files into printer-profiled plain G-code through real slicer CLIs, with backend discovery, input inspection, dry runs and static validation.
autonomous-ai/openharness
Turns a home-automation request into standard, testable automations.yaml, run against Home Assistant Core's real triggers and verified with its own trace tool.
autonomous-ai/openharness
Turns a musical brief into LilyPond concert-pitch music, checked parts for each instrument and a playable practice pack.
autonomous-ai/openharness
Turns an STL and explicit printer and material requirements into compared OrcaSlicer plans, an editable 3MF project, checked G-code and a portable handoff.
autonomous-ai/openharness
Builds an editable DOCX report, a formula-driven XLSX workbook and a fresh LibreOffice PDF preview from one structured source file, then checks them together.
autonomous-ai/openharness
Dry-run, upload, and cautiously initiate local Bambu Lab print jobs from validated plain .gcode, using Bambu LAN FTPS/MQTT handoffs.
A skill your agent uses when handling user input in Phaser 4. Input Keyboard Mouse Touch is an agent skill from autonomous-ai/openharness. Use this skill when handling user input in Phaser 4.
Input Keyboard Mouse Touch fits situations like: handling user input in Phaser 4.
Run `npx skills add autonomous-ai/openharness --skill input-keyboard-mouse-touch -a claude-code`. Or copy the skill folder (store/agents/phaser/skills/input-keyboard-mouse-touch in autonomous-ai/openharness) into .claude/skills/input-keyboard-mouse-touch in your project. Claude Code loads it when a task matches its description.
Run `npx skills add autonomous-ai/openharness --skill input-keyboard-mouse-touch -a codex`. Or copy the skill folder (store/agents/phaser/skills/input-keyboard-mouse-touch in autonomous-ai/openharness) into .agents/skills/input-keyboard-mouse-touch in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add autonomous-ai/openharness --skill input-keyboard-mouse-touch -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/input-keyboard-mouse-touch, .gemini/skills/input-keyboard-mouse-touch, .github/skills/input-keyboard-mouse-touch and .opencode/skills/input-keyboard-mouse-touch in your project.
SKILL.md names no scripts, command-line tools or credentials: Input Keyboard Mouse Touch is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Input Keyboard Mouse Touch is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.6k tokens (SKILL.md is roughly 18k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 4.3k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Input Keyboard Mouse Touch: Uloop Simulate Mouse Input (CyberAgentGameEntertainment/NovaShader, 1.6k stars), Search Input (thedaviddias/Front-End-Checklist, 74k stars), Input Types (thedaviddias/Front-End-Checklist, 74k stars) and Keyboard Navigation (thedaviddias/Front-End-Checklist, 74k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
autonomous-ai (a GitHub organization) maintains it in autonomous-ai/openharness, which has 1,149 GitHub stars. The repository holds 100 skills in this directory. The repository was last updated on October 8, 2026.
Source: autonomous-ai/openharness on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.