Mouse capture: Difference between revisions

From Wiki G1R-MP G1 Remake Multiplayer
Jump to navigation Jump to search
Document upcoming 0.1.4 weapon confirmation and mouse camera APIs
 
Release 0.1.4 BUILD133 / Protocol 36 and document authenticated event origin
 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
= Mouse capture =
= Mouse capture =
'''Since 0.1.4 — in development. Not available in public 0.1.3. Matching client and server are required. Live game acceptance tests are still required.'''
'''Since 0.1.4. Not available in public 0.1.3. Matching client and server are required. Live game acceptance tests are still required.'''


Client Lua can acquire relative mouse motion for camera scripts without replacing GUI click handling. One resource owns capture; another resource cannot steal it. Acquisition is asynchronous: <code>true</code> from [[setMouseCapture]] means acceptance, not active input.
Client Lua can acquire relative mouse motion for camera scripts without replacing GUI click handling. One resource owns capture; another resource cannot steal it. Acquisition is asynchronous: <code>true</code> from [[setMouseCapture]] means acceptance, not active input.


== API ==
== API ==
* [[setMouseCapture]]: <code>boolean setMouseCapture(boolean enabled)</code>.
* [[setMouseCapture]]: <code>boolean setMouseCapture(boolean enabled [, boolean exclusiveInput = false])</code>.
* [[getMouseCaptureState]]: <code>string getMouseCaptureState()</code>, returning inactive, pending, active or suspended for the calling resource.
* [[getMouseCaptureState]]: <code>string getMouseCaptureState()</code>, returning inactive, pending, active or suspended for the calling resource.
* [[onClientMouseMove]]: <code>function(dx, dy, elapsedMs)</code>. Relative raw counts, positive X right and positive Y down, not pixels or degrees. Apply sensitivity; do not multiply displacement by elapsed time. Only non-zero movement is delivered, at most approximately 60 events/second. Absolute tablet input is not included.
* [[onClientMouseMove]]: <code>function(dx, dy, elapsedMs)</code>. Relative raw counts, positive X right and positive Y down, not pixels or degrees. Apply sensitivity; do not multiply displacement by elapsed time. Only non-zero movement is delivered, at most approximately 60 events/second. Absolute tablet input is not included.
Line 12: Line 12:


== Ownership and safety ==
== Ownership and safety ==
Capture suspends on loss of game focus, GUI or keyboard capture, detected native menu/input blocking, death or missing game state. It resumes after the blocker clears and native confirmation arrives. Resource stop and IPC loss release capture. A 750 ms native lease expires when heartbeats stop. Native look locking balances only this feature's own lock; it does not reset another subsystem's lock.
Capture suspends on loss of game focus, GUI or another resource's keyboard capture, detected native menu/input blocking, death or missing game state. It resumes after the blocker clears and native confirmation arrives. Resource stop and IPC loss release capture. A 750 ms native lease expires when heartbeats stop. Native look locking balances only this feature's own lock; it does not reset another subsystem's lock.


Capture does not imply a camera lease. Acquire the camera with existing <code>RequestCameraState</code>, <code>SetCameraPose</code> and <code>onClientCameraCommandResult</code> before streaming poses. Release it separately with <code>ResetCameraPos</code>. GUI interaction pauses capture; simultaneous GUI dragging is not provided by this API.
Capture does not imply a camera lease. Acquire the camera with existing <code>RequestCameraState</code>, <code>SetCameraPose</code> and <code>onClientCameraCommandResult</code> before streaming poses. Release it separately with <code>ResetCameraPos</code>. GUI interaction pauses capture; simultaneous GUI dragging is not provided by this API.
Line 36: Line 36:
Verify Alt-Tab, native menus/inventory, chat, GUI clicks, resource restart and disconnect in the live game. Automated tests do not establish that every native G1R menu/custom input path respects the look gate.
Verify Alt-Tab, native menus/inventory, chat, GUI clicks, resource restart and disconnect in the live game. Automated tests do not establish that every native G1R menu/custom input path respects the look gate.
[[Category:Lua API]]
[[Category:Lua API]]
<!-- map-editor014:start -->
== Exclusive input for freecam (since 0.1.4) ==
Use <code>setMouseCapture(true, true)</code> to request continuous character-input suppression together with relative mouse capture. The default second argument is false: existing <code>setMouseCapture(true)</code> calls remain look-only.
Exclusive mode stops pre-existing character movement and holds this feature's own balanced movement/look locks plus viewport gate for the capture lease. It does not itself move a camera: acquire a scripted camera and use [[UpdateCameraPose]]. Bound keys owned by the mouse-owning resource can operate together (for example W+D+Shift); another resource's held keys, interactive GUI, native menus, loss of focus or readiness still suspend input. Wait for active state, clear held-key state on suspension and release with <code>setMouseCapture(false)</code>. Stop/disconnect/lease expiry release owned locks without resetting foreign locks. See [[Map editor]] for a complete resource using this mode.
<!-- map-editor014:end -->

Latest revision as of 20:40, 21 September 2026

Mouse capture

Since 0.1.4. Not available in public 0.1.3. Matching client and server are required. Live game acceptance tests are still required.

Client Lua can acquire relative mouse motion for camera scripts without replacing GUI click handling. One resource owns capture; another resource cannot steal it. Acquisition is asynchronous: true from setMouseCapture means acceptance, not active input.

API

  • setMouseCapture: boolean setMouseCapture(boolean enabled [, boolean exclusiveInput = false]).
  • getMouseCaptureState: string getMouseCaptureState(), returning inactive, pending, active or suspended for the calling resource.
  • onClientMouseMove: function(dx, dy, elapsedMs). Relative raw counts, positive X right and positive Y down, not pixels or degrees. Apply sensitivity; do not multiply displacement by elapsed time. Only non-zero movement is delivered, at most approximately 60 events/second. Absolute tablet input is not included.
  • onClientMouseCaptureChanged: function(state, reason), delivered to the owning resource only.
  • UpdateCameraPose / updateCameraPose: coalesced updates for an already acquired scripted camera.

Ownership and safety

Capture suspends on loss of game focus, GUI or another resource's keyboard capture, detected native menu/input blocking, death or missing game state. It resumes after the blocker clears and native confirmation arrives. Resource stop and IPC loss release capture. A 750 ms native lease expires when heartbeats stop. Native look locking balances only this feature's own lock; it does not reset another subsystem's lock.

Capture does not imply a camera lease. Acquire the camera with existing RequestCameraState, SetCameraPose and onClientCameraCommandResult before streaming poses. Release it separately with ResetCameraPos. GUI interaction pauses capture; simultaneous GUI dragging is not provided by this API.

-- Acquire your camera first and wait for its successful command result.
local yaw, pitch = 0, -12
addEventHandler("onClientMouseMove", resourceRoot, function(dx, dy, elapsedMs)
    yaw = (yaw + dx * 0.12) % 360
    pitch = math.max(-80, math.min(80, pitch - dy * 0.12))
    UpdateCameraPose({yaw = yaw, pitch = pitch})
end)
setMouseCapture(true)
-- Later: setMouseCapture(false); ResetCameraPos(250)

Development test

The gothic_rp test commands require a spawned, authenticated character, enabled test tools and admin.players permission:

  • /mousetest camera, /mousetest orbit, /mousetest observe.
  • /mousetest gui checks suspension and return from GUI input.
  • F8 or /mousetest stop releases capture and restores the test camera. Automatic stop after 60 seconds.

Verify Alt-Tab, native menus/inventory, chat, GUI clicks, resource restart and disconnect in the live game. Automated tests do not establish that every native G1R menu/custom input path respects the look gate.

Exclusive input for freecam (since 0.1.4)

Use setMouseCapture(true, true) to request continuous character-input suppression together with relative mouse capture. The default second argument is false: existing setMouseCapture(true) calls remain look-only.

Exclusive mode stops pre-existing character movement and holds this feature's own balanced movement/look locks plus viewport gate for the capture lease. It does not itself move a camera: acquire a scripted camera and use UpdateCameraPose. Bound keys owned by the mouse-owning resource can operate together (for example W+D+Shift); another resource's held keys, interactive GUI, native menus, loss of focus or readiness still suspend input. Wait for active state, clear held-key state on suspension and release with setMouseCapture(false). Stop/disconnect/lease expiry release owned locks without resetting foreign locks. See Map editor for a complete resource using this mode.