ソースを参照

New input manual. Fixes to getting started and gui layouts manuals.

Mikael Säker 7 年 前
コミット
2bac775837
38 ファイル変更164 行追加323 行削除
  1. 1 1
      docs/en/manuals/gui-layouts.md
  2. BIN
      docs/en/manuals/images/input/actions.png
  3. BIN
      docs/en/manuals/images/input/[email protected]
  4. BIN
      docs/en/manuals/images/input/consuming.png
  5. BIN
      docs/en/manuals/images/input/[email protected]
  6. BIN
      docs/en/manuals/images/input/game.png
  7. BIN
      docs/en/manuals/images/input/[email protected]
  8. BIN
      docs/en/manuals/images/input/game_paused.png
  9. BIN
      docs/en/manuals/images/input/[email protected]
  10. BIN
      docs/en/manuals/images/input/gamepad_setting.png
  11. BIN
      docs/en/manuals/images/input/[email protected]
  12. BIN
      docs/en/manuals/images/input/gamepads.png
  13. BIN
      docs/en/manuals/images/input/[email protected]
  14. BIN
      docs/en/manuals/images/input/input_binding.png
  15. BIN
      docs/en/manuals/images/input/[email protected]
  16. BIN
      docs/en/manuals/images/input/input_bindings.png
  17. BIN
      docs/en/manuals/images/input/input_key_bindings.png
  18. BIN
      docs/en/manuals/images/input/input_marked_text.png
  19. BIN
      docs/en/manuals/images/input/input_multitouch.png
  20. BIN
      docs/en/manuals/images/input/input_pause_gui.png
  21. BIN
      docs/en/manuals/images/input/input_pause_menu_1.png
  22. BIN
      docs/en/manuals/images/input/input_pause_menu_2.png
  23. BIN
      docs/en/manuals/images/input/input_set_bindings.png
  24. BIN
      docs/en/manuals/images/input/input_stack.png
  25. BIN
      docs/en/manuals/images/input/[email protected]
  26. BIN
      docs/en/manuals/images/input/input_stack_consume.png
  27. BIN
      docs/en/manuals/images/input/input_stack_order.png
  28. BIN
      docs/en/manuals/images/input/input_stack_proxy.png
  29. BIN
      docs/en/manuals/images/input/marked_text.png
  30. BIN
      docs/en/manuals/images/input/[email protected]
  31. BIN
      docs/en/manuals/images/input/overview.png
  32. BIN
      docs/en/manuals/images/input/[email protected]
  33. BIN
      docs/en/manuals/images/input/proxy.png
  34. BIN
      docs/en/manuals/images/input/[email protected]
  35. BIN
      docs/en/manuals/images/input/setting.png
  36. BIN
      docs/en/manuals/images/input/[email protected]
  37. 162 321
      docs/en/manuals/input.md
  38. 1 1
      docs/en/tutorials/getting-started.md

+ 1 - 1
docs/en/manuals/gui-layouts.md

@@ -22,7 +22,7 @@ Height
 : The pixel height of the qualifier.
 
 Device Models
-: A comma separated list of device models. The device model matches the start of the device model name, e.g. "iPhone10" will match "iPhone10,3". Note that the only platforms reporting a device model when calling `sys.get_sys_info()` is Android and iOS. Other platforms return an empty string and will therefore never pick a display profile that has a device model qualifier.
+: A comma separated list of device models. The device model matches the start of the device model name, e.g. `iPhone10` will match "iPhone10,\*" models. Model names with commas should be enclosed in quotes, i.e. `"iPhone10,3", "iPhone10,6"` matches iPhone X models (see https://www.theiphonewiki.com/wiki/Models). Note that the only platforms reporting a device model when calling `sys.get_sys_info()` is Android and iOS. Other platforms return an empty string and will therefore never pick a display profile that has a device model qualifier.
 
 ![New display profiles](images/gui-layouts/new_profiles.png){srcset="images/gui-layouts/[email protected] 2x"}
 

BIN
docs/en/manuals/images/input/actions.png


BIN
docs/en/manuals/images/input/[email protected]


BIN
docs/en/manuals/images/input/consuming.png


BIN
docs/en/manuals/images/input/[email protected]


BIN
docs/en/manuals/images/input/game.png


BIN
docs/en/manuals/images/input/[email protected]


BIN
docs/en/manuals/images/input/game_paused.png


BIN
docs/en/manuals/images/input/[email protected]


BIN
docs/en/manuals/images/input/gamepad_setting.png


BIN
docs/en/manuals/images/input/[email protected]


BIN
docs/en/manuals/images/input/gamepads.png


BIN
docs/en/manuals/images/input/[email protected]


BIN
docs/en/manuals/images/input/input_binding.png


BIN
docs/en/manuals/images/input/[email protected]


BIN
docs/en/manuals/images/input/input_bindings.png


BIN
docs/en/manuals/images/input/input_key_bindings.png


BIN
docs/en/manuals/images/input/input_marked_text.png


BIN
docs/en/manuals/images/input/input_multitouch.png


BIN
docs/en/manuals/images/input/input_pause_gui.png


BIN
docs/en/manuals/images/input/input_pause_menu_1.png


BIN
docs/en/manuals/images/input/input_pause_menu_2.png


BIN
docs/en/manuals/images/input/input_set_bindings.png


BIN
docs/en/manuals/images/input/input_stack.png


BIN
docs/en/manuals/images/input/[email protected]


BIN
docs/en/manuals/images/input/input_stack_consume.png


BIN
docs/en/manuals/images/input/input_stack_order.png


BIN
docs/en/manuals/images/input/input_stack_proxy.png


BIN
docs/en/manuals/images/input/marked_text.png


BIN
docs/en/manuals/images/input/[email protected]


BIN
docs/en/manuals/images/input/overview.png


BIN
docs/en/manuals/images/input/[email protected]


BIN
docs/en/manuals/images/input/proxy.png


BIN
docs/en/manuals/images/input/[email protected]


BIN
docs/en/manuals/images/input/setting.png


BIN
docs/en/manuals/images/input/[email protected]


+ 162 - 321
docs/en/manuals/input.md

@@ -1,355 +1,213 @@
 ---
 title: Device input in Defold
-brief: This manual explains how you capture input actions and create interactive script reactions.
+brief: This manual explains how input works, how to capture input actions and create interactive script reactions.
 ---
 
 # Device input
 
-Defold is capable of listening to input from a variety of devices and you can set up custom mapping from device input to input *actions* that your script logic can react to. Input handling in Defold is simple and powerful, allowing you to manage input as you see fit for your game. 
+All user input is captured by the engine and dispatched as actions to script- and GUI script components in game objects that have acquired input focus and that implement the `on_input()` function. This manual explains how you set up bindings to capture input and how you create code that responds to it. 
 
-Defold supports the following input device types:
+The input system uses a set of simple and powerful concepts, allowing you to manage input as you see fit for your game.
 
-1. Keyboard (key and text input)
-2. Mouse (including mouse wheel actions)
-3. Multitouch (on iOS and Android devices)
-4. Gamepads (as supported through the operating system)
+![Input bindings](images/input/overview.png){srcset="images/input/[email protected] 2x"}
 
-::: important
-On Windows, only XBox 360 controllers are currently supported. To hook up your 360 controller to your Windows machine, make sure it is setup correctly. See http://www.wikihow.com/Use-Your-Xbox-360-Controller-for-Windows
-:::
+Devices
+: Input devices that are either part of, or plugged into, your computer or mobile device provide raw system level input to the Defold runtime. The following device types are supported:
 
-All user input is captured by the engine and dispatched as actions to script- and GUI script components in game objects that have acquired input focus and that implement the `on_input()` function.
+  1. Keyboard (single key as well as text input)
+  2. Mouse (position, button clicks and mouse wheel actions)
+  3. Multitouch (on iOS and Android devices)
+  4. Gamepads (as supported through the operating system and mapped in the [gamepads](#_gamepads) file)
 
-Before the input reaches your scripts it is translated through input bindings into meaningful actions:
+Input bindings
+: Before input is sent to a script the raw input from the device is translated into meaningful *actions* via the input bindings table.
 
-![Input bindings](images/input/input_bindings.png)
+Actions
+: Actions are identified by the (hashed) names that you list in the input bindings file. Each action also contain relevant data about the input: if a button is pressed or released, the coordinates of the mouse and touch etc.
 
-Depending on which components have acquired input focus and whether they consume this input or pass it on, the input may or may not reach a specific component's `on_input()`. We will look at how this works in detail below.
+Input listeners
+: Any script component or GUI script can receive input actions by *acquiring input focus*. Several listeners can be active at the same time.
 
-## Input bindings
+Input stack
+: The list of input listeners with the first acquirer of focus at the bottom of the stack and the last acquirer at the top.
 
-The input bindings is a project wide table that allows you to specify how raw input should translated into meaningful *actions* before they are dispatched to your Lua scripts. The input bindings is by default named *game.input_binding* and is found in the *input* folder at the root of your project. You can, however, easily change its name and location and update the project settings so the engine will find the bindings (see [Project settings](/manuals/project-settings)).
+Consuming input
+: A script may choose to consume the input it received, preventing listeners further down the stack to receive it.
 
-![Input set bindings](images/input/input_set_bindings.png)
+## Setting up input bindings
 
-There are five types of triggers that you can create. They are device specific:
+The input bindings is a project wide table that allows you to specify how device input should translate into named *actions* before they are dispatched to your script components and GUI scripts. You can create a new input binding file, <kbd>right click</kbd> a location in the *Assets* view and select <kbd>New... ▸ Input Binding</kbd>. To make the enginen use the new file, change the *Game Binding* entry in "game.project".
 
-1. `key_trigger` and `text_trigger` are for keyboard button input.
-2. `mouse_trigger` is for mouse input.
-3. `gamepad_trigger` is for system gamepads (e.g. Xbox or Playstation controllers).
-4. `touch_trigger` is for all types of touch input.
-5. `text_trigger` is for text input.
+![Input binding setting](images/input/setting.png){srcset="images/input/[email protected] 2x"}
 
-Right click on a trigger type and select <kbd>Add [TYPE]\_trigger...</kbd> to add a new trigger. Each trigger has two fields:
+A default input binding file is automatically created with all new project templates so there is usually no need to create a new binding file. The default file is called "game.input_binding" and can be found in the "input" folder in the project root. <kbd>Double click</kbd> the file to open it in the editor:
 
-*input*
-: The raw input to listen for, selected from a scroll list of available inputs.
-
-*action*
-: The action name given to input actions when they are created and dispatched to your scripts. It is fine to have the same action names assigned to multiple actions. For instance, it is convenient to be able to bind the <kbd>Space</kbd> key to the action `jump` and the gamepad "A" button to the same action name.
-
-::: sidenote
-There is a known bug where touch inputs unfortunately cannot have the same action names as other inputs.
-:::
-
-For instance, to set up key bindings for movement left and right for a game, you might want to do something like this:
-
-![Input key bindings](images/input/input_key_bindings.png)
-
-Here, the inputs `KEY_LEFT` (the left arrow key on the keyboard) and `KEY_RIGHT` (the right arrow key) are bound to the action names `move_left` and `move_right` respectively. The benefit of separating the hardware input from the logical actions is that if you decide later on that you want to change which hardware inputs trigger what actions, you only have to modify it in one place.
-
-## Acquiring and releasing input focus
+![Input set bindings](images/input/input_binding.png){srcset="images/input/[email protected] 2x"}
 
-To listen to input actions, create a game object with a script (or GUI script) component. In the script, send the game object itself a message `acquire_input_focus`:
+To create a new binding, click the <kbd>+</kbd> button at the bottom of the relevant trigger type section. Each entry has two fields:
 
-```lua
-function init(self)
-    msg.post(".", "acquire_input_focus")
-end
-```
+*Input*
+: The raw input to listen for, selected from a scroll list of available inputs.
 
-This message instructs Defold to direct input actions to the current game object. Technically, what happens is that the object is added to an *input stack* (see below for further details).
-To stop listening to input actions, simply send a `release_input_focus` message to the game object:
+*Action*
+: The action name given to input actions when they are created and dispatched to your scripts. The same action name can be assigned to multiple inputs. For instance, you can bind the <kbd>Space</kbd> key and the gamepad "A" button to the action `jump`. Note that there is a known bug where touch inputs unfortunately cannot have the same action names as other inputs.
 
-```lua
-...
-msg.post(".", "release_input_focus")
-...
-```
+## Trigger types
 
-## on_input()
+There are five device specific types of triggers that you can create
 
-To react to input actions, you need a component in your game object (that has acquired input focus) with a script and an `on_input()` function. The engine will then dispatch input actions to the function.
+Key Triggers
+: Single key keyboard input. Each key is mapped separately into a corresponding action. Key triggers are used to tie specific buttons to specific functions, like character movement with the arrow or WASD keys. If you need to read arbitrary keyboard input, use text triggers (see below).
 
-```lua
-function on_input(self, action_id, action)
-```
+Mouse Triggers
+: Input from mouse buttons and scroll wheels. Mouse movement is handled separately. Mouse movement events are not received unless at least one mouse trigger is set up in your input bindings.
 
-The function takes 2 parameters (besides "self"):
+  - Mouse button inputs `MOUSE_BUTTON_LEFT`, `MOUSE_BUTTON_RIGHT` and `MOUSE_BUTTON_MIDDLE` are equivalent to `MOUSE_BUTTON_1`, `MOUSE_BUTTON_2` and `MOUSE_BUTTON_3`. `MOUSE_BUTTON_LEFT` (or `MOUSE_BUTTON_1`) input actions are sent for single touch inputs as well.
 
-`action_id`
-: The name of the message, as set up in the input bindings. The name is hashed.
+  - Mouse wheel inputs detect scroll actions. The field `action.value` is `1` if the wheel is scrolled and `0` otherwise. (Scroll actions are dealt with as they were button presses. Defold does not currently support fine grained scroll input on touch pads.)
 
-`action`
-: A Lua table containing the message data.
+  - Mouse movement are not bound in the input bindings but `action_id` is set to `nil` and the `action` table is populated with the location and delta movement of the mouse position.
 
-To (very crudely) handle the `move_left` and `move_right` bindings we set up above, we can write the following code:
+Gamepad Triggers
+: Gamepad triggers allow you to bind standard gamepad input to game functions. Defold supports multiple gamepads through the host operating system, actions set the `gamepad` field of the action table to the gamepad number the input originated from:
 
-```lua
-function on_input(self, action_id, action)
-    if action_id == hash("move_left") and action.pressed then
-        local pos = go.get_position()
-        pos.x = pos.x - 100
-        go.set_position(pos)
-    elseif action_id == hash("move_right") and action.pressed then
-        local pos = go.get_position()
-        pos.x = pos.x + 100
-        go.set_position(pos)
+  ```lua
+  if action_id == hash("gamepad_start") then
+    if action.gamepad == 0 then
+      -- gamepad 0 wants to join the game
     end
-end
-```
-
-::: important
-When working with collection proxies it is imperative to understand how input is dispatched through collections. If you can't get input to work with your collection proxies, make sure to read "Input and Collection Proxies" below.
-:::
-
-## Action fields
-
-The `action` parameter sent to `on_input()` for each input message is a Lua table containing useful data like the value of the input, the position of the input and whether button input was `pressed`, `repeated` or `released`.
-
-`action.pressed`
-: `true` the first frame the input was detected, otherwise `false`.
-
-`action.repeated`
-: `true` if the input was repeated, otherwise `false`. Note that this value is _not_ set each frame by default, but depends on the `repeat_delay` and `repeat_interval` [project settings](/manuals/project-settings#_input).
-
-`action.released`
-: `true` the frame the input was released, otherwise `false`.
-
-
-::: sidenote
-See [on_input()](/ref/go#on_input) for details on the available action fields.
-:::
-
-## Screen positions
-
-Mouse and touch inputs set fields in the `action` table for location (`x` and `y`) as well as movement (`dx` and `dy`). These inputs also set specific fields that are calculated against the real screen space. These fields are called:
-
-`screen_x` and `screen_y`
-: The real screen position
-
-`screen_dx` and `screen_dy`
-: The real screen delta change since last update
-
-These fields are useful on devices where the screen pixel position differs from the game position--for instance if you run a lower resolution game on a retina screen that scales the game. For instance, on the iPad you can have a screen that is 1024x768 but each "logical" pixels consists of 4 real ones and maps to a physical resolution of 2048x1536.
+  end
+  ```
 
-## Key triggers
+  Gamepad input and offers bindings for:
 
-Key triggers are simple one-key inputs that act as button inputs. They are useful for games that need to tie specific buttons to specific functions, like the `move_left` and `move_right` button setup above. If you need to read arbitrary key input, use text triggers (see below).
+  - Left and right sticks (direction and clicks)
+  - Left and right digital pads. Right pad usually translates to the "A", "B", "X" and "Y" buttons on the Xbox controller and "square", "circle", "triangle" and "cross" buttons on the Playstation controller.
+  - Left and right triggers
+  - Left and right shoulder buttons
+  - Start, Back and Guide buttons
 
-## Mouse triggers
+  On Windows, only XBox 360 controllers are currently supported. To hook up your 360 controller to your Windows machine, make sure it is setup correctly. See http://www.wikihow.com/Use-Your-Xbox-360-Controller-for-Windows
 
-Mouse input comes in two forms. First there are mouse button and wheel inputs, which are set up in your input bindings just like key triggers; then there is mouse movement input, which is handled differently (see below).
+  Gamepad input setup uses a separate mapping file for each hardware gamepad type. See below for more information.
 
-Mouse button inputs
-: Use these to detect mouse button presses.
+Touch Triggers
+: Multi-touch type triggers are available on iOS and Android devices. They populate a table in the action table called `touch`. The elements in the table are integer-indexed with numbers `1`--`N`where `N` is the number of touch points. Each element of the table contains fields with input data:
 
-  Note that the inputs `MOUSE_BUTTON_LEFT`, `MOUSE_BUTTON_RIGHT` and `MOUSE_BUTTON_MIDDLE` are equivalent to `MOUSE_BUTTON_1`, `MOUSE_BUTTON_2` and `MOUSE_BUTTON_3`.
+  ```lua
+  -- Spawn at each touch point
+  for i, touchdata in ipairs(action.touch) do
+    local pos = vmath.vector3(touchdata.x, touchdata.y, 0)
+    factory.create("#factory", pos)
+  end
+  ```
 
-::: sidenote
-Currently, `MOUSE_BUTTON_LEFT` (or `MOUSE_BUTTON_1`) input actions are sent for single touch inputs as well.
-:::
+Text Triggers
+: Text triggers are used to read arbitrary text input. There are two types of text triggers:
 
-Mouse wheel inputs
-: Use these to detect scroll actions. The field `action.value` is `1` if the wheel is scrolled and `0` otherwise. (Scroll actions are dealt with as they were button presses. Defold does not currently support fine grained scroll input on touch pads.)
+  - `text` captures normal text input. It sets the `text` field of the action table to a string containing the typed character. The action is only fired at the press of the button, no `release` or `repeated` action is sent.
 
-Mouse movement
-: Mouse movement cannot be bound in the input bindings, and does not set the `action_id` to a name. Instead, the `action_id` is set to `nil` and the `action` table is populated with the location and delta movement of the mouse position. Note that mouse movement events are not received unless at least one mouse trigger is set up in your input bindings.
+    ```lua
+    if action_id == hash("text") then
+      -- Concatenate the typed character to the "user" node...
+      local node = gui.get_node("user")
+      local name = gui.get_text(node)
+      name = name .. action.text
+      gui.set_text(node, name)
+    end
+    ```
 
-## Gamepad triggers
+  - `marked-text` is used primarily for asian keyboards where multiple keypresses can map to single inputs. For example, with the iOS "Japanese-Kana" keyboard, the user can type combinations and the top of the keyboard will display avaliable symbols or sequences of symbols that can be entered.
 
-Gamepad triggers allow you to bind standard gamepad input to game functions. Defold supports multiple gamepads through the host operating system and offers bindings for:
+  ![Input marked text](images/input/marked_text.png){srcset="images/input/[email protected] 2x"}
 
-1. Left and right sticks (direction and clicks)
-2. Left and right digital pads
-3. Left and right triggers
-4. Left and right shoulder buttons
-5. Start, Back and Guide buttons
+  - Each keypress generates a separate action and sets the action field `text` to the currently entered sequence of symbols (the "marked text").
+  - When the user selects a symbol or symbol combination, a separate `text` type trigger action is sent (provided that one is set up in the input binding list). The separate action sets the action field `text` to the final sequence of symbols.
 
-::: sidenote
-Right pad usually translates to the "A", "B", "X" and "Y" buttons on the Xbox controller and "square", "circle", "triangle" and "cross" buttons on the Playstation controller.
-:::
+## Input focus
 
-Gamepad input sets the `gamepad` field of the action table to the gamepad number the
-input originated from.
+To listen to input actions in a script component or GUI script, the message `acquire_input_focus` should be sent to the game object holding the component:
 
 ```lua
-function on_input(self, action_id, action)
-    if action_id == hash("gamepad_start") then
-        ...
-        if action.gamepad == 0 then
-            -- gamepad 0 wants to join the game
-            ...
-        end
-    end
-end
+-- tell the current game object (".") to acquire input focus
+msg.post(".", "acquire_input_focus")
 ```
 
-## Touch triggers
+This message instructs the engine to add input capable components (script components, GUI components and collection proxies) in the game objects to the *input stack*. The game object components are put on top of the input stack; the component that is added last will be top of the stack. Note that if the game object contains more than one input capable component, all components will be added to the stack: 
+
+![Input stack](images/input/input_stack.png){srcset="images/input/[email protected] 2x"}
 
-Touch and multi-touch triggers populate a subtable in the action table called `action.touch`. The elements in the table are numbered `1`--`N` (where `N` is the number of touch points) and each element contains fields with input data.
+Each game world that is dynamically loaded through a collection proxy has its own input stack. For action dispatch to reach the loaded world's input stack, the proxy component must be on the main world's input stack.
 
-::: sidenote
-See [`on_input()`](/ref/go#on_input) for details on the available touch action fields.
-:::
+If a game object that has already aquired input focus does so again, its component(s) will be moved to the top of the stack.
 
-Since the elements are in a numbered table, array-like, you can traverse it easily:
+To stop listening to input actions, send a `release_input_focus` message to the game object. This message will remove any of the game object's components from the input stack:
 
 ```lua
-function on_input(self, action_id, action)
-        if action_id == hash("touch") and #action.touch > 1 and #action.touch < 4 then
-                -- If there's 2-3 touch point we'll spawn
-                -- magic spark particles at each point.
-                for i, tpoint in ipairs(action.touch) do
-                        local pos = vmath.vector3(tpoint.x, tpoint.y, 0)
-                        factory.create("#factory", pos)
-                end
-        end
-end
+-- tell the current game object (".") to release input focus.
+msg.post(".", "release_input_focus")
 ```
 
-Here, a component "factory" is used to spawn a simple particle effect with `factory.create()`. The result is a nice trail of spawned particles for each finger as you touch the device screen using 2 or 3 fingers.
+## Input dispatch and on_input()
 
-![Input multitouch](images/input/input_multitouch.png)
+Input actions are dispatched according to the input stack, from the top to the bottom. 
 
-## Text triggers
+![Action dispatch](images/input/actions.png){srcset="images/input/[email protected] 2x"}
 
-Text triggers allow you to read arbitrary text input. There are two types of text triggers:
+Any component that is on the stack containing an `on_input()` function will have that function called with the following arguments:
 
-`TEXT`
-: This input trigger captures normal text input.
+`self`
+: The current script instance.
 
-  A text trigger sets the `text` field of the action table to a string containing the typed character. The action is only fired at the press of the button, no `release` or `repeated` action is sent.
-
-  ```lua
-  function on_input(self, action_id, action)
-      if action_id == hash("text") then
-          -- Concatenate the input character to the "text" node...
-          local node = gui.get_node("text")
-          local text = gui.get_text(node)
-          text = text .. action.text
-          gui.set_text(node, text)
-      end
-  end
-  ```
-
-`MARKED_TEXT`
-: This is used primarily for asian keyboards where multiple keypresses can map to single inputs.
-
-  For example, the iOS "Japanese-Kana" keyboard is a 10 key keyboard. The user can type combinations and the top of the keyboard will display avaliable symbols or sequences of symbols that can be entered.
-
-  ![Input marked text](images/input/input_marked_text.png)
-
-  Each keypress generates a separate action and sets the action field with the series of entered keypresses in the `text` field:
-
-  ```lua
-  {
-    repeated = false,
-    released = false,
-    text = た,
-    value = 0,
-    pressed = false,
-  }
-  ```
-
-  When the user selects a symbol or symbol combination, an ordinary text trigger action is sent.
-
-## The input stack
-
-Any game object that acquires input focus is put first in the list of objects that listen to input. This list is called the *input stack*. Input actions are dispatched to the top object's components first and actions then trickle further down the stack to other components that listen to input:
-
-![Input stack](images/input/input_stack.png)
-
-All actions are dispatched within the same frame so unless you deliberately control the dispatch of actions down the stack (see "Consuming input" below) it will appear as if all listening components' `on_input()` functions will receive actions simultaneously.
-
-## Stack order
-
-If you have a set of game objects that all acquire input, they get added to the top of the input stack one by one:
-
-```lua
--- in "listener1.script"
-function init(self)
-    msg.post(".", "acquire_input_focus")
-end
-
--- in "listener2.script"
-function init(self)
-    msg.post(".", "acquire_input_focus")
-end
-```
-
-Initialization and update order between objects is, however, unknown. So there is no guarantee that the listeners will appear on the stack in any specific order.
+`action_id`
+: The hashed name of the message, as set up in the input bindings.
 
-In situations where you need the listeners on the stack in a particular order you can force a specific input order between objects by chaining a series of messages:
+`action`
+: A table containing the useful data about the action, like the value of the input, its location (absolute and delta positions), whether button input was `pressed` etc. See [on_input()](/ref/go#on_input) for details on the available action fields.
 
 ```lua
--- in "listener1.script"
-function init(self)
-    -- We're added to the input stack first, "listener2" second.
-    msg.post(".", "acquire_input_focus")
-    msg.post("listener2", "acquire_input")
-end
-
--- in "listener2.script"
-function on_message(self, message_id, message, sender)
-    if message_id == hash("acquire_input") then
-        -- Acquire input when we get this message.
-        msg.post(".", "acquire_input_focus")
-    end
+function on_input(self, action_id, action)
+  if action_id == hash("left") and action.pressed then
+    -- move left
+    local pos = go.get_position()
+    pos.x = pos.x - 100
+    go.set_position(pos)
+  elseif action_id == hash("right") and action.pressed then
+    -- move right
+    local pos = go.get_position()
+    pos.x = pos.x + 100
+    go.set_position(pos)
+  end
 end
 ```
 
-Running this code will result in an input stack ordered like this:
+Collection proxy components must be on the main world's stack for input to be dispatched to the components on the loaded world's input stack. All components on a loaded world's stack are handled before dispatch continues down the main stack:
 
-![Input stack order](images/input/input_stack_order.png)
+![Action dispatch to proxies](images/input/proxy.png){srcset="images/input/[email protected] 2x"}
 
-If the same game object is added more than once to the input stack, the previous entry in the stack will be removed and entries above will be shifted down. The duplicate game object will be placed at the top of the stack. If this happens the engine will issue a warning in the console.
+It is a common error to forget to send `acquire_input_focus` to the game object holding the collection proxy component. Skipping this step prevents input from reaching any of the components on the loaded world's input stack.
 
 ## Consuming input
 
-A component's `on_input()` code can actively control whether actions should be passed on down the stack or not:
-
-1. If the component's `on_input()` code returns `false`, or if there is no return statement in the code (an omitted return statement implies a `nil` return which is a false value in Lua) input actions will be passed on to the next game object on the input stack.
-2. If any of a game object components' scripts return `true` in its `on_input()` then the input is consumed and not passed on to other objects further down the input stack.
-
-::: sidenote
-A game object can contain several script components. All input actions are broadcast to the game object's components.
+A component's `on_input()` can actively control whether actions should be passed on further down the stack or not:
 
-A game object that lacks an `on_input()` function will pass on input actions down the stack just as if it had returned `false` in an `on_input()`  function.
-:::
+- If `on_input()` returns `false`, or a return is omitted (this implies a `nil` return which is a false value in Lua) input actions will be passed on to the next component on the input stack.
+- If `on_input()` returns `true` input is consumed. No component further down the input stack will receive the input. Note that this applies to *all* input stacks. A component on a proxy-loaded world's stack can consume input preventing components on the main stack to receive input:
 
-![Consuming input](images/input/input_stack_consume.png)
+![consuming input](images/input/consuming.png){srcset="images/input/[email protected] 2x"}
 
-There are several good use cases where input consumption provides a simple and powerful way to shift input between different parts of a game. For example, if you need a pop-up menu that temporarily is the only part of the game that listens to input.
+There are manu good use cases where input consumption provides a simple and powerful way to shift input between different parts of a game. For example, if you need a pop-up menu that temporarily is the only part of the game that listens to input:
 
-Let's say that you are building a game where you control a wizard through touch input. In the corner, you put a HUD menu item that allows the player to pause the game.
-
-![Input pause menu](images/input/input_pause_menu_1.png)
+![consuming input](images/input/game.png){srcset="images/input/[email protected] 2x"}
 
 The pause menu is initially hidden (disabled) and when the player touches the "PAUSE" HUD item, it is enabled:
 
 ```lua
-function init(self)
-    msg.post(".", "acquire_input_focus")
-end
-
 function on_input(self, action_id, action)
     if action_id == hash("mouse_press") and action.pressed then
-        local x = action.x
-        local y = action.y
-        -- Get the "pause" node and see if player has pressed it.
+        -- Did the player press PAUSE?
         local pausenode = gui.get_node("pause")
-        if gui.pick_node(pausenode, x, y) then
+        if gui.pick_node(pausenode, action.x, action.y) then
             -- Tell the pause menu to take over.
             msg.post("pause_menu", "show")
         end
@@ -357,77 +215,60 @@ function on_input(self, action_id, action)
 end
 ```
 
-![Input pause menu](images/input/input_pause_menu_2.png)
+![pause menu](images/input/game_paused.png){srcset="images/input/[email protected] 2x"}
 
-The pause menu consists of a coloured background containing a set of child menu items. By disabling and enabling the "background" node, the whole pause menu GUI can be shown and hidden:
-
-![Input pause GUI](images/input/input_pause_gui.png)
-
-The pause menu GUI runs the following code:
+The pause menu GUI acquires input focus and consumes input, preventing any input other than what's relevant for the pop-up menu:
 
 ```lua
-function init(self)
-    -- Fetch background node and disable it.
-    -- Everything is childed under it.
-    local node = gui.get_node("background")
-    gui.set_enabled(node, false)
-end
-
 function on_message(self, message_id, message, sender)
-    if message_id == hash("show") then
-        -- First, show the pause menu.
-        local node = gui.get_node("background")
-        gui.set_enabled(node, true)
-
-        -- Now, acquire input. We're gonna be on top of
-        -- the input stack. Yay!
-        msg.post(".", "acquire_input_focus")
-    end
+  if message_id == hash("show") then
+    -- Show the pause menu.
+    local node = gui.get_node("pause_menu")
+    gui.set_enabled(node, true)
+
+    -- Acquire input.
+    msg.post(".", "acquire_input_focus")
+  end
 end
 
 function on_input(self, action_id, action)
-    if action_id == hash("mouse_press") and action.pressed then
-        local x = action.x
-        local y = action.y
-        -- Get the nodes and see if we have pressed any.
-        local loadnode = gui.get_node("load")
-        local savenode = gui.get_node("save")
-        local resumenode = gui.get_node("resume")
-        if gui.pick_node(loadnode, x, y) then
-            print("THE GAME WILL LOAD...")
-        elseif gui.pick_node(savenode, x, y) then
-            print("THE GAME WILL SAVE...")
-        elseif gui.pick_node(resumenode, x, y) then
-            -- Resume the game...
-            -- First, hide the pause menu.
-            local node = gui.get_node("background")
-            gui.set_enabled(node, false)
-
-            -- Finally, release input.
-            msg.post(".", "release_input_focus")
-        end
+  if action_id == hash("mouse_press") and action.pressed then
+
+    -- do things...
+
+    local resumenode = gui.get_node("resume")
+    if gui.pick_node(resumenode, action.x, action.y) then
+        -- Hide the pause menu
+        local node = gui.get_node("pause_menu")
+        gui.set_enabled(node, false)
+
+        -- Release input.
+        msg.post(".", "release_input_focus")
     end
+  end
 
-    -- As long as we're listening to input, we're gonna consume it.
-    -- This disables game controls while the pause menu is showing.
-    return true
+  -- Consume all input. Anything below us on the input stack
+  -- will never see input until we release input focus.
+  return true
 end
 ```
 
-The `on_input()` function of the pause menu GUI script returns `true` as long as the menu shows. This means that it will consume all input actions. The game is thus effectively paused from a user input perspective.
-
-## Input and Collection Proxies
+## Gamepads settings file
 
-The input stack is actually not global---there exists a separate local input stack for each collection. If you use collection proxies to structure your game it is imperative to understand how input is dispatched through collections.
+Gamepad mappings for specific hardware gamepads are set in a *gamepads* file. Defold ships with a built in gamepads file with settings for common gamepads:
 
-When input actions are passed on down the current collection's input stack and reach a game object that contains a collection proxy component that is enabled, those actions will continue down the input stack of the dynamically loaded collection before they continue down the main collection's stack. The following diagram clarifies the process:
+![Gamepad settings](images/input/gamepads.png){srcset="images/input/[email protected] 2x"}
 
-![Input stack proxy](images/input/input_stack_proxy.png)
+If you need to create a new gamepad settings file, we have a simple tool to help:
 
-It is clear now that in order for any `on_input()` component code in a dynamically loaded collection to receive input actions, the game object containing the collection proxy *must* be on the input stack.
+[Click to download gdc.zip](https://forum.defold.com/uploads/default/original/2X/1/1d05d81d57b40da69831ae822e818a834e3dc3ac.zip).
 
-Even if the collection proxy's game object contain no `on_input()` code at all, it must still send a `acquire_input_focus` message to itself to be added on top of the input stack. Any game object inside the loaded collection must send "acquire_input_focus" to get added to the collection's input stack.
+It includes binaries for Windows, Linux and macOS. Run it from the command line:
 
-Note that if at any step down the input stack an `on_input()` function returns true, then it will consume the input. It does not matter where that happens, actions will not be passed on further. If necessary, a loaded collection can therefore consume input and prevent objects further down the main collection input stack from receiving any actions.
+```sh
+./gdc
+```
 
+The tool will ask you to press different buttons on your connected controller. It will then output a new gamepads file with correct mappings for your controller. Save the new file, or merge it with your existing gamepads file, then update the setting in "game.project";
 
+![Gamepad settings](images/input/gamepad_setting.png){srcset="images/input/[email protected] 2x"}

+ 1 - 1
docs/en/tutorials/getting-started.md

@@ -5,7 +5,7 @@ brief: This tutorial explains how to get started doing tutorials in Defold.
 
 # Getting started
 
-The Defold engine and editor are powerful tools but takes a little while to get accustomed to. You should expect having to spend some time working in Defold before you know how to use it well. To help you on your way we have created a variety of tutorials. They are available directly from within the editor so you can start your journey towards becoming a Defold pro right away.
+The Defold engine and editor are powerful tools that will take a little while to get accustomed to. You should expect having to spend some time working in Defold before you know how to use it well. To help you on your way we have created a variety of tutorials. They are available directly from within the editor so you can start your journey towards becoming a Defold pro right away.
 
 ## Starting a tutorial