@indiegems/gem-web-sdk 10.2.0 → 10.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@
2
2
  "schema_version": 2,
3
3
  "source": {
4
4
  "repo": "IndieGems/gem-web-sdk",
5
- "version": "10.2.0"
5
+ "version": "10.3.0"
6
6
  },
7
7
  "entries": [
8
8
  {
@@ -65,6 +65,10 @@
65
65
  "key": "vibration",
66
66
  "title": "Vibrating the device"
67
67
  },
68
+ {
69
+ "key": "controls",
70
+ "title": "Camera and look controls"
71
+ },
68
72
  {
69
73
  "key": "config",
70
74
  "title": "Your published config"
@@ -5385,6 +5389,572 @@
5385
5389
  "defaultValue": null,
5386
5390
  "guides": []
5387
5391
  },
5392
+ {
5393
+ "id": "GemLookSpeed",
5394
+ "name": "GemLookSpeed",
5395
+ "anchor": "gemlookspeed",
5396
+ "group": "controls",
5397
+ "signature": "interface GemLookSpeed",
5398
+ "documented": true,
5399
+ "summary": "A look speed per axis, in radians: per CSS px for a pointer, per second at\nfull tilt for a stick.",
5400
+ "deprecated": null,
5401
+ "params": [],
5402
+ "returns": null,
5403
+ "throws": null,
5404
+ "example": null,
5405
+ "defaultValue": null,
5406
+ "guides": []
5407
+ },
5408
+ {
5409
+ "id": "GemLookSpeed.yaw",
5410
+ "name": "yaw",
5411
+ "anchor": "gemlookspeed-yaw",
5412
+ "group": "controls",
5413
+ "signature": "readonly yaw: number",
5414
+ "documented": true,
5415
+ "summary": "Across: radians of yaw.",
5416
+ "deprecated": null,
5417
+ "params": [],
5418
+ "returns": null,
5419
+ "throws": null,
5420
+ "example": null,
5421
+ "defaultValue": null,
5422
+ "guides": []
5423
+ },
5424
+ {
5425
+ "id": "GemLookSpeed.pitch",
5426
+ "name": "pitch",
5427
+ "anchor": "gemlookspeed-pitch",
5428
+ "group": "controls",
5429
+ "signature": "readonly pitch: number",
5430
+ "documented": true,
5431
+ "summary": "Up/down: radians of pitch.",
5432
+ "deprecated": null,
5433
+ "params": [],
5434
+ "returns": null,
5435
+ "throws": null,
5436
+ "example": null,
5437
+ "defaultValue": null,
5438
+ "guides": []
5439
+ },
5440
+ {
5441
+ "id": "GemLookBase",
5442
+ "name": "GemLookBase",
5443
+ "anchor": "gemlookbase",
5444
+ "group": "controls",
5445
+ "signature": "interface GemLookBase",
5446
+ "documented": true,
5447
+ "summary": "The shape of `gem.controls.LOOK_BASE`: Roblox's base look speeds and the\nstick and touch shaping constants `gem.controls.look()` applies.",
5448
+ "deprecated": null,
5449
+ "params": [],
5450
+ "returns": null,
5451
+ "throws": null,
5452
+ "example": null,
5453
+ "defaultValue": null,
5454
+ "guides": []
5455
+ },
5456
+ {
5457
+ "id": "GemLookBase.touch",
5458
+ "name": "touch",
5459
+ "anchor": "gemlookbase-touch",
5460
+ "group": "controls",
5461
+ "signature": "readonly touch: GemLookSpeed",
5462
+ "documented": true,
5463
+ "summary": "Radians per CSS px, for touch and pen: 1° across, 0.66° up/down.",
5464
+ "deprecated": null,
5465
+ "params": [],
5466
+ "returns": null,
5467
+ "throws": null,
5468
+ "example": null,
5469
+ "defaultValue": null,
5470
+ "guides": []
5471
+ },
5472
+ {
5473
+ "id": "GemLookBase.mouse",
5474
+ "name": "mouse",
5475
+ "anchor": "gemlookbase-mouse",
5476
+ "group": "controls",
5477
+ "signature": "readonly mouse: GemLookSpeed",
5478
+ "documented": true,
5479
+ "summary": "Radians per CSS px, for a mouse: 0.5° across, 0.385° up/down.",
5480
+ "deprecated": null,
5481
+ "params": [],
5482
+ "returns": null,
5483
+ "throws": null,
5484
+ "example": null,
5485
+ "defaultValue": null,
5486
+ "guides": []
5487
+ },
5488
+ {
5489
+ "id": "GemLookBase.stick",
5490
+ "name": "stick",
5491
+ "anchor": "gemlookbase-stick",
5492
+ "group": "controls",
5493
+ "signature": "readonly stick: GemLookSpeed",
5494
+ "documented": true,
5495
+ "summary": "Radians per second at full tilt, for a gamepad stick: 240° across, 184.8° up/down.",
5496
+ "deprecated": null,
5497
+ "params": [],
5498
+ "returns": null,
5499
+ "throws": null,
5500
+ "example": null,
5501
+ "defaultValue": null,
5502
+ "guides": []
5503
+ },
5504
+ {
5505
+ "id": "GemLookBase.stickDeadzone",
5506
+ "name": "stickDeadzone",
5507
+ "anchor": "gemlookbase-stickdeadzone",
5508
+ "group": "controls",
5509
+ "signature": "readonly stickDeadzone: number",
5510
+ "documented": true,
5511
+ "summary": "A stick axis below this magnitude turns nothing: 0.1.",
5512
+ "deprecated": null,
5513
+ "params": [],
5514
+ "returns": null,
5515
+ "throws": null,
5516
+ "example": null,
5517
+ "defaultValue": null,
5518
+ "guides": []
5519
+ },
5520
+ {
5521
+ "id": "GemLookBase.stickCurve",
5522
+ "name": "stickCurve",
5523
+ "anchor": "gemlookbase-stickcurve",
5524
+ "group": "controls",
5525
+ "signature": "readonly stickCurve: number",
5526
+ "documented": true,
5527
+ "summary": "The stick curve's curvature `k` in `(e^(k·d) − 1) / (e^k − 1)`: 2.",
5528
+ "deprecated": null,
5529
+ "params": [],
5530
+ "returns": null,
5531
+ "throws": null,
5532
+ "example": null,
5533
+ "defaultValue": null,
5534
+ "guides": []
5535
+ },
5536
+ {
5537
+ "id": "GemLookBase.touchPitchMin",
5538
+ "name": "touchPitchMin",
5539
+ "anchor": "gemlookbase-touchpitchmin",
5540
+ "group": "controls",
5541
+ "signature": "readonly touchPitchMin: number",
5542
+ "documented": true,
5543
+ "summary": "The least fraction of the pitch speed a touch drag keeps straight up or down: 0.25.",
5544
+ "deprecated": null,
5545
+ "params": [],
5546
+ "returns": null,
5547
+ "throws": null,
5548
+ "example": null,
5549
+ "defaultValue": null,
5550
+ "guides": []
5551
+ },
5552
+ {
5553
+ "id": "GemLookOptions",
5554
+ "name": "GemLookOptions",
5555
+ "anchor": "gemlookoptions",
5556
+ "group": "controls",
5557
+ "signature": "interface GemLookOptions",
5558
+ "documented": true,
5559
+ "summary": "The game's own overrides for `gem.controls.look()` — what the player chose in\nYOUR settings screen. Each one wins over the Arcade's value; leave one out to\nfollow the Arcade.",
5560
+ "deprecated": null,
5561
+ "params": [],
5562
+ "returns": null,
5563
+ "throws": null,
5564
+ "example": null,
5565
+ "defaultValue": null,
5566
+ "guides": []
5567
+ },
5568
+ {
5569
+ "id": "GemLookOptions.sensitivity",
5570
+ "name": "sensitivity",
5571
+ "anchor": "gemlookoptions-sensitivity",
5572
+ "group": "controls",
5573
+ "signature": "readonly sensitivity?: number",
5574
+ "documented": true,
5575
+ "summary": "The player's own look speed for touch, mouse and pen, as a multiplier\n(`1` = the base speed). Wins over `gem.prefs.recommended.lookSensitivity`.",
5576
+ "deprecated": null,
5577
+ "params": [],
5578
+ "returns": null,
5579
+ "throws": null,
5580
+ "example": null,
5581
+ "defaultValue": null,
5582
+ "guides": []
5583
+ },
5584
+ {
5585
+ "id": "GemLookOptions.gamepadSensitivity",
5586
+ "name": "gamepadSensitivity",
5587
+ "anchor": "gemlookoptions-gamepadsensitivity",
5588
+ "group": "controls",
5589
+ "signature": "readonly gamepadSensitivity?: number",
5590
+ "documented": true,
5591
+ "summary": "The player's own look speed for a gamepad stick, as a multiplier. Wins\nover `gem.prefs.recommended.gamepadLookSensitivity`.",
5592
+ "deprecated": null,
5593
+ "params": [],
5594
+ "returns": null,
5595
+ "throws": null,
5596
+ "example": null,
5597
+ "defaultValue": null,
5598
+ "guides": []
5599
+ },
5600
+ {
5601
+ "id": "GemLookOptions.invertY",
5602
+ "name": "invertY",
5603
+ "anchor": "gemlookoptions-inverty",
5604
+ "group": "controls",
5605
+ "signature": "readonly invertY?: boolean",
5606
+ "documented": true,
5607
+ "summary": "The player's own inverted up/down look. Wins over\n`gem.prefs.recommended.invertLookY`.",
5608
+ "deprecated": null,
5609
+ "params": [],
5610
+ "returns": null,
5611
+ "throws": null,
5612
+ "example": null,
5613
+ "defaultValue": null,
5614
+ "guides": []
5615
+ },
5616
+ {
5617
+ "id": "GemLookDelta",
5618
+ "name": "GemLookDelta",
5619
+ "anchor": "gemlookdelta",
5620
+ "group": "controls",
5621
+ "signature": "interface GemLookDelta",
5622
+ "documented": true,
5623
+ "summary": "A turn to apply to your camera, in radians to ADD: `yaw` positive turns\nright (clockwise seen from above), `pitch` positive looks up.",
5624
+ "deprecated": null,
5625
+ "params": [],
5626
+ "returns": null,
5627
+ "throws": null,
5628
+ "example": null,
5629
+ "defaultValue": null,
5630
+ "guides": []
5631
+ },
5632
+ {
5633
+ "id": "GemLookDelta.yaw",
5634
+ "name": "yaw",
5635
+ "anchor": "gemlookdelta-yaw",
5636
+ "group": "controls",
5637
+ "signature": "readonly yaw: number",
5638
+ "documented": true,
5639
+ "summary": "Radians to add to the camera's yaw; positive turns right.",
5640
+ "deprecated": null,
5641
+ "params": [],
5642
+ "returns": null,
5643
+ "throws": null,
5644
+ "example": null,
5645
+ "defaultValue": null,
5646
+ "guides": []
5647
+ },
5648
+ {
5649
+ "id": "GemLookDelta.pitch",
5650
+ "name": "pitch",
5651
+ "anchor": "gemlookdelta-pitch",
5652
+ "group": "controls",
5653
+ "signature": "readonly pitch: number",
5654
+ "documented": true,
5655
+ "summary": "Radians to add to the camera's pitch; positive looks up.",
5656
+ "deprecated": null,
5657
+ "params": [],
5658
+ "returns": null,
5659
+ "throws": null,
5660
+ "example": null,
5661
+ "defaultValue": null,
5662
+ "guides": []
5663
+ },
5664
+ {
5665
+ "id": "GemLook",
5666
+ "name": "GemLook",
5667
+ "anchor": "gemlook",
5668
+ "group": "controls",
5669
+ "signature": "interface GemLook",
5670
+ "documented": true,
5671
+ "summary": "The look helper `gem.controls.look()` returns. Pure math: it listens to\nnothing and moves no camera — feed it the deltas your input code already\nhas and add what it returns to your camera's yaw and pitch, then clamp the\npitch as you always do.",
5672
+ "deprecated": null,
5673
+ "params": [],
5674
+ "returns": null,
5675
+ "throws": null,
5676
+ "example": null,
5677
+ "defaultValue": null,
5678
+ "guides": []
5679
+ },
5680
+ {
5681
+ "id": "GemLook.fromPointer",
5682
+ "name": "fromPointer",
5683
+ "anchor": "gemlook-frompointer",
5684
+ "group": "controls",
5685
+ "signature": "fromPointer(dx: number, dy: number, pointerType: string, pitch?: number): GemLookDelta",
5686
+ "documented": true,
5687
+ "summary": "A pointer move — a touch drag, a mouse move (under pointer lock,\n`movementX` / `movementY`) or a pen — turned into a look turn.",
5688
+ "deprecated": null,
5689
+ "params": [
5690
+ {
5691
+ "name": "dx",
5692
+ "type": "number",
5693
+ "optional": false,
5694
+ "summary": "The move across, in CSS px, right positive."
5695
+ },
5696
+ {
5697
+ "name": "dy",
5698
+ "type": "number",
5699
+ "optional": false,
5700
+ "summary": "The move down the screen, in CSS px, DOWN positive (as\n `PointerEvent` reports it). Dragging up looks up."
5701
+ },
5702
+ {
5703
+ "name": "pointerType",
5704
+ "type": "string",
5705
+ "optional": false,
5706
+ "summary": "The event's `pointerType`: `'touch'` and `'pen'` take\n the touch speeds, anything else the mouse speeds."
5707
+ },
5708
+ {
5709
+ "name": "pitch",
5710
+ "type": "number",
5711
+ "optional": true,
5712
+ "summary": "The camera's current pitch in radians (0 = the horizon,\n positive = looking up), for the touch slowdown near straight up or\n down. Leave it out to skip the slowdown."
5713
+ }
5714
+ ],
5715
+ "returns": null,
5716
+ "throws": null,
5717
+ "example": null,
5718
+ "defaultValue": null,
5719
+ "guides": []
5720
+ },
5721
+ {
5722
+ "id": "GemLook.fromStick",
5723
+ "name": "fromStick",
5724
+ "anchor": "gemlook-fromstick",
5725
+ "group": "controls",
5726
+ "signature": "fromStick(x: number, y: number, dt: number): GemLookDelta",
5727
+ "documented": true,
5728
+ "summary": "A right stick turned into a look turn over one frame.",
5729
+ "deprecated": null,
5730
+ "params": [
5731
+ {
5732
+ "name": "x",
5733
+ "type": "number",
5734
+ "optional": false,
5735
+ "summary": "The stick's horizontal axis as the Gamepad API reports it,\n −1..1, right positive."
5736
+ },
5737
+ {
5738
+ "name": "y",
5739
+ "type": "number",
5740
+ "optional": false,
5741
+ "summary": "The stick's vertical axis as the Gamepad API reports it, −1..1,\n DOWN positive. Pushing up looks up."
5742
+ },
5743
+ {
5744
+ "name": "dt",
5745
+ "type": "number",
5746
+ "optional": false,
5747
+ "summary": "The frame's duration in seconds."
5748
+ }
5749
+ ],
5750
+ "returns": null,
5751
+ "throws": null,
5752
+ "example": null,
5753
+ "defaultValue": null,
5754
+ "guides": []
5755
+ },
5756
+ {
5757
+ "id": "GemLook.set",
5758
+ "name": "set",
5759
+ "anchor": "gemlook-set",
5760
+ "group": "controls",
5761
+ "signature": "set(options: GemLookOptions): void",
5762
+ "documented": true,
5763
+ "summary": "Change your game's overrides — call it when the player changes a setting\nin your settings screen. Each key you pass replaces that override; a key\npassed as `undefined` removes it, so that input follows the Arcade again;\na key you leave out is unchanged.",
5764
+ "deprecated": null,
5765
+ "params": [
5766
+ {
5767
+ "name": "options",
5768
+ "type": "GemLookOptions",
5769
+ "optional": false,
5770
+ "summary": null
5771
+ }
5772
+ ],
5773
+ "returns": null,
5774
+ "throws": "TypeError when a sensitivity is not a finite number above 0, or\n `invertY` is not a boolean.",
5775
+ "example": null,
5776
+ "defaultValue": null,
5777
+ "guides": []
5778
+ },
5779
+ {
5780
+ "id": "ControlsApi",
5781
+ "name": "ControlsApi",
5782
+ "anchor": "controlsapi",
5783
+ "group": "controls",
5784
+ "signature": "interface ControlsApi",
5785
+ "documented": true,
5786
+ "summary": "`gem.controls` — the player's camera and controls settings: tell the Arcade\nwhich ones your game leaves to the player, and turn look input into a camera\nturn at the player's sensitivity.",
5787
+ "deprecated": null,
5788
+ "params": [],
5789
+ "returns": null,
5790
+ "throws": null,
5791
+ "example": null,
5792
+ "defaultValue": null,
5793
+ "guides": [
5794
+ {
5795
+ "slug": "what-a-game-must-do",
5796
+ "anchor": null
5797
+ }
5798
+ ]
5799
+ },
5800
+ {
5801
+ "id": "ControlsApi.declare",
5802
+ "name": "declare",
5803
+ "anchor": "controlsapi-declare",
5804
+ "group": "controls",
5805
+ "signature": "declare(uses: GemControlsDeclaration): boolean",
5806
+ "documented": true,
5807
+ "summary": "Tell the Arcade which of the player's camera and controls settings your\ngame uses, and for each one who decides it: `'player'` — you apply the\nArcade's value from `gem.prefs.recommended` (or the player's own choice\nin your settings, which wins) — or `'game'` — you decide it yourself, and\nthe Arcade's Settings shows that row as \"Set by this game\". Leave out a\nsetting your game does not use.\n\n```js\ngem.controls.declare({\n lookSensitivity: 'player',\n gamepadLookSensitivity: 'player',\n invertLookY: 'player',\n touchMovement: 'game', // this game always uses a fixed stick\n});\n```\n\n**It is screen state, not a toggle.** Each call is the whole answer and\nreplaces the last. The SDK holds it and sends it again after every\nreconnect, so call it once at boot, and again only when the answer\nchanges. Any other key or value is dropped.",
5808
+ "deprecated": null,
5809
+ "params": [
5810
+ {
5811
+ "name": "uses",
5812
+ "type": "GemControlsDeclaration",
5813
+ "optional": false,
5814
+ "summary": null
5815
+ }
5816
+ ],
5817
+ "returns": "`true` when the Arcade was told now; `false` before the bridge is\n up (the declaration is held and sent when it connects), outside the\n Arcade, and under an embedder that does not show these settings. Never\n throws.",
5818
+ "throws": null,
5819
+ "example": null,
5820
+ "defaultValue": null,
5821
+ "guides": []
5822
+ },
5823
+ {
5824
+ "id": "ControlsApi.look",
5825
+ "name": "look",
5826
+ "anchor": "controlsapi-look",
5827
+ "group": "controls",
5828
+ "signature": "look(options?: GemLookOptions): GemLook",
5829
+ "documented": true,
5830
+ "summary": "Make a look helper: Roblox's camera-input math at the player's look\nsensitivity and invert. Make one and keep it.\n\n```js\nconst look = gem.controls.look();\n// A mouse under pointer lock; for touch, pass the change in clientX/clientY.\ncanvas.addEventListener('pointermove', (e) => {\n if (document.pointerLockElement !== canvas) return;\n const t = look.fromPointer(e.movementX, e.movementY, e.pointerType, camera.pitch);\n camera.yaw += t.yaw;\n camera.pitch = clamp(camera.pitch + t.pitch, -1.4, 1.4);\n});\n```\n\nThe sensitivity and invert are read **live** on every call: the Arcade's\n`gem.prefs.recommended` values, unless `options` (or a later\n[GemLook.set](api-reference-game.md#gemlook-set)) gives your game's own, which win.",
5831
+ "deprecated": null,
5832
+ "params": [
5833
+ {
5834
+ "name": "options",
5835
+ "type": "GemLookOptions",
5836
+ "optional": true,
5837
+ "summary": null
5838
+ }
5839
+ ],
5840
+ "returns": null,
5841
+ "throws": "TypeError when an option is malformed, as [GemLook.set](api-reference-game.md#gemlook-set).",
5842
+ "example": null,
5843
+ "defaultValue": null,
5844
+ "guides": []
5845
+ },
5846
+ {
5847
+ "id": "ControlsApi.LOOK_BASE",
5848
+ "name": "LOOK_BASE",
5849
+ "anchor": "controlsapi-look_base",
5850
+ "group": "controls",
5851
+ "signature": "readonly LOOK_BASE: GemLookBase",
5852
+ "documented": true,
5853
+ "summary": "The base speeds `look` applies at 1×, in radians. Frozen.",
5854
+ "deprecated": null,
5855
+ "params": [],
5856
+ "returns": null,
5857
+ "throws": null,
5858
+ "example": null,
5859
+ "defaultValue": null,
5860
+ "guides": []
5861
+ },
5862
+ {
5863
+ "id": "GemControlChoice",
5864
+ "name": "GemControlChoice",
5865
+ "anchor": "gemcontrolchoice",
5866
+ "group": "controls",
5867
+ "signature": "type GemControlChoice = \"player\" | \"game\"",
5868
+ "documented": true,
5869
+ "summary": "Who decides one camera or controls setting: `'player'` — your game applies\nthe Arcade's value, or the player's own in-game choice, which wins — or\n`'game'` — your game decides it itself, and the Arcade's Settings shows the\nrow as \"Set by this game\".",
5870
+ "deprecated": null,
5871
+ "params": [],
5872
+ "returns": null,
5873
+ "throws": null,
5874
+ "example": null,
5875
+ "defaultValue": null,
5876
+ "guides": []
5877
+ },
5878
+ {
5879
+ "id": "GemControlsDeclaration",
5880
+ "name": "GemControlsDeclaration",
5881
+ "anchor": "gemcontrolsdeclaration",
5882
+ "group": "controls",
5883
+ "signature": "interface GemControlsDeclaration",
5884
+ "documented": true,
5885
+ "summary": "What `gem.controls.declare` takes: for each of the player's camera and\ncontrols settings your game uses, who decides it. Leave a setting out when\nyour game does not use it at all — the Arcade then says \"This game doesn't\nuse this\" beside that row.",
5886
+ "deprecated": null,
5887
+ "params": [],
5888
+ "returns": null,
5889
+ "throws": null,
5890
+ "example": null,
5891
+ "defaultValue": null,
5892
+ "guides": []
5893
+ },
5894
+ {
5895
+ "id": "GemControlsDeclaration.lookSensitivity",
5896
+ "name": "lookSensitivity",
5897
+ "anchor": "gemcontrolsdeclaration-looksensitivity",
5898
+ "group": "controls",
5899
+ "signature": "readonly lookSensitivity?: GemControlChoice",
5900
+ "documented": true,
5901
+ "summary": "Look speed for touch, mouse and pen — `gem.prefs.recommended.lookSensitivity`.",
5902
+ "deprecated": null,
5903
+ "params": [],
5904
+ "returns": null,
5905
+ "throws": null,
5906
+ "example": null,
5907
+ "defaultValue": null,
5908
+ "guides": []
5909
+ },
5910
+ {
5911
+ "id": "GemControlsDeclaration.gamepadLookSensitivity",
5912
+ "name": "gamepadLookSensitivity",
5913
+ "anchor": "gemcontrolsdeclaration-gamepadlooksensitivity",
5914
+ "group": "controls",
5915
+ "signature": "readonly gamepadLookSensitivity?: GemControlChoice",
5916
+ "documented": true,
5917
+ "summary": "Look speed for a gamepad stick — `gem.prefs.recommended.gamepadLookSensitivity`.",
5918
+ "deprecated": null,
5919
+ "params": [],
5920
+ "returns": null,
5921
+ "throws": null,
5922
+ "example": null,
5923
+ "defaultValue": null,
5924
+ "guides": []
5925
+ },
5926
+ {
5927
+ "id": "GemControlsDeclaration.invertLookY",
5928
+ "name": "invertLookY",
5929
+ "anchor": "gemcontrolsdeclaration-invertlooky",
5930
+ "group": "controls",
5931
+ "signature": "readonly invertLookY?: GemControlChoice",
5932
+ "documented": true,
5933
+ "summary": "Inverted up/down look — `gem.prefs.recommended.invertLookY`.",
5934
+ "deprecated": null,
5935
+ "params": [],
5936
+ "returns": null,
5937
+ "throws": null,
5938
+ "example": null,
5939
+ "defaultValue": null,
5940
+ "guides": []
5941
+ },
5942
+ {
5943
+ "id": "GemControlsDeclaration.touchMovement",
5944
+ "name": "touchMovement",
5945
+ "anchor": "gemcontrolsdeclaration-touchmovement",
5946
+ "group": "controls",
5947
+ "signature": "readonly touchMovement?: GemControlChoice",
5948
+ "documented": true,
5949
+ "summary": "The touch movement thumbstick, floating or fixed — `gem.prefs.recommended.touchMovement`.",
5950
+ "deprecated": null,
5951
+ "params": [],
5952
+ "returns": null,
5953
+ "throws": null,
5954
+ "example": null,
5955
+ "defaultValue": null,
5956
+ "guides": []
5957
+ },
5388
5958
  {
5389
5959
  "id": "DEVICE_SETTINGS_MAX_BYTES",
5390
5960
  "name": "DEVICE_SETTINGS_MAX_BYTES",
@@ -5982,6 +6552,29 @@
5982
6552
  "defaultValue": null,
5983
6553
  "guides": []
5984
6554
  },
6555
+ {
6556
+ "id": "GemFrame.declareControls",
6557
+ "name": "declareControls",
6558
+ "anchor": "gemframe-declarecontrols",
6559
+ "group": "frame",
6560
+ "signature": "declareControls(uses: GemControlsDeclaration): boolean",
6561
+ "documented": true,
6562
+ "summary": "Tell the arcade which of the player's camera and controls settings your\ngame leaves to the player and which it decides itself — the whole answer\neach time, the latest one winning.\n\nPrefer `gem.controls.declare`, which holds the declaration across a\nreconnect. This one sends only while connected, and only to an arcade\nthat shows these settings.",
6563
+ "deprecated": null,
6564
+ "params": [
6565
+ {
6566
+ "name": "uses",
6567
+ "type": "GemControlsDeclaration",
6568
+ "optional": false,
6569
+ "summary": null
6570
+ }
6571
+ ],
6572
+ "returns": "whether the message left the frame — `false` before the bridge is\n up, for an arcade that does not show these settings, and past this\n frame's own limit.",
6573
+ "throws": null,
6574
+ "example": null,
6575
+ "defaultValue": null,
6576
+ "guides": []
6577
+ },
5985
6578
  {
5986
6579
  "id": "GemFrame.setMenu",
5987
6580
  "name": "setMenu",
@@ -8109,7 +8702,7 @@
8109
8702
  "group": "player",
8110
8703
  "signature": "readonly recommended: GemRecommendedSettings | null",
8111
8704
  "documented": true,
8112
- "summary": "The player's Arcade-wide defaults for this device — a volume, battery\nsaver, a keyboard layout, the gamepad's confirm button and vibration — or\n`null` when the Arcade did not send them.\n\n**Recommendations only; the player's own choice in your game wins.** Start\na setting from here while the player has made no choice of their own for\nit, and never overwrite one they made because this changed:\n\n```js\nconst saved = gem.deviceSettings.current ?? {};\nconst volume = saved.volume ?? gem.prefs?.recommended?.volume ?? 100;\n```\n\nUnlike `muted` and `reducedMotion`, nothing here is applied for you, and\nnothing obliges you to use it. See the guide's \"Game settings\" section.",
8705
+ "summary": "The player's Arcade-wide defaults for this device — a volume, battery\nsaver, a keyboard layout, the gamepad's confirm button, vibration, and the\ncamera and controls settings (look sensitivity, gamepad look sensitivity,\ninvert look, touch movement) — or `null` when the Arcade did not send them.\n\n**Recommendations only; the player's own choice in your game wins.** Start\na setting from here while the player has made no choice of their own for\nit, and never overwrite one they made because this changed:\n\n```js\nconst saved = gem.deviceSettings.current ?? {};\nconst volume = saved.volume ?? gem.prefs?.recommended?.volume ?? 100;\n```\n\nUnlike `muted` and `reducedMotion`, nothing here is applied for you, and\nnothing obliges you to use it. See the guide's \"Game settings\" section.",
8113
8706
  "deprecated": null,
8114
8707
  "params": [],
8115
8708
  "returns": null,
@@ -8219,6 +8812,70 @@
8219
8812
  "defaultValue": null,
8220
8813
  "guides": []
8221
8814
  },
8815
+ {
8816
+ "id": "GemRecommendedSettings.lookSensitivity",
8817
+ "name": "lookSensitivity",
8818
+ "anchor": "gemrecommendedsettings-looksensitivity",
8819
+ "group": "player",
8820
+ "signature": "readonly lookSensitivity: number",
8821
+ "documented": true,
8822
+ "summary": "The player's look speed for touch, mouse and pen, as a percentage of the\nbase speeds: `100` is 1×, from `20` (0.2×) to `400` (4×). `100` when the\nArcade did not say. `gem.controls.look()` applies it for you.",
8823
+ "deprecated": null,
8824
+ "params": [],
8825
+ "returns": null,
8826
+ "throws": null,
8827
+ "example": null,
8828
+ "defaultValue": null,
8829
+ "guides": []
8830
+ },
8831
+ {
8832
+ "id": "GemRecommendedSettings.gamepadLookSensitivity",
8833
+ "name": "gamepadLookSensitivity",
8834
+ "anchor": "gemrecommendedsettings-gamepadlooksensitivity",
8835
+ "group": "player",
8836
+ "signature": "readonly gamepadLookSensitivity: number",
8837
+ "documented": true,
8838
+ "summary": "The player's look speed for a gamepad stick, as a percentage: `100` is 1×,\nfrom `20` to `400`. `100` when the Arcade did not say.\n`gem.controls.look()` applies it for you.",
8839
+ "deprecated": null,
8840
+ "params": [],
8841
+ "returns": null,
8842
+ "throws": null,
8843
+ "example": null,
8844
+ "defaultValue": null,
8845
+ "guides": []
8846
+ },
8847
+ {
8848
+ "id": "GemRecommendedSettings.invertLookY",
8849
+ "name": "invertLookY",
8850
+ "anchor": "gemrecommendedsettings-invertlooky",
8851
+ "group": "player",
8852
+ "signature": "readonly invertLookY: boolean",
8853
+ "documented": true,
8854
+ "summary": "Whether the player wants up/down look inverted: pushing up or dragging up\nlooks down. Flips pitch only, never yaw. `false` when the Arcade did not\nsay. `gem.controls.look()` applies it for you.",
8855
+ "deprecated": null,
8856
+ "params": [],
8857
+ "returns": null,
8858
+ "throws": null,
8859
+ "example": null,
8860
+ "defaultValue": null,
8861
+ "guides": []
8862
+ },
8863
+ {
8864
+ "id": "GemRecommendedSettings.touchMovement",
8865
+ "name": "touchMovement",
8866
+ "anchor": "gemrecommendedsettings-touchmovement",
8867
+ "group": "player",
8868
+ "signature": "readonly touchMovement: \"floating\" | \"fixed\"",
8869
+ "documented": true,
8870
+ "summary": "On a touch screen, the movement thumbstick the player wants: `'floating'`\nappears where the thumb lands, `'fixed'` stays in one place. `'floating'`\nwhen the Arcade did not say. Your game draws the stick.",
8871
+ "deprecated": null,
8872
+ "params": [],
8873
+ "returns": null,
8874
+ "throws": null,
8875
+ "example": null,
8876
+ "defaultValue": null,
8877
+ "guides": []
8878
+ },
8222
8879
  {
8223
8880
  "id": "GemCohort",
8224
8881
  "name": "GemCohort",
@@ -9099,6 +9756,22 @@
9099
9756
  }
9100
9757
  ]
9101
9758
  },
9759
+ {
9760
+ "id": "Gem.controls",
9761
+ "name": "controls",
9762
+ "anchor": "gem-controls",
9763
+ "group": "start",
9764
+ "signature": "readonly controls: ControlsApi",
9765
+ "documented": true,
9766
+ "summary": "The player's camera and controls settings — look sensitivity, gamepad look\nsensitivity, invert look and touch movement, which arrive in\n`gem.prefs.recommended`. Two things to do with them:\n\n```js\n// 1. Tell the Arcade which ones your game leaves to the player.\ngem.controls.declare({ lookSensitivity: 'player', invertLookY: 'player' });\n\n// 2. Turn look input into a camera turn at the player's sensitivity.\nconst look = gem.controls.look();\n// dx, dy: the pointer's move in CSS px since the last event.\nconst t = look.fromPointer(dx, dy, e.pointerType, camera.pitch);\ncamera.yaw += t.yaw;\ncamera.pitch += t.pitch;\n```\n\nSee the guide's \"Camera and look controls\" section.",
9767
+ "deprecated": null,
9768
+ "params": [],
9769
+ "returns": null,
9770
+ "throws": null,
9771
+ "example": null,
9772
+ "defaultValue": null,
9773
+ "guides": []
9774
+ },
9102
9775
  {
9103
9776
  "id": "Gem.analytics",
9104
9777
  "name": "analytics",