Răsfoiți Sursa

Merge branch 'master' of https://github.com/defold/doc

Björn Ritzl 5 ani în urmă
părinte
comite
80a9353ff9
100 a modificat fișierele cu 4606 adăugiri și 760 ștergeri
  1. 286 0
      docs/zh/faq/faq.md
  2. 62 0
      docs/zh/manuals/ads.md
  3. 22 30
      docs/zh/manuals/android.md
  4. 0 30
      docs/zh/manuals/animation.md
  5. 1 1
      docs/zh/manuals/application-lifecycle.md
  6. 1 1
      docs/zh/manuals/bob.md
  7. 8 11
      docs/zh/manuals/bundling.md
  8. 1 1
      docs/zh/manuals/collection-proxy.md
  9. 6 1
      docs/zh/manuals/components.md
  10. 92 0
      docs/zh/manuals/debugging-game-and-system-logs.md
  11. 132 0
      docs/zh/manuals/debugging-game-logic.md
  12. 83 0
      docs/zh/manuals/debugging-native-code-android.md
  13. 136 0
      docs/zh/manuals/debugging-native-code-ios.md
  14. 147 0
      docs/zh/manuals/debugging-native-code.md
  15. 1 1
      docs/zh/manuals/dev-app.md
  16. 163 69
      docs/zh/manuals/editor.md
  17. 212 0
      docs/zh/manuals/extension-facebook.md
  18. 85 0
      docs/zh/manuals/extension-fbinstant.md
  19. 21 0
      docs/zh/manuals/extension-gpgs.md
  20. 31 18
      docs/zh/manuals/extensions-debugging.md
  21. 1 1
      docs/zh/manuals/extensions-details.md
  22. 59 4
      docs/zh/manuals/extensions.md
  23. 1 207
      docs/zh/manuals/facebook.md
  24. 50 0
      docs/zh/manuals/file-access.md
  25. 33 18
      docs/zh/manuals/getting-help.md
  26. 6 0
      docs/zh/manuals/gpgs.md
  27. 0 33
      docs/zh/manuals/graphics.md
  28. 3 5
      docs/zh/manuals/gui-layouts.md
  29. 5 2
      docs/zh/manuals/html5.md
  30. 54 0
      docs/zh/manuals/http-requests.md
  31. 27 7
      docs/zh/manuals/importing-assets.md
  32. 83 0
      docs/zh/manuals/importing-graphics.md
  33. 77 0
      docs/zh/manuals/importing-models.md
  34. 5 1
      docs/zh/manuals/input.md
  35. 1 80
      docs/zh/manuals/instant-games.md
  36. 10 10
      docs/zh/manuals/introduction.md
  37. 5 3
      docs/zh/manuals/label.md
  38. 1 1
      docs/zh/manuals/libraries.md
  39. 15 0
      docs/zh/manuals/linux.md
  40. 16 0
      docs/zh/manuals/lua.md
  41. 122 0
      docs/zh/manuals/macos.md
  42. 1 1
      docs/zh/manuals/material.md
  43. 95 0
      docs/zh/manuals/mesh.md
  44. 84 18
      docs/zh/manuals/model.md
  45. 22 13
      docs/zh/manuals/networking.md
  46. 42 0
      docs/zh/manuals/nintendo-switch.md
  47. 25 0
      docs/zh/manuals/online-services.md
  48. 5 1
      docs/zh/manuals/optimization.md
  49. 12 2
      docs/zh/manuals/particlefx.md
  50. 42 12
      docs/zh/manuals/physics.md
  51. 13 2
      docs/zh/manuals/profiling.md
  52. 136 111
      docs/zh/manuals/project-settings.md
  53. 3 3
      docs/zh/manuals/push.md
  54. 22 0
      docs/zh/manuals/socket-connections.md
  55. 43 9
      docs/zh/manuals/spinemodel.md
  56. 21 5
      docs/zh/manuals/sprite.md
  57. 132 0
      docs/zh/manuals/test.md
  58. 34 0
      docs/zh/manuals/texture-filtering.md
  59. 12 7
      docs/zh/manuals/texture-profiles.md
  60. 39 2
      docs/zh/manuals/tilemap.md
  61. 1 1
      docs/zh/manuals/tilesource.md
  62. 124 0
      docs/zh/manuals/web-monetization.md
  63. 7 0
      docs/zh/manuals/websocket-connections.md
  64. 22 35
      docs/zh/manuals/webview.md
  65. 2 3
      docs/zh/manuals/windows.md
  66. 55 0
      docs/zh/manuals/working-offline.md
  67. 15 0
      docs/zh/shared/android-faq.md
  68. 13 0
      docs/zh/shared/blend-modes.md
  69. 24 0
      docs/zh/shared/components.md
  70. 11 0
      docs/zh/shared/editor-versions.md
  71. 0 0
      docs/zh/shared/editor-views.md
  72. 7 0
      docs/zh/shared/html5-faq.md
  73. 63 0
      docs/zh/shared/install.md
  74. 55 0
      docs/zh/shared/linux-faq.md
  75. 13 0
      docs/zh/shared/nintendo-switch-faq.md
  76. 3 0
      docs/zh/shared/platforms.md
  77. 5 0
      docs/zh/shared/test.md
  78. 17 0
      docs/zh/shared/url-shorthands.md
  79. 8 0
      docs/zh/shared/windows-faq.md
  80. 393 0
      docs/zh/tutorials/15-puzzle.md
  81. 27 0
      docs/zh/tutorials/astronaut.md
  82. 226 0
      docs/zh/tutorials/car.md
  83. 28 0
      docs/zh/tutorials/colorslide.md
  84. 35 0
      docs/zh/tutorials/getting-started.md
  85. 460 0
      docs/zh/tutorials/grading.md
  86. 145 0
      docs/zh/tutorials/hud.md
  87. BIN
      docs/zh/tutorials/images/15-puzzle/display_settings.png
  88. BIN
      docs/zh/tutorials/images/15-puzzle/input.png
  89. BIN
      docs/zh/tutorials/images/15-puzzle/main_collection.png
  90. BIN
      docs/zh/tutorials/images/15-puzzle/monalisa.png
  91. BIN
      docs/zh/tutorials/images/15-puzzle/slide.png
  92. BIN
      docs/zh/tutorials/images/15-puzzle/tilemap.png
  93. BIN
      docs/zh/tutorials/images/15-puzzle/tilesource.png
  94. BIN
      docs/zh/tutorials/images/car/start_add_car_component.png
  95. BIN
      docs/zh/tutorials/images/car/start_add_car_gameobject.png
  96. BIN
      docs/zh/tutorials/images/car/start_adding_car_collection.png
  97. BIN
      docs/zh/tutorials/images/car/start_build_and_launch.png
  98. BIN
      docs/zh/tutorials/images/car/start_car.png
  99. BIN
      docs/zh/tutorials/images/car/start_car_collection_complete.png
  100. BIN
      docs/zh/tutorials/images/car/start_delete_go.png

+ 286 - 0
docs/zh/faq/faq.md

@@ -0,0 +1,286 @@
+---
+title: Defold engine and editor FAQ
+brief: Frequently asked questions about the Defold game engine, editor and platform.
+---
+
+# Frequently asked questions
+
+## General questions
+
+#### Q: Is Defold really free?
+
+A: Yes, the Defold engine and editor with full functionality is completely free of charge. No hidden costs, fees or royalties. Just free.
+
+
+#### Q: Why on earth would the Defold Foundation give Defold away?
+
+A: One of the objectives of the [Defold Foundation](/foundation) is to make sure that the Defold software is available to developers world-wide and that the source code is available free of charge.
+
+
+#### Q: How long will you support Defold?
+
+A: We are deeply committed to Defold. The [Defold Foundation](/foundation) has been set up in such a way that it is guaranteed to exist as a responsible owner for Defold for many years to come. It is not going away.
+
+
+#### Q: Can I trust Defold for professional development?
+
+A: Absolutely. Defold is used by a growing number of professional game developers and game studios. Check out the [games showcase](/showcase) for examples of games created using Defold.
+
+
+#### Q: What kind of user tracking are you doing?
+
+A: We log anonymous usage data from our websites and the Defold editor in order to improve our services and product. There is no user tracking in the games you create (unless you add an analytics service yourself). Read more about this in our [Privacy Policy](/privacy-policy).
+
+
+#### Q: Who made Defold?
+
+A: Defold was created by Ragnar Svensson and Christian Murray. They started working on the engine, editor and servers in 2009. King and Defold started a partnership in 2013 and King acquired Defold in 2014. Read the full story [here](/about).
+
+
+## Platform questions
+
+#### Q: What platforms does Defold run on?
+
+A: The following platforms are supported for the editor/tools and the engine runtime:
+
+  | System                     | Supported            |
+  | -------------------------- | -------------------- |
+  | macOS 10.7 Lion            | Editor and runtime   |
+  | Windows Vista              | Editor and runtime   |
+  | Ubuntu 18.04 (64 bit)(1)   | Editor               |
+  | Linux (64 bit)(2)          | Runtime              |
+  | iOS 8.0                    | Runtime              |
+  | Android 4.1 (API level 16) | Runtime              |
+  | HTML5                      | Runtime              |
+
+  (1 The editor is built and tested for 64-bit Ubuntu 18.04. It should work on other distributions as well but we give no guarantees.)
+
+  (2 The engine runtime should run on most 64-bit Linux distributions as long as graphics drivers are up to date and supporting OpenGL ES 2.0.)
+
+
+#### Q: What are the system requirements for the editor
+
+A: The editor will use up to 75% of the available memory of the system. On a computer with 4 GB of RAM this should be enough for smaller Defold projects. For mid-sized or large projects it is recommended to use 6 GB or more of RAM.
+
+
+#### Q: What target platforms can I develop games for with Defold?
+
+A: With one click you can publish to Nintendo Switch, iOS, Android and HTML5 as well as macOS/OS X, Windows and Linux. It’s truly one codebase with multiple supported platforms.
+
+
+#### Q: What rendering API does Defold rely on?
+
+A: Defold uses OpenGL ES 2.0 for graphics rendering, which is available on all our supported platforms.
+
+
+#### Q: Can I do 3D games in Defold?
+
+A: Absolutely! The engine is a full blown 3D engine. However, the toolset is made for 2D so you will have to do a lot of heavy lifting yourself. Better 3D support is planned.
+
+
+#### Q: What programming language do I work with in Defold?
+
+A: Game logic in your Defold project is primarily written using the Lua language (specifically Lua 5.1/LuaJIT, refer to the [Lua manual](/manuals/lua) for details). Lua is a lightweight dynamic language that is fast and very powerful. You can also use native code (C/C++, Objective-C, Java and JavaScript depending on the platform) to extend the Defold engine with new functionality. When building custom materials, OpenGL ES SL shader language is used to write vertex and fragment
+shaders.
+
+
+#### Q: Is there a way to know what version I'm running?
+
+A: Yes, select the "About" option in the Help menu. The popup clearly shows Defold beta version and, more importantly, the specific release SHA1. For runtime version lookup, use [`sys.get_engine_info()`](/ref/sys/#sys.get_engine_info).
+
+The latest beta version available for download from http://d.defold.com/beta can be checked by opening http://d.defold.com/beta/info.json (the same file exists for stable versions as well: http://d.defold.com/stable/info.json)
+
+
+#### Q: Is there a way to know what platform the game is running on at runtime?
+
+A: Yes, check out [`sys.get_sys_info()`](/ref/sys#sys.get_sys_info).
+
+
+#### Q: Are Defold beta versions auto-updating?
+
+A: Yes. The Defold beta editor checks for an update at startup, just like the Defold stable version does.
+
+
+## Publishing games
+
+#### Q: I'm trying to publish my game to AppStore. How should I respond to IDFA?
+
+A: When submitting, Apple has three checkboxes for their three valid use cases for the IDFA:
+
+  1. Serve ads within the app
+  2. Install attribution from ads
+  3. User action attribution from ads
+
+  If you check option 1, the app reviewer will look for ads to show up in the app. If your game does not show ads, the game might get rejected. Defold itself doesn't use AD id.
+
+
+#### Q: How do I monetize my game?
+
+A: Defold has support for in-app purchases and various advertising solutions. Check the [Monetization category in the Asset Portal](https://defold.com/tags/stars/monetization/) for an up to date list of available monetization options.
+
+
+## Errors using Defold
+
+#### Q: Why doesn't the editor start or open my project?
+
+A: Check if there are spaces in the path leading up to the Defold application. For instance, if you put the folder *Defold-macosx* containing the OSX version of the editor in your *Applications* folder, then you should be ok.  If you rename the folder *Defold macosx* the editor might not start anymore. On Windows, putting Defold under *C:\\Program Files\\* can trigger this problem. This is due to a known bug in the underlying Eclipse framework.
+
+
+#### Q: I can't start the game and there is no build error. What's wrong?
+
+A: The build process can fail to rebuild files in rare cases where it have previously encountered build errors that you have fixed. Force a full rebuild by selecting *Project > Rebuild And Launch* from the menu.
+
+
+#### Q: Why am I getting a java exception when I try to start Defold?
+
+A: `javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target`
+
+This exception occurs when the editor tries to make an https connection but the certificate chain provided by the server cannot be verified.
+
+See [this link](https://github.com/defold/editor2-issues/blob/master/faq/pkixpathbuilding.md) for details on this error.
+
+
+## Linux
+:[Linux FAQ](../shared/linux-faq.md)
+
+
+## Android
+:[Android FAQ](../shared/android-faq.md)
+
+
+## HTML5
+:[HTML5 FAQ](../shared/html5-faq.md)
+
+
+## Windows
+:[Windows FAQ](../shared/windows-faq.md)
+
+## Nintendo Switch
+:[Nintendo Switch FAQ](../shared/nintendo-switch-faq.md)
+
+
+## Game content
+
+#### Q: Does Defold support prefabs?
+
+A: Yes, it does. They are called [collections](/manuals/building-blocks/#collections). They allow you to create complex game object hierarchies and store those as a separate building blocks that you can instance in the editor or at runtime (through collection spawning). For GUI nodes there is support for GUI templates.
+
+
+#### Q: I can't add a game object as a child to another game object, why?
+
+A: Chances are that you try to add a child in the game object file and that is not possible. To understand why, you have to remember that parent-child hierarchies are strictly a _scene-graph_ transform hierarchy. A game object that has not been placed (or spawned) into a scene (collection) is not part of a scene-graph and can't therefore be part of a scene-graph hierarchy.
+
+
+#### Q: Why can't I broadcast messages to all children of a game object?
+
+A: Parent-child relations express nothing else than the scene-graph transform relations and should not be mistaken for object orientation aggregates. If you try to focus on your game data and how to best transform it as your game alter its state you will likely find less need to send messages with state data to many objects all the time. In the cases where you will need data hierarchies, these are easily constructed and handled in Lua.
+
+
+#### Q: Why am I experiencing visual artifacts around the edges of my sprites?
+
+A: That is a visual artifact called "edge bleeding" where the edge pixels of neighboring pixels in an atlas bleed into the image assigned to your sprite. The solution is to pad the edge of your atlas images with extra row(s) and column(s) of identical pixels. Luckily this can be done automatically by the atlas editor in Defold. Open your atlas and set the *Extrude Borders* value to 1.
+
+
+#### Q: Can I tint my sprites or make them transparent, or do I have to write my own shader for it?
+
+A: The built-in sprite shader that is used by default for all sprites has a constant "tint" defined:
+
+  ```lua
+  local red = 1
+  local green = 0.3
+  local blue = 0.55
+  local alpha = 1
+  sprite.set_constant("#sprite", "tint", vmath.vector4(red, green, blue, alpha))
+  ```
+
+
+#### Q: If I set the z coordinate of a sprite to 100 then it's not rendered. Why?
+
+A: The Z-position of a game object controls rendering order. Low values are drawn before higher values. In the default render script game objects with a depth ranging between -1 and 1 are drawn, anything lower or higher will not be drawn. You can read more about the rendering script in the official [Render documentation](/manuals/render). On GUI nodes the Z value is ignored and does not affect rendering order at all. Instead nodes are rendered in the order they are listed and according to child hierarchies (and layering). Read more about gui rendering and draw call optimization using layers in the official [GUI documentation](/manuals/gui).
+
+
+#### Q: Would changing the view projection Z-range to -100 to 100 impact performance?
+
+A: No. The only effect is precision. The z-buffer is logarithmic and have very fine resolution of z values close to 0 and less resolution far away from 0. For instance, with a 24 bit buffer the values 10.0 and 10.000005 can be differentiated whereas 10000 and 10005 cannot.
+
+
+#### Q: There is no consistency to how angles are represented, why?
+
+A: Actually there is consistency. Angles are expressed as degrees everywhere in the editor and the game APIs. The math libs use radians. Currently the convention breaks for the `angular_velocity` physics property that is currently expressed as radians/s. That is expected to change.
+
+
+#### Q: When creating a GUI box-node with only color (no texture), how will it be rendered?
+
+A: It is just a vertex colored shape. Bear in mind that it will still cost fill-rate.
+
+
+#### Q: If I change assets on the fly, will the engine automatically unload them?
+
+A: All resources are ref-counted internally. As soon as the ref-count is zero the resource is released.
+
+
+#### Q: Is it possible to play audio without the use of an audio component attached to a game object?
+
+A: Everything is component-based. It's possible to create a headless game object with multiple sounds and play sounds by sending messages to the sound-controller object.
+
+
+#### Q: Is it possible to change the audio file associated with an audio component at run time?
+
+A: In general all resources are statically declared with the benefit that you get resource management for free. You can use [resource properties](/manuals/script-properties/#resource-properties) to change which resource that is assigned to a component.
+
+
+#### Q: Is there a way to access the physics collision shape properties?
+
+A: No, it is currently not possible.
+
+
+#### Q: Is there any quick way to render the collision objects in my scene? (like Box2D's debugdraw)
+
+A: Yes, set *physics.debug* flag in *game.project*. (Refer to the official [Project settings documentation](/manuals/project-settings/#debug))
+
+
+#### Q: What are the performance costs of having many contacts/collisions?
+
+A: Defold runs a modified version of Box2D in the background and the performance cost should be quite similar. You can always see how much time the engine spends on physics by bringing up the [profiler](/manuals/debugging). You should also consider what kind of collisions objects you use. Static objects are cheaper performance wise for instance. Refer to the official [Physics documentation](/manuals/physics) in Defold for more details.
+
+
+#### Q: What's the performance impact of having many particle effect components?
+
+A: It depends on if they are playing or not. A ParticleFx that isn't playing have zero performance cost. The performance implication of a playing ParticleFx must be evaluated using the profiler since its impact depends on how it is configured. As with most other things the memory is allocated up front for the number of ParticleFx defined as max_count in game.project.
+
+
+#### Q: How do I receive input to a game object inside a collection loaded via a collection proxy?
+
+A: Each proxy loaded collection has their own input stack. Input is routed from the main collection input stack via the proxy component to the objects in the collection. This means that it's not enough for the game object in the loaded collection to acquire input focus, the game object that _holds_ the proxy component need to acquire input focus as well. See the [Input documentation](/manuals/input) for details.
+
+
+#### Q: Can I use string type script properties?
+
+A: No. Defold supports properties of [hash](/ref/builtins#hash) types. These can be used to indicate types, state identifiers or keys of any kind. Hashes can also be used to store game object id's (paths) although [url](/ref/msg#msg.url) properties are often preferable since the editor automatically populate a drop-down with relevant URLs for you. See the [Script properties documentation](/manuals/script-properties) for details.
+
+
+#### Q: How do I access the individual cells of a matrix (created using [vmath.matrix4()](/ref/vmath/#vmath.matrix4:m1) or similar)?
+
+A: You access the cells using `mymatrix.m11`, `mymatrix.m12`, `mymatrix.m21` etc
+
+
+#### Q: I am getting `Not enough resources to clone the node` when using [gui.clone()](/ref/gui/#gui.clone:node) or [gui.clone_tree()](/ref/gui/#gui.clone_tree:node)
+
+A: Increase the `Max Nodes` value of the gui component. You find this value in the Properties panel when selecting the root of the component in the Outline.
+
+
+## The forum
+
+#### Q: Can I post a thread where I advertise my work?
+
+A: Of course! We have a special ["Work for hire" category](https://forum.defold.com/c/work-for-hire) for that. We will always encourage everything which benefits the community, and offering your services to the community---for remuneration or not---is a good example of that.
+
+
+#### Q: I made a thread and added my work—can I add more?
+
+A: In order to reduce bumping of "Work for hire" threads, you may not post more than once per 14 days in your own thread (unless it’s a direct reply to a comment in the thread, in which case you may reply). If you want to add additional work to your thread within the 14-day period, you must edit your existing posts with your added content.
+
+
+#### Q: Can I use the Work for Hire category to post job offerings?
+
+A: Sure, knock yourselves out! It can be used for offerings as well as requests, e.g. “Programmer looking for 2D pixel artist; I’m rich and I’ll pay you well”.

+ 62 - 0
docs/zh/manuals/ads.md

@@ -0,0 +1,62 @@
+---
+title: 在 Defold 中播放广告
+brief: 广告是网页游戏和手机游戏的基本盈利方式. 本教程介绍了在 Defold 中如何通过广告盈利.
+---
+
+# 广告
+
+Ads has become a very common way of monetizing web and mobile games and it has turned into a billion dollar industry. As a developer you get paid based on the number of people watching the ads you show in your game. It is usually as simple as more viewers equals more money, but other factors also have an impact on how much you get paid:
+
+* The ad quality - relevant ads are more likely to get interaction and attention from your players.
+* The ad format - banner ads usually pay less while full screen ads viewed from start to to finish pays more.
+* The ad network - the amount you get paid varies from ad networks to ad network.
+
+::: sidenote
+CPM = Cost per mille. The amount an advertiser pays per one thousand views. The CPM varies between ad networks and ad formats.
+:::
+
+## Formats
+
+There are many different kinds of ad formats that can be used in games. Some of the more common ones are banner, interstitial and reward ads:
+
+### Banner ads
+
+Banner ads are text, image or video based and cover a relatively small part of the screen, usually at the top or bottom of the screen. Banner ads are very easy to implement and they fit very well with casual single screen games where it is easy to reserve an area of the screen for advertisements. Banner ads maximize exposure as users play your game without interruption.
+
+### Interstitial ads
+
+Interstitial ads are large full screen experiences with animations and sometimes also interactive rich media content. Interstitial ads are typically shown in between levels or game sessions as it is a natural break in the game experience. Interstitial ads typically generate less views than banner ads, but the cost (CPM) is much higher than for banner ads, resulting in significant overall ad revenue.
+
+### Rewarded ads
+
+Rewarded ads (also know as Incentivized ads) are optional and therefore less obtrusive than many other forms of ads. Rewarded ads are usually full screen experiences like interstitial ads. The user can choose a reward in exchange for viewing the ad - for instance loot, coins, lives, time or some other in-game currency or benefit. Rewarded ads usually has the highest cost (CPM), but the number of views is directly related to user opt-in rates. Rewarded ads will only generate great performance if the rewards are valuable enough and offered at the right time.
+
+
+## Ad networks
+
+The [Defold Asset Portal](/tags/stars/ads/) contains several assets which integrate with ad providers:
+
+* [AdMob](https://defold.com/assets/admob/) - Show ads using the Google ad network.
+* [Enhance](https://defold.com/assets/enhance/) - Supports a number of different ad networks. Requires an additional post-build step.
+* [Facebook Instant Games](https://defold.com/assets/facebookinstantgames/) - Show ads in your Facebook Instant Game.
+* [IronSource](https://defold.com/assets/ironsource/) - Show ads using the IronSource Ad network.
+* [Unity Ads](https://defold.com/assets/defvideoads/) - Show ads using the Unity Ads network.
+
+
+# How to integrate ads in your game
+
+When you have decided on an ad network to integrate in your game you need to follow the installation and usage instructions for that particular asset. What you typically do is to first add the extension as a [project dependency](/manuals/libraries/#setting-up-library-dependencies). Once you have the asset added to your project you can proceed with the integration and call the functions specific to the asset to load and show ads.
+
+
+# Combining ads and in-app purchases
+
+It is quite common in mobile games to offer an [In-app purchase](/manuals/iap) to get rid of ads permanently.
+
+
+## Learn more
+
+There are many online resources to learn from when it comes to optimizing ad revenue:
+
+* Google AdMob [Monetize mobile games with ads](https://admob.google.com/home/resources/monetize-mobile-game-with-ads/)
+* Game Analytics [Popular ad formats and how to use them](https://gameanalytics.com/blog/popular-mobile-game-ad-formats.html)
+* deltaDNA [Ad serving in games: 10 expert tips](https://deltadna.com/blog/ad-serving-in-games-10-tips/)

+ 22 - 30
docs/zh/manuals/android.md

@@ -9,40 +9,44 @@ Android 设备允许自由允许你开发的应用. 可以很容易地编译好
 
 ## Android 和 Google Play 签名
 
-Android 需要安装的应用都进行数字签名. 不像 iOS 证书都需要由 Apple 签发, Android 允许开发者自己创建证书和密匙来对应用签名.
+Android 要求每个 APK 文件在被安装到设备上或者在设备上更新之前必须进行数字签名. 如果你是安卓开发者, 只需要在把程序包上传到 Play Console 之前, 经过 [Play App Signing](https://developer.android.com/studio/publish/app-signing#app-signing-google-play) 的自动处理即可. 然而, 你还可以选择手动对程序包进行签名以便上传到 Google Play, 其他应用商店以及在整个互联网上传播.
 
-创建证书和密匙的过程看似复杂但是开发阶段 Defold 对此有自动化功能.你可以在打包 Android应用时指定证书和密匙. 不指定的话, Defold 会自动创建证书和密匙打包 *.apk* (Android Application Package) 文件.
+从 Defold 编辑器或者 [命令行工具](/manuals/bob) 打包安卓包需要提供一个 keystore (包括证书和公匙), 然后对应用签名时还要用到私匙. 没有的话, Defold 会自动生成一个临时调试用 keystore 用于打包和签名.
 
-注意如果要把应用上传至 Google Play, 就需要用自己的证书和密匙签名应用. 因为后续应用更新时, _新版本 *.apk* 文件签名需要与老版本保持一致_. 如果不一致, Google Play 会拒绝 *.apk* 更新上架, 除非作为全新应用发布.
+::: 注意
+千万 **不要** 带着调试签名就上传到 Google Play 上去. 开发者必须自己制作属于自己的签名.
+:::
 
-详情请见 [Google Play 开发者中心](https://play.google.com/apps/publish/).
+## 制作 keystore
 
-## 创建证书和密匙
+::: 注意
+Defold 应对安卓应用包签名的改变是从 1.2.173 版开始的, 就是使用单独的证书和密码来合成 keystore.
+:::
 
-基于 *.pem*-格式创建证书, 基于 *.pk8*-格式创建密匙. 二者的创建都可以使用 `openssl` 工具:
+也可以 [使用 Android Studio](https://developer.android.com/studio/publish/app-signing#generate-key) 或者通过使用控制台命令来生成签名:
 
-```sh
-$ openssl genrsa -out key.pem 2048
-$ openssl req -new -key key.pem -out request.pem
-$ openssl x509 -req -days 9999 -in request.pem -signkey key.pem -out certificate.pem
-$ openssl pkcs8 -topk8 -outform DER -in key.pem -inform PEM -out key.pk8 -nocrypt
+```bash
+keytool -genkey -v -noprompt -dname "CN=John Smith, OU=Area 51, O=US Air Force, L=Unknown, ST=Nevada, C=US" -keystore mykeystore.keystore -storepass 5Up3r_53cR3t -alias myAlias -keyalg RSA -validity 9125
 ```
 
-这样就生成了 *certificate.pem* 和 *key.pk8* 文件可以用来签名应用包.
+这个命令会生成一个叫做 `mykeystore.keystore` 的签名, 其中包含了证书和密码. 密匙 `5Up3r_53cR3t` 保护其不备破解. 这个签名有效期为 25 年 (9125 天). 这个签名的id叫做 `myAlias`.
 
 ::: 注意
-注意保存好证书和密匙文件. 一点丢失就 _不能_ 上传 *.apk* 更新文件到 Google Play 了.
+要把签名和密匙保存好. 如果要手动上传 Google Play 但是签名密码丢失的话就没办法使用 Google Play 来更新你的应用了. 图省事的话就用 Google Play App Signing 搞定签名把.
 :::
 
-## 创建 Android 应用包
 
-使用编辑器可以很容易地进行应用打包.打包前可以在  "game.project" [项目配置文件](/manuals/project-settings/#android) 里为应用设置图标, 版本号之类的. 菜单选择 <kbd>Project ▸ Bundle... ▸ Android Application...</kbd> 来进行打包.
+## 证书和安卓包
 
-如果希望编辑器自动生成调试用证书, 把 *Certificate* 和 *Private key* 置空即可:
+编辑器打包安卓包十分方便. 打包之前可以为应用指定图标, 设置版本号等等, 都在 "game.project" [项目配置文件](/manuals/project-settings/#android) 里设置.
+
+选择菜单栏 <kbd>Project ▸ Bundle... ▸ Android Application...</kbd> 就可以打包了.
+
+要让编辑器自动生成调试用签名, 只需把 *Keystore* 和 *Keystore password* 字段留空即可:
 
 ![Signing Android bundle](images/android/sign_bundle.png)
 
-如果希望使用自己的证书和密匙, 配置 *.pem* 和 *.pk8* 文件即可:
+要让编辑器使用你自己指定的签名打包, 就要设置好 *Keystore* 和 *Keystore password* 字段. *Kyestore* 的扩展名是 `.keystore`, 而密码要保存成文本 `.txt` 文件:
 
 ![Signing Android bundle](images/android/sign_bundle2.png)
 
@@ -127,17 +131,5 @@ I/defold  ( 6210):
 D/defold  ( 6210): DEBUG:SCRIPT: Hello there, log!
 ...
 ```
-
 ## 常见问题
-
-安装时报 "Failure [INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES]" 错误
-: Android 发现了你使用不同的证书安装应用. 编译调试包时, 使用的是临时证书. 安装前先卸载旧应用:
-
-  ```
-  $ adb uninstall com.defold.examples
-  Success
-  $ adb install Defold\ examples.apk
-  4826 KB/s (18774344 bytes in 3.798s)
-          pkg: /data/local/tmp/Defold examples.apk
-  Success
-  ```
+:[Android FAQ](../shared/android-faq.md)

+ 0 - 30
docs/zh/manuals/animation.md

@@ -388,36 +388,6 @@ pingpong 模式先正向播放, 再反向播放. GUI 属性动画也有这些播
 | gui.EASING_INQUINT | gui.EASING_OUTQUINT |
 | gui.EASING_INOUTQUINT | gui.EASING_OUTINQUINT |
 
-<div id="game-container" class="game-container">
-<canvas id="game-canvas" tabindex="1" width="640" height="512"></canvas>
-<script src="//storage.googleapis.com/defold-doc/assets/easier/dmloader.js"></script>
-<script>
-  var extra_params = {
-   archive_location_filter: function( path ) { return ('//storage.googleapis.com/defold-doc/assets/easier/archive' + path + ''); },
-   splash_image: '//storage.googleapis.com/defold-doc/assets/easier/preview.jpg',
-   custom_heap_size: 268435456,
-   disable_context_menu: true,
-   game_start: function() {}
-  };
-  Module['onRuntimeInitialized'] = function() { Module.runApp("game-canvas", extra_params); };
-  Module['locateFile'] = function(path, scriptDirectory) {
-   if (path == "dmengine.wasm" || path == "dmengine_release.wasm" || path == "dmengine_headless.wasm") { path = "easier.wasm"; }
-   return scriptDirectory + path;
-  };
-  function load_engine() {
-   var engineJS = document.createElement('script');
-   engineJS.type = 'text/javascript';
-   if (Module['isWASMSupported']) {
-   engineJS.src = '//storage.googleapis.com/defold-doc/assets/easier/easier_wasm.js';
-   } else {
-   engineJS.src = '//storage.googleapis.com/defold-doc/assets/easier/easier_asmjs.js';
-   }
-   document.head.appendChild(engineJS);
-  }
-  load_engine();
-</script>
-</div>
-
 ![Linear interpolation](images/properties/easing_linear.png){.inline}
 ![In back](images/properties/easing_inback.png){.inline}
 ![Out back](images/properties/easing_outback.png){.inline}

+ 1 - 1
docs/zh/manuals/application-lifecycle.md

@@ -102,7 +102,7 @@ end
 
 每秒帧数 (即每秒更新循环运行次数) 可以在项目配置里设置, 或者通过发送 `set_update_frequency` 消息到 `@system` 接口手动设置. 而且, 可以通过发送 `set_time_step` 消息给代理来为集合单独设置 _时间步_. 修改集合时间步不影响帧率. 它影响的是物理时间步与发送到 `update()` 函数中的 `dt` 值. 注意修改时间步不影响 `update()` 调用的频率---永远是每帧调用一次.
 
-(See the [Collection proxy manual](/manuals/collection-proxy) and [`set_time_step`](/ref/collection-proxy#set-time-step) for details)
+(See the [Collection proxy manual](/manuals/collection-proxy) and [`set_time_step`](/ref/collectionproxy#set-time-step) for details)
 
 ## 析构
 

+ 1 - 1
docs/zh/manuals/bob.md

@@ -7,7 +7,7 @@ brief: Bob 是用于 Defold 项目的命令行编译工具. 本教程详述如
 
 Bob 是一个用于Defold项目编辑器之外的命令行编译工具.
 
-Bob 用来编译操作 (对应编辑器里的 <kbd>Project ▸ Build And Launch</kbd>), 来创建数据档或者创建可独立发布的应用 (对应编辑器里的 <kbd>Project ▸ Bundle ▸ ...</kbd> 选项)
+Bob 用来编译操作 (对应编辑器里的 <kbd>Project ▸ Build</kbd>), 来创建数据档或者创建可独立发布的应用 (对应编辑器里的 <kbd>Project ▸ Bundle ▸ ...</kbd> 选项)
 
 Bob 集合了编译所需的一切, 作为Java包 _JAR_ 发布. 你可以在其发布地址 http://d.defold.com 里下载到 *bob.jar* . 先选择版本, 再下载 *bob/bob.jar*. 要运行 Bob 工具, 你需要 [安装OpenJDK 11](https://openjdk.java.net/projects/jdk/11/).
 

+ 8 - 11
docs/zh/manuals/bundling.md

@@ -23,35 +23,32 @@ brief: 本教程介绍了如何打包应用.
 
 ![build report](images/profiling/build_report.png){srcset="images/profiling/[email protected] 2x"}
 
-To learn more about build reports please refer to the [Profiling manual](/manuals/profiling/#编译报告).
+关于编译报告详情请见 [调试教程](/manuals/profiling/#编译报告).
+
 
 ### Android
 
-打包安卓应用 (.apk 文件) 及其准备工作详见 [Android 教程](/manuals/android/#打包Android应用).
+建立安卓应用 (.apk 文件) 详见 [安卓教程](/manuals/android/#creating-an-android-application-bundle).
 
 ### iOS
 
-打包ios应用 (.ipa 文件) 及其准备工作详见 [iOS 教程](/manuals/ios/#打包ios应用).
+建立苹果移动应用 (.ipa 文件) 详见 [iOS 教程](/manuals/ios/#creating-an-ios-application-bundle).
 
 ### OSX
 
-打包 OSX 应用 (.app 文件) 无需什么准备, 但是要在 "game.project" 文件中做相应设置, 详见 [项目配置文件](/manuals/project-settings/#macos--os-x).
+建立Mac系统应用 (.app 文件) 详见 [macOS 教程](/manuals/macos).
 
 ### Linux
 
-打包 Linux 应用无需什么准备, 但是要在 "game.project" 文件中做相应设置, 详见 [项目配置文件](/manuals/project-settings/).
+建立Linux应用无需特别设置 "game.project" [项目配置文件](/manuals/project-settings/#linux).
 
 ### Windows
 
-打包 Windows 应用 (.exe file) 无需什么准备, 但是要在 "game.project" 文件中做相应设置, 详见但是要在 "game.project" 文件中做相应设置, 详见 [项目配置文件](/manuals/project-settings/#windows).
-
-#### Facebook Gameroom
-
-可以为 Facebook Gameroom 打包成 Windows 应用的一种特殊版本. 这一过程详见 [Facebook Gameroom 教程](/manuals/gameroom/).
+建立Windows应用 (.exe 文件) 详见 [Windows 教程](/manuals/windows).
 
 ### HTML5
 
-打包 HTML5 应用及其参数设置详见 [HTML5 教程](/manuals/html5/#打包html5应用).
+建立HTML5应用及其参数设置详见 [HTML5 教程](/manuals/html5/#打包html5应用).
 
 #### Facebook Instant Games
 

+ 1 - 1
docs/zh/manuals/collection-proxy.md

@@ -23,7 +23,7 @@ Defold 把所有游戏对象组织在集合里. 集合可以包含游戏对象
 
 ## 启动集合
 
-当 Defold 引擎开始工作最先把 *启动集合* 导入运行环境并对其中的所有游戏对象进行初始化. 然后开启游戏对象和它们的组件. 在 [项目配置](/manuals/project-settings) 里设置把哪个集合作为启动集合使用. 依照惯例启动集合都叫做 "main.collection".
+当 Defold 引擎开始工作最先把 *启动集合* 导入运行环境并对其中的所有游戏对象进行初始化. 然后开启游戏对象和它们的组件. 在 [项目配置](/manuals/project-settings/#main-collection) 里设置把哪个集合作为启动集合使用. 依照惯例启动集合都叫做 "main.collection".
 
 ![bootstrap](images/collection-proxy/bootstrap.png){srcset="images/collection-proxy/[email protected] 2x"}
 

+ 6 - 1
docs/zh/manuals/components.md

@@ -22,7 +22,7 @@ Defold 提供以下组件类型:
 * [Particle FX](/manuals/particlefx) -  创建粒子
 * [Script](/manuals/script) - 添加游戏逻辑
 * [Sound](/manuals/sound) - 播放音效音乐
-* [Spine model](/manuals/spine-model) - 渲染spine动画
+* [Spine model](/manuals/spinemodel) - 渲染spine动画
 * [Sprite](/manuals/sprite) - 显示2D图像 (可以带逐帧动画)
 * [Tilemap](/manuals/tilemap) - 显示一组瓷砖图
 
@@ -69,6 +69,10 @@ Defold 组件属性各不相同.在 [Outline 视图](/manuals/editor/#编辑器
 每个组件都有 [材质](/manuals/material/) 而且每个材质都有一个或多个标签. 渲染脚本依次定义一系列优先级, 每个优先级匹配一个或多个材质标签. 渲染脚本在 *update()* 函数里 [按优先级依次渲染](/manuals/render/#render-predicates) , 匹配优先级标签的组件会被显示出来. 默认渲染脚本先绘制 sprites 和 tilemaps, 再渲染粒子特效, 二者都使用世界坐标系. 最后渲染脚本会在屏幕坐标系中渲染 GUI 组件.
 
 ### 组件z值
+所有游戏对象都使用一个 vector3 作为其在 3D 空间中的位置. 如果是 2D 游戏, 则 X 和 Y 表示其在 "横向" 和 "纵向" 轴上的位置, 而 Z 值表示其在 "深度" 轴上的位置. 使用Z值可以操控游戏对象之间的层叠关系: Z 值是 1 的总是显示在 Z 值是 0 的对象上面. 默认情况下, Defold 使用 Z 值范围是 -1 到 1:
+
+![model](images/graphics/z-order.png){srcset="images/graphics/[email protected] 2x"}
+
 匹配某个优先级的组件在一起渲染, 它们之间的渲染顺序取决于组件的 z 值. 组件的最终z值是由组件的z值, 游戏对象和其父级游戏对象的z值之和.
 
 ::: 注意
@@ -89,4 +93,5 @@ Defold 组件属性各不相同.在 [Outline 视图](/manuals/editor/#编辑器
 如果两个组件 z 值相同则可能造成两个组件来回穿梭闪烁或者不同平台顺序不同的结果.
 
 渲染脚本为 z 值定义了极近端和极远端平面. z值在此范围之外的组件不会被渲染. 默认范围是 -1 到 1 但是 [可以任意修改](/manuals/render/#默认视口映射).
+Z 值得极近与极远坐标范围是 -1 到 1 的话, 需要很高的数值精度. 在处理 3D 资源时, 可能需要在你的自定义渲染脚本中修改极近和极远的坐标范围. 详情请见 [渲染教程](/manuals/render/).
 :::

+ 92 - 0
docs/zh/manuals/debugging-game-and-system-logs.md

@@ -0,0 +1,92 @@
+---
+title: Debugging - game and system logs
+brief: This manual explains how to read game and system logs.
+---
+
+# Game and system log
+
+The game log shows all of the output from the engine, native extensions and your game logic. The [print()](/ref/stable/base/#print:...) and [pprint()](/ref/stable/builtins/?q=pprint#pprint:v) commands can be used from your scripts and Lua modules to show information in the game log. You can use the functions in the [dmLog namespace](/ref/stable/dmLog/) to write to the game log from native extensions. The game log can be read from the editor, from a terminal window, using platform specific tools or from a log file.
+
+System logs are generated by the operating system and it can provide additional information that can help you pintpoint a problem. The system logs can contain stack traces for crashes and low memory warnings.
+
+::: important
+The game log will only show information in debug builds. The log will be completely empty in release builds.
+:::
+
+## Reading the game log from the editor
+
+When you run your game locally from the editor or connected to the [mobile dev app](/manuals/dev-app) all of the output will be shown in the console pane of the editor:
+
+![Editor 2](images/editor/editor2_overview.png)
+
+## Reading the game log from the terminal
+
+When you run a Defold game from the terminal the log will show in the terminal window itself. On Windows and Linux you type the name of the executable in the terminal to start the game. On macOS you need to launch the engine from within the .app file:
+
+```
+$ > ./mygame.app/Contenst/MacOS/mygame
+```
+
+## Reading game and system logs using platform specific tools
+
+### HTML5
+
+Logs can be read using the developer tools provided by most browsers.
+
+* [Chrome](https://developers.google.com/web/tools/chrome-devtools/console) - Menu > More Tools > Developer Tools
+* [Firefox](https://developer.mozilla.org/en-US/docs/Tools/Browser_Console) - Tools > Web Developer > Web Console
+* [Edge](https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/console)
+* [Safari](https://support.apple.com/guide/safari-developer/log-messages-with-the-console-dev4e7dedc90/mac) - Develop > Show JavaScript Console
+
+### Android
+
+You can use the [Android Debug Bridge (ADB) tool](https://developer.android.com/studio/command-line/adb.html) to view the game and system log.
+
+  Once installed and setup, connect your device with USB, open a terminal and run:
+
+  ```txt
+  cd <path_to_android_sdk>/platform-tools/
+  adb logcat
+  ```
+
+  The device will then dump all the output to the current terminal, along with any prints from the game.
+
+  If you want to see only Defold application outputs use this command:
+
+  ```txt
+  cd <path_to_android_sdk>/platform-tools/
+  adb logcat -s defold
+  ```
+
+### iOS
+
+You can use the [Console tool](https://support.apple.com/guide/console/welcome/mac) to read game and system log. You can use the LLDB debugger to attach to a game running on device. To debug a game it needs to be signed with a “Apple Developer Provisioning Profile” that include the device you want to debug on. Bundle the game from the editor and supply the provisioning profile in the bundle dialog (bundling for iOS is only available on macOS).
+
+  To launch the game and attach the debugger you will need a tool called [ios-deploy](https://github.com/phonegap/ios-deploy). Install and debug your game by running the following in a terminal:
+
+  ```txt
+  ios-deploy --debug --bundle <path_to_game.app> # NOTE: not the .ipa file
+  ```
+
+  This will install the app on your device, start it and automatically attach a LLDB debugger to it. If you are new to LLDB, read [Getting Started with LLDB](https://developer.apple.com/library/content/documentation/IDEs/Conceptual/gdb_to_lldb_transition_guide/document/lldb-basics.html).
+
+
+## Reading the game log from the log file
+
+If you enable the *Write Log* setting in "game.project", any game output will be written to disk, to a file called "log.txt". Here is how you extract the file if you run the game on device:
+
+iOS
+: Connect your device to a computer with macOS and Xcode installed.
+
+  Open Xcode and go to <kbd>Window ▸ Devices and Simulators</kbd>.
+
+  Select your device in the list, then select the relevant app in the *Installed Apps* list.
+
+  Click the cog icon below the list and select <kbd>Download Container...</kbd>.
+
+  ![download container](images/debugging/download_container.png){srcset="images/debugging/[email protected] 2x"}
+
+  Once the container has been extracted it will be shown in *Finder*. Right click the container and select <kbd>Show Package Content</kbd>. Locate the file "log.txt", which should be located in "AppData/Documents/".
+
+Android
+: The ability to extract the "log.txt" depends on OS version and manufacturer. Here is a short and simple step by step guide: https://stackoverflow.com/a/48077004/129360

+ 132 - 0
docs/zh/manuals/debugging-game-logic.md

@@ -0,0 +1,132 @@
+---
+title: Defold 中的调试
+brief: 本教程介绍了 Defold 中自带的调试功能.
+---
+
+# 调试游戏逻辑
+
+Defold contains an integrated Lua debugger with an inspection facility. Together with the built-in [profiling tools](/manuals/profiling) it is a powerful tool that can help finding the cause of bugs in your game logic or help analyze performance issues.
+
+## Print and visual debugging
+
+The simplest way to debug your game in Defold is to use [print debugging](http://en.wikipedia.org/wiki/Debugging#Techniques). Use `print()` or [`pprint()`](/ref/builtins#pprint) statements to watch variables or indicate the flow of execution. If a game object without a script acts weird, you can just attach a script to it with the sole purpose of debugging. Using any of the printing functions will print to the *Console* view in the editor and to the [game log](/manuals/debugging-game-and-system-logs).
+
+In addition to printing, the engine can also draw debug text and straight lines on the screen. This is done by posting messages to the `@render` socket:
+
+```lua
+-- Draw value of "my_val" with debug text on the screen
+msg.post("@render:", "draw_text", { text = "My value: " .. my_val, position = vmath.vector3(200, 200, 0) })
+
+-- Draw colored text on the screen
+local color_green = vmath.vector4(0, 1, 0, 1)
+msg.post("@render:", "draw_debug_text", { text = "Custom color", position = vmath.vector3(200, 180, 0), color = color_green })
+
+-- Draw debug line between player and enemy on the screen
+local start_p = go.get_position("player")
+local end_p = go.get_position("enemy")
+local color_red = vmath.vector4(1, 0, 0, 1)
+msg.post("@render:", "draw_line", { start_point = start_p, end_point = end_p, color = color_red })
+```
+
+The visual debug messages adds data to the rendering pipeline and is drawn as part of the regular render pipeline.
+
+* `"draw_line"` adds data that is rendered with the `render.draw_debug3d()` function in the render script.
+* `"draw_text"` is rendered with the "/builtins/fonts/system_font.font" that uses the "/builtins/fonts/system_font.material" material.
+* `"draw_debug_text"` is the same as `"draw_text"`, but it's rendered in a custom color.
+
+Note that you probably want to update this data every frame so posting the messages in the `update()` function is a good idea.
+
+## Running the debugger
+
+To run the debugger, either <kbd>Debug ▸ Run with Debugger</kbd> which starts up the game with the debugger attached, or select <kbd>Debug ▸ Attach Debugger</kbd> to attach the debugger to an already running game.
+
+![overview](images/debugging/overview.png){srcset="images/debugging/[email protected] 2x"}
+
+As soon as the debugger is attached, you have control of the execution of the game through the debugger control buttons in the console, or through the <kbd>Debug</kbd> menu:
+
+Break
+: ![pause](images/debugging/pause.svg){width=60px .left}
+  Break execution of the game immediately. The game will break at its current point. You are now able to inspect the state of the game, advance the game step by step, or continue running it until the next breakpoint. The current point of execution is marked in the code editor:
+
+  ![script](images/debugging/script.png){srcset="images/debugging/[email protected] 2x"}
+
+Continue
+: ![play](images/debugging/play.svg){width=60px .left}
+  Continue running the game. The game code will continue to run until you either press pause or the execution hits a breakpoint that you have set. If execution breaks at a set breakpoint, the the execution point is marked in the code editor on top of the breakpoint marker:
+
+  ![break](images/debugging/break.png){srcset="images/debugging/[email protected] 2x"}
+
+Stop
+: ![stop](images/debugging/stop.svg){width=60px .left}
+  Stop the debugger. Pressing this button will immediately stop the debugger, detach it from the game and terminate the running game.
+
+Step Over
+: ![step over](images/debugging/step_over.svg){width=60px .left}
+  Advance execution of the program one step. If the execution involves running another Lua function, the execution _will not step into the function_ but continue running and stop on the next line below the function call. In this example, if the user presses "step over", the debugger will execute code and stop at the `end` statement below the line with the call to the function `nextspawn()`:
+
+  ![step](images/debugging/step.png){srcset="images/debugging/[email protected] 2x"}
+
+::: sidenote
+A line of Lua code does not correspond to a single expression. Stepping in the debugger moves ahead one expression at a time, meaning that currently you may have to hit the step button more than once to advance to the next line.
+:::
+
+Step Into
+: ![step in](images/debugging/step_in.svg){width=60px .left}
+  Advance execution of the program one step. If the execution involves running another Lua function, the execution _will step into the function_. Calling the function adds an entry to the call stack. You can click each entry in the call stack list to view the entry point and the content of all variables in that closure. Here, the user has stepped into the function `nextspawn()`:
+
+  ![step into](images/debugging/step_into.png){srcset="images/debugging/[email protected] 2x"}
+
+Step Out
+: ![step out](images/debugging/step_out.svg){width=60px .left}
+  Continue execution until it returns from the current function. If you have stepped execution into a function, pressing the button "step out" will continue execution until the function returns.
+
+Setting and clearing breakpoints
+: You can set an arbitrary number of breakpoints in your Lua code. When the game runs with the debugger attached, it will stop execution at the next breakpoint it encounters and wait for further interaction from you.
+
+  ![add breakpoint](images/debugging/add_breakpoint.png){srcset="images/debugging/[email protected] 2x"}
+
+  To set or clear a breakpoint, click in the column just right of the line numbers in the code editor. You can also select <kbd>Edit ▸ Toggle Breakpoint</kbd> from the menu.
+
+Evaluating Lua expressions
+: With the debugger attached and the game stopped at a breakpoint, a Lua runtime is available with the current context. Type Lua expressions in the bottom of the console and press <kbd>Enter</kbd> to evaluate them:
+
+  ![console](images/debugging/console.png){srcset="images/debugging/[email protected] 2x"}
+
+  It is currently not possible to modify variables through the evaluator.
+
+Detaching the debugger
+: Select <kbd>Debug ▸ Detach Debugger</kbd> to detach the debugger from the game. It will continue running immediately.
+
+## Lua debug library
+
+Lua comes with a debug library that is useful in some situations, particularly if you need to inspect the innards of your Lua environment. You can find more information about it here: http://www.lua.org/pil/contents.html#23.
+
+## Debugging checklist
+
+If you encounter an error or if your game does not behave like expected, here is a debugging checklist:
+
+1. Check the console output and verify that there are no runtime errors.
+
+2. Add `print` statements to your code to verify that the code is actually running.
+
+3. If it's not running, check that you have done the proper setup in the editor required for the code to run. Is the script added to the right game object? Have your script acquired input focus? Are the input-triggers correct? Is the shader code added to the material? Etc.
+
+4. If your code is depending on the values of variables (in an if-statement, for example), either `print` those values where they are used or checked, or inspect them with the debugger.
+
+Sometimes finding a bug can be a hard and time consuming process, requiring you to go through your code bit by bit, checking everything and narrowing down the faulty code and eliminating sources of error. This is best done by a method called "divide and conquer":
+
+1. Figure out which half (or less) of the code that must contain the bug.
+2. Again, figure out which half, of that half, must contain the bug.
+3. Continue narrowing down the code that must cause the bug until you find it.
+
+Happy hunting!
+
+## Debugging problems with physics
+
+If you have problems with physics and collisions aren't working as expected it is recommended to enable physics debugging. Check the *Debug* checkbox in the *Physics* section of the *game.project* file:
+
+![physics debug setting](images/debugging/physics_debug_setting.png)
+
+When this checkbox is enabled Defold will draw all collision shapes and contact points of collisions:
+
+![physics debug visualisation](images/debugging/physics_debug_visualisation.png)

+ 83 - 0
docs/zh/manuals/debugging-native-code-android.md

@@ -0,0 +1,83 @@
+---
+title: Debugging on Android
+brief: This manual describes how to debug a build running on an Android device.
+---
+
+# Debugging on Android
+
+Here we list some ways to debug your executable running on an Android device
+
+## Android Studio
+
+* Prepare the bundle by setting the `android.debuggable` option in `game.project`
+
+	![android.debuggable](images/extensions/debugging/android/game_project_debuggable.png)
+
+* Bundle the app in debug mode into a folder of choice.
+
+	![bundle_android](images/extensions/debugging/android/bundle_android.png)
+
+* Launch [Android Studio](https://developer.android.com/studio/)
+
+* Choose `Profile or debug APK`
+
+	![debug_apk](images/extensions/debugging/android/android_profile_or_debug.png)
+
+* Choose the apk bundle you just created
+
+	![select_apk](images/extensions/debugging/android/android_select_apk.png)
+
+* Select the main `.so` file, and make sure it has debug symbols
+
+	![select_so](images/extensions/debugging/android/android_missing_symbols.png)
+
+* If it doesn't, upload an unstripped `.so` file. (size is around 20mb)
+
+* Path mappings help you remap where the individual paths from where the executable was built (in the cloud) to an actual folder on your local drive.
+
+* Select the .so file, then add a mapping your local drive
+
+	![path_mapping1](images/extensions/debugging/android/path_mappings_android.png)
+
+	![path_mapping2](images/extensions/debugging/android/path_mappings_android2.png)
+
+* If you have access to the engine source, add a path mapping to that too
+
+		* make sure to checkout the version you are currently debugging
+
+			defold$ git checkout 1.2.148
+
+* Press `Apply changes`
+
+* You should now see the source mapped in your project
+
+	![source](images/extensions/debugging/android/source_mappings_android.png)
+
+* Add a breakpoint
+
+	![breakpoint](images/extensions/debugging/android/breakpoint_android.png)
+
+* Press `Run` -> `Debug "Appname"` and invoke the code you meant to break into
+
+	![breakpoint](images/extensions/debugging/android/callstack_variables_android.png)
+
+* You can now step in the callstack as well as inspect the variables
+
+
+## Notes
+
+### Native Extension job folder
+
+Currently, the workflow is a bit troublesome for development. This is because the job folder name
+is random for each build, making the path mapping invalid for each build.
+
+However, it works fine for a debugging session.
+
+The path mappings are stored in the <project>.iml file in the Android Studio project.
+
+It's possible to get the job folder from the executable
+
+	$ arm-linux-androideabi-readelf --string-dump=.debug_str build/armv7-android/libdmengine.so | grep /job
+
+The jobfolder is named like so `job1298751322870374150`, each time with a random number.
+

+ 136 - 0
docs/zh/manuals/debugging-native-code-ios.md

@@ -0,0 +1,136 @@
+---
+title: Debugging on iOS/macOS
+brief: This manual describes how to debug a build using Xcode.
+---
+
+# Debugging on iOS/macOS
+
+Here we describe how to debug a build using [Xcode](https://developer.apple.com/xcode/), Apple's preferred IDE for developing for macOS and iOS.
+
+## Xcode
+
+* Bundle the app by using bob, with the `--with-symbols` option
+
+		$ cd myproject
+		$ wget http://d.defold.com/archive/<sha1>/bob/bob.jar
+		$ java -jar bob.jar --platform armv7-darwin build --with-symbols debug --archive bundle -bo build/ios -mp <app>.mobileprovision --identity "iPhone Developer: Your Name (ID)"
+
+* Install the app, either with `Xcode`, `iTunes` or [ios-deploy](https://github.com/ios-control/ios-deploy)
+
+		$ ios-deploy -b <AppName>.ipa
+
+* Get the `.dSYM` folder (i.e the debug symbols)
+
+	* If it's not using Native Extensions, you can download the `.dSYM` file from [d.defold.com](http://d.defold.com)
+
+	* If you are using a native extension, then the `.dSYM` folder is generated when you build with [bob.jar](https://www.defold.com/manuals/bob/). Only building is required (no archive or bundling):
+
+			$ cd myproject
+			$ unzip .internal/cache/arm64-ios/build.zip
+			$ mv dmengine.dSYM <AppName>.dSYM
+			$ mv <AppName>.dSYM/Contents/Resources/DWARF/dmengine <AppName>.dSYM/Contents/Resources/DWARF/<AppName>
+
+
+### Create Project
+
+To properly debug, we need to have a project, and the source code mapped.
+We're not using this project to build things, only debug.
+
+* Create new Xcode project, choose the `Game` template
+
+	![project_template](images/extensions/debugging/ios/project_template.png)
+
+* Choose a name (e.g. `debug`) and the default settings
+
+* Choose a folder to save the project into
+
+* Add your code to the app
+
+	![add_files](images/extensions/debugging/ios/add_files.png)
+
+* Make sure the "Copy items if needed" is unchecked.
+
+	![add_source](images/extensions/debugging/ios/add_source.png)
+
+* This is the end result
+
+	![added_source](images/extensions/debugging/ios/added_source.png)
+
+
+* Disable the `Build` step
+
+	![edit_scheme](images/extensions/debugging/ios/edit_scheme.png)
+
+	![disable_build](images/extensions/debugging/ios/disable_build.png)
+
+* Set the `Deployment target` version so it's now larger than your device iOS version
+
+	![deployment_version](images/extensions/debugging/ios/deployment_version.png)
+
+* Select the target device
+
+	![select_device](images/extensions/debugging/ios/select_device.png)
+
+
+### Launch the debugger
+
+You have a few options to debug an app
+
+1. Either choose `Debug` -> `Attach to process...` and select the app from there
+
+1. Or choose the `Attach to process by PID or Process name`
+
+	![select_device](images/extensions/debugging/ios/attach_to_process_name.png)
+
+	1. Start the app on the device
+
+1. In `Edit Scheme` add the <AppName>.app folder as the executable
+
+### Debug symbols
+
+**To use lldb, the execution must be paused**
+
+* Add the `.dSYM` path to lldb
+
+		(lldb) add-dsym <PathTo.dSYM>
+
+	![add_dsym](images/extensions/debugging/ios/add_dsym.png)
+
+* Verify that `lldb` read the symbols successfully
+
+		(lldb) image list <AppName>
+
+### Path mappings
+
+* Add the engine source (change accordingly for your need)
+
+		(lldb) settings set target.source-map /Users/builder/ci/builds/engine-ios-64-master/build /Users/mathiaswesterdahl/work/defold
+		(lldb) settings append target.source-map /private/var/folders/m5/bcw7ykhd6vq9lwjzq1mkp8j00000gn/T/job4836347589046353012/upload/videoplayer/src /Users/mathiaswesterdahl/work/projects/extension-videoplayer-native/videoplayer/src
+
+	* It's possible to get the job folder from the executable.
+	The jobfolder is named like so `job1298751322870374150`, each time with a random number.
+
+			$ dsymutil -dump-debug-map <executable> 2>&1 >/dev/null | grep /job
+
+* Verify the source mappings
+
+		(lldb) settings show target.source-map
+
+You can check what source file a symbol was originating from using
+
+	(lldb) image lookup -va <SymbolName>
+
+
+### Breakpoints
+
+* Open a file in the project view, and set a breakpoint
+
+	![breakpoint](images/extensions/debugging/ios/breakpoint.png)
+
+## Notes
+
+### Check UUID of binary
+
+In order for the debugger to accept the `.dSYM` folder, the UUID need to match the UUID of the executable being debugged. You can check the UUID like so:
+
+	$ dwarfdump -u <PathToBinary>

+ 147 - 0
docs/zh/manuals/debugging-native-code.md

@@ -0,0 +1,147 @@
+---
+title: Debugging native code in Defold
+brief: This manual explains how to debug native code in Defold.
+---
+
+# Debugging native code
+
+Defold is well tested and should very rarely crash under normal circumstances. It is however impossible to guarantee that it will never crash, especially if your game uses native extensions. If you run into problems with crashes or native code that doesn't behave as expected there are a number of different ways forward:
+
+* Use a debugger to step through the code
+* Use print debugging
+* Analyze a crash log
+* Symbolicate a callstack
+
+
+## Use a debugger
+
+The most common way is to run the code via a `debugger`. It let's you step through the code, set `breakpoints` and it will stop the execution if you get a crash.
+
+There are several debuggers for each platform.
+
+* Visual studio - Windows
+* VSCode - Windows, macOS, Linux
+* Android Studio - Windows, macOS, Linux
+* Xcode - macOS
+* WinDBG - Windows
+* lldb / gdb - macOS, Linux, (Windows)
+* ios-deploy - macOS
+
+Each tool can debug certain platforms:
+
+* Visual studio - Windows + platforms supporting gdbserver (E.g. Linux/Android)
+* VSCode - Windows, macOS (lldb), Linux (lldb/gdb) + platforms supporting gdbserver
+* Xcode -  macOS, iOS ([learn more](/manuals/debugging-native-code-ios))
+* Android Studio - Android ([learn more](/manuals/debugging-native-code-android))
+* WinDBG - Windows
+* lldb/gdb - macOS, Linux, (iOS)
+* ios-deploy - iOS (via lldb)
+
+
+## Use print debugging
+
+The simplest way to debug your native code is to use [print debugging](http://en.wikipedia.org/wiki/Debugging#Techniques). Use the functions in the [dmLog namespace](/ref/stable/dmLog/) to watch variables or indicate the flow of execution. Using any of the log functions will print to the *Console* view in the editor and to the [game log](/manuals/debugging-game-and-system-logs).
+
+
+## Analyze a crash log
+
+The Defold engine saves a `_crash` file if it does a hard crash. The crash file will contain information about the system as well as the crash. The [game log output](/manuals/debugging-game-and-system-logs) will write where the crash file is located (it varies depending on operating system, device and application).
+
+You can use the [crash module](https://www.defold.com/ref/crash/) to read this file in the subsequent session. It is recommended that you read the file, gather the information, print it to the console and send it to an [analytics services](/tags/stars/analytics/) that supports collection of crash logs.
+
+::: important
+On Windows a `_crash.dmp` file is also generated. This file is useful when debugging a crash.
+:::
+
+### Getting the crash log from a device
+
+If a crash happens on a mobile device you can chose to download the crash file to your own computer and parse it locally.
+
+#### Android
+
+If the app is [debuggable](/manuals/project-settings/#android), you can get the crash log using the [Android Debug Bridge (ADB) tool](https://developer.android.com/studio/command-line/adb.html) and the `adb shell` command:
+
+```
+	$ adb shell "run-as com.defold.example sh -c 'cat /data/data/com.defold.example/files/_crash'" > ./_crash
+```
+
+#### iOS
+
+In iTunes, you can view/download an apps container.
+
+In the `Xcode -> Devices` window, you can also select the crash logs
+
+
+## Symbolicate a callstack
+
+If you get a callstack from either a `_crash` file or a [log file](/manuals/debugging-game-and-system-logs), you can symbolicate. This means translating each address in the callstack into a filename and line number, which in turn helps when finding out the root cause.
+
+It is important that you match the correct engine with the callstack. Otherwise it's very likely to send you debugging the incorrect things. If you are building with native extensions, be sure to add the flag [--with-symbols](https://www.defold.com/manuals/bob/) so that you get all the needed data from the build server:
+
+* iOS and macOS - the `dmengine.dSYM` folder in the `build.zip` contains the debug symbols for iOS/macOS builds.
+* Android and Linux - the executables themselves contain the debug symbols.
+* Windows - the `dmengine.pdb` file in the `build.zip` contains the debug symbols for Windows builds.
+* HTML5 - the `dmengine.js.symbols` file in the `build.zip` contains the debug symbols for HTML5 builds.
+
+If you are building without native extensions the debug symbols are available from the [Defold download website](http://d.defold.com):
+
+* iOS - The `engine/armv7-darwin/dmengine_release.dSYM.zip` and `engine/arm64-darwin/dmengine_release.dSYM.zip` files contain the debug symbols for 32 and 64-bit engine versions.
+* macOS - The `engine/x86_64-darwin/dmengine_release.dSYM.zip` file contains the debug symbols.
+* Android - The `engine/armv7-android/dmengine.apk` and `engine/arm64-android/dmengine.apk` engines include the debug symbols for 32 and 64-bit engine versions.
+* Linux - The `engine/x86_64-linux/dmengine_release` engine includes the debug symbols.
+* Windows -  The `engine/x86_64-win32/dmengine_release.pdb` file contains the debug symbols.
+* HTML5 - The `engine/js-web/dmengine_release.js.symbols` file contaons the debug symbols.
+
+::: important
+It is very important that your save the debug symbols somewhere for each public release you make of your game and that you know which release the debug symbols belong to. You will not be able to debug any native crashes if you do not have the debug symbols! Also, you should keep an unstripped version of the engine. This allows for the best symbolication of the callstack.
+:::
+
+### Symbolicate an Android callstack
+
+1. Get it from your build folder
+
+	$ ls <project>/build/<platform>/[lib]dmengine[.exe|.so]
+
+1. Unzip to a folder:
+
+	$ unzip dmengine.apk -d dmengine_1_2_105
+
+1. Find the callstack address
+
+	E.g. in the non symbolicated callstack it could look like this
+
+	#00 pc 00257224 libmy_game_name.so
+
+	Where *00257224* is the address
+
+1. Resolve the address
+
+    $ arm-linux-androideabi-addr2line -C -f -e dmengine_1_2_105/lib/armeabi-v7a/libdmengine.so _address_
+
+Note: If you get hold of a stack trace from the [Android logs](/manuals/debugging-game-and-system-logs), you might be able to symbolicate it using [ndk-stack](https://developer.android.com/ndk/guides/ndk-stack.html)
+
+### Symbolicate an iOS callstack
+
+1. If you are using Native Extensions, the server can provide the symbols (.dSYM) for you (pass `--with-symbols` to bob.jar)
+
+	$ unzip <project>/build/arm64-darwin/build.zip
+	# it will produce a Contents/Resources/DWARF/dmengine
+
+1. If you're not using Native Extensions, download the vanilla symbols:
+
+	$ wget http://d.defold.com/archive/<sha1>/engine/arm64-darwin/dmengine.dSYM
+
+1. Symbolicate using load address
+
+	For some reason, simply putting the address from the callstack doesn't work (i.e. load address 0x0)
+
+		$ atos -arch arm64 -o Contents/Resources/DWARF/dmengine 0x1492c4
+
+	# Neither does specifying the load address directly
+
+		$ atos -arch arm64 -o MyApp.dSYM/Contents/Resources/DWARF/MyApp -l0x100000000 0x1492c4
+
+	Adding the load address to the address works:
+
+		$ atos -arch arm64 -o MyApp.dSYM/Contents/Resources/DWARF/MyApp 0x1001492c4
+		dmCrash::OnCrash(int) (in MyApp) (backtrace_execinfo.cpp:27)

+ 1 - 1
docs/zh/manuals/dev-app.md

@@ -48,7 +48,7 @@ Success
 1. 确保编辑器处于运行中.
 2. 在设备上启动开发用app.
 3. 在编辑器的 <kbd>Project ▸ Targets</kbd> 中选择设备.
-4. 选择 <kbd>Project ▸ Build And Launch</kbd> 运行游戏. 如果用网络连接的话可能需要等一小会儿.
+4. 选择 <kbd>Project ▸ Build</kbd> 运行游戏. 如果用网络连接的话可能需要等一小会儿.
 5. 游戏运行时, 就可以照常使用 [热重载](/manuals/hot-reload/) 功能了.
 
 ![launch](images/dev-app/launch.png)

+ 163 - 69
docs/zh/manuals/editor.md

@@ -1,140 +1,234 @@
 ---
 title: 编辑器概述
-brief: This manual gives an overview on how the Defold editor look and works, and how to navigate in it.
+brief: 本教程介绍了 Defold 编辑器的外观和用法, 以及切换导航方法.
 ---
 
-# Editor overview
+# 编辑器概述
 
-The editor allows you to browse and manipulate all files in your game project in an efficient manner. Editing files brings up a suitable editor and shows all relevant information about the file in separate views.
+编辑器在布局排版, 切换导航上设计得尽量让游戏开发更有效率. 编辑各个视图里的文件时都会有适当的编辑器自动弹出以方便使用.
 
-## Starting the editor
+## 打开编辑器
 
-When you run the Defold editor, you are presented with a project selection and creation screen. On the left side there are three main views available. Click to select what you want to do:
+打开 Defold 编辑器, 首先呈现的是一个项目选择和新建窗口. 通过点选上面的按钮可以:
 
 Home
-: Click to show a lists your recently opened projects so you can quickly access them. This is the default view.
+: 显示最近编辑的项目以便快速打开. 这是默认视图.
 
-New
-: Click if you want to create a new Defold project, then select if you want to base your project on a basic template (from the *From Template* tab), if you would like to follow a tutorial (the *From Tutorial* tab), or try one of the sample projects (the *From Sample* tab).
+New Project
+: 创建新的项目, 然后会让你 (从 *Template* 窗口) 选择是否需要基于模板创建新项目, 还可以选择是否要参考 (*Tutorial* 窗口) 里的教程, 或者学习 (*Sample* 窗口) 里的示例项目.
 
   ![new project](images/editor/new_project.png){srcset="images/editor/[email protected] 2x"}
 
-  When you create a new project it is stored on your local drive and any edits you do are saved locally. To share the project with members of your team, use the *Synchronize* feature in the editor. It creates a Defold cloud Git storage project for you through which you and your team can synchronize work.
+  新建项目完成后所有项目文件都保存在了本地硬盘上.
 
-Import project
-: Create a working copy from an existing project from you Defold cloud Git storage account. The local copy is linked to the cloud Git project so it's ready for team synchronization.
+详情请见 [项目设立教程](https://www.defold.com/manuals/project-setup/).
 
-  ![import project](images/editor/import_project.png){srcset="images/editor/[email protected] 2x"}
+## 编辑器面板
 
-  Access to the Defold cloud git storage requires that you provide your Defold account credentials.
-
-You can learn more about the different options in the [Project Setup manual](https://www.defold.com/manuals/project-setup/).
-
-## The editor views
-
-The Defold editor is separated into a set of panes, or views, that display specific information.
+Defold 编辑器被划分为许多面板, 或称视图, 以展示和编辑数据.
 
 ![Editor 2](images/editor/editor2_overview.png)
 
-The *Assets* view
-: Lists all the files that are part of your project. Click and scroll to navigate the list. All file oriented operations can be made in this view:
+*Assets* 面板
+: 展示项目的所有文件. 点选和滚动鼠标滚轮可以在面板上滑动. 在这个视图上可以做的操作有:
 
-   - <kbd>Double click</kbd> a file to open it in an editor for that file type.
-   - <kbd>Drag and drop</kbd> to add files from elsewhere on your disk to the project or move files and folders to new locations in the project.
-   - <kbd>Right click</kbd> to open a _context menu_ from where you can create new files or folders, rename, delete, track file dependencies and more.
+   - <kbd>双击</kbd> 文件会根据文件类型启动相应的编辑器打开文件.
+   - <kbd>拖放</kbd> 文件可以向项目中添加资源或者移动资源到想要的位置.
+   - <kbd>右键单击</kbd> 会弹出 _上下文菜单_ , 可以用来进行新建文件/文件夹, 重命名, 删除, 查看文件依赖等操作.
 
-The *Editor* view
+*Editor* 面板
 
-: The center view shows the currently open file in an editor for that file type. All visual editors allows you to change the camera view:
+: 中间的视图显示当前打开的文件. 所有可视视图都可以进行如下操作:
 
-- Pan: <kbd>Alt + left mouse button</kbd>.
-- Zoom: <kbd>Alt + Right button</kbd> (three button mouse) or <kbd>Ctrl + Mouse button</kbd> (one button). If your mouse has a scroll wheel, it can be used to zoom.
-- Rotate in 3D: <kbd>Ctrl + left mouse button</kbd>.
+- 平移: <kbd>Alt + 鼠标左键</kbd>.
+- 缩放: <kbd>Alt + 鼠标右键</kbd> 或者使用鼠标滚轮.
+- 旋转: <kbd>Ctrl + 鼠标左键</kbd>.
 
-There is a toolbar in the top right corner of the scene view where you find object manipulation tools: *Move*, *Rotate* and *Scale*.
+场景试图右上角的工具栏里也有这些功能按钮: *平移*, *旋转* 和 *缩放*.
 
 ![toolbar](images/editor/toolbar.png){srcset="images/editor/[email protected] 2x"}
 
-The *Outline*
-: This view shows the content of the file currently being edited, but in a hierarchial tree structure. The outline reflects the editor view and allows you to perform operations on your items:
-   - <kbd>Click</kbd> to select an item. Hold <kbd>Shift</kbd> or <kbd>Option</kbd> to expand the selection.
-   - <kbd>Drag and drop</kbd> to move items. Drop a game object on another game object in a collection to child it.
-   - <kbd>Right click</kbd> to open a _context menu_ from where you can add items, delete selected items etc.
+*Outline* 面板
+: 这个视图以一个树形结构展示当前打开文件的内容. 大纲树的内容与场景视图内容是一一对应的, 可以方便操作:
+   - <kbd>单击</kbd> 选中一个物体. 按住 <kbd>Shift</kbd> 或 <kbd>Option</kbd> 键可以进行多选.
+   - <kbd>拖放</kbd> 移动物体. 在集合里把一个游戏对象拖放到另一个游戏对象上可以建立父子关系.
+   - <kbd>右键单击</kbd> 弹出 _上下文菜单_ 以便进行添加, 删除选中的物体等操作.
 
-The *Properties* view
-: This view shows properties associated with the currently selected item, like Position, Rotation, Animation etc, etc.
+*Properties* 面板
+: 这个视图显示出当前选中物体的属性, 比如位置, 旋转, 动画等等.
 
-The *Console*
-: This view shows any error output or purposeful printing that you do while your game is running. Alongside the console are tabs containing the *Curve Editor* which is used when editing curves in the particle editor, the *Build Errors* view that shows build errors, and the *Search Results* view that displays search results. The console is also used for interacting with the integrated debugger.
+*Tools* 面板
+: 这个视图分为几个组. *Console* 组显示游戏输出和报错信息. 旁边是显示 *编译错误*, *查找结果* 和编辑粒子曲线数据时用到的 *曲线编辑器*. 同时工具面板也负责与调试器进行交互.
 
-The *Changed Files* view:
-: This view lists any files that has been changed, added or deleted in your project. By synchronizing the project regularly you can bring your local copy in sync with what is stored in the project Git repository, that way you can collaborate within a team, and you won’t lose your work if unfortune strikes. Some file oriented operations can be performed in this view:
+*Changed Files* 面板
+: 如果项目使用 Git 做版本控制, 这个视图会列出项目中被修改, 添加或者删除的文件. 同步机制会把你的本地项目文件与 Git 托管项目进行同步, 这种机制方便团队合作开发, 而且云端备份可以保证项目不易损坏丢失. 相关操作:
 
-   - <kbd>Double click</kbd> a file to open a diff view of the file. Editor 2 opens the file in a suitable editor, just like in the assets view.
-   - <kbd>Right click</kbd> a file to open a pop up menu from where you can open a diff view, revert all changes done to the file, find the file on the filesystem and more (editor 2).
+   - <kbd>双击</kbd> 文件显示版本区别窗口. 同样, 编辑器会根据文件类型选择合适的显示窗口.
+   - <kbd>右键点击</kbd> 文件弹出的上下文菜单中, 可以进行显示版本区别窗口, 回退文件的更改, 打开文件系统浏览器显示文件位置等操作.
 
-## Side-by-side editing
+## 同时编辑
 
-If you have multiple files open, a separate tab for each file is shown at the top of the editor view. It is possible to open 2 editor views side by side. <kbd>Right click</kbd> the tab for the editor you want to move and select <kbd>Move to Other Tab Pane</kbd>.
+如果同时打开了多个文件, 编辑器视图上方就会出现多个标签. 要想两个视图对照着同时进行编辑工作. <kbd>右键点击</kbd> 想要移动的视图标签, 然后选择 <kbd>Move to Other Tab Pane</kbd>.
 
 ![2 panes](images/editor/2-panes.png){srcset="images/editor/[email protected] 2x"}
 
-You can also use the tab menu to swap the position of the two panes and join them to a single pane.
+使用视图标签还可以让两个视图交换位置或者把多个面板合为一组.
 
-## The scene editor
+## 场景编辑器
 
-Double clicking a collection or game object file brings up the *Scene Editor*:
+双击集合文件或者游戏对象文件就会打开 *场景编辑器*:
 
 ![Select object](images/editor/select.jpg)
 
-Selecting objects
-: Click on objects in the main window to select them. The rectangle surrounding the object in the editor view will highlight green to indicate what item is selected. The selected object is also highlighted in the *Outline* view.
+选择物体
+: 在主视图中点选可以选中单个物体. 框选可以选中绿色方框套住的多个物体. 被选中的物体则在 *大纲* 视图中被高亮显示.
 
-  You can also select objects by:
+  大纲中还可以:
 
-  - <kbd>Click and drag</kbd> to select all objects inside the selection region.
-  - <kbd>Click</kbd> objects in the Outline view.
+  - <kbd>点击左键拖拉</kbd> 框选中多个物体.
+  - <kbd>单击</kbd> 选中单个物体.
 
-  Hold <kbd>Shift</kbd> or <kbd>⌘</kbd> (Mac) / <kbd>Ctrl</kbd> (Win/Linux) while clicking to expand the selection.
+  按住 <kbd>Shift</kbd> 或 <kbd>⌘</kbd> (Mac) / <kbd>Ctrl</kbd> (Win/Linux) 键可以在已选中物体的基础上增选物体.
 
-The move tool
+移动工具
 : ![Move tool](images/editor/icon_move.png){.left}
-  To move objects, use the *Move Tool*. You find it in the toolbar in the top right corner of the scene editor, or by pressing the <kbd>W</kbd> key.
+  使用 *移动工具* 来移动物体. 移动工具位于场景编辑器右上角的工具栏内, 快捷键是 <kbd>W</kbd>.
 
   ![Move object](images/editor/move.jpg)
 
-  The selected object shows a set of manipulators (squares and arrows). Click and drag the green center square handle to move the object freely in screen space, click and drag the arrows to move the object along the X, Y or Z-axis. There arn also square handles for moving the object in the X-Y plane and (visible if rotating the camera in 3D) for moving the object in the X-Z and Y-Z planes.
+  被选中的物体会显示出坐标轴 (方块和箭头). 拖拽绿方块可以在屏幕空间内任意移动这个物体, 拖拽箭头则是让这个物体在 X, Y 或 Z 轴上进行移动. 拖拽别的方块则可以让这个物体在 X-Y 平面上 (在3D视图中可见) 移动或者在 X-Z , Y-Z 平面上移动.
 
-The rotate tool
+旋转工具
 : ![Rotate tool](images/editor/icon_rotate.png){.left}
-  To rotate objects, use the *Rotate Tool* by selecting it in the toolbar, or by pressing the <kbd>E</kbd> key.
+  使用 *旋转工具* 来旋转物体. 旋转工具位于场景编辑器右上角的工具栏内, 快捷键是 <kbd>E</kbd>.
 
   ![Move object](images/editor/rotate.jpg)
 
-  This tool consists of four circular manipulators. An orange manipulator that rotates the object in screen space and one for rotation around each of the X, Y and Z axes. Since the view is peripendicular to the X- and Y-axis, the circles only appear as two lines crossing the object.
+  旋转工具的坐标轴显示为圆形. 拖拽橙色的圆可以在屏幕空间内任意旋转这个物体, 可以沿着 X, Y 和 Z 轴旋转. 因为 X 和 Y 轴的位置关系, 在2D视图上仅显示为穿过物体的两条线.
 
-The scale tool
+缩放工具
 : ![Scale tool](images/editor/icon_scale.png){.left}
-  To scale objects, use the *Scale Tool* by selecting it in the toolbar, or by pressing the <kbd>R</kbd> key.
+  使用 *缩放工具* 来缩放物体. 缩放工具位于场景编辑器右上角的工具栏内, 快捷键是 <kbd>R</kbd>.
 
   ![Scale object](images/editor/scale.jpg)
 
-  This tool consists of a set of square handles. The center one scales the object uniformly in all axes (including Z). There also one handle for scaling along each of the X, Y and Z axes and one handle for scaling in the X-Y plane, the X-Z plane and the Y-Z plane.
+  缩放工具坐标轴显示为一组方块. 拖拽中间的方块可以将物体等比缩放 (包括Z轴). 同样也可以沿着 X, Y 和 Z 轴方向, 以及 X-Y , X-Z 和 Y-Z 平面上进行缩放.
 
-## Creating new project files
+## 新建文件
 
-To create new resource files, either select <kbd>File ▸ New...</kbd> and then choose the file type from the menu, or use the context menu:
+新建资源文件有两种方法, 通过点选菜单栏 <kbd>File ▸ New...</kbd> 按钮, 或者使用上下文菜单:
 
-<kbd>Right click</kbd> the target location in the *Assets* browser, then select <kbd>New... ▸ [file type]</kbd>:
+在 *资源* 浏览器目标位置 <kbd>右键单击</kbd> , 选择 <kbd>New... ▸ [file type]</kbd> 按钮:
 
 ![create file](images/editor/create_file.png){srcset="images/editor/[email protected] 2x"}
 
-Type a suitable name for the new file. The full file name including the file type suffix is shown under *Path* in the dialog:
+为新文件取一个有意义的名字. 完整文件名包括类型扩展名会显示在 *路径* 对话框内:
 
 ![create file name](images/editor/create_file_name.png){srcset="images/editor/[email protected] 2x"}
 
-## Importing files to your project
+## 向项目添加资源文件
 
-To add asset files (images, sounds, models etc) to your project, simply drag and drop them to the correct position in the *Assets* browser. This will make _copies_ of the files at the selected location in the project file structure.
+要向项目添加资源 (图片, 声音, 模型等) 文件, 只需把文件拖放到 *资源* 浏览器里适当的位置上. 这样做实际上是把文件系统中的资源文件 _拷贝_ 到项目中来. 详情请见 [导入资源教程](/manuals/importing-assets/).
 
 ![Import files](images/editor/import.png){srcset="images/editor/[email protected] 2x"}
+
+## 快捷键
+
+| Command | Windows | macOS | Linux |
+|---------|---------|-------|-------|
+| Add | <kbd>A</kbd> | <kbd>A</kbd> | <kbd>A</kbd> |
+| Add secondary | <kbd>Shift</kbd>+<kbd>A</kbd> | <kbd>Shift</kbd>+<kbd>A</kbd> | <kbd>Shift</kbd>+<kbd>A</kbd> |
+| Backwards tab trigger | <kbd>Shift</kbd>+<kbd>Tab</kbd> | <kbd>Shift</kbd>+<kbd>Tab</kbd> | <kbd>Shift</kbd>+<kbd>Tab</kbd> |
+| Beginning of file | <kbd>Ctrl</kbd>+<kbd>Home</kbd> | <kbd>Cmd</kbd>+<kbd>Up</kbd> | <kbd>Ctrl</kbd>+<kbd>Home</kbd> |
+| Beginning of line |  | <kbd>Ctrl</kbd>+<kbd>A</kbd> |  |
+| Beginning of line text | <kbd>Home</kbd> | <kbd>Home</kbd> | <kbd>Home</kbd> |
+| Build | <kbd>Ctrl</kbd>+<kbd>B</kbd> | <kbd>Cmd</kbd>+<kbd>B</kbd> | <kbd>Ctrl</kbd>+<kbd>B</kbd> |
+| Close | <kbd>Ctrl</kbd>+<kbd>W</kbd> | <kbd>Cmd</kbd>+<kbd>W</kbd> | <kbd>Ctrl</kbd>+<kbd>W</kbd> |
+| Close all | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>W</kbd> | <kbd>Shift</kbd>+<kbd>Cmd</kbd>+<kbd>W</kbd> | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>W</kbd> |
+| Continue | <kbd>F5</kbd> | <kbd>F5</kbd> | <kbd>F5</kbd> |
+| Copy | <kbd>Ctrl</kbd>+<kbd>C</kbd> | <kbd>Cmd</kbd>+<kbd>C</kbd> | <kbd>Ctrl</kbd>+<kbd>C</kbd> |
+| Cut | <kbd>Ctrl</kbd>+<kbd>X</kbd> | <kbd>Cmd</kbd>+<kbd>X</kbd> | <kbd>Ctrl</kbd>+<kbd>X</kbd> |
+| Delete | <kbd>Delete</kbd> | <kbd>Delete</kbd> | <kbd>Delete</kbd> |
+| Delete backward | <kbd>Backspace</kbd> | <kbd>Backspace</kbd> | <kbd>Backspace</kbd> |
+| Delete line |  | <kbd>Ctrl</kbd>+<kbd>D</kbd> |  |
+| Delete next word | <kbd>Ctrl</kbd>+<kbd>Delete</kbd> | <kbd>Alt</kbd>+<kbd>Delete</kbd> | <kbd>Ctrl</kbd>+<kbd>Delete</kbd> |
+| Delete prev word | <kbd>Ctrl</kbd>+<kbd>Backspace</kbd> | <kbd>Alt</kbd>+<kbd>Backspace</kbd> | <kbd>Ctrl</kbd>+<kbd>Backspace</kbd> |
+| Delete to end of line | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>Delete</kbd> | <kbd>Cmd</kbd>+<kbd>Delete</kbd> | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>Delete</kbd> |
+| Documentation | <kbd>F1</kbd> | <kbd>F1</kbd> | <kbd>F1</kbd> |
+| Down | <kbd>Down</kbd> | <kbd>Down</kbd> | <kbd>Down</kbd> |
+| End of file | <kbd>Ctrl</kbd>+<kbd>End</kbd> | <kbd>Cmd</kbd>+<kbd>Down</kbd> | <kbd>Ctrl</kbd>+<kbd>End</kbd> |
+| End of line | <kbd>End</kbd> | <kbd>Ctrl</kbd>+<kbd>E</kbd> | <kbd>End</kbd> |
+| Enter | <kbd>Enter</kbd> | <kbd>Enter</kbd> | <kbd>Enter</kbd> |
+| Erase tool | <kbd>Shift</kbd>+<kbd>E</kbd> | <kbd>Shift</kbd>+<kbd>E</kbd> | <kbd>Shift</kbd>+<kbd>E</kbd> |
+| Escape | <kbd>Esc</kbd> | <kbd>Esc</kbd> | <kbd>Esc</kbd> |
+| Find next | <kbd>Ctrl</kbd>+<kbd>G</kbd> | <kbd>Cmd</kbd>+<kbd>G</kbd> | <kbd>Ctrl</kbd>+<kbd>G</kbd> |
+| Find prev | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>G</kbd> | <kbd>Shift</kbd>+<kbd>Cmd</kbd>+<kbd>G</kbd> | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>G</kbd> |
+| Find text | <kbd>Ctrl</kbd>+<kbd>F</kbd> | <kbd>Cmd</kbd>+<kbd>F</kbd> | <kbd>Ctrl</kbd>+<kbd>F</kbd> |
+| Frame selection | <kbd>F</kbd> | <kbd>F</kbd> | <kbd>F</kbd> |
+| Goto line | <kbd>Ctrl</kbd>+<kbd>L</kbd> | <kbd>Cmd</kbd>+<kbd>L</kbd> | <kbd>Ctrl</kbd>+<kbd>L</kbd> |
+| Hide selected | <kbd>Ctrl</kbd>+<kbd>E</kbd> | <kbd>Cmd</kbd>+<kbd>E</kbd> | <kbd>Ctrl</kbd>+<kbd>E</kbd> |
+| Hot reload | <kbd>Ctrl</kbd>+<kbd>R</kbd> | <kbd>Cmd</kbd>+<kbd>R</kbd> | <kbd>Ctrl</kbd>+<kbd>R</kbd> |
+| Left | <kbd>Left</kbd> | <kbd>Left</kbd> | <kbd>Left</kbd> |
+| Move down | <kbd>Alt</kbd>+<kbd>Down</kbd> | <kbd>Alt</kbd>+<kbd>Down</kbd> | <kbd>Alt</kbd>+<kbd>Down</kbd> |
+| Move tool | <kbd>W</kbd> | <kbd>W</kbd> | <kbd>W</kbd> |
+| Move up | <kbd>Alt</kbd>+<kbd>Up</kbd> | <kbd>Alt</kbd>+<kbd>Up</kbd> | <kbd>Alt</kbd>+<kbd>Up</kbd> |
+| New file | <kbd>Ctrl</kbd>+<kbd>N</kbd> | <kbd>Cmd</kbd>+<kbd>N</kbd> | <kbd>Ctrl</kbd>+<kbd>N</kbd> |
+| Next word | <kbd>Ctrl</kbd>+<kbd>Right</kbd> | <kbd>Alt</kbd>+<kbd>Right</kbd> | <kbd>Ctrl</kbd>+<kbd>Right</kbd> |
+| Open | <kbd>Ctrl</kbd>+<kbd>O</kbd> | <kbd>Cmd</kbd>+<kbd>O</kbd> | <kbd>Ctrl</kbd>+<kbd>O</kbd> |
+| Open asset | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>R</kbd> | <kbd>Cmd</kbd>+<kbd>P</kbd> | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>R</kbd> |
+| Page down | <kbd>Page Down</kbd> | <kbd>Page Down</kbd> | <kbd>Page Down</kbd> |
+| Page up | <kbd>Page Up</kbd> | <kbd>Page Up</kbd> | <kbd>Page Up</kbd> |
+| Paste | <kbd>Ctrl</kbd>+<kbd>V</kbd> | <kbd>Cmd</kbd>+<kbd>V</kbd> | <kbd>Ctrl</kbd>+<kbd>V</kbd> |
+| Preferences | <kbd>Ctrl</kbd>+<kbd>Comma</kbd> | <kbd>Cmd</kbd>+<kbd>Comma</kbd> | <kbd>Ctrl</kbd>+<kbd>Comma</kbd> |
+| Prev word | <kbd>Ctrl</kbd>+<kbd>Left</kbd> | <kbd>Alt</kbd>+<kbd>Left</kbd> | <kbd>Ctrl</kbd>+<kbd>Left</kbd> |
+| Proposals | <kbd>Ctrl</kbd>+<kbd>Space</kbd> | <kbd>Ctrl</kbd>+<kbd>Space</kbd> | <kbd>Ctrl</kbd>+<kbd>Space</kbd> |
+| Quit | <kbd>Ctrl</kbd>+<kbd>Q</kbd> | <kbd>Cmd</kbd>+<kbd>Q</kbd> | <kbd>Ctrl</kbd>+<kbd>Q</kbd> |
+| Realign camera | <kbd>Period</kbd> | <kbd>Period</kbd> | <kbd>Period</kbd> |
+| Rebuild | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>B</kbd> | <kbd>Shift</kbd>+<kbd>Cmd</kbd>+<kbd>B</kbd> | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>B</kbd> |
+| Rebundle | <kbd>Ctrl</kbd>+<kbd>U</kbd> | <kbd>Cmd</kbd>+<kbd>U</kbd> | <kbd>Ctrl</kbd>+<kbd>U</kbd> |
+| Redo | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>Z</kbd> | <kbd>Shift</kbd>+<kbd>Cmd</kbd>+<kbd>Z</kbd> | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>Z</kbd> |
+| Reindent | <kbd>Ctrl</kbd>+<kbd>I</kbd> | <kbd>Ctrl</kbd>+<kbd>I</kbd> | <kbd>Ctrl</kbd>+<kbd>I</kbd> |
+| Reload stylesheet |  | <kbd>Ctrl</kbd>+<kbd>R</kbd> |  |
+| Rename | <kbd>F2</kbd> | <kbd>F2</kbd> | <kbd>F2</kbd> |
+| Replace next | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>H</kbd> | <kbd>Alt</kbd>+<kbd>Cmd</kbd>+<kbd>G</kbd> | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>H</kbd> |
+| Replace text |  | <kbd>Alt</kbd>+<kbd>Cmd</kbd>+<kbd>F</kbd> |  |
+| Right | <kbd>Right</kbd> | <kbd>Right</kbd> | <kbd>Right</kbd> |
+| Rotate tool | <kbd>E</kbd> | <kbd>E</kbd> | <kbd>E</kbd> |
+| Save all | <kbd>Ctrl</kbd>+<kbd>S</kbd> | <kbd>Cmd</kbd>+<kbd>S</kbd> | <kbd>Ctrl</kbd>+<kbd>S</kbd> |
+| Scale tool | <kbd>R</kbd> | <kbd>R</kbd> | <kbd>R</kbd> |
+| Scene stop | <kbd>Ctrl</kbd>+<kbd>T</kbd> | <kbd>Cmd</kbd>+<kbd>T</kbd> | <kbd>Ctrl</kbd>+<kbd>T</kbd> |
+| Search in files | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>F</kbd> | <kbd>Shift</kbd>+<kbd>Cmd</kbd>+<kbd>F</kbd> | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>F</kbd> |
+| Select all | <kbd>Ctrl</kbd>+<kbd>A</kbd> | <kbd>Cmd</kbd>+<kbd>A</kbd> | <kbd>Ctrl</kbd>+<kbd>A</kbd> |
+| Select beginning of file | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>Home</kbd> | <kbd>Shift</kbd>+<kbd>Cmd</kbd>+<kbd>Up</kbd> | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>Home</kbd> |
+| Select beginning of line |  | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>A</kbd> |  |
+| Select beginning of line text | <kbd>Shift</kbd>+<kbd>Home</kbd> | <kbd>Shift</kbd>+<kbd>Home</kbd> | <kbd>Shift</kbd>+<kbd>Home</kbd> |
+| Select down | <kbd>Shift</kbd>+<kbd>Down</kbd> | <kbd>Shift</kbd>+<kbd>Down</kbd> | <kbd>Shift</kbd>+<kbd>Down</kbd> |
+| Select end of file | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>End</kbd> | <kbd>Shift</kbd>+<kbd>Cmd</kbd>+<kbd>Down</kbd> | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>End</kbd> |
+| Select end of line | <kbd>Shift</kbd>+<kbd>End</kbd> | <kbd>Shift</kbd>+<kbd>Alt</kbd>+<kbd>Down</kbd> | <kbd>Shift</kbd>+<kbd>End</kbd> |
+| Select left | <kbd>Shift</kbd>+<kbd>Left</kbd> | <kbd>Shift</kbd>+<kbd>Left</kbd> | <kbd>Shift</kbd>+<kbd>Left</kbd> |
+| Select next occurrence | <kbd>Ctrl</kbd>+<kbd>D</kbd> | <kbd>Cmd</kbd>+<kbd>D</kbd> | <kbd>Ctrl</kbd>+<kbd>D</kbd> |
+| Select next word | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>Right</kbd> | <kbd>Shift</kbd>+<kbd>Alt</kbd>+<kbd>Right</kbd> | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>Right</kbd> |
+| Select page down | <kbd>Shift</kbd>+<kbd>Page Down</kbd> | <kbd>Shift</kbd>+<kbd>Page Down</kbd> | <kbd>Shift</kbd>+<kbd>Page Down</kbd> |
+| Select page up | <kbd>Shift</kbd>+<kbd>Page Up</kbd> | <kbd>Shift</kbd>+<kbd>Page Up</kbd> | <kbd>Shift</kbd>+<kbd>Page Up</kbd> |
+| Select prev word | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>Left</kbd> | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>Left</kbd> | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>Left</kbd> |
+| Select right | <kbd>Shift</kbd>+<kbd>Right</kbd> | <kbd>Shift</kbd>+<kbd>Right</kbd> | <kbd>Shift</kbd>+<kbd>Right</kbd> |
+| Show last hidden | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>E</kbd> | <kbd>Shift</kbd>+<kbd>Cmd</kbd>+<kbd>E</kbd> | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>E</kbd> |
+| Show palette | <kbd>Space</kbd> | <kbd>Space</kbd> | <kbd>Space</kbd> |
+| Split selection into lines | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>L</kbd> | <kbd>Shift</kbd>+<kbd>Cmd</kbd>+<kbd>L</kbd> | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>L</kbd> |
+| Step into | <kbd>F11</kbd> | <kbd>F11</kbd> | <kbd>F11</kbd> |
+| Step out | <kbd>Shift</kbd>+<kbd>F11</kbd> | <kbd>Shift</kbd>+<kbd>F11</kbd> | <kbd>Shift</kbd>+<kbd>F11</kbd> |
+| Step over | <kbd>F10</kbd> | <kbd>F10</kbd> | <kbd>F10</kbd> |
+| Stop debugger | <kbd>Shift</kbd>+<kbd>F5</kbd> |  | <kbd>Shift</kbd>+<kbd>F5</kbd> |
+| Tab | <kbd>Tab</kbd> | <kbd>Tab</kbd> | <kbd>Tab</kbd> |
+| Toggle breakpoint | <kbd>F9</kbd> | <kbd>F9</kbd> | <kbd>F9</kbd> |
+| Toggle comment | <kbd>Ctrl</kbd>+<kbd>Slash</kbd> | <kbd>Cmd</kbd>+<kbd>Slash</kbd> | <kbd>Ctrl</kbd>+<kbd>Slash</kbd> |
+| Toggle component guides | <kbd>Ctrl</kbd>+<kbd>H</kbd> | <kbd>Ctrl</kbd>+<kbd>Cmd</kbd>+<kbd>H</kbd> | <kbd>Ctrl</kbd>+<kbd>H</kbd> |
+| Toggle pane bottom | <kbd>F7</kbd> | <kbd>F7</kbd> | <kbd>F7</kbd> |
+| Toggle pane left | <kbd>F6</kbd> | <kbd>F6</kbd> | <kbd>F6</kbd> |
+| Toggle pane right | <kbd>F8</kbd> | <kbd>F8</kbd> | <kbd>F8</kbd> |
+| Toggle visibility filters | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>I</kbd> | <kbd>Shift</kbd>+<kbd>Cmd</kbd>+<kbd>I</kbd> | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>I</kbd> |
+| Undo | <kbd>Ctrl</kbd>+<kbd>Z</kbd> | <kbd>Cmd</kbd>+<kbd>Z</kbd> | <kbd>Ctrl</kbd>+<kbd>Z</kbd> |
+| Up | <kbd>Up</kbd> | <kbd>Up</kbd> | <kbd>Up</kbd> |
+| Up major | <kbd>Shift</kbd>+<kbd>Up</kbd> | <kbd>Shift</kbd>+<kbd>Up</kbd> | <kbd>Shift</kbd>+<kbd>Up</kbd> |
+| Zoom in | <kbd>Ctrl</kbd>+<kbd>'</kbd>+<kbd>'</kbd> | <kbd>Cmd</kbd>+<kbd>'</kbd>+<kbd>'</kbd> | <kbd>Ctrl</kbd>+<kbd>'</kbd>+<kbd>'</kbd> |
+| Zoom out | <kbd>Ctrl</kbd>+<kbd>'-'</kbd> | <kbd>Cmd</kbd>+<kbd>'-'</kbd> | <kbd>Ctrl</kbd>+<kbd>'-'</kbd> |

+ 212 - 0
docs/zh/manuals/extension-facebook.md

@@ -0,0 +1,212 @@
+---
+title: Defold Facebook 教程
+brief: 本教程介绍了如何在 Defold 游戏中设置和整合 Facebook 功能.
+---
+
+API 文档位于 [这里](https://defold.github.io/extension-facebook/).
+
+## 注册成为 Facebook 开发者
+# Facebook
+
+Facebook API 作为 [原生扩展](/manuals/extensions/) 提供. 此扩展使得 iOS, Android 和 HTML5 游戏可以使用 Facebook 的在线交互功能. Defold Facebook 扩展对于 iOS, Android 和 HTML5 (基于 Facebook Canvas) 不同平台封装了同一的 Facebook API 函数库. 要在游戏中使用 Facebook 在线交互功能, 首先需要有一个 Facebook 账户.
+
+## 安装扩展
+
+要使用 Facebook 扩展, 需要在 `game.project` 文件中设置依赖. 最新稳定版的 URL 是:
+```
+https://github.com/defold/extension-facebook/archive/master.zip
+```
+
+推荐使用 [指定版本](https://github.com/defold/extension-facebook/releases) 的zip包链接作为依赖.
+
+从 Defold 1.2.162 开始, 此扩展需要其他依赖:
+```
+https://github.com/defold/extension-gps/archive/master.zip
+```
+
+
+开发 Facebook 应用首先要注册成为 Facebook 开发者. 这样你的 Defold 游戏就能与 Facebook 应用交互了.
+
+* 访问 [Facebook 开发者网站](https://developers.facebook.com) 进行注册
+* 登入你的 Facebook 账户.
+* 注册激活你的开发者身份.
+
+![Register as a developer](images/facebook/register_dev.png)
+![ developer](images/facebook/register_verify.png)
+
+## 创建 Facebook 应用
+
+下一步要创建一个 Facebook 应用. 右上角 <kbd>My Apps</kbd> 菜单列出了你的应用, 以及 <kbd>Add a New App</kbd> 按钮.
+
+![Add new app](images/facebook/add_new_app_menu.png)
+
+然后是选择目标平台界面. 点击 *basic setup* 可以略过引导界面.
+
+::: 注意
+引导界面里绝大多数内容与开发 Defold 游戏无关. 而且, 一般不需要自己修改 *Info.plist* 或者 *AndroidManifest.xml* 文件. Defold 会自动完成.
+:::
+
+![Add new app platform](images/facebook/add_new_app_platform.png)
+
+在 dashboard 里可以随意添加, 删除应用或者更改平台设置. 接下来需要设置 *Display Name*, *Namespace* 和 *Category*. 这些也都可以在 dashboard 里设置. 设置完后, Facebook 会给你的应用创建唯一id. *App ID* 是不可修改的.
+
+![New app id](images/facebook/new_app_id.png)
+
+![App dashboard settings](images/facebook/add_platform.png)
+
+点击 *Settings* 面板. 这里显示了 *App ID*. 你要在 Defold 游戏的 [项目设置](/manuals/project-settings) 里输入这个id. 从 *资源面板* 里打开 *game.project* 文件, 滚动到 *Facebook* 部分, 在 `Appid` 这里填入 *App ID*.
+
+现在回到 Facebook 网站的 *Settings* 页面, 点击 *+ Add Platform* 来为应用设置目标平台. 针对每个平台都有不同的设置.
+
+![Select platform](images/facebook/select_platform.png)
+
+## iOS
+
+iOS 平台需要填写和 *game.project* 里一样的 `bundle_identifier`.
+
+![iOS settings](images/facebook/settings_ios.png)
+
+## Android
+
+Android 平台需要填写 *Google Play Package Name*, 也就是 *game.project* 里的 *package* id. 还要在 *Key Hashes* 里填入证书的 Hashes. 可以使用 openssl 从 *certificate.pem* 文件生成 Hashes:
+
+```sh
+$ cat certificate.pem | openssl x509 -outform der | openssl sha1 -binary | openssl base64
+```
+
+(关于签名文件详细信息参见 [创建证书和密匙](/manuals/android/#creating-certificates-and-keys).)
+
+![Android settings](images/facebook/settings_android.png)
+
+## Facebook Canvas
+
+对于 HTML5 游戏, 过程略有不同. Facebook 需要直接在线访问你的游戏内容. 两个办法:
+
+![Facebook Canvas settings](images/facebook/settings_canvas.png)
+
+1. 使用 Facebook 的 *Simple Application Hosting*. 点击 *Yes* 使用在线托管. 选择 *uploaded assets* 打开托管资源管理器.
+
+    ![Simple hosting](images/facebook/simple_hosting.png)
+
+    托管类型选择 "HTML5 Bundle":
+
+    ![HTML5 bundle](images/facebook/html5_bundle.png)
+
+    把你的 HTML5 游戏包压缩为一个 .7z 或者 .zip 包上传至 Facebook. 点击 *Push to production* 即可在线发布.
+
+2. 另一个办法就是把你的 HTML5 游戏包托管到你自己选择的服务器上通过 HTTPS 访问. *Secure Canvas URL* 这里填写你的游戏地址.
+
+至此 Facebook 就能通过 *Canvas Page* 发布你的游戏了.
+
+## 小测试
+
+可以通过创建一个小测试来看看扩展工作是否顺利.
+
+1. 新建游戏对象然后在上面添加一个脚本.
+2. 脚本里加入如下代码 (需要 Facebook 扩展 v.2 版及以上):
+
+```lua
+local function get_me_callback(self, id, response)
+    -- The response table includes all the response data
+    pprint(response)
+end
+
+local function fb_login(self, data)
+    if data.status == facebook.STATE_OPEN then
+        -- Logged in ok. Let's try reading some "me" data through the
+        -- HTTP graph API.
+        local token = facebook.access_token()
+        local url = "https://graph.facebook.com/me/?access_token=" .. token
+        http.request(url, "GET", get_me_callback)
+    elseif data.status == facebook.STATE_CLOSED_LOGIN_FAILED then
+        -- Do something to indicate that login failed
+    end
+    if data.error then
+        -- An error occurred
+    else
+        -- No error
+    end
+end
+
+function init(self)
+    -- Log in with read permissions.
+    local permissions = { "public_profile", "email" }
+    facebook.login_with_permissions(permissions, facebook.AUDIENCE_EVERYONE, fb_login)
+end
+```
+
+直接运行, 控制台输出大概这样:
+
+```txt
+DEBUG:SCRIPT:
+{
+  status = 200,
+  headers = {
+    connection = keep-alive,
+    date = Fri, 04 Nov 2016 13:54:33 GMT,
+    etag = "0725a4f703fe6af27da183cfec0bb22637e331e0",
+    access-control-allow-origin = *,
+    content-length = 53,
+    expires = Sat, 01 Jan 2000 00:00:00 GMT,
+    content-type = text/javascript; charset=UTF-8,
+    x-fb-debug = Pr1qUssb8Xa3x3r1t913hHMdefh69DSYYV5vcxeOB7O33mcfShIw+r7BoLpn147I2wzLF2CZRTpnR3/VYOtFpA==,
+    facebook-api-version = v2.5,
+    cache-control = private, no-cache, no-store, must-revalidate,
+    pragma = no-cache,
+    x-fb-trace-id = F03S5dtsdaS,
+    x-fb-rev = 2664414,
+  }
+  response = {"name":"Max de Fold ","id":"14159265358979323"},
+}
+```
+
+* 完整的 Defold Facebook API 文档在 [这里](https://defold.github.io/extension-facebook/).
+* Facebook Graph API 在这里: https://developers.facebook.com/docs/graph-api
+
+
+## Facebook Analytics
+
+Facebook Analytics 可以对游戏相关信息汇总统计并提供适当建议, 比如开启游戏人数, 付款频率和其他各种信息.
+
+### 配置
+
+使用 Facebook Analytics 之前你得创建好 Facebook 应用. 然后就是把分析功能整合进去:
+
+![Add Facebook Analytics](images/facebook/add_facebook_analytics.png)
+
+分析功能也有很多配置选项. 详情请见:
+
+![Add Facebook Analytics](images/facebook/facebook_analytics_settings.png)
+
+### 使用
+
+分析功能配置好之后就可以通过发布分析事件来进行信息统计了:
+
+```lua
+function init(self)
+    -- post a spent credits event
+    local params = { [facebook.PARAM_LEVEL] = 30, [facebook.PARAM_NUM_ITEMS] = 2 }
+    facebook.post_event(facebook.EVENT_SPENT_CREDITS, 25, params)
+
+    -- post a custom event
+    local level = 19
+    local params = { kills = 23, gold = 4, xp = 890 }
+    facebook.post_event("level_completed", level, params)
+end
+```
+
+各种事件和参数详情请见 [Facebook 扩展 API 文档](https://defold.github.io/extension-facebook/). 这些应该与 Facebook 的 [标准事件](https://developers.facebook.com/docs/analytics/send_data/events#standard) 和 [参数](https://developers.facebook.com/docs/analytics/send_data/events#parameter) 文档相一致.
+
+除了分析统计事件, Defold 使用 Facebook SDK 时也会自动产生一些事件, 比如装机次数启动次数之类的. 详情请见 Facebook 的 [自动日志事件](https://developers.facebook.com/docs/analytics/send_data/events#autologged) 文档.
+
+事件汇总后会在 Facebook Analytics dashboard 中显示出来, 点击 *View Analytics* 按钮查看分析信息:
+
+![Add Facebook Analytics](images/facebook/facebook_analytics_open_dashboard.png)
+
+通过页面里 *Events* 选项可以看到各种事件:
+
+![Add Facebook Analytics](images/facebook/facebook_analytics_show_events.png)
+
+### Facebook 的事件分享
+
+你可以选择是否向 Facebook 分享你的事件数据. 通过 [`enable_event_usage()`](https://defold.github.io/extension-facebook/#enable_event_usage) 和 [`disable_event_usage()`](https://defold.github.io/extension-facebook/#disable_event_usage) 函数控制. 默认不分享.

+ 85 - 0
docs/zh/manuals/extension-fbinstant.md

@@ -0,0 +1,85 @@
+---
+title: Facebook Instant Games
+brief: 本教程介绍了如何使用 Defold 创建 Facebook Instant Games.
+---
+
+# Facebook Instant Games
+
+Instant Games 可以让玩家在 Facebook 平台上随时玩到游戏的新方式. 基于 HTML5 技术, 可以让玩家直接从新闻Feed或者聊天消息中打开游戏, 同时支持桌面和移动设备.
+
+![InstantGames](images/instant-games/instantgames.png)
+
+## 发布 Instant Games
+
+在把你的 Defold 游戏发布到 Facebook 之前, 需要对游戏项目进行一些设定:
+
+1. 在 [Facebook App Dashboard](https://developers.facebook.com/apps) 里创建 Instant Games 应用. 详情请见 [Instant Games 入门指南](https://developers.facebook.com/docs/games/instant-games/getting-started/game-setup).
+
+2. 在你的 "game.project" 文件中添加 Instant Games 扩展依赖. 即把 "https://github.com/defold/extension-fbinstant/archive/master.zip" 添加到 *Dependencies* 属性中.
+
+   ![Project settings](images/instant-games/game_project.png)
+
+3. 确保在你打包游戏生成的 "index.html" 文件包含了 Instant Games SDK.
+
+   ```html
+   <script src="https://connect.facebook.net/en_US/fbinstant.6.3.js"></script>
+   ```
+
+   关于打包设置详情请见 [HTML5 教程](/manuals/html5/#自定义html5打包).
+
+4. 都准备好之后, 打包 HTML5 游戏并上传至 Facebook.
+
+## API 使用
+
+Instant Games 扩展使用命名空间 `fbinstant.*` , 用 Lua API 对 Javascript SDK 进行了封装. 此扩展基本上是从 Javascript SDK 到 Lua API 一一对应的.
+
+比如, 看以下 Javascript 代码:
+
+```javascript
+FBInstant.initializeAsync().then(function() {
+    FBInstant.startGameAsync().then(function() {
+      var playerID = FBInstant.player.getID();
+      var playerName = FBInstant.player.getName();
+    });
+});
+```
+
+相应的 Lua 代码是这样的:
+
+```lua
+fbinstant.initialize(function(self, success)
+    fbinstant.start_game(function(self, success)
+        local player_id = fbinstant.get_player().id
+        local player_name = fbinstant.get_player().name
+    end)
+end)
+```
+
+关于如何在Defold中使用 Instant Games SDK 详情请见 [API documentation](https://github.com/defold/extension-fbinstant/blob/master/README.md).
+
+## 示例游戏
+
+有个 Defold 游戏 "Tic Tac Toe" 的 Instant Games 版本在 [官方 GitHub 代码库](https://github.com/defold/extension-fbinstant) 提供了完整的源码和素材. 可以作为学习资料或者素材来使用.
+
+![Tic Tac Toe](images/instant-games/tictactoe.png)
+
+## 减小包体
+
+Facebook Instant Games [最佳实践](https://developers.facebook.com/docs/games/instant-games/best-practices) 建议游戏首次载入时间不得超过5秒. 这对 Defold 来说有点勉强, 好在还有一些方法能减小游戏体积:
+
+去掉未使用引擎特性
+: HTML5 版的标准 Defold 引擎用gzip压缩后小于 1.2MB, 但是可以通过去掉不必要的引擎特效来达到减少包体的效果. 在 "app.manifest" 文件中可以指定去掉引擎哪方面特性, 此文件在 "game.project" 文件的 [Native Extension 部分](/manuals/project-settings/#原生扩展) 引用.
+
+  此功能尚处于测试阶段且没有说明文档. 这里: https://forum.defold.com/t/stripping-appmanifest-maker/16059 有一个可以自动生成 app.manifests 文件的工具.
+
+使用纹理压缩
+: 纹理压缩是有效减少包体和内存占用的方法. 关于纹理压缩详情请见 [Texture Profiles 教程](/manuals/texture-profiles/).
+
+减少启动所需资源按需下载
+: 许多游戏把内容分成各个关卡或者各个篇章. 这种类型的游戏可以把内容放到玩家玩到的时候再下载.
+
+这种把内容分块, 保存到服务器上然后按需下载并缓存的方法可以有效减少 Instant Game 包体. 这种方法由 Defold 的 [热更新](/manuals/live-update/) 系统提供支持.
+
+## 已知问题
+
+关于 HTML5 和 Instant Games 的已知问题详见 [HTML5 教程已知问题部分](/manuals/html5/#known-issues-and-limitations).

+ 21 - 0
docs/zh/manuals/extension-gpgs.md

@@ -0,0 +1,21 @@
+---
+title: Defold 中的 Google Play Game 服务
+brief: 本教程介绍了配置使用 Google Play Game 服务的方法
+---
+
+# Google Play Game Services
+
+[Google Play Game Services](https://developers.google.com/games/services) 可以给你的安卓游戏增加用户认证, 云存储, 成就系统, 排行榜等各种功能. Google Play Game 服务在 Defold 中作为一个 [原生扩展](/manuals/extensions/).
+
+## 安装扩展
+
+要使用 Google Play Game 服务扩展你需要在 `game.project` 文件中加入依赖. 最新稳定版地址:
+```
+https://github.com/defold/extension-gpgs/archive/master.zip
+```
+
+推荐使用发布页的zip链接 [指定某个版本](https://github.com/defold/extension-gpgs/releases).
+
+## 使用扩展
+
+使用的介绍以及 API 文档位于 [GitHub 扩展项目网页](https://defold.github.io/extension-gpgs/).

+ 31 - 18
docs/zh/manuals/extensions-debugging.md

@@ -1,16 +1,28 @@
 ---
-title: 调试原生代码
-brief: 本教程介绍了一些调试应用以及解析崩溃日志的方法.
+title: 调试原生扩展
+brief: 本教程介绍了一些调试包含原生扩展程序应用的方法.
 ---
 
-# 调试原生代码
+# 调试原生扩展
 
-这里我们介绍了一些调试应用以及读取崩溃日志的方法.
+开发原生扩展程序的时候总会碰到这样那样的问题,比如在编译服务器上编译不通过或者应用里扩展程序无效等等.
 
-## 调试
+## 报错调试
 
-当你的代码出现问题时,
-有一些方法可以找到问题根源.
+通常一旦原生扩展程序在编译服务器上报错, 服务器控制台会给出所有的错误信息. 包括错误类型和哪个文件哪一行出的错. 同时 `log.txt` 日志文件也会被保存在编译文件夹当中.
+
+## 运行时调试
+
+一旦原生扩展的程序代码出了问题, 有一下途径可以找到问题所在.
+
+* Using a debugger
+* Using print debugging
+* Analyzing a crash log
+* Symbolicating a callstack
+
+### 使用调试器
+
+当你的代码出现问题时, 有一些方法可以找到问题的根源.
 
 最普通的就是使用 `调试器`.
 调试可以让你在代码中步进, 设置 `断点` 而且能在崩溃时冻结运行.
@@ -36,34 +48,33 @@ brief: 本教程介绍了一些调试应用以及解析崩溃日志的方法.
 * ios-deploy - iOS (via lldb)
 
 
-## 打印调试信息
+### 打印调试信息
 
 有些时候, 需要在代码里加入 printf() 声明.
 之后, 你就可以从设备上获取日志文件来分析它.
 
 注意 Defold 的debug编译版本默认只输出 dmLog* 函数结果.
 
-### [Android](/manuals/extensions-debugging-android.md)
+#### [Android](/manuals/extensions-debugging-android)
 
 在 Android 上, 获取日志最简单办法是通过终端的 `adb`.
 还可以在 Android Studio 里使用 `console`, 这俩是一样的.
 
 如果你从 Android 日志中获得了跟踪堆栈, 你可能要使用 [ndk-stack](https://developer.android.com/ndk/guides/ndk-stack.html) 来进行解析.
 
-### [iOS](/manuals/extensions-debugging-ios.md)
+#### [iOS](/manuals/extensions-debugging-ios)
 
 在 iOS 中, 你要使用 iTunes 或者 XCode 来观察设备日志.
 
-## Defold 崩溃日志
+### Defold 崩溃日志
 
 当 Defold 引擎硬崩溃时会保存一个 `_crash` 文件.
 它包含了关于系统和崩溃的信息.
 
 你可以使用 [crash module](https://www.defold.com/ref/crash/) 来读取这个文件.
 
-鼓励你读取文件, 收集信息然后放送到自己适用的服务器上来归集数据.
+建议你读取这个文件, 收集信息然后放送到自己适用的服务器上来归集数据.
 
-### 获取设备上的崩溃日志
 
 #### Android
 
@@ -71,21 +82,23 @@ adb 可以显示此文件在哪 (不同设备保存位置不同)
 
 如果应用是 [可调试的](https://www.defold.com/manuals/project-settings/#android), 可以这样获取崩溃日志:
 
+```
 	$ adb shell "run-as com.defold.adtest sh -c 'cat /data/data/com.defold.adtest/files/_crash'" > ./_crash
+```
 
-#### iOS
+##### iOS
 
 在 iTunes 中, 你可以 view/download 应用容器.
 
 在 `XCode -> Devices` 窗口中, 也可以选择崩溃日志
 
 
-## Symbolication
+### Symbolication
 
 如果你从 `_crash` 文件或者日志文件获得了调用堆栈, 就可以开始解析它.
 也就是把各个调用堆栈的地址转化为文件名和代码行, 这样有助于找到出问题的原因.
 
-### 获取正确的引擎
+#### 获取正确的引擎
 
 使调用堆栈匹配正确的引擎是很重要的.
 否则很容易让你调试到不正确的地方.
@@ -99,7 +112,7 @@ Android/Linux 可运行文件已经包含了调试信息.
 这样有助于分析调试文件的调用堆栈.
 
 
-### Android
+#### Android
 
 1. 从 build 文件夹获取
 
@@ -121,7 +134,7 @@ Android/Linux 可运行文件已经包含了调试信息.
 
     $ arm-linux-androideabi-addr2line -C -f -e dmengine_1_2_105/lib/armeabi-v7a/libdmengine.so _address_
 
-### iOS
+#### iOS
 
 1. 如果使用了原生扩展, 服务器会提供解析文件 (.dSYM) 给你 (使用 bob.jar 加 "--with-symbols" 选项)
 

+ 1 - 1
docs/zh/manuals/extensions-details.md

@@ -3,7 +3,7 @@ title: 原生扩展 - 详述
 brief: 本教程介绍了有关编译系统用来编译原生扩展的一些细节.
 ---
 
-# Defold 编译器 (流程应该是 编译--构建--打包,  为了方便这里把编译和构建统称为了编译)
+# Defold 编译器
 
 为了让你的扩展整合更加方便, 我们这里列举了一些编译相关的细节.
 

+ 59 - 4
docs/zh/manuals/extensions.md

@@ -1,5 +1,5 @@
 ---
-title: 为 Defold 编写原生扩展
+title: Writing native extensions for Defold
 brief: This manual explains how to write a native extension for the Defold game engine and how to compile it through the zero setup cloud builders.
 ---
 
@@ -13,7 +13,7 @@ If you need custom interaction with external software or hardware on a low level
 
 ## The build platform
 
-Defold provides a zero setup entry point to native extensions with a cloud based build solution. Any native extension that is developed and added to a game project becomes part of the ordinary project content. There is no need to build special versions of the engine and distribute them to team members, that is handled automatically---any team member that builds and runs the project will get a project specific engine executable with all native extensions baked in.
+Defold provides a zero setup entry point to native extensions with a cloud based build solution. Any native extension that is developed and added to a game project, either directly or through a [Library Project](/manuals/libraries/), becomes part of the ordinary project content. There is no need to build special versions of the engine and distribute them to team members, that is handled automatically---any team member that builds and runs the project will get a project specific engine executable with all native extensions baked in.
 
 ![Cloud build](images/extensions/cloud_build.png)
 
@@ -21,8 +21,25 @@ Defold provides a zero setup entry point to native extensions with a cloud based
 
 To create a new extension, create a folder in the project root. This folder will contain all settings, source code, libraries and resources associated with the extension. The extension builder recognizes the folder structure and collects any source files and libraries.
 
-![Project layout](images/extensions/layout.png)
+```
+ myextension/
+ │
+ ├── ext.manifest
+ │
+ ├── src/
+ │
+ ├── include/
+ │
+ ├── lib/
+ │   └──[platforms]
+ │
+ ├── manifests/
+ │   └──[platforms]
+ │
+ └── res/
+     └──[platforms]
 
+```
 *ext.manifest*
 : The extension folder _must_ contain an *ext.manifest* file. This file is a YAML format file that is picked up by the extension builder. A minimal manifest file should contain the name of the extension.
 
@@ -36,10 +53,23 @@ To create a new extension, create a folder in the project root. This folder will
 : This optional folder contains any compiled libraries that the extension depends on. Library files should be placed in subfolders named by `platform`, or `architecure-platform`, depending on what architectures are supported by your libraries.
 
   :[platforms](../shared/platforms.md)
+  
+*manifests*
+: This optional folder contains additional files used in the build or bundling process. See below for details.
 
 *res*
 : This optional folder contains any extra resources that the extension depends on. Resource files should be placed in subfolders named by `platform`, or `architecure-platform` just as the "lib" subfolders. A subfolder `common` is also allowed, containing resource files common for all platforms.
 
+### Manifest files
+
+The optional *manifests* folder of an extension contains additional files used in the build and bundling process. Files should be placed in subfolders named by `platform`:
+
+* `android` - This folder accepts a manifest stub file to be merged into the main application ([as described here](extension-manifest-merge-tool)). The folder can also contain a `build.gradle` file with dependencies to be resolved by Gradle ([example](https://github.com/defold/extension-facebook/blob/master/facebook/manifests/android/build.gradle)). Finally the folder can also contain zero or more ProGuard files (experimental).
+* `ios` - This folder accepts a manifest stub file to be merged into the main application ([as described here](extension-manifest-merge-tool)).
+* `osx` - This folder accepts a manifest stub file to be merged into the main application ([as described here](extension-manifest-merge-tool)).
+* `web` - This folder accepts a manifest stub file to be merged into the main application ([as described here](extension-manifest-merge-tool)).
+
+
 ## Sharing an extension
 
 Extensions are treated just like any other assets in your project and they can be shared in the same way. If a native extension folder is added as a Library folder it can be shared and used by others as a project dependency. Refer to the [Library project manual](/manuals/libraries/) for more information.
@@ -175,6 +205,30 @@ print(rot_s) --> nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM
 
 And that's it! We have created a fully working native extension.
 
+## Extension Lifecycle
+
+As we saw above the `DM_DECLARE_EXTENSION` macro is used to declare the various entry points into the extension code:
+
+`DM_DECLARE_EXTENSION(symbol, name, app_init, app_final, init, update, on_event, final)`
+
+The entry points will allow you to run code at various points in the lifecycle of an extension:
+
+* Engine start
+  * Engine systems are starting
+  * Extension `app_init`
+  * Extension `init` - All Defold APIs have been initialized. This is the recommended point in the extension lifecycle where Lua bindings to extension code is created.
+  * Script init - The `init()` function of script files are called.
+* Engine loop
+  * Engine update
+    * Extension `update`
+    * Script update - The `update()` function of script files are called.
+  * Engine events (window minimize/maximize etc)
+    * Extension `on_event`
+* Engine shutdown (or reboot)
+  * Script final - The `final()` function of script files are called.
+  * Extension `final`
+  * Extension `app_final`
+
 ## Defined platform identifiers
 
 The following identifiers are defined by the builder on each respective platform:
@@ -233,6 +287,7 @@ Allowed keys are for platform specific compile flags are:
 * [HTML5 extension example](https://github.com/defold/extension-html5)
 * [MacOS, iOS and Android videoplayer extension](https://github.com/defold/extension-videoplayer)
 * [MacOS and iOS camera extension](https://github.com/defold/extension-camera)
-* [iOS and Android Admob extension](https://github.com/defold/extension-admob)
+* [iOS and Android In-app Purchase extension](https://github.com/defold/extension-iap)
+* [iOS and Android Firebase Analytics extension](https://github.com/defold/extension-firebase-analytics)
 
 The [Defold asset portal](https://www.defold.com/assets/) also contain several native extensions.

+ 1 - 207
docs/zh/manuals/facebook.md

@@ -3,210 +3,4 @@ title: Defold Facebook 教程
 brief: 本教程介绍了如何在 Defold 游戏中设置和整合 Facebook 功能.
 ---
 
-# Facebook
-
-Facebook API 作为 [原生扩展](/manuals/extensions/) 提供. 此扩展使得 iOS, Android 和 HTML5 游戏可以使用 Facebook 的在线交互功能. Defold Facebook 扩展对于 iOS, Android 和 HTML5 (基于 Facebook Canvas) 不同平台封装了同一的 Facebook API 函数库. 要在游戏中使用 Facebook 在线交互功能, 首先需要有一个 Facebook 账户.
-
-## 安装扩展
-
-要使用 Facebook 扩展, 需要在 `game.project` 文件中设置依赖. 最新稳定版的 URL 是:
-```
-https://github.com/defold/extension-facebook/archive/master.zip
-```
-
-推荐使用 [指定版本](https://github.com/defold/extension-facebook/releases) 的zip包链接作为依赖.
-
-从 Defold 1.2.162 开始, 此扩展需要其他依赖:
-```
-https://github.com/defold/extension-gps/archive/master.zip
-```
-
-API 文档位于 [这里](https://defold.github.io/extension-facebook/).
-
-## 注册成为 Facebook 开发者
-
-开发 Facebook 应用首先要注册成为 Facebook 开发者. 这样你的 Defold 游戏就能与 Facebook 应用交互了.
-
-* 访问 [Facebook 开发者网站](https://developers.facebook.com) 进行注册
-* 登入你的 Facebook 账户.
-* 注册激活你的开发者身份.
-
-![Register as a developer](images/facebook/register_dev.png)
-![ developer](images/facebook/register_verify.png)
-
-## 创建 Facebook 应用
-
-下一步要创建一个 Facebook 应用. 右上角 <kbd>My Apps</kbd> 菜单列出了你的应用, 以及 <kbd>Add a New App</kbd> 按钮.
-
-![Add new app](images/facebook/add_new_app_menu.png)
-
-然后是选择目标平台界面. 点击 *basic setup* 可以略过引导界面.
-
-::: 注意
-引导界面里绝大多数内容与开发 Defold 游戏无关. 而且, 一般不需要自己修改 *Info.plist* 或者 *AndroidManifest.xml* 文件. Defold 会自动完成.
-:::
-
-![Add new app platform](images/facebook/add_new_app_platform.png)
-
-在 dashboard 里可以随意添加, 删除应用或者更改平台设置. 接下来需要设置 *Display Name*, *Namespace* 和 *Category*. 这些也都可以在 dashboard 里设置. 设置完后, Facebook 会给你的应用创建唯一id. *App ID* 是不可修改的.
-
-![New app id](images/facebook/new_app_id.png)
-
-![App dashboard settings](images/facebook/add_platform.png)
-
-点击 *Settings* 面板. 这里显示了 *App ID*. 你要在 Defold 游戏的 [项目设置](/manuals/project-settings) 里输入这个id. 通过 *Project Explorer* 打开 *game.project* 文件, 滚动到 *Facebook* 部分, 在 `Appid` 这里填入 *App ID*.
-
-现在回到 Facebook 网站的 *Settings* 页面, 点击 *+ Add Platform* 来为应用设置目标平台. 针对每个平台都有不同的设置.
-
-![Select platform](images/facebook/select_platform.png)
-
-## iOS
-
-iOS 平台需要填写和 *game.project* 里一样的 `bundle_identifier`.
-
-![iOS settings](images/facebook/settings_ios.png)
-
-## Android
-
-Android 平台需要填写 *Google Play Package Name*, 也就是 *game.project* 里的 *package* id. 还要在 *Key Hashes* 里填入证书的 Hashes. 可以使用 openssl 从 *certificate.pem* 文件生成 Hashes:
-
-```sh
-$ cat certificate.pem | openssl x509 -outform der | openssl sha1 -binary | openssl base64
-```
-
-(关于签名文件详细信息参见 [创建证书和密匙](/manuals/android/#creating-certificates-and-keys).)
-
-![Android settings](images/facebook/settings_android.png)
-
-## Facebook Canvas
-
-对于 HTML5 游戏, 过程略有不同. Facebook 需要直接在线访问你的游戏内容. 两个办法:
-
-![Facebook Canvas settings](images/facebook/settings_canvas.png)
-
-1. 使用 Facebook 的 *Simple Application Hosting*. 点击 *Yes* 使用在线托管. 选择 *uploaded assets* 打开托管资源管理器.
-
-    ![Simple hosting](images/facebook/simple_hosting.png)
-
-    托管类型选择 "HTML5 Bundle":
-
-    ![HTML5 bundle](images/facebook/html5_bundle.png)
-
-    把你的 HTML5 游戏包压缩为一个 .7z 或者 .zip 包上传至 Facebook. 点击 *Push to production* 即可在线发布.
-
-2. 另一个办法就是把你的 HTML5 游戏包托管到你自己选择的服务器上通过 HTTPS 访问. *Secure Canvas URL* 这里填写你的游戏地址.
-
-至此 Facebook 就能通过 *Canvas Page* 发布你的游戏了.
-
-## 小测试
-
-可以通过创建一个小测试来看看扩展工作是否顺利.
-
-1. 新建游戏对象然后在上面添加一个脚本.
-2. 脚本里加入如下代码 (需要 Facebook 扩展 v.2 版及以上):
-
-```lua
-local function get_me_callback(self, id, response)
-    -- The response table includes all the response data
-    pprint(response)
-end
-
-local function fb_login(self, data)
-    if data.status == facebook.STATE_OPEN then
-        -- Logged in ok. Let's try reading some "me" data through the
-        -- HTTP graph API.
-        local token = facebook.access_token()
-        local url = "https://graph.facebook.com/me/?access_token=" .. token
-        http.request(url, "GET", get_me_callback)
-    elseif data.status == facebook.STATE_CLOSED_LOGIN_FAILED then
-        -- Do something to indicate that login failed
-    end
-    if data.error then
-        -- An error occurred
-    else
-        -- No error
-    end
-end
-
-function init(self)
-    -- Log in with read permissions.
-    local permissions = { "public_profile", "email" }
-    facebook.login_with_permissions(permissions, facebook.AUDIENCE_EVERYONE, fb_login)
-end
-```
-
-直接运行, 控制台输出大概这样:
-
-```txt
-DEBUG:SCRIPT:
-{
-  status = 200,
-  headers = {
-    connection = keep-alive,
-    date = Fri, 04 Nov 2016 13:54:33 GMT,
-    etag = "0725a4f703fe6af27da183cfec0bb22637e331e0",
-    access-control-allow-origin = *,
-    content-length = 53,
-    expires = Sat, 01 Jan 2000 00:00:00 GMT,
-    content-type = text/javascript; charset=UTF-8,
-    x-fb-debug = Pr1qUssb8Xa3x3r1t913hHMdefh69DSYYV5vcxeOB7O33mcfShIw+r7BoLpn147I2wzLF2CZRTpnR3/VYOtFpA==,
-    facebook-api-version = v2.5,
-    cache-control = private, no-cache, no-store, must-revalidate,
-    pragma = no-cache,
-    x-fb-trace-id = F03S5dtsdaS,
-    x-fb-rev = 2664414,
-  }
-  response = {"name":"Max de Fold ","id":"14159265358979323"},
-}
-```
-
-* 完整的 Defold Facebook API 文档在 [这里](https://defold.github.io/extension-facebook/).
-* Facebook Graph API 在这里: https://developers.facebook.com/docs/graph-api
-
-
-## Facebook Analytics
-
-Facebook Analytics 可以对游戏相关信息汇总统计并提供适当建议, 比如开启游戏人数, 付款频率和其他各种信息.
-
-### 配置
-
-使用 Facebook Analytics 之前你得创建好 Facebook 应用. 然后就是把分析功能整合进去:
-
-![Add Facebook Analytics](images/facebook/add_facebook_analytics.png)
-
-分析功能也有很多配置选项. 详情请见:
-
-![Add Facebook Analytics](images/facebook/facebook_analytics_settings.png)
-
-### 使用
-
-分析功能配置好之后就可以通过发布分析事件来进行信息统计了:
-
-```lua
-function init(self)
-    -- post a spent credits event
-    local params = { [facebook.PARAM_LEVEL] = 30, [facebook.PARAM_NUM_ITEMS] = 2 }
-    facebook.post_event(facebook.EVENT_SPENT_CREDITS, 25, params)
-
-    -- post a custom event
-    local level = 19
-    local params = { kills = 23, gold = 4, xp = 890 }
-    facebook.post_event("level_completed", level, params)
-end
-```
-
-各种事件和参数详情请见 [Facebook 扩展 API 文档](https://defold.github.io/extension-facebook/). 这些应该与 Facebook 的 [标准事件](https://developers.facebook.com/docs/analytics/send_data/events#standard) 和 [参数](https://developers.facebook.com/docs/analytics/send_data/events#parameter) 文档相一致.
-
-除了分析统计事件, Defold 使用 Facebook SDK 时也会自动产生一些事件, 比如装机次数启动次数之类的. 详情请见 Facebook 的 [自动日志事件](https://developers.facebook.com/docs/analytics/send_data/events#autologged) 文档.
-
-事件汇总后会在 Facebook Analytics dashboard 中显示出来, 点击 *View Analytics* 按钮查看分析信息:
-
-![Add Facebook Analytics](images/facebook/facebook_analytics_open_dashboard.png)
-
-通过页面里 *Events* 选项可以看到各种事件:
-
-![Add Facebook Analytics](images/facebook/facebook_analytics_show_events.png)
-
-### Facebook 的事件分享
-
-你可以选择是否向 Facebook 分享你的事件数据. 通过 [`enable_event_usage()`](https://defold.github.io/extension-facebook/#enable_event_usage) 和 [`disable_event_usage()`](https://defold.github.io/extension-facebook/#disable_event_usage) 函数控制. 默认不分享.
+[本教程已被移除](/extension-facebook)

+ 50 - 0
docs/zh/manuals/file-access.md

@@ -0,0 +1,50 @@
+---
+title: Working with files
+brief: This manual explains how to save and load files and perform other kinds of file operations.
+---
+
+# Working with files
+There are many different ways to create and/or access files. The file paths and the ways your access these files varies depending on the type of file and the location of the file.
+
+## Functions for file and folder access
+Defold provides several different functions to work with files:
+
+* You can use the standard [`io.*` functions](https://defold.com/ref/stable/io/) to read and write files. These functions give you very fine-grained control over the entire I/O process.
+* You can use [`os.rename()`](https://defold.com/ref/stable/os/#os.rename:oldname-newname) and [`os.remove()`](https://defold.com/ref/stable/os/#os.remove:filename) to rename and remove files.
+* You can use [`sys.save()`](https://defold.com/ref/stable/sys/#sys.save:filename-table) and [`sys.load()`](https://defold.com/ref/stable/sys/#sys.load:filename) to read and write Lua tables. Additional [`sys.*`](https://defold.com/ref/stable/sys/) functions exist to help with platform independent file path resolution.
+
+## File and folder locations
+File and folder locations can be divided into three categories:
+
+* Application specific files created by your application
+* Files and folders bundled with your application
+* System specific files accessed by your application
+
+### How to save and load application specific files
+When saving and loading application specific files such as high scores, user settings and game state it is recommended to do so in a location provided by the operating system and intended specifically for this purpose. You can use [`sys.get_save_file()`](https://defold.com/ref/stable/sys/#sys.get_save_file:application_id-file_name) to get the OS specific absolute path to a file. Once you have the absolute path you can use the `sys.*`, `io.*` and `os.*` functions (see above).
+
+[Check the example showing how to use sys.save() and sys.load()](/examples/file/sys_save_load/).
+
+### How to access files bundled with the application
+You can bundle files with your application in two ways:
+
+1. As part of the game archive using the [*Custom Resources* field](https://defold.com/manuals/project-settings/#project) in *game.project*. You can read these files using [`sys.load_resource()`](https://defold.com/ref/sys/#sys.load_resource). Note that these aren't actual files on the file system. Files included this way becomes part of the binary game archive and the only way to access them is through `sys.load_resource()`.
+
+2. As additional files and folders located as a part of your application bundle using the [*Bundle Resources* field](https://defold.com/manuals/project-settings/#project) in *game.project*. You can use [`sys.get_application_path()`](https://defold.com/ref/stable/sys/#sys.get_application_path:) to get the path to where the application is stored. Use this application base path to create the final absolute path to the files you need access to. Once you have the absolute path of these files you can use the `io.*` and `os.*` functions to access the files (see above).
+
+::: sidenote
+For security reasons browsers (and by extension any JavaScript running in a browser) is prevented from accessing system files. File operations in HTML5 builds in Defold still work, but only on a "virtual file system" using the IndexedDB API in the browser. What this means is that there is no way to access bundle resources using `io.*` or `os.*` functions. You can however access bundle resources using `http.request()`.
+:::
+
+### System file access
+Access to system files may be restricted by the operating system for security reasons. You can use the [`extension-directiories`](https://defold.com/assets/extensiondirectories/) native extension to get the absolute path to some common system directories (ie documents, resource, temp). Once you have the absolute path of these files you can use the `io.*` and `os.*` functions to access the files (see above).
+
+::: sidenote
+For security reasons browsers (and by extension any JavaScript running in a browser) is prevented from accessing system files. File operations in HTML5 builds in Defold still work, but only on a "virtual file system" using the IndexedDB API in the browser. What this means is that there is no way to access system files in HTML5 builds.
+:::
+
+## Extensions
+The [Asset Portal](https://defold.com/assets/) contains several assets to simplify file and folder access. Some examples:
+
+* [Lua File System (LFS)](https://defold.com/assets/luafilesystemlfs/) - Functions to work with directories, file permissions etc
+* [DefSave](https://defold.com/assets/defsave/) - A module to help you save / load config and player data between session.

+ 33 - 18
docs/zh/manuals/getting-help.md

@@ -9,7 +9,7 @@ brief: 本教程介绍了使用 Defold 遇到麻烦时该如何寻求帮助.
 
 ## 在论坛里提交问题
 
-在我们的 [论坛](https://www.defold.com/forum) 上提交问题是一个好方法. 依据你的问题的类型可以在 [Questions](https://forum.defold.com/c/questions) 或者 [Bugs](https://forum.defold.com/c/bugs) 类目下发帖. 提交问题的时候请尽附加可能多的信息. 记得发问之前在论坛 [搜索](https://forum.defold.com/search) 一下相关内容, 也许论坛上已经存在你的问题的解决方案了. 提问时请填写以下信息:
+在我们的 [论坛](https://forum.defold.com) 上提交问题是一个好方法. 依据你的问题的类型可以在 [Questions](https://forum.defold.com/c/questions) 或者 [Bugs](https://forum.defold.com/c/bugs) 类目下发帖. 提交问题的时候请尽附加可能多的信息. 记得发问之前在论坛 [搜索](https://forum.defold.com/search) 一下相关内容, 也许论坛上已经存在你的问题的解决方案了. 提问时请填写以下信息:
 
 * **问题的描述 (必须)** - 问题的简短描述.
 
@@ -28,23 +28,10 @@ brief: 本教程介绍了使用 Defold 遇到麻烦时该如何寻求帮助.
   - 系统: [比如 iOS8.1, Windows 10, High Sierra]
   - 设备: [比如 iPhone6]
 
-* **日志 (可选)** - 请附加相关日志 (引擎或者编辑器的). 编辑器日志位于:
-  - Windows: `C:\Users\ **Your Username** \AppData\Local\Defold`
-  - macOS: `/Users/ **Your Username** /Library/Application Support/` 或者 `~/Library/Application Support/Defold`
-  - Linux: `~/.Defold`
+* **详细系统信息 (可选)** - 有关错误出现系统平台的详细信息.
+  - HTML5: 提供关于 WebGL 的详细信息, 参考网站 https://webglreport.com/?v=1
 
-  Android 的引擎日志可以通过使用 `adb` (Android Debug Bridge) 命令行工具获取. 关于 `adb` 命令行工具详情请见 [Android 教程](/manuals/android/#android-debug-bridge).
-
-  iOS 的引擎日志可以通过使用 XCode 和设备模拟器菜单项获取.
-
-  HTML5 的引擎日志可以通过使用浏览器开发者控制台获取:
-  - Chrome: 菜单 > 更多工具 > 开发者工具
-  - Firefox: 工具 > web 开发者 > Web 控制台
-  - Safari: 开发 > 显示 JavaScript 控制台
-
-  桌面应用的引擎日志通过使用终端运行Defold应用获取.
-
-  你还可以把引擎日志写入一个文件便于存取. 详情请见 [调试教程](/manuals/debugging/#提取日志文件).
+* **日志 (可选)** - 请附带相关 (云编译服务器, 引擎和编辑器) 日志. 参考 [下面关于日志文件获取的章节](#log-files).
 
 * **问题复现小项目 (可选)** - 请附加一个可以再现问题的最小项目包. 这可以对别人研究修复问题提供极大帮助. 如果你把项目打成zip包请去掉其中的 `.git`, `.internal` 和 `build` 文件夹.
 
@@ -61,9 +48,37 @@ brief: 本教程介绍了使用 Defold 遇到麻烦时该如何寻求帮助.
 
 ![](images/getting_help/report_issue.png)
 
-选择此菜单项会在 GitHub 上提交一个 issue tracker. 请把尽量多的信息填入报表. 注意此种方法需要你有 GitHub 账号.
+这样就会在 GitHub 上生成一个错误报告. 请尽量详述错误的相关信息. 参考 [下面关于日志文件获取的章节](#log-files).
+
+::: 注意
+报告之前确保你已经拥有 GitHub 账户.
+:::
 
 
 ## 在 Slack 上讨论问题
 
 如果在使用 Defold 时遇到困难你可以尝试在 [Slack](https://www.defold.com/slack/) 上提出问题. 虽然我们推荐复杂问题应该在论坛上深入讨论. 而且注意 Slack 上不支持错误报告.
+
+
+# 日志文件
+
+游戏引擎, 编辑器和云编译服务器都有日志系统, 这对于定位调试错误十分有利. 报告错误时请务必带上日志文件.
+
+## 引擎日志
+- Android: 可以使用 `adb` (Android Debug Bridge) 命令获取. 有关 `adb` 命令详情请见 [Android 教程](/manuals/android/#android-debug-bridge).
+- iOS: 可以使用 XCode 的设备和模拟器菜单项获取.
+- HTML5: 浏览器控制台会输出日志:
+  - Chrome: 菜单 > 更多工具 > 开发者工具
+  - Firefox: 工具 > 网络开发者 > 网络控制台
+  - Safari: 开发 > 显示 JavaScript 控制台
+- Desktop: 如果从终端/命令控制台启动 Defold 程序的话, 就可以在上面看到输出的日志了.
+
+有个功能就是程序崩溃时把相关信息写入一个日志文件中去. 详情请见 [调试教程](/manuals/debugging/#extracting-the-logtxt-file).
+
+## 编辑器日志
+- Windows: `C:\Users\ **Your Username** \AppData\Local\Defold`
+- macOS: `/Users/ **Your Username** /Library/Application Support/` 或者 `~/Library/Application Support/Defold`
+- Linux: `~/.Defold`
+
+## 云编译服务器日志
+使用原生扩展时才会有编译服务器日志. 编译时其日志文件 (`log.txt`) 与自定义引擎一起下载并保存在 `.internal/%platform%/build.zip` 文件中.

+ 6 - 0
docs/zh/manuals/gpgs.md

@@ -0,0 +1,6 @@
+---
+title: Google Play Game Services in Defold
+brief: This document describes how to set up and use Google Play Game Services
+---
+
+[本教程已被移除](/extension-gpgs)

+ 0 - 33
docs/zh/manuals/graphics.md

@@ -7,14 +7,6 @@ brief: 本教程简述了 Defold 支持的图像组件.
 
 Defold是一个全3D引擎, 但是设计上还是为2D提供强大支持的. 目前该引擎比较适用于开发2D游戏.
 
-## 导入图片文件
-
-Defold使用的资源全部保存在项目目录下. 需要显示什么样的图像, 就要先导入图像资源. 要导入一个资源只要简单的把文件从电脑上拖拽到Defold编辑器的 _资源目录_.
-
-![Importing image files](images/graphics/import.png){srcset="images/graphics/[email protected] 2x"}
-
-Defold支持PNG和JPEG图片格式. 如果需要模型, Defold支持Collada DAE格式.
-
 ## 图片资源
 
 Defold中, 可视组件使用两种图片资源:
@@ -127,31 +119,6 @@ Collada 支持
   渲染脚本如何工作详情请见 [Render documentation](/manuals/render).
 
 
-## Z 排序
-
-所有游戏对象和组件在 3D 空间中的位置由 vector3 对象来决定. 在2D图像中, X 和 Y 值决定了物体在"横" , "竖" 轴的位置, Z 值决定了其在"深度"上的位置. Z轴位置可以让你控制可见物体的遮挡情况: Z 值为 1 的sprite会出现在 Z 值为 0 的sprite前面. 默认情况下, Defold 允许的 Z 值范围是 -1 到 1:
-
-![model](images/graphics/z-order.png){srcset="images/graphics/[email protected] 2x"}
-
--1 到 1 的远近限制使得Z轴的数值精度很高. 在制作3D游戏时, 你可能需要在自定义渲染脚本里调整这个限制. 更多详情请见 [Render manual](/manuals/render/).
-
-## 混合模式
-
-*Blend Mode* 属性定义了 sprite 如何和其后面的图像混合. 以下列举了支持的混合模式及其混合算法:
-
-Alpha
-: 普通混合: a~0~ * rgb~0~ + (1 - a~0~) * rgb~1~
-
-Add
-: 使用相应的 sprite 像素颜色值提亮背景: rgb~0~ + rgb~1~
-
-Add Alpha (废弃!)
-: 使用相应的可见 sprite 像素颜色值提亮背景: a~0~ * rgb~0~ + rgb~1~
-
-Multiply
-: 使用相应的 sprite 像素颜色值调暗背景: rgb~0~ * rgb~1~
-
-
 ## 纹理过滤和采样
 
 你可以控制在纹理采样时完成的过滤方法. 比如当一个 _纹素_ (纹理上的一个像素) 不是和屏幕完美的像素对齐时, 可以由过滤器决定显示结果 . 当你移动一个带纹理的图像元素少于一个像素时它就会发生. 下面的过滤方法是可选的:

+ 3 - 5
docs/zh/manuals/gui-layouts.md

@@ -58,13 +58,11 @@ A layout cannot delete or create new nodes, only override properties. If you nee
 
 The dynamic layout matcher scores each display profile qualifier according to the following rules:
 
-1. If there is no device model set, or the device model matches, a score $S$ is calculated for the qualifier.
+1. If there is no device model set, or the device model matches, a score (S) is calculated for the qualifier.
 
-2. The score ($S$) is calculated with the area of the display ($A$), the area from the qualifier ($A_Q$), the aspect ratio of the display ($R$) and the aspect ratio of the qualifier ($R_Q$):
+2. The score (S) is calculated with the area of the display (A), the area from the qualifier (A_Q), the aspect ratio of the display (R) and the aspect ratio of the qualifier (R_Q):
 
-   $$
-   S=\left|1 - \frac{A}{A_Q}\right| + \left|1 - \frac{R}{R_Q}\right|
-   $$
+<img src="https://latex.codecogs.com/svg.latex?\inline&space;S=\left|1&space;-&space;\frac{A}{A_Q}\right|&space;&plus;&space;\left|1&space;-&space;\frac{R}{R_Q}\right|" title="S=\left|1 - \frac{A}{A_Q}\right| + \left|1 - \frac{R}{R_Q}\right|" />
 
 3. The profile with the lowest scoring qualifier is selected, if the orientation (landscape or portrait) of the qualifier matches the display.
 

+ 5 - 2
docs/zh/manuals/html5.md

@@ -48,13 +48,13 @@ Defold 打包 HTML5 游戏很简单, 跟其他平台一样: 从菜单栏选择 <
 
 ## 已知问题和局限性
 
-* Live update - Defold 应用必须通过服务器加载运行才能接收热更新. 纯浏览器网页无法获得热更新.
+* Hot Reload - HTML5 游戏不支持热更新. Defold 应用必须通过服务器加载运行才能接收热更新. 纯浏览器网页无法获得热更新.
 * Internet Explorer 11
   * Audio - Defold 使用 HTML5 _WebAudio_ (详见 http://www.w3.org/TR/webaudio) 来处理声音, 目前 Internet Explorer 11 还不支持. 所以这种情况下没有声音.
   * WebGL - Microsoft 没有完全实现 _WebGL_ API (详见 https://www.khronos.org/registry/webgl/specs/latest/). 所以, 较其他浏览器而言对WebGL支持不好.
   * Full screen - 全屏模式在浏览器中不可靠.
 * Chrome
-  * Slow debug builds - 为了在 HTML5 平台更好地调试我们开启了校验所有 WebGL 图像调用来检测错误. 但是这样做在 Chrome 上会运行缓慢. 可以把 *game.project* 里的 *Engine Arguments* 部分设置为 `–verify-graphics-calls=false` 来关闭图像调用校验.
+  * Slow debug builds - 为了在 HTML5 平台更好地调试我们开启了校验所有 WebGL 图像调用来检测错误. 但是这样做在 Chrome 上会运行缓慢. 可以把 *game.project* 里的 *Engine Arguments* 部分设置为 `–-verify-graphics-calls=false` 来关闭图像调用校验.
 
 ## 自定义 HTML5 打包
 
@@ -212,3 +212,6 @@ DEFOLD_ENGINE_ARGUMENTS
 ## HTML5 的文件操作
 
 HTML5 支持 `sys.save()`, `sys.load()` 和 `io.open()` 之类的文件操作, 但是与其他平台实现方法不同. 基于安全考虑浏览器里运行的 Javascript 无权直接读写本地文件. Emscripten (即 Defold) 使用 [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB) 代替, 它是基于浏览器的持久化存储方案, 基于浏览器的虚拟文件系统. 与其他平台的区别主要是比直接读写文件要慢而且实质上读写的是一个数据库. 浏览器开发者工具通常都提供了 IndexedDB 的读写功能.
+
+## FAQ
+:[HTML5 FAQ](../shared/html5-faq.md)

+ 54 - 0
docs/zh/manuals/http-requests.md

@@ -0,0 +1,54 @@
+---
+title: HTTP Requests
+brief: This manual explains how to make HTTP requests.
+---
+
+## HTTP requests
+
+Defold can make normal HTTP requests using the `http.request()` function.
+
+### HTTP GET
+
+This is the most basic request to get some data from the server. Example:
+
+```Lua
+local function handle_response(self, id, response)
+	print(response.status, response.response)
+end
+
+http.request("https://www.defold.com", "GET", handle_response)
+```
+
+This will make an HTTP GET request to https://www.defold.com. The function is asynchronous and will not block while making the request. Once the request has been made and a server has sent a response it will invoke/call the provided callback function. The callback function will receive the full server response, including status code and response headers.
+
+::: sidenote
+HTTP requests are automatically cached in the client to improve network performance. The cached files are stored in an OS specific application support path in a folder named `defold/http-cache`. You usually don't have to care about the HTTP cache but if you need to clear the cache during development you can manually delete the folder containing the cached files. On macOS this folder is located in `%HOME%/Library/Application Support/Defold/http-cache/` and on Windows in `%APP_DATA%/defold/http-cache`.
+:::
+
+### HTTP POST
+
+When sending data, like a score or some authentication data, to a server it is typically done using a POST requests:
+
+```Lua
+local function handle_response(self, id, response)
+	print(response.status, response.response)
+end
+
+local headers = {
+	["Content-Type"] = "application/x-www-form-urlencoded"
+}
+local body = "foo=bar"
+http.request("https://httpbin.org/post", "POST", handle_response, headers, body)
+```
+
+### Other HTTP methods
+
+Defold HTTP requests also support the HEAD, DELETE and PUT methods.
+
+### API Reference
+
+Refer to the [API reference](/ref/http/) to learn more.
+
+### Extensions
+
+An alternative HTTP request implementation can be found in the [TinyHTTP extension](https://defold.com/assets/tinyhttp/).

+ 27 - 7
docs/zh/manuals/importing-assets.md

@@ -1,25 +1,45 @@
 ---
 title: 导入和编辑资源
-brief: 本教程介绍了在 Defold 中如何使用外部编辑器编辑资源文件.
+brief: 本教程介绍了导入, 编辑资源的方法.
 ---
 
 # 导入和编辑资源导入和编辑资源
 
 一个游戏项目通常包含了大量其他程序生成的资源文件, 比如图像, 3D 模型, 音乐文件, 动画之类的. Defold 工作流就包括使用第三方工具创建资源然后导入Defold中使用. 当这些资源导入之后就可以被Defold的各种组件使用, 比如 逐帧动画, 瓷砖地图, 粒子特效之类的:
 
-* 图片用于创建 [图集](/manuals/atlas) 瓷砖图源可以用于 [sprite](/manuals/sprite), [瓷砖地图](/manuals/tilemap) 和 [粒子特效](/manuals/particlefx). 详情请见 [图像教程](/manuals/graphics/#importing-image-files).
+
+## 导入资源
+
+Defold 要求其所用资源全部位于项目文件夹内. 先导入后使用. 导入方法很简单, 从文件系统任意位置拖动任意文件放入 Defold 编辑器 _资源面板_ 里即可.
+
+![Importing files](images/graphics/import.png){srcset="images/graphics/[email protected] 2x"}
+
+::: 注意
+Defold 支持 PNG 和 JPEG 图片格式. 其中 PNG 图片必须是 32 位 RGBA 格式的. 其他格式要先转换成支持格式后再使用.
+:::
+
+## 使用资源
+
+当资源文件导入 Defold 之后就可以使用各种组件来创造逐帧动画, 瓷砖地图, 粒子特效等各种内容:
+
+* 图片可以用来实现2D游戏常见的各种可视内容. 详情请见 [如何导入和使用2D图像](/manuals/importing-graphics).
 * 声音文件可以用 [声音组件](/manuals/sound)来播放.
 * Spine 动画数据可以用于 [Spine 组件](/manuals/spinemodel) 来显示.
 * 字体文件 可以用于 [Label 组件](/manuals/label) 和GUI中的 [text 节点](/manuals/gui-text).
-* Collada 模型可以用于 [Model 组件](/manuals/model) 来显示3D模型和动画.
+* Collada 模型可以用于 [Model 组件](/manuals/model) 来显示3D模型和动画. [关于3D模型导入详见这里](/manuals/importing-models).
+
 
+## 编辑外部资源
 
-## 第三方工具
+Defold 并不提供图片, 声音, 模型 或者 动画文件的创建功能. 这些文件应该由 Defold 以外的工具创建好之后再导入到 Defold 里使用. Defold 自动检测资源文件的改动然后自动刷新到编辑器里. 之后 Defold 会自动进行资源文件的更新.
 
-Defold 并不提供图片, 声音, 模型 或者 动画文件的创建功能. 这些文件应该由 Defold 以外的工具创建好之后再导入到 Defold 里使用. Defold 自动检测资源文件的改动然后自动刷新到编辑器里.
 
-目前内置编译器不提供自定义编译流程, 但是我们提供了另一个编译工具 (详见 [Bob编译器](/manuals/bob)) 方便加入任何编译流程.
+## 编辑 Defold 资源
 
-Defold 编辑器自己生成的资源都是纯文本格式的以方便合并.甚至可以使用代码来修改 参见 [这个帖子](https://forum.defold.com/t/deftree-a-python-module-for-editing-defold-files/15210). 注意我们没有发布固定的资源文本格式, 因为格式可能随着升级不断变化.
+Defold 编辑器自己生成的资源都是纯文本格式的以方便合并.甚至可以使用代码来修改 参见 [这个帖子](https://forum.defold.com/t/deftree-a-python-module-for-editing-defold-files/15210).
+
+注意我们没有发布固定的资源文本格式, 因为格式可能随着升级不断变化. 你也可以使用 [编辑器脚本](/manuals/editor-scripts/) 在编辑器特定的生命周期中运行脚本来生成或者修改资源.
 
 另外要注意一点就是如果使用外部编辑器破坏了资源文本的话, 再回到 Defold 可能就无法打开这个文件了.
+
+某些第三方工具比如 [Tiled](/assets/tiled/) 和 [Tilesetter](https://www.tilesetter.org/beta) 也可以用来自动生成 Defold 资源.

+ 83 - 0
docs/zh/manuals/importing-graphics.md

@@ -0,0 +1,83 @@
+---
+title: 导入和使用2D图像
+brief: 本教程介绍了如何导入和使用2D图像.
+---
+
+# 导入2D图像
+
+Defold 支持2D游戏常见的可视内容. 可以使用 Defold 制作静态或动态Sprite, UI 组件, 粒子特效, 瓷砖地图, 位图字体和 Spine 动画. 先导入图片文件再创建相应资源以使用它们. 把文件系统任意图片文件拖放到 Defold 编辑器的 *资源面板* 中即完成导入操作.
+
+![Importing files](images/graphics/import.png){srcset="images/graphics/[email protected] 2x"}
+
+::: 注意
+Defold 支持 PNG 和 JPEG 图片格式. 其他格式要先转换成支持格式后使用.
+:::
+
+
+## 创建 Defold 资源
+
+图片导入 Defold 后即可创建相应资源:
+
+![atlas](images/icons/atlas.png){.icon} Atlas
+: 图集是多张图片组成的大图. 图集可以包含单个图片或者 *动画组*, 即组成逐帧动画的一组图片.
+
+  ![atlas](images/graphics/atlas.png){srcset="images/graphics/[email protected] 2x"}
+
+关于图集资源详情请见 [图集教程](/manuals/atlas).
+
+![tile source](images/icons/tilesource.png){.icon} Tile Source
+: 瓷砖图集是由小图按一定顺序排列好的大图. 这种图又被叫做 _精灵表_. 瓷砖图集也可以通过指定第一帧与最后一帧的图块, 来创造逐帧动画. 也可以使用图片自动生成图块的碰撞方块.
+
+  ![tile source](images/graphics/tilesource.png){srcset="images/graphics/[email protected] 2x"}
+
+关于瓷砖图集资源详情请见 [瓷砖图集教程](/manuals/tilesource).
+
+![bitmap font](images/icons/font.png){.icon} Bitmap Font
+: 位图字体是 PNG 图片格式的文字表. 这种字体比起 TrueType 或者 OpenType 字体文件并没有性能优势, 但是由于是图片, 颜色阴影等效果可以随意加入.
+
+关于字体资源详情请见 [字体教程](/manuals/font/#bitmap-bmfonts).
+
+  ![BMfont](images/font/bm_font.png){srcset="images/font/[email protected] 2x"}
+
+
+## 使用 Defold 资源
+
+当图片转化为图集或者瓷砖图集之后就可以用于各种可视组件之中:
+
+![sprite](images/icons/sprite.png){.icon}
+: Sprite是可以显示的图片或者逐帧动画.
+
+  ![sprite](images/graphics/sprite.png){srcset="images/graphics/[email protected] 2x"}
+
+关于Sprite详情请见 [Sprite教程](/manuals/sprite).
+
+![tile map](images/icons/tilemap.png){.icon} Tile map
+: 瓷砖地图是由若干源自瓷砖图集的地图块 (图片连同其碰撞方块) 组成的可视组件. 瓷砖地图不能使用图集资源.
+
+  ![tilemap](images/graphics/tilemap.png){srcset="images/graphics/[email protected] 2x"}
+
+关于瓷砖地图详情请见 [瓷砖地图教程](/manuals/tilemap).
+
+![particle effect](images/icons/particlefx.png){.icon} Particle fx
+: 粒子是由粒子发射器发射的, 源自图集或者瓷砖图集图片生成的一组组静态图片或逐帧动画.
+
+  ![particles](images/graphics/particles.png){srcset="images/graphics/[email protected] 2x"}
+
+关于粒子特效详情请见 [粒子特效教程](/manuals/particlefx).
+
+![gui](images/icons/gui.png){.icon} GUI
+: GUI 方块节点和 饼图节点也可以使用来自图集或者瓷砖图集的静态或逐帧动画.
+
+  ![gui](images/graphics/gui.png){srcset="images/graphics/[email protected] 2x"}
+
+关于GUI详情请见 [GUI教程](/manuals/gui).
+
+![spine](images/icons/spine-model.png){.icon} Spine model
+: Spine models 从 Spine scene 资源中获取数据. 包括两部分:
+
+  1. 一个描述骨骼与动画的 Spine Json 文件.
+  2. 依附于骨骼的图片图集. Spine models 不能使用瓷砖图集资源.
+
+  ![spine](images/graphics/spine.png){srcset="images/graphics/[email protected] 2x"}
+
+关于 Spine models 详情请见 [Spine model 教程](/manuals/spinemodel).

+ 77 - 0
docs/zh/manuals/importing-models.md

@@ -0,0 +1,77 @@
+---
+title: 导入模型
+brief: 本教程介绍了通过模型组件导入 3D 模型的方法.
+---
+
+# 导入3D模型
+Defold 目前只支持 Collada *.dae* 格式的骨骼和动画模型. 可以使用类似 Maya, 3D Max, Sketchup 和 Blender 的软件保存或者转换3D模型为Collada格式. Blender 是一个著名的3D建模, 动画及渲染软件. 它在 Windows, Mac OS X 和 Linux 都能运行并且在 http://www.blender.org 上免费下载.
+
+![Model in Blender](images/model/blender.png){srcset="images/model/[email protected] 2x"}
+
+## 导出 Collada 格式文件
+导出的 Collada 格式文件扩展名是 *.dae*. 此文件包含模型所有的点, 边和面的信息, 如果模型贴了图, 同时还包含 _UV 坐标_ (用于确定纹理如何铺在模型表面), 以及骨架骨骼和动画数据.
+
+* 关于多边形网格的解释详见 http://en.wikipedia.org/wiki/Polygon_mesh.
+
+* UV 坐标和 UV 映射的解释详见 http://en.wikipedia.org/wiki/UV_mapping.
+
+Defold 对于导出的动画作了一些限制:
+
+* Defold 目前只支持烘焙好的动画. 动画每一关键帧每个骨骼都要提供矩阵数据而不是位置, 旋转和缩放这样分开的数据.
+
+* 动画都是线性插值的. 如果需要曲线插值请在导出前预烘焙好.
+
+* 不支持 Collada 的动画片段. 一个模型如有多个动画, 请分别导出 *.dae* 文件然后在 Defold 中合并成一个 *.animationset* 文件.
+
+
+### 需求
+对于导出的 Collada 格式模型需遵循以下需求:
+
+* 模型必须由单个网格组成
+* 模型必须使用单个材质
+
+
+#### 网格组合
+可以使用 Blender 来组合多个网格. 选中所有网格, 按 `CTRL`/`CMD` + `J` 来进行组合操作.
+
+![组合网格](images/model/blender_join_meshes.png)
+
+
+#### 删除材质
+可以使用 Blender 删除模型上的多余材质. 选中要删除的材质, 按 `-` 来进行删除.
+
+![删除材质](images/model/blender_remove_materials.png)
+
+
+#### 导出纹理
+如果模型没有纹理, 可以使用 Blender 来生成一个. 这个工作要在删除多余材质之前完成. 从选择网格及其所有的点开始:
+
+![Select all](images/model/blender_select_all_vertices.png)
+
+选中所有点后即可展开UV:
+
+![Unwrap mesh](images/model/blender_unwrap_mesh.png)
+
+接下来就可以把它保存为图片文件作为网格纹理:
+
+![Export UV layout](images/model/blender_export_uv_layout.png)
+
+![Export UV layout settings](images/model/blender_export_uv_layout_settings.png)
+
+![Export UV layout result](images/model/blender_export_uv_layout_result.png)
+
+
+## 从 Blender 中导出
+从导出菜单选项中导出 Collada 格式文件. 选中模型然后点选 导出为 Collada 菜单项, 选中 "Selection Only" 选项即可导出文件.
+
+![Exporting using Blender](images/model/blender_export.png)
+
+
+## 导入到 Defold 中
+要导入模型, 只需要把 *.dae* 文件及其相应纹理图片拖放到 *资源面板* 里即可.
+
+![Imported model assets](images/model/assets.png){srcset="images/model/[email protected] 2x"}
+
+
+## 使用模型
+模型导入 Defold 后就可以使用 [模型组件](/manuals/model) 了.

+ 5 - 1
docs/zh/manuals/input.md

@@ -16,7 +16,7 @@ Devices
 
   1. Keyboard (single key as well as text input)
   2. Mouse (position, button clicks and mouse wheel actions)
-  3. Single and multi-touch (on iOS and Android devices)
+  3. Single and multi-touch (on iOS, Android devices and HTML5 on mobile)
   4. Gamepads (as supported through the operating system and mapped in the [gamepads](#gamepads-settings-file) file)
 
 Input bindings
@@ -110,6 +110,10 @@ Touch Triggers
 Multi-touch must not be assigned the same action as the mouse button input for `MOUSE_BUTTON_LEFT` or `MOUSE_BUTTON_1`. Assigning the same action will effectively override single-touch and prevent you from receiving any single-touch events.
 :::
 
+::: sidenote
+The [Defold-Input asset](https://defold.com/assets/defoldinput/) can be used to easily set up virtual on-screen controls such as buttons and analog sticks with support for multi touch.
+:::
+
 Text Triggers
 : Text triggers are used to read arbitrary text input. There are two types of text triggers:
 

+ 1 - 80
docs/zh/manuals/instant-games.md

@@ -3,83 +3,4 @@ title: Facebook Instant Games
 brief: 本教程介绍了如何使用 Defold 创建 Facebook Instant Games.
 ---
 
-# Facebook Instant Games
-
-Instant Games 可以让玩家在 Facebook 平台上随时玩到游戏的新方式. 基于 HTML5 技术, 可以让玩家直接从新闻Feed或者聊天消息中打开游戏, 同时支持桌面和移动设备.
-
-![InstantGames](images/instant-games/instantgames.png)
-
-## 发布 Instant Games
-
-在把你的 Defold 游戏发布到 Facebook 之前, 需要对游戏项目进行一些设定:
-
-1. 在 [Facebook App Dashboard](https://developers.facebook.com/apps) 里创建 Instant Games 应用. 详情请见 [Instant Games 入门指南](https://developers.facebook.com/docs/games/instant-games/getting-started/game-setup).
-
-2. 在你的 "game.project" 文件中添加 Instant Games 扩展依赖. 即把 "https://github.com/defold/extension-fbinstant/archive/master.zip" 添加到 *Dependencies* 属性中.
-
-   ![Project settings](images/instant-games/game_project.png)
-
-3. 确保在你打包游戏生成的 "index.html" 文件包含了 Instant Games SDK.
-
-   ```html
-   <script src="https://connect.facebook.net/en_US/fbinstant.6.3.js"></script>
-   ```
-
-   关于打包设置详情请见 [HTML5 教程](/manuals/html5/#自定义html5打包).
-
-4. 都准备好之后, 打包 HTML5 游戏并上传至 Facebook.
-
-## API 使用
-
-Instant Games 扩展使用命名空间 `fbinstant.*` , 用 Lua API 对 Javascript SDK 进行了封装. 此扩展基本上是从 Javascript SDK 到 Lua API 一一对应的.
-
-比如, 看以下 Javascript 代码:
-
-```javascript
-FBInstant.initializeAsync().then(function() {
-    FBInstant.startGameAsync().then(function() {
-      var playerID = FBInstant.player.getID();
-      var playerName = FBInstant.player.getName();
-    });
-});
-```
-
-相应的 Lua 代码是这样的:
-
-```lua
-fbinstant.initialize(function(self, success)
-    fbinstant.start_game(function(self, success)
-        local player_id = fbinstant.get_player().id
-        local player_name = fbinstant.get_player().name
-    end)
-end)
-```
-
-关于如何在Defold中使用 Instant Games SDK 详情请见 [API documentation](https://github.com/defold/extension-fbinstant/blob/master/README.md).
-
-## 示例游戏
-
-有个 Defold 游戏 "Tic Tac Toe" 的 Instant Games 版本在 [官方 GitHub 代码库](https://github.com/defold/extension-fbinstant) 提供了完整的源码和素材. 可以作为学习资料或者素材来使用.
-
-![Tic Tac Toe](images/instant-games/tictactoe.png)
-
-## 减小包体
-
-Facebook Instant Games [最佳实践](https://developers.facebook.com/docs/games/instant-games/best-practices) 建议游戏首次载入时间不得超过5秒. 这对 Defold 来说有点勉强, 好在还有一些方法能减小游戏体积:
-
-去掉未使用引擎特性
-: HTML5 版的标准 Defold 引擎用gzip压缩后小于 1.2MB, 但是可以通过去掉不必要的引擎特效来达到减少包体的效果. 在 "app.manifest" 文件中可以指定去掉引擎哪方面特性, 此文件在 "game.project" 文件的 [Native Extension 部分](/manuals/project-settings/#原生扩展) 引用.
-
-  此功能尚处于测试阶段且没有说明文档. 这里: https://forum.defold.com/t/stripping-appmanifest-maker/16059 有一个可以自动生成 app.manifests 文件的工具.
-
-使用纹理压缩
-: 纹理压缩是有效减少包体和内存占用的方法. 关于纹理压缩详情请见 [Texture Profiles 教程](/manuals/texture-profiles/).
-
-减少启动所需资源按需下载
-: 许多游戏把内容分成各个关卡或者各个篇章. 这种类型的游戏可以把内容放到玩家玩到的时候再下载.
-
-这种把内容分块, 保存到服务器上然后按需下载并缓存的方法可以有效减少 Instant Game 包体. 这种方法由 Defold 的 [热更新](/manuals/live-update/) 系统提供支持.
-
-## 已知问题
-
-关于 HTML5 和 Instant Games 的已知问题详见 [HTML5 教程已知问题部分](/manuals/html5/#known-issues-and-limitations).
+[此教程已被移除](/extension-fbinstant)

+ 10 - 10
docs/zh/manuals/introduction.md

@@ -5,31 +5,31 @@ brief: Defold 简介.
 
 # 欢迎来到 Defold
 
-Defold 被设计为一个专业的游戏开发平台. 它能帮助开发团队设计, 构建以及 _发布_ 游戏产品. 它并不高度集成一切功能. 目前也没有特别复杂的组件. 相对的, 我们相信Defold可以为开发团队提供简便的, 适于多人共同开发合作的工具. 这就需要你来手动完成一些工作, 与此同时也使得你的道路和目标更加明晰.
+Defold 是提供设计, 编译和发布游戏功能的一站式工具. 具体功能详见 [Product Overview](/product).
 
-不管是菜鸟还是老司机, 你可能一时无法充分理解我们的理念. 对此我们鼓励你去实验, 看教程, 看教程和API文档, 在论坛里积极学习和关注其他使用Defold的老同志.
+我们致力于使游戏开发阶段尽可能的有效率, 这使得 Defold 在诸多游戏引擎中脱颖而出. 请看 [使用 Defold 的理由](/why).
 
-## 从开始?
+## 从开始?
 
-我们有许多文档, 比如开发教程, API 文档, 实例项目和教程. 如果不知道从哪学起, 这里有些重点内容:
+我们建议你先尝试一下, 学习手册, 阅读教程和 API 文档, 然后到官方论坛里向他人积极取经并且关注 Defold 的每次更新公告. 教程材料多多, 如果还不知道从哪下手, 建议学学下面的内容:
 
 #### 编辑器
-: ![Editor overview](images/introduction/editor.png){.left} [编辑器概述](/manuals/editor/) 是个能让你快速入门的介绍, 使用可视的工具进行创作和代码编写. 如果你对 3D 建模软件和各种代码编辑器比较熟悉, 那我们的编辑器看起来会很亲切, 虽说可能在某些地方还是和你想象的稍有区别.
+![Editor overview](images/introduction/editor.png){.left} [编辑器概述](/manuals/editor/) 是个能让你快速入门的介绍, 使用可视的工具进行创作和代码编写. 如果你对 3D 建模软件和各种代码编辑器比较熟悉, 那我们的编辑器看起来会很亲切, 虽说可能在某些地方还是和你想象的稍有区别.
 
 #### 简单实例
-: ![Examples](images/introduction/examples.jpg){.left} [简单实例集](/examples/) 直接展示出了各个功能运行时的小例子. 在这里你可以看到这些功能在Defold里是如何实现的.
+![Examples](images/introduction/examples.jpg){.left} [简单实例集](/examples/) 直接展示出了各个功能运行时的小例子. 在这里你可以看到这些功能在Defold里是如何实现的.
 
 #### Lua 语言
-: ![Lua overview](images/introduction/lua.png){.left} [Defold 使用 Lua](/manuals/lua/) 来控制所有游戏逻辑. 引擎是高效 C++ 程序, 但是其控制脚本是高层 Lua 语言. 如果你编写过 Python, Javascript 或者其他高级语言代码, 你就会发现 Lua 非常好理解. 没写过脚本程序的, 可以先从Lua教程开始学.
+![Lua overview](images/introduction/lua.png){.left} [Defold 使用 Lua](/manuals/lua/) 来控制所有游戏逻辑. 引擎是高效 C++ 程序, 但是其控制脚本是高层 Lua 语言. 如果你编写过 Python, Javascript 或者其他高级语言代码, 你就会发现 Lua 非常好理解. 没写过脚本程序的, 可以先从Lua教程开始学.
 
 #### 游戏教程
-: ![Tutorials](images/introduction/tutorials.jpg){.left} 我们相信做是学的最好方法. 这就是我们花费很多精力在Defold [编辑器](/manuals/editor/) 里集成一些教程和复杂关卡的原因.打开一两个教程跟着做一遍就知道 Defold 是怎么编译和工作的了.
+![Tutorials](images/introduction/tutorials.jpg){.left} 我们相信做是学的最好方法. 这就是我们花费很多精力在Defold [编辑器](/manuals/editor/) 里集成一些教程和复杂关卡的原因.打开一两个教程跟着做一遍就知道 Defold 是怎么编译和工作的了.
 
 #### Defold 的资源组成
-: ![Building blocks](images/introduction/building_blocks.png){.left} [Defold 游戏由许多资源构成](/manuals/building-blocks/), 有些和其他游戏引擎类似. 还有另一些 Defold 里特有的, 用熟才感觉方便的东西. 要想知道Defold的底层工作方式可以先从资源教程学起.
+![Building blocks](images/introduction/building_blocks.png){.left} [Defold 游戏由许多资源构成](/manuals/building-blocks/), 有些和其他游戏引擎类似. 还有另一些 Defold 里特有的, 用熟才感觉方便的东西. 要想知道Defold的底层工作方式可以先从资源教程学起.
 
 #### 社区论坛
-: ![论坛](images/introduction/forum.jpg){.left} [论坛](//forum.defold.com/) 是一个互相学习的好地方. 我们的社区很友好, 我们的老司机在游戏开发, 尤其是 Defold 开发方面都很精通. 如果你卡壳了, 可以来论坛寻求帮助!
+![论坛](images/introduction/forum.jpg){.left} [论坛](//forum.defold.com/) 是一个互相学习的好地方. 我们的社区很友好, 我们的老司机在游戏开发, 尤其是 Defold 开发方面都很精通. 如果你卡壳了, 可以来论坛寻求帮助!
 
 不管从哪开始学习 Defold, 都可以随时回来这个页面再深入理解 Defold 提供的功能和方法. 哪里不理解或者哪里写错了都可以跟我们说. 我们的初衷就是把这套教程做的尽善尽美.
 

+ 5 - 3
docs/zh/manuals/label.md

@@ -54,7 +54,7 @@ brief: 本教程介绍了文本组件 label 的使用方法.
 : 文本的锚点. 此值关系到文本对齐效果 (详见下文).
 
 *Blend Mode*
-: 组件渲染时使用的混合模式.
+: 此 label 渲染时使用的混合模式.
 
 *Line Break*
 : 文本对齐与锚点相关, 此属性可以让文本流动几行. 节点宽度决定文本在哪里换行.文本对齐与锚点相关, 此属性可以让文本溢出几行. 节点宽度决定文本在哪里换行. 注意文本换行处要留有空间.
@@ -65,7 +65,10 @@ brief: 本教程介绍了文本组件 label 的使用方法.
 *Material*
 : 用于渲染此 label 所使用的材质. 确保选中的材质是为你所使用的字体 (bitmap, distance field or BMFont) 创建的.
 
-## 锚点和对齐
+### 混合模式
+:[blend-modes](../shared/blend-modes.md)
+
+### 锚点和对齐
 
 你可以通过设置锚点来改变文本的对齐方式.
 
@@ -122,4 +125,3 @@ function init(self)
     go.set("#my_label", "scale.x", scale_x * 2)
 end
 ```
-

+ 1 - 1
docs/zh/manuals/libraries.md

@@ -45,7 +45,7 @@ brief: 项目间可以使用库共享资源. 本教程解释了其工作方式.
 
 ![Fetch Libraries](images/libraries/libraries_fetch_libraries.png)
 
-此时你共享的文件夹就会出现在项目浏览器中等待使用. 库的各种修改都会同步到你的项目之中.
+此时你共享的文件夹就会出现在资源面板中等待使用. 库的各种修改都会同步到你的项目之中.
 
 ![Library setup done](images/libraries/libraries_done.png)
 

+ 15 - 0
docs/zh/manuals/linux.md

@@ -0,0 +1,15 @@
+---
+title: Defold development for the Linux platform
+brief: This manual describes how to build and run Defold applications on Linux
+---
+
+# Linux development
+
+Developing Defold applications for the Linux platform is a straight forward process with very few considerations to make.
+
+## Project settings
+
+Linux specific application configuration is done from the [Linux section](/manuals/project-settings/#linux) of the *game.project* settings file.
+
+## FAQ
+:[Linux FAQ](../shared/linux-faq.md)

+ 16 - 0
docs/zh/manuals/lua.md

@@ -16,6 +16,22 @@ Defold 引擎嵌入了 Lua 语言用以编写脚本. Lua 是一种轻量级脚
 要真正做到跨所有平台建议只使用 Lua 5.1 功能.
 :::
 
+Defold 包含所有 [Lua 5.1 标准库](http://www.lua.org/manual/5.1/manual.html#5) 连同 socket 和少量操作系统功能库:
+
+  - base (`assert()`, `error()`, `print()`, `ipairs()`, `require()` 等等)
+  - coroutine
+  - package
+  - string
+  - table
+  - math
+  - io
+  - os
+  - debug
+  - socket (参考 [LuaSocket](https://github.com/diegonehab/luasocket))
+  - bitop (参考 [BitOp](http://bitop.luajit.org/api.html))
+
+所有库的用法都可以在 [API 文档](/ref/go) 中找到.
+
 ## Lua 书籍和资源
 
 * [Programming in Lua (first edition)](http://www.lua.org/pil/contents.html) 已有第二版.

+ 122 - 0
docs/zh/manuals/macos.md

@@ -0,0 +1,122 @@
+---
+title: Defold development for the macOS platform
+brief: This manual describes how to build and run Defold applications on macOS
+---
+
+# macOS development
+
+Developing Defold applications for the macOS platform is a straight forward process with very few considerations to make.
+
+## Project settings
+
+macOS specific application configuration is done from the [OSX section](/manuals/project-settings/#osx) of the *game.project* settings file.
+
+## Application icon
+
+The application icon used for a macOS game must be in the .icns format. You can easily create a .icns file from a set of .png files collected as an iconset. Follow the [official instructions for creating a .icns file](https://developer.apple.com/library/archive/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Optimizing/Optimizing.html). Brief summary of the steps involved are:
+
+* Create an iconset folder, eg `game.iconset`
+* Copy icon files to the created folder:
+
+    * `icon_16x16.png`
+    * `[email protected]`
+    * `icon_32x32.png`
+    * `[email protected]`
+    * `icon_128x128.png`
+    * `[email protected]`
+    * `icon_256x256.png`
+    * `[email protected]`
+    * `icon_512x512.png`
+    * `[email protected]`
+
+* Convert the .iconset folder to a .icns file using the `iconutil` command line tool:
+
+```
+iconutil -c icns -o game.icns game.iconset
+```
+
+## Publishing your application
+You can publish your application to the Mac App Store, using a 3rd party store or portal such as Steam or itch.io or on your own through a website. Before publishing your application you need to prepare it for submission. The following steps are required regardless of how you intend to distribute the application:
+
+* 1) Make sure that anyone is able to run your game by adding the execute permissions (the default is that only the file owner has execute permissions):
+
+```
+$ chmod +x Game.app/Contents/MacOS/Game
+```
+
+* 2) Create an entitlements file specifying the permissions required by your game. For most games the following permissions are enough:
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+  <dict>
+    <key>com.apple.security.cs.allow-jit</key>
+    <true/>
+    <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
+    <true/>
+    <key>com.apple.security.cs.allow-dyld-environment-variables</key>
+    <true/>
+  </dict>
+</plist>
+```
+
+  * `com.apple.security.cs.allow-jit` - Indicates whether the app may create writable and executable memory using the MAP_JIT flag
+  * `com.apple.security.cs.allow-unsigned-executable-memory` - Indicates whether the app may create writable and executable memory without the restrictions imposed by using the MAP_JIT flag
+  * `com.apple.security.cs.allow-dyld-environment-variables` - Indicates whether the app may be affected by dynamic linker environment variables, which you can use to inject code into your app’s process
+
+Some applications may also need additional entitlements. The Steamworks extension needs this extra entitlement:
+
+```
+<key>com.apple.security.cs.disable-library-validation</key>
+<true/>
+```
+
+    * `com.apple.security.cs.disable-library-validation` - Indicates whether the app may load arbitrary plug-ins or frameworks, without requiring code signing.
+
+All of the entitlements that can be granted to an application are listed in the official [Apple developer documentation](https://developer.apple.com/documentation/bundleresources/entitlements).
+
+* 3) Sign your game using `codesign`:
+
+```
+$ codesign --force --sign "Developer ID Application: Company Name" --options runtime --deep --timestamp --entitlements entitlement.plist Game.app
+```
+
+## Publishing outside the Mac App Store
+Apple requires all software distributed outside the Mac App Store to be notarized by Apple in order to run by default on macOS Catalina. Refer to the [official documentation](https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution/customizing_the_notarization_workflow) to learn how to add notarization to a scripted build environment outside of Xcode. Brief summary of the steps involved are:
+
+* 1) Follow the above steps of adding permissions and signing the application.
+
+* 2) Zip and upload your game for notarization using `altool`.
+
+```
+$ xcrun altool --notarize-app
+               --primary-bundle-id "com.acme.foobar"
+               --username "AC_USERNAME"
+               --password "@keychain:AC_PASSWORD"
+               --asc-provider <ProviderShortname>
+               --file Game.zip
+
+altool[16765:378423] No errors uploading 'Game.zip'.
+RequestUUID = 2EFE2717-52EF-43A5-96DC-0797E4CA1041
+```
+
+* 3) Check the status of your submission using the returned request UUID from the call to `altool --notarize-app`:
+
+```
+$ xcrun altool --notarization-info 2EFE2717-52EF-43A5-96DC-0797E4CA1041
+               -u "AC_USERNAME"
+```
+
+* 4) Wait until the status becomes `success` and staple the notarization ticket to the game:
+
+```
+$ xcrun stapler staple "Game.app"
+```
+
+* 5) Your game is now ready for distribution.
+
+## Publishing to the Mac App Store
+The process when publishing to the Mac App Store is well documented in the [Apple Developer documentation](https://developer.apple.com/macos/submit/). Make sure to add permissions and codesign the application as described above before submitting.
+
+Note: The game does not have to be notarized when publishing to the Mac App Store.

+ 1 - 1
docs/zh/manuals/material.md

@@ -68,7 +68,7 @@ CONSTANT_TYPE_NORMAL
 : A matrix to compute normal orientation. The world transform might include non-uniform scaling, which breaks the orthogonality of the combined world-view transform. The normal matrix is used to avoid issues with the direction when transforming normals. (The normal matrix is the transpose inverse of the world-view matrix).
 
 CONSTANT_TYPE_USER
-: A vector4 constant that you can use for any custom data you want to pass into your shader programs. You can set the initial value of the constant in the constant definition, but it is mutable through the functions `.set_constant()` and `.reset_constant()` for each component type (`sprite`, `model`, `spine`, `particlefx` and `tilemap`)
+: A vector4 constant that you can use for any custom data you want to pass into your shader programs. You can set the initial value of the constant in the constant definition, but it is mutable through the functions `.set_constant()` and `.reset_constant()` for each component type (`sprite`, `model`, `spine`, `particlefx` and `tilemap`). Changing a material constant of a single component instance [breaks render batching and will result in additional draw calls](/manuals/render/#draw-calls-and-batching).
 
 ## Samplers
 

+ 95 - 0
docs/zh/manuals/mesh.md

@@ -0,0 +1,95 @@
+---
+title: Defold 中的3D模型
+brief: 本教程介绍了如何在你的 Defold 游戏中添加3D模型.
+---
+
+# Mesh 组件
+
+Defold 本质是3D的. 即使 2D 材质也是以 3D 方法进行渲染, 再通过正交投射显示在屏幕上. Defold 也可以使用全3D素材, 也可以在运行时建立3D模型. 纯3D还是混合2D、3D游戏根据需要随意创作.
+
+## 新建 Mesh 组件
+
+Mesh 组件的创建和其他组件一样. 有两种方法:
+
+- 在 *Assets* 浏览器里 的 *Mesh 文件* 上 <kbd>右键单击</kbd> , 然后选择 <kbd>New... ▸ Mesh</kbd>.
+- 在 *Outline* 视图里的游戏对象上 <kbd>right-clicking</kbd> 然后选择 <kbd>Add Component ▸ Mesh</kbd>.
+
+![Mesh in game object](images/mesh/mesh.png)
+
+Mesh 组件包含一些列属性:
+
+### Mesh 属性
+
+除了 *Id*, *Position* 和 *Rotation*, 还有如下属性:
+
+*Material*
+: 3D模型材质.
+
+*Vertices*
+: 描述3D模型各种流顶点信息的缓冲文件.
+
+*Primitive Type*
+: Lines, Triangles 还是 Triangle Strip.
+
+*Position Stream*
+: *位置* 流. 流在顶点着色器输入数据时自动提供.
+
+*Normal Stream*
+: *法线* 流. 流在顶点着色器输入数据时自动提供.
+
+*tex0*
+: 3D模型的纹理.
+
+## 编辑时操作
+
+3D模型组件建立好之后就可以使用编辑器和 *Scene Editor* 工具, 像普通游戏对象一样, 随意进行旋转缩放.
+
+## 运行时操作
+
+可以使用 Defold 缓存在运行时修改3D模型.
+
+## 顶点的局部/世界坐标空间
+如果3D模型材质的坐标空间设为局部坐标空间, 则数据会原封不动传入着色器, 这样通常要在着色器程序里进行GPU顶点/法线的转换.
+
+如果3D模型材质的坐标空间设为世界坐标空间, 则必须要么提供默认的 “位置” 和 “法线”, 流, 要么在编辑3D模型时, 在下拉菜单中选择好. 这样便于引擎把同样是世界坐标系的3D模型进行数据合批.
+
+## 举例
+关于3D模型操作及示例项目和代码片段请参考 [这个论坛帖子](https://forum.defold.com/t/mesh-component-in-defold-1-2-169-beta/65137).
+
+用三角形建立方块的例子:
+
+```Lua
+
+-- 方块
+local vertices = {
+	0, 0, 0,
+	0, 1, 0,
+	1, 0, 0,
+	1, 1, 0,
+	1, 1, 1,
+	0, 1, 0,
+	0, 1, 1,
+	0, 0, 1,
+	1, 1, 1,
+	1, 0, 1,
+	1, 0, 0,
+	0, 0, 1,
+	0, 0, 0,
+	0, 1, 0
+}
+
+-- 用位置流建立3D模型缓存
+local buf = buffer.create(#vertices / 3, {
+	{ name = hash("position"), type=buffer.VALUE_TYPE_FLOAT32, count = 3 }
+})
+
+-- 读取流数据, 写入三角形数据
+local positions = buffer.get_stream(buf, "position")
+for i, value in ipairs(vertices) do
+	positions[i] = vertices[i]
+end
+
+-- 用三角形数据建立方块3D模型
+local res = go.get("#mesh", "vertices")
+resource.set_buffer(res, buf)
+```

+ 84 - 18
docs/zh/manuals/model.md

@@ -7,24 +7,6 @@ brief: 本教程介绍了如何将3D模型, 骨骼和动画带入你的游戏之
 
 Defold 核心是3D的. 就算只有2D材质的话渲染也是3D的, 只不过是映射到平面屏幕上而已.  Defold 允许在集合中使用 3D 资源, 或者称作 _模型_ . 你可以用Defold制作全3D的, 或者2D和3D混合的游戏.
 
-## 创建模型
-
-来看一个示例. 我们已经用 _Blender_ 做好了一个带骨骼和动画的模型.
-
-Blender 是一个著名的3D软件. 它可以运行在 Windows, Mac OS X and Linux 系统上并且可以在 http://www.blender.org 免费下载.
-
-现在我们把它来导入 Defold.
-
-![Model in Blender](images/model/blender.png){srcset="images/model/[email protected] 2x"}
-
-首先需要使用 Blender Collada 导出器输出 *.dae* 格式的文件. 导出的文件包含模型的所有点, 线和面, 还包含 _UV 坐标_ (模型与纹理的部位对部位的映射). 如果做了, 还包含骨骼和动画数据.
-
-关于多边形网格详见 http://en.wikipedia.org/wiki/Polygon_mesh. 关于 UV 坐标与 UV 映射详见 http://en.wikipedia.org/wiki/UV_mapping.
-
-现在要导入模型, 简单的拖拽 *.dae* 文件及其相应的纹理图到 *Project 浏览器* 的某个位置.
-
-![Imported model assets](images/model/assets.png){srcset="images/model/[email protected] 2x"}
-
 ## 创建 model 组件
 
 Model 组件和其他游戏对象组件一样, 两种创建办法:
@@ -36,6 +18,10 @@ Model 组件和其他游戏对象组件一样, 两种创建办法:
 
 模型组件需要设置一些属性:
 
+### 模型属性
+
+除了常见的 *Id*, *Position* 和 *Rotation* 属性, 模型组件还有如下特有属性:
+
 *Mesh*
 : 这个属性指定 Collada *.dae* 文件的模型网格. 如果文件包含多组网格, 只读取第一个.
 
@@ -54,9 +40,89 @@ Model 组件和其他游戏对象组件一样, 两种创建办法:
 *Default Animation*
 : 指定自动播放的默认动画 (从动画集之中) .
 
+## 编辑时操作
 
 有了模型组件就可以使用随意使用组件功能同时可以使用 *Scene Editor* 工具移动, 旋转和缩放模型游戏对象了.
 
 ![Wiggler ingame](images/model/ingame.png){srcset="images/model/[email protected] 2x"}
 
+## 运行时操作
+
+有一套用于在运行时修改模型的方法和属性 (参见 [API文档](/ref/model/)).
+
+### 运行时动画
+
+Defold 提供了强大的运行时动画控制方法:
+
+```lua
+local play_properties = { blend_duration = 0.1 }
+spine.play_anim("#model", "jump", go.PLAYBACK_ONCE_FORWARD, play_properties)
+```
+
+可以手动播放动画甚至使用属性动画系统控制播放头:
+
+```lua
+-- set the run animation
+model.play_anim("#model", "run", go.PLAYBACK_NONE)
+-- animate the cursor
+go.animate("#model", "cursor", go.PLAYBACK_LOOP_PINGPONG, 1, go.EASING_LINEAR, 10)
+```
+
+### 修改属性
+
+使用 `go.get()` 和 `go.set()` 方法可以修改模型的属性:
+
+`animation`
+: 当前动画 (`hash`) (只读). 使用 `model.play_anim()` 方法来更改播放动画 (见上文).
+
+`cursor`
+: 标准化动画头 (`number`).
+
+`material`
+: Spine模型材质 (`hash`). 可使用 `go.set()` 修改. 参见 [这个例子的 API 用法](/ref/model/#material).
+
+`playback_rate`
+: 动画播放速率 (`number`).
+
+`textureN`
+: 模型材质. 其中 N 的范围是 0-7 (`hash`). 可使用 `go.set()` 修改. 参见 [这个例子的 API 用法](/ref/model/#textureN).
+
+
+## 材质
+
+3D 一半都有给网格赋予材质的功能, 比如颜色和贴图. 在 Collada *.dae* 文件输出时, 这些信息被写入文件. 应该基于游戏需要选择或者建造 _高性能_ 材质. 材质由 _着色器程序_ 及其若干相关属性组成.
+
+在内置材质文件夹里有一个3D模型材质. 如果需要自定义材质, 请参考 [材质文档](/manuals/material). [着色器教程](/manuals/shader) 介绍了着色器程序的工作方式.
+
+
+### 材质属性
+
+模型的默认材质属性可以用 `model.set_constant()` 和 `model.reset_constant()` 方法来设置和重置 (详情参见 [材质教程](/manuals/material/#vertex-and-fragment-constants)):
+
+`tint`
+: 模型的染色 (`vector4`). 四元数 x, y, z, 和 w 代表染色的红, 绿, 蓝 和不透明度. 参见 [这个例子的 API 用法](/ref/model/#model.set_constant:url-constant-value).
+
+
+## 渲染
+
+默认的渲染脚本是为2D游戏而不是3D模型制作的. 但是你可以把默认渲染脚本拷贝出来, 自己加几行代码就能用来渲染模型. 比如:
+
+  ```lua
+
+  function init(self)
+    self.model_pred = render.predicate({"model"})
+    ...
+  end
+
+  function update()
+    ...
+    render.set_depth_mask(true)
+    render.enable_state(render.STATE_DEPTH_TEST)
+    render.set_projection(stretch_projection(-1000, 1000))  -- orthographic
+    render.draw(self.model_pred)
+    render.set_depth_mask(false)
+    ...
+  end
+  ```
 
+关于渲染脚本详情请见 [Render documentation](/manuals/render).

+ 22 - 13
docs/zh/manuals/networking.md

@@ -5,7 +5,11 @@ brief: 本教程介绍了如何连接远程服务器以及建立其他各种连
 
 # 联网
 
-游戏需要连接各种后台服务器的情况很常见, 比如为了记录分数, 匹配对战玩家或者在云端存档. 还有的游戏有点对点交互的功能, 而不必连接中央服务器.
+游戏需要连接各种后台服务器的情况很常见, 比如为了记录分数, 匹配对战玩家或者在云端存档. 还有的游戏有点对点交互的功能, 而不必连接中央服务器. 网络连接和数据交换可以用多种方式实现:
+
+* [HTTP Requests](#http-requests)
+* [Socket connections](#socket-connections)
+* [WebSocket connections](#websocket-connections)
 
 
 ## HTTP 请求
@@ -22,18 +26,9 @@ http.request("https://www.defold.com", "GET", handle_response)
 
 这样就建立了一个到 https://www.defold.com 的 HTTP GET 请求. 这个函数是异步的所以请求同时游戏并不卡住等待响应. 当服务器发回响应数据后会进入设置好的回调函数. 回调函数接收了相应包含的所有信息, 包括状态码和响应头. 同样可以建立 HTTP POST 请求来向服务器发送数据也能设置请求头信息. 更多详情请见 [API 教程](/ref/http/).
 
-使用 HTTP 请求可以让你能够和互联网上各种各样的服务器交互, 但是通常不会这么简单的发送 HTTP 请求. 通常你需要做一些认证和数据序列化之类的操作. 当然手动操作也可以, 但是我们有很多现成的服务插件可以使用. 使用这些插件能简化许多操作:
-
-* [AWS SDK](https://github.com/britzl/aws-sdk-lua) - 让游戏能够使用 Amazon Web Services
-* [Colyseus](https://github.com/colyseus/colyseus-defold) - 网游客户端
-* [Firebase Analytics](https://github.com/defold/extension-firebase-analytics) - 让游戏能够使用 Firebase Analytics
-* [Google Analytics](https://github.com/britzl/defold-googleanalytics) - 让游戏能够使用 Google Analytics
-* [Google Play Game Services](https://github.com/defold/extension-gpgs) - 让游戏能够使用 Google Play Game Services 来进行用户认证和云端存档
-* [PlayFab](https://github.com/PlayFab/LuaSdk) - 让游戏能够使用 用户认证, 玩家匹配, 跟踪分析, 云端存档等等功能
-* [Steamworks](https://github.com/britzl/steamworks-defold/) - 让游戏能够使用 Steam 支持
-
-可以在 [资源大厅](https://www.defold.com/assets/) 找到更多扩展程序!
-
+::: 注意
+为了提高效率, HTTP 请求会自动缓存在客户端. 缓存文件保存在一个叫 `defold/http-cache` 的文件夹里, 其路径根据操作系统不同而不同. 一般来说不必关心缓存的存在, 除非你需要手动清除缓存文件. macOS 系统路径是 `%HOME%/Library/Application Support/Defold/http-cache/` , Windows 系统路径是 `%APP_DATA%/defold/http-cache`.
+:::
 
 ## Socket 连接
 
@@ -53,3 +48,17 @@ local response = client:receive("*l")
 ## WebSocket 连接
 
 Defold 不提供现成的建立 WebSocket 连接的方法. 对于 WebSocket 联网功能推荐使用 [Defold-WebSocket 扩展](https://github.com/britzl/defold-websocket).
+
+# 游戏服务器
+
+使用 HTTP 请求可以让你能够和互联网上各种各样的服务器交互, 但是通常不会这么简单的发送 HTTP 请求. 通常你需要做一些认证和数据序列化之类的操作. 当然手动操作也可以, 但是我们有很多现成的服务插件可以使用. 使用这些插件能简化许多操作:
+
+* [AWS SDK](https://github.com/britzl/aws-sdk-lua) - 让游戏能够使用 Amazon Web Services
+* [Colyseus](https://github.com/colyseus/colyseus-defold) - 网游客户端
+* [Firebase Analytics](https://github.com/defold/extension-firebase-analytics) - 让游戏能够使用 Firebase Analytics
+* [Google Analytics](https://github.com/britzl/defold-googleanalytics) - 让游戏能够使用 Google Analytics
+* [Google Play Game Services](https://github.com/defold/extension-gpgs) - 让游戏能够使用 Google Play Game Services 来进行用户认证和云端存档
+* [PlayFab](https://github.com/PlayFab/LuaSdk) - 让游戏能够使用 用户认证, 玩家匹配, 跟踪分析, 云端存档等等功能
+* [Steamworks](https://github.com/britzl/steamworks-defold/) - 让游戏能够使用 Steam 支持
+
+可以在 [资源大厅](https://www.defold.com/assets/) 找到更多扩展程序!

+ 42 - 0
docs/zh/manuals/nintendo-switch.md

@@ -0,0 +1,42 @@
+---
+title: Defold development for Nintendo Switch
+brief: This manual describes how to get Nintendo Switch access
+---
+
+# Sign up for Nintendo Switch development
+
+Support for the Nintendo Switch platform is not included in the standard version of Defold. In order to get access to Nintendo Switch support in Defold you need to:
+
+1. Become a Defold community donor with Nintendo Switch access included in your membership tier, and
+2. Become a registered game developer for Nintendo platforms.
+
+
+## Become a Defold community donor with Nintendo Switch access
+
+You become a Defold community donor on the [Defold community donation page](/community-donations/). You can become a donor with Nintendo Switch access using either GitHub Sponsors or Patreon. Pay attention to the available tiers and select one which includes Nintendo Switch access.
+
+![](images/nintendo-switch/register-defold.png)
+
+## Register as a game developer for Nintendo platforms
+
+You register as a game developer for Nintendo platforms at the [Nintendo Developer Portal](https://developer.nintendo.com/register):
+
+![](images/nintendo-switch/register-nintendo.png)
+
+When you register you will get access to Nintendo developer tools and resources to create and publish games and applications for current Nintendo platforms.
+
+
+### Request Defold access
+
+When you have been approved by Nintendo you need to log in to the Nintendo Developer Portal and visit the Tools and Middleware page and sign up for Defold access. When you register for Defold access we will get an email from Nintendo verifying you as a registered Nintendo developer. We will then proceed to verify you as a community donor with Nintendo Switch access included in your membership tier.
+
+When we have verified you as a donor with Nintendo Switch access we will provide you with the access to the following:
+
+* Versions of the Defold editor and the Defold command line tools (bob.jar) with support for bundling to the Nintendo Switch platform.
+* Private forum group where you are able to get Nintendo Switch specific support.
+* Nintendo Switch specific documentation
+* API reference to Nintendo Switch specific engine functionality.
+
+
+## FAQ
+:[Nintendo Switch FAQ](../shared/nintendo-switch-faq.md)

+ 25 - 0
docs/zh/manuals/online-services.md

@@ -0,0 +1,25 @@
+---
+title: Online Services
+brief: This manual explains how to connect to different game and backend services.
+---
+# Game services
+
+Using HTTP requests and socket connections allows you to connect to and interact with thousands of different services on the internet, but in most cases there's more to it than simply making an HTTP request. You usually need to use some kind of authentication, the request data may need to be formatted in a certain way and the response may need to be parsed before it can be used. This can of course be done manually by you but there are also extensions and libraries to take care of this sort of thing for you. Below you'll find a list of some extensions that can be used to more easily interact with specific backend services:
+
+## General purpose
+* [Colyseus](https://defold.com/assets/colyseus/) - Multiplayer game client
+* [Nakama](https://defold.com/assets/nakama/) - Add authentication, matchmaking, analytics, cloud save, multiplayer, chat and more to your game
+* [PlayFab](https://defold.com/assets/playfabsdk/) - Add authentication, matchmaking, analytics, cloud save and more to your game
+* [AWS SDK](https://github.com/britzl/aws-sdk-lua) - Use Amazon Web Services from within your game
+
+## Authentication, leaderboards, achievements
+* [Google Play Game Services](https://defold.com/assets/googleplaygameservices/) - Use Google Play Game Services to authenticate and use cloud save in your game
+* [Steamworks](https://defold.com/assets/steamworks/) - Add Steam support to your game
+* [Apple GameKit Game Center](https://defold.com/assets/gamekit/)
+
+## Analytics
+* [Firebase Analytics](https://defold.com/assets/googleanalyticsforfirebase/) - Add Firebase Analytics to your game
+* [Game Analytics](https://gameanalytics.com/docs/item/defold-sdk) - Add GameAnalytics to your game
+* [Google Analytics](https://defold.com/assets/gameanalytics/) - Add Google Analytics to your game
+
+Check the [Asset Portal](https://www.defold.com/assets/) for even more extensions!

+ 5 - 1
docs/zh/manuals/optimization.md

@@ -20,6 +20,10 @@ Defold 编译和打包时建立了一个依赖树. 编译系统从 *game.project
   * 这虽然没有直接规定大小, 我们讨论认为大小应该限制在 20 MB 以内.
 * Playable ads 基于广告商网络一般限制在 2 到 5 MB.
 
+:::注意
+根据 2017 年一项研究表明 "APK 文件大小每增加 6 MB, 安装率就会相应降低 1%." ([source](https://medium.com/googleplaydev/shrinking-apks-growing-installs-5d3fcba23ce2))
+:::
+
 为了更好的分析包体空间占用可以在编译时 [生成编译报告](/manuals/bundling/#build-reports). 通常声音和图片占游戏空间最大部分.
 
 ### 声音优化
@@ -110,7 +114,7 @@ end
     end
 
     function update(self, dt)
-        local pos = go.get_position(enemy_url)
+        local pos = go.get_position(self.enemy_url)
         -- 处理位置变量
     end
 ```

+ 12 - 2
docs/zh/manuals/particlefx.md

@@ -3,7 +3,7 @@ title: Defold 的粒子特效
 brief: 本教程介绍了粒子特效组件的使用以及特效的编辑方法.
 ---
 
-# Particle FX
+# 粒子特效
 
 粒子特效用以为游戏呈现视觉效果.可以用来表现爆炸, 喷血, 拖尾, 天气等等效果.
 
@@ -17,7 +17,7 @@ Emitter
 Modifier
 : 修改器会影响生成的粒子的速度,以使其在特定方向上加速或减速,径向移动或绕点旋转。修改器可以影响单个的粒子或者整个发射器。
 
-## Creating an effect
+## 新建粒子特效
 
 Select <kbd>New... ▸ Particle FX</kbd> from the context menu in the *Assets* browser. Name the new particle effect file. The editor will now open the file using the [Scene Editor](/manuals/editor/#the-scene-editor).
 
@@ -120,6 +120,9 @@ Inherit Velocity
 Stretch With Velocity
 : Check to scale any particle stretch in the direction of movement.
 
+### 混合模式
+:[blend-modes](../shared/blend-modes.md)
+
 ## Keyable emitter properties
 
 These properties have two fields: a value and a spread. The spread is a variation which is applied randomly for each spawned particle. E.g. if the value is 50 and the spread is 3, each spawned particle will get a value between 47 and 53 (50 +/- 3).
@@ -227,3 +230,10 @@ particlefx.stop("#particles")
 A particle effect will continue to emit particles even if the game object the particle effect component belonged to is deleted.
 :::
 See the [Particle FX reference documentation](/ref/particlefx) for more information.
+
+## Material constants
+
+The default particle effect material has the following constants that can be changed using `particlefx.set_constant()` and reset using `particlefx.reset_constant()` (refer to the [Material manual for more details](/manuals/material/#vertex-and-fragment-constants)):
+
+`tint`
+: The color tint of the particle effect (`vector4`). The vector4 is used to represent the tint with x, y, z, and w corresponding to the red, green, blue and alpha tint. Refer to the [API reference for an example](/ref/particlefx/#particlefx.set_constant:url-constant-value).

+ 42 - 12
docs/zh/manuals/physics.md

@@ -1,6 +1,6 @@
 ---
-title: Defold 中的物理
-brief: Defold 包含 2D 和 3D 物理引擎. 它们可以用来模拟牛顿物理学碰撞对象之间的交互. 本教程介绍了其工作方法.
+title: Physics in Defold
+brief: Defold includes physics engines for 2D and 3D. They allow you to simulate Newtonian physics interactions between different types of collision objects. This manual explains how this works.
 ---
 
 # Physics
@@ -30,7 +30,7 @@ A collision object component has a set of *Properties* that sets its type and ph
 To add a collision object component to a game object:
 
 1. In the *Outline* view, <kbd>right click</kbd> the game object and select <kbd>Add Component ▸ Collision Object</kbd> from the context menu. This creates a new component with no shapes.
-2. <kbd>Right click</kbd> the new component and select <kbd>Add Shape ▸ Box / Capsule / Sphere</kbd>. This adds a new shape to the collision object component. You can add any number of shapes to the component.
+2. <kbd>Right click</kbd> the new component and select <kbd>Add Shape ▸ Box / Capsule / Sphere</kbd>. This adds a new shape to the collision object component. You can add any number of shapes to the component. You can also use a tilemap or a convex hull to define the shape of the physics object.
 3. Use the move, rotate and scale tools to edit the shapes.
 4. Select the component in the *Outline* and edit the collision object's *Properties*.
 
@@ -85,23 +85,27 @@ Group
 Mask
 : The other _groups_ this object should collide with. You can name one group or specify multiple groups in a comma separated list. If you leave the Mask field empty, the object will not collide with anything.
 
-### Units used by the physics engine simulation
+### Collision shapes
 
-The physics engine simulates Newtonian physics and it is designed to work well with meters, kilograms and seconds (MKS) units. Furthermore, the physics engine is tuned to work well with moving objects of a size in the 0.1 to 10 meters range (static objects can be larger) and by default the engine treats 1 unit (pixel) as 1 meter. This conversion between pixels and meters is convenient on a simulation level, but from a game creation perspective it isn't very useful. With default settings a collision shape with a size of 200 pixels would be treated as having a size of 200 meters which is well outside of the recommended range, at least for a moving object. In general it is required that the physics simulation is scaled for it to work well with the typical size of objects in a game. The scale of the physics simulation can be changed in `game.project` via the [physics scale setting](/manuals/project-settings/#physics). Setting this value to for instance 0.02 would mean that 200 pixels would be treated as a 4 meters. Do note that the gravity (also changed in `game.project`) has to be increased to accommodate for the change in scale.
+A collision component can either use several primitive shapes or a single complex shape. The primitive shapes are *box*, *sphere* and *capsule*. A complex shape can either be created from a tilemap component or from a convex hull shape.
 
-## Group and mask
+### Box shape
+A box has a position, rotation and dimensions (width, height and depth):
 
-The physics engine allows you to group your physics objects and filter how they should collide. This is handled by named _collision groups_. For each collision object you create two properties control how the object collides with other objects, *Group* and *Mask*.
+![Box shape](images/physics/box.png)
 
-For a collision between two objects to register both objects must mutually specify each other's groups in their *Mask* field.
+### Sphere shape
+A sphere has a position, rotation and diameter:
 
-![Physics collision group](images/physics/collision_group.png){srcset="images/physics/[email protected] 2x"}
+![Sphere shape](images/physics/sphere.png)
 
-The *Mask* field can contain multiple group names, allowing for complex interaction scenarios.
+### Capsule shape
+A capsule has a position, rotation, diameter and height:
 
-## Tilemap collision shapes
+![Sphere shape](images/physics/capsule.png)
 
-Defold includes a feature allowing you to easily generate physics shapes for a tile map. The [Tilemap manual](/manuals/tilemap/) explains how to add collision groups to a tile source and assign tiles to collision groups.
+### Tilemap collision shape
+Defold includes a feature allowing you to easily generate physics shapes for a tile map. The [Tilemap manual](/manuals/tilemap/) explains how to add collision groups to a tile source and assign tiles to collision groups ([example](/examples/tilemap/collisions/)).
 
 To add collision to a tile map:
 
@@ -116,6 +120,32 @@ To add collision to a tile map:
 Note that the *Group* property is **not** used here since the collision groups are defined in the tile map's tile source.
 :::
 
+### Convex hull shape
+Defold includes a feature allowing you to create a convex hull shape from three or more points. You can use an external tool such as the [Defold Polygon Editor](/assets/defoldpolygoneditor/) or the [Physics Body Editor](/assets/physicsbodyeditor/) to create a convex hull shape.
+
+1. Create convex hull shape file (file extension `.convexshape`) using an external editor.
+2. Instead of adding shapes to the collision object component, set the *Collision Shape* property to the *convex shape* file.
+
+::: sidenote
+The shape will not be drawn in the editor. You can [enable Physics debugging](/manuals/debugging/#debugging-problems-with-physics) at runtime to see the shape.
+:::
+
+
+### Units used by the physics engine simulation
+
+The physics engine simulates Newtonian physics and it is designed to work well with meters, kilograms and seconds (MKS) units. Furthermore, the physics engine is tuned to work well with moving objects of a size in the 0.1 to 10 meters range (static objects can be larger) and by default the engine treats 1 unit (pixel) as 1 meter. This conversion between pixels and meters is convenient on a simulation level, but from a game creation perspective it isn't very useful. With default settings a collision shape with a size of 200 pixels would be treated as having a size of 200 meters which is well outside of the recommended range, at least for a moving object. In general it is required that the physics simulation is scaled for it to work well with the typical size of objects in a game. The scale of the physics simulation can be changed in `game.project` via the [physics scale setting](/manuals/project-settings/#physics). Setting this value to for instance 0.02 would mean that 200 pixels would be treated as a 4 meters. Do note that the gravity (also changed in `game.project`) has to be increased to accommodate for the change in scale.
+
+## Group and mask
+
+The physics engine allows you to group your physics objects and filter how they should collide. This is handled by named _collision groups_. For each collision object you create two properties control how the object collides with other objects, *Group* and *Mask*.
+
+For a collision between two objects to register both objects must mutually specify each other's groups in their *Mask* field.
+
+![Physics collision group](images/physics/collision_group.png){srcset="images/physics/[email protected] 2x"}
+
+The *Mask* field can contain multiple group names, allowing for complex interaction scenarios.
+
+
 ## Collision messages
 
 When two objects collide, the engine will broadcast messages to all components in both objects:

+ 13 - 2
docs/zh/manuals/profiling.md

@@ -9,17 +9,28 @@ Defold 引擎内置了性能分析工具. 这些工具用来分析查找性能
 
 ## 运行时可视分析表
 
-Debug 应用包含运行时可视分析工具可以在应用最上层把分析信息显示出来. 可以向 "system" 接口发送 "toggle_profile" 消息控制其开关:
+Debug 应用包含运行时可视分析工具可以在应用最上层把分析信息显示出来:
 
 ```lua
 function on_reload(self)
     -- 热重载时打开分析表.
-    msg.post("@system:", "toggle_profile")
+    profiler.enable_ui(true)
 end
 ```
 
 ![Visual profiler](images/profiling/visual_profiler.png)
 
+此分析器提供了一些用来改变其数据显示方式的函数:
+
+```lua
+
+profiler.set_ui_mode()
+profiler.set_ui_view_mode()
+profiler.view_recorded_frame()
+```
+
+详情请见 [分析器 API 文档](/ref/stable/profiler/).
+
 ## 网页版分析器
 
 运行debug版游戏时, 也可以从浏览器访问一个基于网页的分析器. 它可以对游戏每一帧进行取样并分析.

+ 136 - 111
docs/zh/manuals/project-settings.md

@@ -16,403 +16,428 @@ brief: 本教程介绍了如何在 Defold 中进行项目配置工作.
 ## Project
 
 Title
-: 项目标题.
+#### 项目标题.
 
 Version
-: 版本.
+#### 版本.
 
 Write Log
-: 选中时, 游戏引擎会在项目根目录记录 *log.txt* 日志. 运行于 iOS 时, 日志文件可以通过 iTunes 和 *Apps* 页的 *File Sharing* 部分访问. 在 Android 上, 日志文件保存在应用的外存中. 在运行 *dmengine* 开发应用时, 可以通过以下命令查看日志:
+#### 选中时, 游戏引擎会在项目根目录记录 *log.txt* 日志. 运行于 iOS 时, 日志文件可以通过 iTunes 和 *Apps* 页的 *File Sharing* 部分访问. 在 Android 上, 日志文件保存在应用的外存中. 在运行 *dmengine* 开发应用时, 可以通过以下命令查看日志:
 
 ```bash
 $ adb shell cat /mnt/sdcard/Android/data/com.defold.dmengine/files/log.txt
 ```
 
 Compress Archive
-: 打包时启用压缩. 注意此设置除了 Android 都有效, 因为apk已经是压缩档了.
+#### 打包时启用压缩. 注意此设置除了 Android 都有效, 因为apk已经是压缩档了.
 
 Dependencies
-: 项目的 *Library URL* 列表. 详情请见 [Libraries 教程](/manuals/libraries/).
+#### 项目的 *Library URL* 列表. 详情请见 [Libraries 教程](/manuals/libraries/).
 
 Custom Resources
-: 项目中包含的以逗号分隔的资源列表. 如指定的是目录, 则目录下所有文件及其子目录都会包含进去. 这些资源可以通过 [`sys.load_resource()`](/ref/sys/#sys.load_resource) 载入.
+#### 项目中包含的以逗号分隔的资源列表. 如指定的是目录, 则目录下所有文件及其子目录都会包含进去. 这些资源可以通过 [`sys.load_resource()`](/ref/sys/#sys.load_resource) 载入.
 
 Bundle Resources
-: 需要根据平台单独打包的以逗号分隔的资源目录列表. 目录必须是以项目根目录开始的绝对路径, 比如像 `/res`. 资源目录里要包含 `platform`, 或者 `architecure-platform` 的子目录.
+#### 需要根据平台单独打包的以逗号分隔的资源目录列表. 目录必须是以项目根目录开始的绝对路径, 比如像 `/res`. 资源目录里要包含 `platform`, 或者 `architecure-platform` 的子目录.
 
   支持的 platform 有 `ios`, `android`, `osx`, `win32`, `linux`, `web`.
 
   允许名叫 `common` 的子目录, 用以容纳平台间共享的资源.
 
 Bundle Exclude Resources
-: 项目中排除的以逗号分隔的资源列表.
+#### 项目中排除的以逗号分隔的资源列表.
 
 ## Bootstrap
 
 Main Collection
-: 打开应用启动的起始集合, 默认 `/logic/main.collection`.
+#### 打开应用启动的起始集合, 默认 `/logic/main.collection`.
 
 Render
-: 指定使用哪个渲染文件, 它决定了渲染流程, 默认 `/builtins/render/default.render`.
+#### 指定使用哪个渲染文件, 它决定了渲染流程, 默认 `/builtins/render/default.render`.
 
 ## Library
 
 Include Dirs
-: 使用库共享机制从项目中共享出去的以逗号分隔的目录列表.
+#### 使用库共享机制从项目中共享出去的以逗号分隔的目录列表.
 
 ## Script
 
 Shared State
-: 打开则共享脚本的Lua状态, 默认关闭.
+#### 打开则共享脚本的Lua状态, 默认关闭.
+
+## Engine
+
+#### Run While Iconified
+当游戏应用程序窗口最小化时允许其在后台继续运行 (仅桌面平台有效), 默认值是 `false`.
 
 ## Display
 
 Width
-: 应用窗口像素为单位宽度, 默认 `960`.
+#### 应用窗口像素为单位宽度, 默认 `960`.
 
 Height
-: 应用窗口像素为单位高度, 默认 `640`.
+#### 应用窗口像素为单位高度, 默认 `640`.
 
 High Dpi
-: 开启高dpi后台缓存来支持超高清. 技术上就是以 *Width* 和 *Height* 设置的双倍进行渲染, 但是脚本和属性使用的逻辑分辨率不变.
+#### 开启高dpi后台缓存来支持超高清. 技术上就是以 *Width* 和 *Height* 设置的双倍进行渲染, 但是脚本和属性使用的逻辑分辨率不变.
 
 Samples
-: 超采样抗锯齿所使用的采样数量. 窗口提示是 GLFW_FSAA_SAMPLES. 默认是 `0`, 相当于关闭抗锯齿.
+#### 超采样抗锯齿所使用的采样数量. 窗口提示是 GLFW_FSAA_SAMPLES. 默认是 `0`, 相当于关闭抗锯齿.
 
 Fullscreen
-: 设置应用启动是否使用全屏. 如果关闭, 应用会以窗口形式启动.
+#### 设置应用启动是否使用全屏. 如果关闭, 应用会以窗口形式启动.
 
 Frame Cap
-: 如果 `Vsync` 开启, 则为锁帧频率匹配最接近的交换间隔. 否则的话依据锁帧设置计时器, 0 代表不锁帧. 此设置相当于 `display.update_frequency`.
+#### 如果 `Vsync` 开启, 则为锁帧频率匹配最接近的交换间隔. 否则的话依据锁帧设置计时器, 0 代表不锁帧. 此设置相当于 `display.update_frequency`.
 
 Vsync
-: 垂直同步, 根据硬件的帧率进行刷新. 可以被驱动程序或者操作系统平台设置覆盖.
+#### 垂直同步, 根据硬件的帧率进行刷新. 可以被驱动程序或者操作系统平台设置覆盖.
 
 Variable Dt (deprecated)
-: 弃用. 如果开启, 编译时将会开启 `Vsync` 同时设置 `Frame Cap` 为 0.
+#### 弃用. 如果开启, 编译时将会开启 `Vsync` 同时设置 `Frame Cap` 为 0.
 
 Display Profiles
-: 指定使用哪个显示样式文件, 默认 `/builtins/render/default.display_profilesc`.
+#### 指定使用哪个显示样式文件, 默认 `/builtins/render/default.display_profilesc`.  详情请见 [GUI 排版教程](/manuals/gui-layouts/#creating-display-profiles).
 
 Dynamic Orientation
-: 开启的话会在设备转动时动态切换横竖显示方向. 注意开发用app(指dmengine)不参考此设置.
+#### 开启的话会在设备转动时动态切换横竖显示方向. 注意开发用app(指dmengine)不参考此设置.
+
+## 渲染
+
+#### Clear Color Red
+清除红色通道, 建立游戏窗口和渲染脚本中使用. 1.2.167 版新增.
+
+#### Clear Color Green
+清除绿色通道, 建立游戏窗口和渲染脚本中使用. 1.2.167 版新增.
+
+#### Clear Color Blue
+清除蓝色通道, 建立游戏窗口和渲染脚本中使用. 1.2.167 版新增.
+
+#### Clear Color ALpha
+清除alpha通道, 建立游戏窗口和渲染脚本中使用. 1.2.167 版新增.
 
 ## Physics
 
 Type
-: 使用何种物理引擎, `2D` (默认) 还是 `3D`.
+#### 使用何种物理引擎, `2D` (默认) 还是 `3D`.
 
 Gravity Y
-: 延Y轴的重力加速度, 默认是 `-10` (自然重力加速度)
+#### 延Y轴的重力加速度, 默认是 `-10` (自然重力加速度)
 
 Debug
-: 设置物理是否显示debug线.
+#### 设置物理是否显示debug线.
 
 Debug Alpha
-: debug线的不透明度, `0`--`1`. 默认是 `0.9`.
+#### debug线的不透明度, `0`--`1`. 默认是 `0.9`.
 
 World Count
-: 可以同时存在的物理世界最大数目, 默认是`4`. 如果需要使用 collection proxies 载入更多物理世界可以提高此设置. 请注意每个物理世界都要占用相应的内存.
+#### 可以同时存在的物理世界最大数目, 默认是`4`. 如果需要使用 collection proxies 载入更多物理世界可以提高此设置. 请注意每个物理世界都要占用相应的内存.
 
 Gravity X
-: 延X轴的重力加速度, 默认是 `0`.
+#### 延X轴的重力加速度, 默认是 `0`.
 
 Gravity Z
-: 延Z轴的重力加速度, 默认是 `0`.
+#### 延Z轴的重力加速度, 默认是 `0`.
 
 Scale
-: 设定物理世界与游戏世界的数值映射比例, `0.01`--`1.0`. 如果设置为 `0.02`, 相当于物理引擎视50个游戏单位为1米 ($1 / 0.02$). 默认值是 `1.0`.
+#### 设定物理世界与游戏世界的数值映射比例, `0.01`--`1.0`. 如果设置为 `0.02`, 相当于物理引擎视50个游戏单位为1米 ($1 / 0.02$). 默认值是 `1.0`.
 
 Debug Scale
-: 设置物理元物体画多大, 比如原向量和法线,  默认是`30`.
+#### 设置物理元物体画多大, 比如原向量和法线,  默认是`30`.
 
 Max Collisions
-: 设置向脚本报告多少个碰撞, 默认是 `64`.
+#### 设置向脚本报告多少个碰撞, 默认是 `64`.
 
 Max Contacts
-: 设置向脚本报告多少碰撞点, 默认是 `128`.
+#### 设置向脚本报告多少碰撞点, 默认是 `128`.
 
 Contact Impulse Limit
-: 设置小于多大的碰撞冲量会被忽略, 默认是 `0.0`.
+#### 设置小于多大的碰撞冲量会被忽略, 默认是 `0.0`.
 
 Ray Cast Limit 2d
-: 每帧中2d射线最大请求数量. 默认是 `64`.
+#### 每帧中2d射线最大请求数量. 默认是 `64`.
 
 Ray Cast Limit 3d
-: 每帧中3d射线最大请求数量. 默认是 `128`.
+#### 每帧中3d射线最大请求数量. 默认是 `128`.
 
 Trigger Overlap Capacity
-: 物理 trigger 的最大重叠数量. 默认是 `16`.
+#### 物理 trigger 的最大重叠数量. 默认是 `16`.
 
 ## Graphics
 
 Default Texture Min Filter
-: 设置缩小过滤方式, `linear` (默认) 或者 `nearest`.
+#### 设置缩小过滤方式, `linear` (默认) 或者 `nearest`.
 
 Default Texture Mag Filter
-: 设置放大过滤方式, `linear` (默认) 或者 `nearest`.
+#### 设置放大过滤方式, `linear` (默认) 或者 `nearest`.
 
 Max Draw Calls
-: 渲染请求最大数目, 默认是 `1024`.
+#### 渲染请求最大数目, 默认是 `1024`.
 
 Max Characters:
-: 在渲染缓冲区预加载字符数目, 也就是每帧最多显示多少字符, 默认是 `8192`.
+#### 在渲染缓冲区预加载字符数目, 也就是每帧最多显示多少字符, 默认是 `8192`.
 
 Max Debug Vertices
-: debug顶点最大数目. 用于物理形状渲染与其他一些功能, 默认是 `10000`.
+#### debug顶点最大数目. 用于物理形状渲染与其他一些功能, 默认是 `10000`.
 
 Texture Profiles
-: 项目使用的纹理档配置文件, 默认是 `/builtins/graphics/default.texture_profiles`.
+#### 项目使用的纹理档配置文件, 默认是 `/builtins/graphics/default.texture_profiles`.
 
 ## Input
 
 Repeat Delay
-: 按下输入保持时等待多少秒后开始算作重复输入, 默认是 `0.5`.
+#### 按下输入保持时等待多少秒后开始算作重复输入, 默认是 `0.5`.
 
 Repeat Interval
-: 按下并保持时重复输入的时间间隔, 默认是 `0.2`.
+#### 按下并保持时重复输入的时间间隔, 默认是 `0.2`.
 
 Gamepads
-: 手柄设置文件的引用, 用于映射手柄到 OS 的输入信号, 默认是 `/builtins/input/default.gamepads`.
+#### 手柄设置文件的引用, 用于映射手柄到 OS 的输入信号, 默认是 `/builtins/input/default.gamepads`.
 
 Game Binding
-: 输入设置文件的引用, 用于映射硬件输入到游戏行为, 默认是 `/input/game.input_binding`.
+#### 输入设置文件的引用, 用于映射硬件输入到游戏行为, 默认是 `/input/game.input_binding`.
 
 Use Accelerometer
-: 开启后游戏引擎会在每帧接收加速度计数据. 关闭会获得少许性能提升, 默认开启.
+#### 开启后游戏引擎会在每帧接收加速度计数据. 关闭会获得少许性能提升, 默认开启.
 
 ## Resource
 
 Http Cache
-: 开启后, 会开启HTTP缓存用于设备上的游戏引擎从缓存中快速导入网络数据, 默认关闭.
+#### 开启后, 会开启HTTP缓存用于设备上的游戏引擎从缓存中快速导入网络数据, 默认关闭.
 
 Uri
-: 项目编译数据地址, URI 格式.
+#### 项目编译数据地址, URI 格式.
 
 Max Resources
-: 一次可以加载资源的最大数目, 默认是 `1024`.
+#### 一次可以加载资源的最大数目, 默认是 `1024`.
 
 ## Network
 
 Http Timeout
-: HTTP超时秒数. 设置为 `0` 则关闭超时, 默认关闭.
+#### HTTP超时秒数. 设置为 `0` 则关闭超时, 默认关闭.
 
 ## Collection
 
 Max Instances
-: 一个集合里容纳游戏对象实例的最大数目, 默认是`1024`.
+#### 一个集合里容纳游戏对象实例的最大数目, 默认是`1024`.
 
 ## Sound
 
 Gain
-: 全局增益 (音量), `0`--`1`, 默认值是 `1`.
+#### 全局增益 (音量), `0`--`1`, 默认值是 `1`.
 
 Max Sound Data
-: 声音资源的最大数目, 也就是运行时声音文件使用数目, 默认是 `128`.
+#### 声音资源的最大数目, 也就是运行时声音文件使用数目, 默认是 `128`.
 
 Max Sound Buffers
-: (目前未使用) 同一时间声音缓冲最大数目, 默认是 `32`.
+#### (目前未使用) 同一时间声音缓冲最大数目, 默认是 `32`.
 
 Max Sound Sources
-: (目前未使用) 同一时间声音音源最大数目, 默认是 `16`.
+#### (目前未使用) 同一时间声音音源最大数目, 默认是 `16`.
 
 Max Sound Instances
-: 同一时间声音实例最大数目, 也就是实际同时播放声音最大数目. 默认是 `256`.
+#### 同一时间声音实例最大数目, 也就是实际同时播放声音最大数目. 默认是 `256`.
 
 ## Sprite
 
 Max Count
-: 每个集合最大sprite数目, 默认是 `128`.
+#### 每个集合最大sprite数目, 默认是 `128`.
 
 Subpixels
-: 开启后允许sprite不与像素对齐, 默认开启.
+#### 开启后允许sprite不与像素对齐, 默认开启.
 
 ## Tilemap
 
 Max Count
-: 每个集合的瓷砖地图最大数目, 默认是 `16`.
+#### 每个集合的瓷砖地图最大数目, 默认是 `16`.
 
 Max Tile Count
-: 每个集合可同时显示的瓷砖最大数目, 默认是 `2048`.
+#### 每个集合可同时显示的瓷砖最大数目, 默认是 `2048`.
 
 ## Spine
 
 Max Count
-: spine 模型最大数目, 默认是 `128`.
+#### spine 模型最大数目, 默认是 `128`.
 
 ## GUI
 
 Max Count
-: GUI 组件最大数目, 默认是 `64`.
+#### GUI 组件最大数目, 默认是 `64`.
 
 Max Particlefx Count
-: 同一时间粒子发射器最大数目, 默认是 `64`.
+#### 同一时间粒子发射器最大数目, 默认是 `64`.
 
 Max Particle Count
-: 同一时间粒子最大数目, 默认是 `1024`.
+#### 同一时间粒子最大数目, 默认是 `1024`.
 
 ## Label
 
 Max Count
-: label 最大数目, 默认是 `64`.
+#### label 最大数目, 默认是 `64`.
 
 Subpixels
-: 开启后允许 lables 不与像素对齐, 默认开启.
+#### 开启后允许 lables 不与像素对齐, 默认开启.
 
 ## Particle FX
 
 Max Count
-: 同一时间粒子发射器最大数目, 默认是 `64`.
+#### 同一时间粒子发射器最大数目, 默认是 `64`.
 
 Max Particle Count
-: 同一时间粒子最大数目, 默认是 `1024`.
+#### 同一时间粒子最大数目, 默认是 `1024`.
 
 ## Collection proxy
 
 Max Count
-: 集合代理最大数目, 默认是 `8`.
+#### 集合代理最大数目, 默认是 `8`.
 
 ## Collection factory
 
 Max Count
-: 集合工厂最大数目, 默认是 `128`.
+#### 集合工厂最大数目, 默认是 `128`.
 
 ## Factory
 
 Max Count
-: 游戏对象工厂最大数目, 默认是 `128`.
+#### 游戏对象工厂最大数目, 默认是 `128`.
 
 ## iOS
 
 App Icon 57x57--180x180
-: 用于应用图标的图片 (.png) 文件, 宽高分辨率表示为 `W` &times; `H`.
+#### 用于应用图标的图片 (.png) 文件, 宽高分辨率表示为 `W` &times; `H`.
 
 Launch Image 320x480--2436x1125
-: 用于应用启动图的图片 (.png) 文件, 宽高分辨率表示为 `W` &times; `H`. iOS 基于启动图选择分辨率.
+#### 用于应用启动图的图片 (.png) 文件, 宽高分辨率表示为 `W` &times; `H`. iOS 基于启动图选择分辨率.
 
 Pre Rendered Icons
-: (iOS 6 及更早) 设置图标是否预渲染. 如果关闭则图标自动添加平滑高光效果.
+#### (iOS 6 及更早) 设置图标是否预渲染. 如果关闭则图标自动添加平滑高光效果.
 
 Bundle Identifier
-: 打包id使得 iOS 认识你的应用的版本更新. 你的打包 ID 必须在 Apple 注册且确保应用唯一性. iOS 与 OS X 应用不可以使用同一id.
+#### 打包id使得 iOS 认识你的应用的版本更新. 你的打包 ID 必须在 Apple 注册且确保应用唯一性. iOS 与 OS X 应用不可以使用同一id.
 
 Info.plist
-: 如果设置了, 则打包应用时使用此 info.plist 文件.
+#### 如果设置了, 则打包应用时使用此 info.plist 文件.
 
 Entitlements
-: 如果设置了, 则覆盖引用档文件 (.entitlements, .xcent, .plist) 中定义的通用权限.
+#### 如果设置了, 则覆盖引用档文件 (.entitlements, .xcent, .plist) 中定义的通用权限.
+
+#### Default Language
+如果用户没有指定 `Localizations` 列表里的语言, 则使用此处设置的语言 (见 [CFBundleDevelopmentRegion](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-130430)).
+
+#### Localizations
+以逗号分割的语言名称缩写或者是 ISO 语言代号 (见 [CFBundleLocalizations](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-109552)).
 
 ## Android
 
 App Icon 36x36--192x192
-: 用于应用图标的图片 (.png) 文件, 宽高分辨率表示为 `W` &times; `H`.
+#### 用于应用图标的图片 (.png) 文件, 宽高分辨率表示为 `W` &times; `H`.
 
 Push Icon Small--LargeXxxhdpi
-: 用于Android上客户推送通知图标的图片 (.png) 文件. 图标会自动应用于本地与远程推送通知. 如果未设置默认使用应用图标.
+#### 用于Android上客户推送通知图标的图片 (.png) 文件. 图标会自动应用于本地与远程推送通知. 如果未设置默认使用应用图标.
 
 Push Field Title
-: 指定用于通知标题的酬载 JSON 域. 保留空白则默认推送应用名作为标题.
+#### 指定用于通知标题的酬载 JSON 域. 保留空白则默认推送应用名作为标题.
 
 Push Field Text
-: 指定用于通知文本的酬载 JSON 域. 保留空白则默认推送 `alert` 域的文本, iOS 同样如此.
+#### 指定用于通知文本的酬载 JSON 域. 保留空白则默认推送 `alert` 域的文本, iOS 同样如此.
 
 Version Code
-: 表示应用版本号的整数值. 随着后续更新增大此值.
+#### 表示应用版本号的整数值. 随着后续更新增大此值.
 
 Package
-: 包id.
+#### 包id.
 
 Gcm Sender Id
-: Google Cloud Messaging Sender Id. 此值由 Google 签发, 设置后才能开启推送通知.
+#### Google Cloud Messaging Sender Id. 此值由 Google 签发, 设置后才能开启推送通知.
 
 Manifest
-: 如果设置了, 则编译时使用指定 Android manifest XML 文件.
+#### 如果设置了, 则编译时使用指定 Android manifest XML 文件.
 
 Iap Provider
-: 指定使用哪个应用商店. 合法值是 `Amazon` 和 `GooglePlay`, 默认是 `GooglePlay`.
+#### 指定使用哪个应用商店. 合法值是 `Amazon` 和 `GooglePlay`, 默认是 `GooglePlay`.
 
 Input Method
-: 指定获取 Android 设备键盘输入的方式. 合法值是 `KeyEvent` (老方法) 和 `HiddenInputField` (新方法). 默认是 `KeyEvent`.
+#### 指定获取 Android 设备键盘输入的方式. 合法值是 `KeyEvent` (老方法) 和 `HiddenInputField` (新方法). 默认是 `KeyEvent`.
 
 Immersive Mode
-: 如果开启, 则隐藏导航条和状态条并且让你的应用获取屏幕上所有触碰信息.
+#### 如果开启, 则隐藏导航条和状态条并且让你的应用获取屏幕上所有触碰信息.
 
 Debuggable
-: 指定应用是否可以使用诸如 [GAPID](https://github.com/google/gapid) 或者 [Android Studio](https://developer.android.com/studio/profile/android-profiler) 之类的工具来调试. 这将开启 Android manifest 的 `android:debuggable` 选项.
+#### 指定应用是否可以使用诸如 [GAPID](https://github.com/google/gapid) 或者 [Android Studio](https://developer.android.com/studio/profile/android-profiler) 之类的工具来调试. 这将开启 Android manifest 的 `android:debuggable` 选项.
 
 ## MacOS / OS X
 
 App Icon
-: 用于MacOS应用图标的图片 (.png) 文件.
+#### 用于MacOS应用图标的图片 (.png) 文件.
 
 Info.plist
-: 如果设置了, 则编译时使用指定的 info.plist 文件.
+#### 如果设置了, 则编译时使用指定的 info.plist 文件.
 
 Bundle Identifier
-: 打包id使得 OS X 认识你的应用的版本更新. 你的打包 ID 必须在 Apple 注册且确保应用唯一性. iOS 与 OS X 应用不可以使用同一id.
+#### 打包id使得 OS X 认识你的应用的版本更新. 你的打包 ID 必须在 Apple 注册且确保应用唯一性. iOS 与 OS X 应用不可以使用同一id.
 
 ## Windows
 
 App Icon
-: 用于Windows应用图标的图片 (.ico) 文件. 对于如何创建图标文件详情请见 [Windows 教程](/manuals/windows).
+#### 用于Windows应用图标的图片 (.ico) 文件. 对于如何创建图标文件详情请见 [Windows 教程](/manuals/windows).
 
 Iap Provider
-: 指定使用哪个应用商店. 合法值是 `None` 和 `Gameroom`, 默认是 `None`.
+#### 指定使用哪个应用商店. 合法值是 `None` 和 `Gameroom`, 默认是 `None`.
 
 ## HTML5
 
 Heap Size
-: 指定Emscripten所使用的堆大小 (兆字节) . 默认值是 256MB.
+#### 指定Emscripten所使用的堆大小 (兆字节) . 默认值是 256MB.
 
 .html Shell
-: 指定编译时使用的 HTML 文件. 默认是 `/builtins/manifests/web/engine_template.html`.
+#### 指定编译时使用的 HTML 文件. 默认是 `/builtins/manifests/web/engine_template.html`.
 
 Custom .css
-: 指定编译时使用的 CSS 文件. 默认是 `/builtins/manifests/web/light_theme.css`.
+#### 指定编译时使用的 CSS 文件. 默认是 `/builtins/manifests/web/light_theme.css`.
 
 Splash Image
-: 如果设置了, 则在打包时使用指定的溅射屏幕图片代替Defold Logo.
+#### 如果设置了, 则在打包时使用指定的溅射屏幕图片代替Defold Logo.
 
 Archive Location Prefix
-: 指定打包 HTML5 时游戏数据是否拆分为多个数据包文件. 游戏启动时, 这些数据文件会被读入内存. 使用此设置指定数据包的位置, 默认值是 `archive`.
+#### 指定打包 HTML5 时游戏数据是否拆分为多个数据包文件. 游戏启动时, 这些数据文件会被读入内存. 使用此设置指定数据包的位置, 默认值是 `archive`.
 
 Archive Location Suffix
-: 指定数据包文件的后缀. 比如说适用于, 来自 CDN 的强制非缓存文件 (比如后缀 `?version2`).
+#### 指定数据包文件的后缀. 比如说适用于, 来自 CDN 的强制非缓存文件 (比如后缀 `?version2`).
 
 Engine Arguments
-: 传到游戏引擎里的参数列表.
+#### 传到游戏引擎里的参数列表.
 
 Show Fullscreen Button
-: 在 `index.html` 文件中开启全屏按钮. 默认是 `true`.
+#### 在 `index.html` 文件中开启全屏按钮. 默认是 `true`.
 
 Show Made With Defold
-:  在 `index.html` 文件中开启 Defold 链接. 默认是 `true`.
+####  在 `index.html` 文件中开启 Defold 链接. 默认是 `true`.
 
 Scale Mode
-: 指定游戏 canvas 所使用的缩放方式. 默认是 `Downscale Fit`.
+#### 指定游戏 canvas 所使用的缩放方式. 默认是 `Downscale Fit`.
 
 ## IAP
 
 Auto Finish Transactions
-: 开启后自动完成 IAP 交易. 如果关闭, 在交易成功后你需要手动调用 `iap.finish()` , 默认开启.
+#### 开启后自动完成 IAP 交易. 如果关闭, 在交易成功后你需要手动调用 `iap.finish()` , 默认开启.
 
 ## Live update
 
 Private Key
-: 如果设置了, 则在编译热更新内容时使用指定的私匙. 如果不设置, 则自动生成一个私匙.
+#### 如果设置了, 则在编译热更新内容时使用指定的私匙. 如果不设置, 则自动生成一个私匙.
 
 Public Key
-: 如果设置了, 则在编译热更新内容时使用指定的公匙. 如果不设置, 则自动生成一个私匙.
+#### 如果设置了, 则在编译热更新内容时使用指定的公匙. 如果不设置, 则自动生成一个私匙.
 
 ## Native extension
 
 _App Manifest_
-: 如果设置了, 则在自定义引擎编译时使用指定的 manifest. 此设置可以让你移除引擎不必要的部分来减小包体. 注意此设置尚在测试中. 使用方法详情请见 [这个帖子](https://forum.defold.com/t/native-extensions/4946/142).
+#### 如果设置了, 则在自定义引擎编译时使用指定的 manifest. 此设置可以让你移除引擎不必要的部分来减小包体. 注意此设置尚在测试中. 使用方法详情请见 [这个帖子](https://forum.defold.com/t/native-extensions/4946/142).
 
 ## Profiler
 
 Track Cpu
-: 如果开启, 则在编译版本中开启 CPU profiling. 通常, 你只能在 debug 版本中进行调试.
+#### 如果开启, 则在编译版本中开启 CPU profiling. 通常, 你只能在 debug 版本中进行调试.
 
 ## File format
 

+ 3 - 3
docs/zh/manuals/push.md

@@ -12,13 +12,13 @@ brief: 本教程介绍了如何配置和实现游戏中的本地和远程 iOS 
 ## 安装扩展
 
 使用之前要在 `game.project` 文件里配置扩展依赖. 最新稳定版依赖的 URL 是:
+
 ```
 https://github.com/defold/extension-push/archive/master.zip
 ```
 
 推荐使用 [指定版本](https://github.com/defold/extension-push/releases) 的zip包链接作为依赖.
 
-此扩展需要依赖 ([firebase](https://github.com/defold/extension-firebase-core/releases)):
 ```
 https://github.com/defold/extension-firebase-core/archive/master.zip
 ```
@@ -28,7 +28,7 @@ API 文档在 [推送通知扩展项目](https://defold.github.io/extension-push
 ## iOS 配置
 
 ::: 注意
-要深入了解 Apple Push Notification Service, 首先熟读 Apple 的服务文档. 文档在 https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html
+为了更好地使用 Apple Push Notification 服务, 最好先熟读 [Apple 的官方文档](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html).
 :::
 
 iOS 上, 推送通知需要做以下准备:
@@ -168,7 +168,7 @@ Android 上, 推送通知需要做以下准备:
 
 用文本编辑器打开 `google-services.json` 文件, 找到 *`project_number`* 和 *`mobilesdk_app_id`*. 把这俩id考入 `game.project` 文件, 对应 *android* 部分, `Gcm Sender Id` (`project_number`) 和 `Fcm Application Id` (`mobilesdk_app_id`).
 
-```json
+```
 {
   "project_info": {
     "project_number": "123456789123",

+ 22 - 0
docs/zh/manuals/socket-connections.md

@@ -0,0 +1,22 @@
+---
+title: Socket connections
+brief: This manual explains how to connect to create socket connections.
+---
+
+## Socket connections
+
+Defold includes the [LuaSocket library](http://w3.impa.br/~diego/software/luasocket/) for creating TCP and UDP socket connections. Example of how to create a socket connection, sending some data and reading a response:
+
+```Lua
+local client = socket.tcp()
+client:connect("127.0.0.1", 8123)
+client:settimeout(0)
+client:send("foobar")
+local response = client:receive("*l")
+```
+
+This will create a TCP socket, connect it to IP 127.0.0.1 (localhost) and port 8123. It will set timeout to 0 to make the socket non-blocking and it will send the string "foobar" over the socket. It will also read a line of data (bytes ending with a newline character) from the socket. Note that the above example doesn't contain any kind of error handling.
+
+### API Reference and examples
+
+Refer to the [API reference](/ref/socket/) to learn more about the functionality available via LuaSocket. The [official LuaSocket documentation](http://w3.impa.br/~diego/software/luasocket/) also contains many examples of how to work with the library. There is also some examples and helper modules in the [DefNet library](https://github.com/britzl/defnet/).

+ 43 - 9
docs/zh/manuals/spinemodel.md

@@ -7,7 +7,7 @@ brief: 本教程介绍了在Defold中如何创建 SpineModel 组件.
 
 SpineModel 组件用于把 _Spine_ 骨骼动画在 Defold 中呈现出来.
 
-## 创建 SpineModel 组件
+## 创建 Spine Model 组件
 
 选择一个游戏对象:
 
@@ -15,28 +15,37 @@ SpineModel 组件用于把 _Spine_ 骨骼动画在 Defold 中呈现出来.
 
 方法二 先创建文件 (在 *资源* 浏览器中 <kbd>右键点击</kbd>, 在上下文菜单中选择 <kbd>New... ▸ Spine Model</kbd>), 再在游戏对象上 <kbd>右键点击</kbd> , 选择 <kbd>Add Component File</kbd>).
 
-设置组件 *Properties*:
+## Spine Model *属性*:
 
-Spine scene
+除了常见的 *Id*, *Position* 和 *Rotation* 属性外, 还有 Spine Model 的特有属性:
+
+*Spine scene*
 : 设置先前创建的 Spine Scene.
 
-Blend Mode
+*Blend Mode*
 : 默认混合模式是 `Alpha`, 想用别的可以修改这个属性.
 
-Material
+*Material*
 : 如果想要使用自定义材质显示Spine模型, 在此指定.
 
-Default animation
+*Default animation*
 : 设置Spine模型默认的动画.
 
-Skin
-: 设置Spine模型的皮肤.
+*Skin*
+: 如果模型包含皮肤的话,这里可以设置Spine模型的默认皮肤.
 
 此时就可以在编辑器里看到Spine模型了:
 
 ![编辑器中的Spine模型](images/spinemodel/spinemodel.png){srcset="images/spinemodel/[email protected] 2x"}
 
-## 运行时动画
+### 混合模式
+:[blend-modes](../shared/blend-modes.md)
+
+## 运行时操作
+
+有一系列方法可以在运行时修改Spine模型 (参见 [API文档](/ref/spine/)).
+
+### 运行时动画
 
 Defold 提供运行时控制动画的功能:
 
@@ -54,3 +63,28 @@ spine.play_anim("#spinemodel", "run", go.PLAYBACK_NONE)
 go.animate("#spinemodel", "cursor", go.PLAYBACK_LOOP_PINGPONG, 1, go.EASING_LINEAR, 10)
 ```
 
+### 修改属性
+
+Spine模型可以使用 `go.get()` 和 `go.set()` 方法修改其属性:
+
+`animation`
+: 当前Spine模型动画 (`hash`) (只读). 使用 `spine.play_anim()` 方法来更改播放动画 (见上文).
+
+`cursor`
+: 标准化动画头 (`number`).
+
+`material`
+: Spine模型材质 (`hash`). 可使用 `go.set()` 修改. 参见 [这个例子的 API 用法](/ref/spine/#material).
+
+`playback_rate`
+: 动画播放速率 (`number`).
+
+`skin`
+: 当前组件的皮肤 (`hash`).
+
+## 材质属性
+
+Spine模型的默认材质属性可以用 `spine.set_constant()` 和 `spine.reset_constant()` 方法来设置和重置. (详情参见 [材质教程](/manuals/material/#vertex-and-fragment-constants)):
+
+`tint`
+: Spine材质的染色 (`vector4`). 四元数 x, y, z, 和 w 代表染色的红, 绿, 蓝 和不透明度. 参见 [这个例子的 API 用法](/ref/spine/#spine.set_constant:url-constant-value).

+ 21 - 5
docs/zh/manuals/sprite.md

@@ -3,7 +3,7 @@ title: 显示 2D 图片
 brief: 本教程介绍了如何使用 sprite 组件显示 2D 图片和动画.
 ---
 
-#  Sprites(精灵)
+#  Sprites
 
 Sprite 组件可以是屏幕上显示的简单图片或者逐帧动画.
 
@@ -16,16 +16,19 @@ Sprite 组件使用 [图集](/manuals/atlas) 或者 [瓷砖图源](/manuals/tile
 除了 *Id*, *Position* 和 *Rotation* 还有如下属性:
 
 *Image*
-: sprite所使用的图集或者瓷砖图源资源.
+: sprite所使用的图集或者瓷砖图源资源.
 
 *DefaultAnimation*
-: sprite的默认动画.
+: sprite的默认动画.
 
 *Material*
-: sprite的渲染材质.
+: sprite的渲染材质.
 
 *Blend Mode*
-: 此组件渲染时使用的混合模式.
+: 组件渲染时使用的混合模式.
+
+### 混合模式
+:[blend-modes](../shared/blend-modes.md)
 
 # 运行时操作
 
@@ -39,6 +42,12 @@ Sprite 组件使用 [图集](/manuals/atlas) 或者 [瓷砖图源](/manuals/tile
 `cursor`
 : 初始化动画播放头 (`number`).
 
+`image`
+: sprite图 (`hash`). 可以通过 `go.set()` 方法使用图集或者瓷砖图集资源来修改此属性. 请参考 [这个例子的 API 文档](/ref/sprite/#image).
+
+`material`
+: sprite材质 (`hash`). 可以通过 `go.set()` 方法使用材质资源来修改此属性. 请参考 [这个例子的 API 文档](/ref/sprite/#material).
+
 `playback_rate`
 : 动画播放速率 (`number`).
 
@@ -47,3 +56,10 @@ Sprite 组件使用 [图集](/manuals/atlas) 或者 [瓷砖图源](/manuals/tile
 
 `size`
 : Sprite大小 (`vector3`) (只读).
+
+## 材质属性
+
+sprite的默认材质属性可以用 `sprite.set_constant()` 和 `sprite.reset_constant()` 方法来设置和重置. (详情参见 [材质教程](/manuals/material/#vertex-and-fragment-constants)):
+
+`tint`
+: sprite染色 (`vector4`). 四元数 x, y, z, 和 w 代表染色的红, 绿, 蓝 和不透明度. 参见 [这个例子的 API 用法](/ref/sprite/#sprite.set_constant:url-constant-value).

+ 132 - 0
docs/zh/manuals/test.md

@@ -0,0 +1,132 @@
+---
+title: Defold markdown test
+brief: This document uses all Markdown features (Commonmark + a couple of extensions) that the Defold docs use.
+---
+
+# Defold markdown test
+
+All defold manuals and tutorials are written in Markdown. This document outlines how to use the various formatting for a consistent look on all documents.
+
+Try to write as if you are talking to the user. Keep the language direct and active and refrain from stating opinions unless it is important to the matter. Try to write paragraphs that flow and do not break them unnecessarily.
+
+You do have some typographic markers to your disposal. The simplest one is the *emphasis* marker. It puts some stress to a word, marking it as important. This marker should also be used to call attention to specific things that the user can encounter in Defold, like the names of properties, buttons etc. For example, a sprite component's *Position*, a button that says *Save...* etc. File names are also typed like that: *game.project* or *main/images/logo.png*.
+
+Do not use the **bold text** emphasis. Do not ***ever*** mark anything with both bold and emphasis.
+
+Generally, when using quotes you can type straight quotes (`""`) and they get automatically converted to "nice typographically correct quotes". Also, the en and em-dashes are nice things to be able to type easily. You do that by typing `--` for en-dash and `---` for em-dash. So now you can get nicely typeset numeric intervals like 23--24, and if you want an em-dash as punctuation in a sentence---that's easy too. Just remember not to put spaces around them. A nice ellipsis character is also automatically inserted whenever you type more than two spaces in a row...
+
+Keystrokes, like the combination <kbd>⌘ + T</kbd> are written surrounded by `<kbd>` tags, as are any references to menu options, like <kbd>File ▸ Save As...</kbd>. Note the small right-pointing triangle that makes menu options stand out a little.
+
+For subscript and superscript you type `~subscript~` and `^superscript^`. For example: <code>X~N~ = y^N^ + O~N~</code> where `N` is a variable. For clarity, maths formulas can be put inside `<code>` tags, or even better---use the LaTeX math extension. Inline math is written surrounded by \$ signs. For instance, $\int\frac {d\theta}{1+\theta^2} = \tan^{-1} \theta+ C$. Separate math blocks are delimited by $$ pairs:
+
+$$
+\int\frac {d\theta}{1+\theta^2} = \tan^{-1} \theta+ C
+$$
+
+For things that the user will type, like function names, message names, string values and similar, use the `code marker`. For instance, `go.some_function()` or a `variable` name, a `message_name` or a `"string value"`. For larger chunks of code or configuration text, use the code fences with language specification to enable syntax highlighting:
+
+```lua
+local pieces = { "ground0", "ground1", "ground2", "ground3",
+                    "ground4", "ground5", "ground6" } -- <1>
+
+function init(self) -- <2>
+    self.speed = 6
+end
+
+-- This is a comment to the functionality of the function and it is running quite long to force a linebreak
+function update(self, dt)
+    for i, p in ipairs(pieces) do -- <3>
+        local pos = go.get_position(p)
+        if pos.x <> -228 then
+            pos.x = 1368 + (pos.x + 228)
+        end
+        pos.x = pos.x - self.speed
+        go.set_position(pos, p)
+    end
+end
+-- This is a comment to the functionality of the function and it is running quite long to force a
+```
+1. Note that the `-- <1>` in the source is changed to a numeric callout that is not part of
+   the source code anymore.
+2. Depending on the source language you type the callout differently. In a C like language
+   you would type `// <2>`
+3. In a shell-like language you would type `# <3>`.
+
+## Two levels of headings, lists and tables
+
+Do not use more than two levels of headings. If you need to describe specific things that you feel call for a third level heading, use a definition list instead:
+
+Some thing
+: Here you can explain what "Some thing" is, what it does and whatnot. You have access to all of markdown in the description, just make sure to indent properly:
+  - A bullet point
+  - Another bullet
+
+Another thing to explain
+: Here you explain that other thing to explain. Try to be specific and avoid vague language when you describe things.
+
+Definition lists are great when you can put a name to each item. Sometimes a bullet list is better, or a numbered list. You can mix and match these:
+
+- Bullet list, indicated with either a `-` or a `*` or a `+` at the start of the line.
+- Another item.
+- A third item. We can also make sub-items, either bullets or numbers:
+    1. A numbered sub-item. Number list items are written either `1.` or `1)`.
+    2. The numbers are increased automatically from the first one.
+- A fourth bullet item. This marks the end of the list.
+
+23. Let's create a numbered list that starts on the number 23.
+1. Another item. Note that this gets the number 24 no matter what I type.
+0. And this gets the number 25 no matter what I type.
+
+Definition lists are good for free flow explanation of things. Sometimes a table would do the job better though. Left-aligned:
+
+| Shortcut                  | Purpose               | Context        |
+| ------------------------- | --------------------- | -------------- |
+| <kbd>F11</kbd>            | Toggle fullscreen     | In application |
+| <kbd>⌘ + T</kbd>         | Open a new tab        | In application |
+| <kbd>⌘ + Shift + N</kbd> | New incognito window  | In application |
+
+Or right-aligned
+
+| Shortcut                  | Purpose               | Context        |
+| ------------------------: | --------------------: | -------------: |
+| <kbd>F11</kbd>            | Toggle fullscreen     | In application |
+| <kbd>⌘ + T</kbd>         | Open a new tab        | In application |
+| <kbd>⌘ + Shift + N</kbd> | New incognito window  | In application |
+
+
+## Notes and images
+
+There are two types of notes that you can insert into the text. Since this is not a printed medium the idea of a footnote doesn't really work. Instead we keep the notes together with the text. Use the `::: sidenote` block for these.
+
+::: sidenote
+The `::: sidenote` block is good for adding footnote-like information to the text. It can be used to add further explanation that is not vital or point to other resources. They are shown to the side of the text they precede.
+:::
+
+When you really want to make the user aware of something, use the `::: important` block:
+
+::: important
+This is a block of text that the user will not miss. Use these sparingly for things that really needs a lot of attention. If you find that your document is littered with these, you might want to group the information a bit.
+:::
+
+Images are inserted into the document like this:
+
+![A large image of sorts](images/test/large.png)
+
+![A small image of sorts](images/test/tiny.png){.left} An image that is put at the start of a paragraph---inline with a class `.left`. This is useful for small images like icons and the like. The rendering of these is not optimal since the image size is needed to figure out image placement in relation to the text. Still, in some cases it can be useful, for paragraph decoration or similar.
+
+![A small image of sorts](images/test/tiny.png){.right} An image that is put at the start of a paragraph---inline with a class `.right`. This is useful for small images like icons and the like. The rendering of these is not optimal since the image size is needed to figure out image placement in relation to the text. Still, in some cases it can be useful, for paragraph decoration or similar.
+
+![A small icon](images/test/icon.svg){.icon} Images with class `.icon` are rendered inline aligned with the text. Use this to insert really small images (like ![A small icon](images/test/icon.svg){.icon}) into running text.
+
+Note that images are usually rendered centered in their own paragraph. Apply class `.inline` for inline behavior if you have several images as part of the same paragragh and you want to line up several images like this:
+
+![A small image of sorts](images/test/small.png){.inline}
+![A small image of sorts](images/test/small.png){.inline}
+
+## Transclusion
+
+Pieces of text that are used in multiple places can be transcluded into a document. See https://github.com/jamesramsay/hercule for details on the transcluder plugin used.
+
+:[link](../shared/test.md)
+
+The end

+ 34 - 0
docs/zh/manuals/texture-filtering.md

@@ -0,0 +1,34 @@
+---
+title: 纹理过滤
+brief: 本教程介绍了渲染图像时纹理过滤的功能.
+---
+
+# 纹理过滤和采样
+
+纹理过滤决定了当一个 _texel_ (图素, 纹理中的一个像素) 与屏幕像素不是完美对齐时的视觉效果. 当可视元素移动小于1个像素的时候就会发生这种现象. 可以选择以下的过滤方式:
+
+Nearest
+: 屏幕像素颜色选取自距离最近的图素. 这样就实现了从纹理到屏幕的像素对齐. 这种过滤模式使得像素移动类似于自动吸附. 要是Sprite移动很慢, 可能会感觉一跳一跳的.
+
+Linear
+: 屏幕像素颜色取决于图素及其旁边图素的颜色的平均值. 这样缓慢的移动能显得十分平滑, 因为渲染之前Sprite的颜色已经与周围进行了融合--所以移动小于一个像素距离也是可以的.
+
+过滤设置保存在 [项目设置](/manuals/project-settings/#graphics) 文件里. 一共有两项:
+
+default_texture_min_filter
+: 当图素小于屏幕像素大小, 要缩小时使用的过滤效果.
+
+default_texture_mag_filter
+: 当图素大于屏幕像素大小, 要放大时使用的过滤效果.
+
+这两项取值都是 `linear` 或者 `nearest`. 比如:
+
+```ini
+[graphics]
+default_texture_min_filter = nearest
+default_texture_mag_filter = nearest
+```
+
+如果不赋值, 默认都是 `linear`.
+
+注意 "game.project" 由默认采样器使用. 如果你在自定义材质里指定了特殊的采样器, 可以对每个采样器采用不同的过滤方法. 详情请见 [材质教程](/manuals/material/).

+ 12 - 7
docs/zh/manuals/texture-profiles.md

@@ -1,15 +1,16 @@
 ---
-title: Defold 里的纹理档案
-brief:  Defold 支持自动纹理处理和图片数据压缩. 本教程介绍这些功能.
+title: Texture profiles in Defold
+brief:  Defold supports automatic texture processing and compression of image data. This manual describes the available functionality.
 ---
 
 # Texture profiles
 
-Defold 支持自动纹理处理和图片数据压缩 (用于 *Atlas*, *Tile sources*, *Cubemaps* 和模型贴图, GUI 等).
+Defold supports automatic texture processing and compression of image data (in *Atlas*, *Tile sources*, *Cubemaps* and stand-alone textures used for models, GUI etc).
 
-压缩有两种类型,软件图像压缩和硬件纹理压缩:
+There are two types of compression, software image compression and hardware texture compression.
+
+1. Software compression (such as PNG and JPEG) reduces the storage size of image resources. This makes the the final bundle size smaller. However, the image files need to be uncompressed when read into memory so even though an image is small on disk, it can have a large memory footprint.
 
-1.软件压缩(例如PNG和JPEG)可减小图像资源的大小。这使最终的打包尺寸更小。但是,图像文件在读入内存时需要解压缩,因此即使图像在磁盘上很小,它也可能占用很大的内存。
 2. Hardware texture compression also reduces the storage size of image resources. But, unlike software compression, it reduces the in-memory footprint for textures. This is because the graphics hardware is able to directly manage compressed textures without first having to uncompress them.
 
 The processing of textures is configured through a specific texture profile. In this file you create _profiles_ that express what compressed format(s) and type should be used when creating bundles for a specific platform. _Profiles_ are then tied to matching file _paths patterns_, allowing fine tuned control over what files in your project should be compressed and exactly how.
@@ -64,19 +65,23 @@ This example contains two path patterns and their corresponding profiles.
 `/**/*.atlas`
 : All *.atlas* files anywhere in the project will be process according to the profile "atlas".
 
-Note that the more generic path is put last. The matcher works top down. The first occurence that matches the resource path will be used. A matching path expression further down the list never overrides the first match. Had the paths been put in the opposite order every atlas would have been processed with profile "atlas", even the ones in directory */gui*.
+Note that the more generic path is put last. The matcher works top down. The first occurrence that matches the resource path will be used. A matching path expression further down the list never overrides the first match. Had the paths been put in the opposite order every atlas would have been processed with profile "atlas", even the ones in directory */gui*.
 
 Texture resources that _do not_ match any path in the profiles file will be compiled and rescaled to the closest power of 2, but will otherwise be left intact.
 
 ## Profiles
 
-The *profiles* section of the texture profiles file contains a list of named profiles. Each profile contains one or more *plaforms*, each platform being described by a list of properties.
+The *profiles* section of the texture profiles file contains a list of named profiles. Each profile contains one or more *platforms*, each platform being described by a list of properties.
 
 ![Profiles](images/texture_profiles/texture_profiles_profiles.png)
 
 *Platforms*
 : Specifies a matching platform. `OS_ID_GENERIC` matches all platforms including dev-app builds on device, `OS_ID_WINDOWS` matches Windows target bundles, `OS_ID_IOS` matches iOS bundles and so on. Note that if `OS_ID_GENERIC` is specified, it will be included for all platforms.
 
+::: important
+If two [path settings](#path-settings) matches the same file and the path uses different profiles with different platforms **both** profiles will be used and **two** texture will be generated.
+:::
+
 *Formats*
 : One or more texture formats to generate. If several formats are specified, textures for each format are generated and included in the bundle. The engine selects textures of a format that is supported by the runtime platform.
 

+ 39 - 2
docs/zh/manuals/tilemap.md

@@ -5,7 +5,7 @@ brief: 本教程介绍了 Defold 对于瓷砖地图的支持.
 
 # Tile map (瓷砖地图)
 
-*瓷砖地图* 是一个可以借由瓷砖图源装配, 绘制成一个大网格地图的组件. 瓷砖地图一般用来作为游戏关卡环境. 你可以在地图上使用瓷砖图源里设置的 *碰撞形状* 来进行碰撞检测或者模拟物理效果.
+*瓷砖地图* 是一个可以借由瓷砖图源装配, 绘制成一个大网格地图的组件. 瓷砖地图一般用来作为游戏关卡环境. 你可以在地图上使用瓷砖图源里设置的 *碰撞形状* 来进行碰撞检测或者模拟物理效果 ([example](/examples/tilemap/collisions/)).
 
 创建瓷砖地图之前要先创建好瓷砖图源. 关于如何创建瓷砖图源, 详情请见 [瓷砖图源教程](/manuals/tilesource).
 
@@ -46,7 +46,11 @@ brief: 本教程介绍了 Defold 对于瓷砖地图的支持.
 
 ![使用瓷砖地图](images/tilemap/use_tilemap.png){srcset="images/tilemap/[email protected] 2x"}
 
-## 用脚本更改瓷砖
+## 运行时操作
+
+有一套用于在运行时修改瓷砖地图的方法和属性 (参见 [API文档](/ref/tilemap/)).
+
+### 用脚本更改瓷砖
 
 游戏运行时可以使用脚本动态读写瓷砖地图的内容. 通过调用 [`tilemap.get_tile()`](/ref/tilemap/#tilemap.get_tile) 和 [`tilemap.set_tile()`](/ref/tilemap/#tilemap.set_tile) 函数:
 
@@ -58,3 +62,36 @@ if tile == 2 then
     tilemap.set_tile("/level#map", "ground", x, y, 4)
 end
 ```
+
+## 瓷砖地图属性
+
+除了 *Id*, *Position*, *Rotation* 和 *Scale*, 瓷砖地图还有如下属性:
+
+*Tile Source*
+: 瓷砖地图的图源.
+
+*Material*
+: 瓷砖地图的材质.
+
+*Blend Mode*
+: 瓷砖地图的混合模式.
+
+### 混合模式
+:[blend-modes](../shared/blend-modes.md)
+
+### 修改属性
+
+使用 `go.get()` 和 `go.set()` 方法可以修改瓷砖地图的属性:
+
+`tile_source`
+: 瓷砖图源 (`hash`). 可以使用 `go.set()` 方法指定瓷砖图源. 参见 [这个例子的 API 用法](/ref/tilemap/#tile_source).
+
+`material`
+: 瓷砖地图材质 (`hash`). 可以使用 `go.set()` 方法指定瓷砖地图材质. 参见 [这个例子的 API 用法](/ref/tilemap/#material).
+
+### 材质属性
+
+材质可以使用 `tilemap.set_constant()` 和 `tilemap.reset_constant()` 方法设置和重置一系列属性 (详情参见 [材质教程](/manuals/material/#vertex-and-fragment-constants)):
+
+`tint`
+: 瓷砖地图染色 (`vector4`). 四元数 x, y, z, 和 w 代表染色的红, 绿, 蓝 和不透明度. 参见 [这个例子的 API 用法](/ref/tilemap/#tilemap.set_constant:url-constant-value).

+ 1 - 1
docs/zh/manuals/tilesource.md

@@ -5,7 +5,7 @@ brief: 本教程介绍了如何使用瓷砖图源资源.
 
 # Tile Source
 
-[Tilemap 组件](/manuals/tilemap) 使用 *瓷砖图源* 来绘制瓷砖地图也可以由 [Sprite](/manuals/sprite) 或 [粒子系统组件](/manuals/particlefx) 来使用. 瓷砖地图还可以使用瓷砖图源里的 *碰撞形状*  [碰撞检测和物理模拟](/manuals/physics).
+[Tilemap 组件](/manuals/tilemap) 使用 *瓷砖图源* 来绘制瓷砖地图也可以由 [Sprite](/manuals/sprite) 或 [粒子系统组件](/manuals/particlefx) 来使用. 瓷砖地图还可以使用瓷砖图源里的 *碰撞形状*  [碰撞检测和物理模拟](/manuals/physics) ([example](/examples/tilemap/collisions/))..
 
 ## 创建 Tile Source
 

+ 124 - 0
docs/zh/manuals/web-monetization.md

@@ -0,0 +1,124 @@
+---
+title: Web Monetization in Defold
+brief: Web Monetization is an exciting new and non-intrusive way for game developers to monetize their web games while at the same time offering premium content to their paying players.
+---
+
+# Web Monetization
+
+[Web Monetization](https://webmonetization.org/) is an open technology that allows someone viewing a webpage or playing a web game to stream very small payments (micropayments) to the creator in real time. It is an exciting new and non-intrusive way for game developers to monetize their web games while at the same time offering premium content to their paying players.
+
+Web Monetization is being [proposed as a W3C standard](https://discourse.wicg.io/t/proposal-web-monetization-a-new-revenue-model-for-the-web/3785). It is based on the [Interledger](https://interledger.org/) protocol which is an open, neutral protocol for transferring money of any currency, including digital currencies such as Bitcoin.
+
+
+## How does it work?
+
+Three things are required in order to send and receive payments:
+
+1. A player must have an account with a **Web Monetization Provider** - The provider streams payments from the player.
+2. The developer must have a **Web Monetization Wallet** - The wallet holds received payments.
+3. The developer must add a **Payment Pointer** on the webpage containing content that should be monetized - The payment pointer tells the provider which wallet to send the money to.
+
+
+### Web Monetization Providers
+
+Players must have an account with a Web Monetization Provider to be able to stream payments to game developers:
+
+[![Coil logo](images/web-monetization/coil_logo.svg)](https://coil.com)
+
+Coil is currently the only provider but others will likely be available in the future
+
+
+### Web Monetization Wallets
+
+Game developers must have a Web Monetization enabled wallet to hold received payments. There are several different services which provide wallets with support for Web Monetization:
+
+[![Uphold logo](images/web-monetization/uphold_logo.svg)](https://www.uphold.com/signup)
+
+[![GateHub logo](images/web-monetization/gatehub_logo.svg)](https://gatehub.net)
+
+[![Stronghold logo](images/web-monetization/stronghold_logo.svg)](https://stronghold.co/real-time-payments#coil)
+
+
+### Payment Pointers
+
+The wallet provider will assign a payment pointer to the wallet. The payment pointer is a public address for a wallet that can be shared with anyone that wants to make a payment to the owner of the wallet. Learn more at [paymentpointers.org](https://paymentpointers.org/). The format of a payment pointer is similar to a URL, but starts with a $:
+
+```
+$ilp.uphold.com/QkG86UgXzKq8
+```
+
+The payment pointer is added to the website content using a `<meta>` tag in the `<head>` of the website:
+
+```html
+<meta name="monetization" content="$ilp.uphold.com/QkG86UgXzKq8">
+```
+
+
+## How to set up Web Monetization in Defold
+
+Enabling Web Monetization in a Defold game is a straightforward process. The steps involved depend on if you are adding Web Monetization to an existing project or if you are starting a new project.
+
+
+### Starting a new project
+
+If you are starting a new project it is recommended that you use the Web Monetization project template from the Defold editor Welcome screen. The Web Monetization template includes the [Web Monetization extension](https://github.com/defold/extension-webmonetization) and it will automatically set up the payment pointer in the generated webpage for your game:
+
+![Web Monetization template](images/web-monetization/web-monetization-template.png)
+
+Next step is to register for a [Web Monetization enabled wallet](/manuals/web-monetization/#web-monetization-wallets) and add your payment pointer to the Web Monetization section of the **game.project** file:
+
+![Adding payment pointer to game.project](images/web-monetization/payment-pointer.png)
+
+
+### Adding Web Monetization to an existing project
+
+Start by registering for a [Web Monetization enabled wallet](/manuals/web-monetization/#web-monetization-wallets) and add your payment pointer to the webpage:
+
+```html
+<meta name="monetization" content="YOUR_PAYMENT_POINTER">
+```
+
+Next you need to add the [Web Monetization extension](https://github.com/defold/extension-webmonetization) as a [project dependency](http://www.defold.com/manuals/libraries/). Open the **game.project** file and in the [Dependencies field in the Project section](https://defold.com/manuals/project-settings/#dependencies) add:
+
+```
+https://github.com/defold/extension-webmonetization/archive/master.zip
+```
+
+
+## How to use Web Monetization in Defold
+
+When you have the Web Monetization extension and payment pointer added to your project you are ready to start using Web Monetization in your game. The API consosts of only two functions:
+
+Check if a player is monetized (ie is streaming payments to you):
+
+```lua
+local monetized = webmonetization.is_monetized()
+if monetized then
+	print("The user has an active payment stream")
+end
+```
+
+Set up a listener to get updates on the current monetization state of the player:
+
+```lua
+webmonetization.set_listener(function(self, event)
+	if event == webmonetization.EVENT_PENDING then
+		print("The user is trying to make a first payment")
+	elseif event == webmonetization.EVENT_START then
+		print("The user has started paying")
+	elseif event == webmonetization.EVENT_PROGRESS then
+		print("The user is still paying")
+	elseif event == webmonetization.EVENT_STOP then
+		print("The user has stopped paying")
+	end
+end)
+```
+
+
+## Best practices
+
+* Offer exclusive content to web monetized players. What you offer depends on the type of game. Some examples:
+  * New skins or other cosmetic changes such as unique in-game decals or stickers
+  * New game modes
+  * Additional levels
+* If your game contains ads you should also consider removing the ads for web monetized players

+ 7 - 0
docs/zh/manuals/websocket-connections.md

@@ -0,0 +1,7 @@
+---
+title: WebSocket connections
+brief: This manual explains how to use WebSocket connections.
+---
+## WebSocket connections
+
+Defold doesn't contain any out of the box solution for creating WebSocket connections. For WebSocket connectivity it is recommended to use the [Defold-WebSocket extension](https://defold.com/assets/websocket/).

+ 22 - 35
docs/zh/manuals/webview.md

@@ -1,69 +1,56 @@
 ---
 title: Defold 的 WebViews
-brief: "WebViews allows you to load and display web pages as overlays in your mobile games. They can
-        also run user supplied JavaScript in the background. This manual explains Defold's official
-        WebView extension, API and functionality."
+brief: "WebViews 可以在你的手机上显示一个网页层. 同时支持在后台运行用户定义的js代码. 本教程介绍了 Defold 的官方 WebView 扩展, API 和功能."
 ---
 
 # WebViews
-The WebView extension provides a unified API to load and display web pages as overlays on mobile
-platforms. In this manual we will first go through some basic information how to create and show a webview.
-Later on we will explore more functionality by implementing a simple player feedback window.
+WebView 提供了一套特殊的 API 用来在手机上显示一个网页层. 首先让我们来实现一个简单的 webview.
+然后我们会讨论如何使用一套简单的控制按钮控制这个 webview.
 
-## Installing the extension
+## 安装扩展
 
-To start using the webview extension you need to add it as a dependency to your `game.project` file.
-The latest stable version is available with the dependency URL:
+在你的 `game.project` 文件中设置 webview 依赖.
+最新版本位于如下 URL:
 ```
 https://github.com/defold/extension-webview/archive/master.zip
 ```
 
-Documentation of the API is available on [extension GitHub page](https://defold.github.io/extension-webview/).
+API文档位于 [扩展首页](https://defold.github.io/extension-webview/).
 
-## Opening a WebView
-Opening a webview is a simple call to `webview.create`, which will return an identification number
-associated with the newly created webview. This ID, which we will call `webview_id` from now on,
-will be used in other `webview` functions to interact with the specific webview instance. This means
-you can create and maintain multiple webviews simultaneously.
+## 打开 webview
+使用 `webview.create` 就能创建一个网页层, 并且返回一个唯一id. 下文中我们把这个 ID 称为 `webview_id`,
+多个 `webview` 之间进行交互时会用到这个id. 也就是说创建和维护多个 webview 是可行的.
 
-The `webview.create` function takes a single argument in the form of a function, we will take a
-closer look at this in the callbacks section below, for now let's just pass in an empty function.
+`webview.create` 带着一个函数参数, 待会儿我们再来仔细看看这个回调, 现在先给它留空.
 ```lua
 local webview_id = webview.create(function()
-        -- do nothing for now
+        -- 目前无代码
     end)
 ```
-Newly created webviews are hidden by default and doesn't actually load anything. But a webview isn't
-much fun without anything to show, so let's load one of our favorite web pages!
+默认状况下新建的 webview 都是不可见的, 因为它还没有加载任何内容. 其主要功能就是显示网页, 现在就来加载个超酷的网页吧!
 
-To open a web page we need to call the function `webview.open` and pass along the `webview_id` we
-got from the previous call and a web URL as the second argument.
+调用 `webview.open` 函数, 第一个参数就是上文的那个 `webview_id`, 第二个参数是要打开的URL.
 
 ```lua
-local request_id = webview.open(webview_id, "http://www.defold.com")
+local request_id = webview.open(webview_id, "http://www.defold.com") --广告无处不在
 ```
 
-The call will return a new id that can be used to keep track of the URL request, it will also be
-provided in the callback which we will go into detail about below.
+这个函数返回网页请求的id, 这个id我们稍后也会用到.
 
-If everything was successful you should now see a webview covering the full screen, it will also
-load the Defold official website.
+如果一切顺利你将看到神奇的网页占满了屏幕, 就是 Defold 官方首页.
 
-::: important
-To load arbitrary URL on iOS you need to add the following key-value inside the
-`NSAppTransportSecurity` dictionary entry in your `Info.plist` file.
+::: 注意
+要在 iOS 里访问的网页必须遵循在 `Info.plist` 文件中的 `NSAppTransportSecurity` 里面设置好的键值对.
 ```
 <key>NSAllowsArbitraryLoads</key>
 <true/>
 ```
 
-This is a valid setting to use while developing your game, but when releasing on the App Store it
-preferred to only allow specific domains by utilizing the `NSExceptionDomains` key instead. These
-options are a bit outside the scope of this manual, but more detailed information can be found
-in the [Apple Developer documentation](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW35).
+开发的时候可以随便设置, 但是发布到 App Store 之后就只能通过使用 `NSExceptionDomains` 键代替. 这有点超出本教程讨论范围,
+详情可以参考 [Apple 开发者文档](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW35).
 :::
 
-## Callback
+## 回调函数
 Just opening web pages inside a webview might be sufficient in most cases, but what happens if the
 URL isn't accessible or something unforeseen happens while loading? Perhaps we want to show a
 notification to the user if we encounter an error, or we want to perform some action if a user

+ 2 - 3
docs/zh/manuals/windows.md

@@ -17,6 +17,5 @@ Windows游戏的图标要使用 .ico 格式. 你可以拿一个 .png 文件, 使
 
 ![Windows icon sizes](images/windows/windows-icon.png)
 
-## Facebook Gameroom
-
-Facebook Gameroom 是全世界都可以免费下载的 Windows 原生游戏客户端. 使用Facebook Gameroom, 玩家可以玩各种网页游戏和各种平台定制游戏. 在编译 Windows 项目时, 在*game.project*文件里有一个选项是选择是否支持 Gameroom . Facebook Gameroom 详情请见 [Gameroom 教程](/manuals/gameroom).
+## FAQ
+:[Windows FAQ](../shared/windows-faq.md)

+ 55 - 0
docs/zh/manuals/working-offline.md

@@ -0,0 +1,55 @@
+---
+title: 断网工作
+brief: 此教程介绍了在离线状态下使用依赖库尤其是使用原生扩展的方法
+---
+
+# 断网工作
+
+Defold 在大多数情况下不需要网络连接. 然而下面几种情况下必须有网络连接:
+
+* 自动更新
+* 问题反馈
+* 下载依赖库
+* 编译原生扩展
+
+
+## 自动更新
+
+Defold 定期查找是否存在更新版本. Defold 查找新版本时会连接 [官方下载地址](https://d.defold.com). 如果找到更新版本会给与用户提示以方便下载.
+
+要是你的网络流量吃紧或者不太关心最新版本, 也可以手动从 [官方下载地址](https://d.defold.com) 下载 Defold.
+
+
+## 问题反馈
+
+如果编辑器发现了错误就会弹出错误报告框让用户选择是否把错误内容回报给 Defold 官方. 错误跟踪表 [存储在 GitHub 上](https://www.github.com/defold/editor2-issues), 所以回报问题时需要联网.
+
+如果在离线状态下遇到错误还可以使用编辑器的 [帮助菜单下的回报错误按钮](/manuals/getting-help/#report-a-problem-from-the-editor) 提交错误报告.
+
+
+## 下载依赖
+
+Defold 支持通过一个叫做 [库项目](/manuals/libraries/) 的功能共享代码和资源. 库被保存为zip文件存放在网络上. 一般 Defold 库项目都保存在 GitHub 和各个代码托管平台上.
+
+在项目设置里可以添加库 [作为项目依赖](/manuals/project-settings/#dependencies). 当项目开启或者 *Project* 菜单栏下的 *Fetch Libraries* 被点选时, Defold 会自动进行项目依赖的下载/更新.
+
+如果必须团队离线工作, 建议把共享依赖存放在本地共享服务器上. GitHub 上的依赖库文件一般都在其发布页面:
+
+![GitHub Library URL](images/libraries/libraries_library_url_github.png)
+
+可以使用 Python 方便地创建简单的本地服务器:
+
+    python -m SimpleHTTPServer
+
+这条命令会在当前文件夹建立本地服务器并且在 `localhost:8000` 地址进行共享服务. 如果这个目录下存放了共享库文件, 就可以在 *game.project* 文件里像这样添加依赖:
+
+    http://localhost:8000/extension-fbinstant-4.1.1.zip
+
+
+## 编译原生扩展
+
+Defold 支持开发者通过一个叫做 [Native Extensions](/manuals/extensions/) 的功能, 使用原生代码扩展引擎功能. Defold 使用云端构建方案以方便开发者编译自己的原生扩展程序.
+
+当第一次编译带原生扩展代码的项目时, 代码会被传送至云端编译服务器编译成用户自定义 Defold 游戏引擎然后再发回给你的电脑. 这个自定义引擎会被缓存在你的项目中随时调用, 直到原生代码被修改需要重新编译.
+
+如果必须离线工作而你的项目又包含原生扩展就要确保至少通过云端编译成功一次, 在你的本地缓存了自定义引擎才能正常工作.

+ 15 - 0
docs/zh/shared/android-faq.md

@@ -0,0 +1,15 @@
+#### Q: 安卓系统有办法隐藏导航栏和状态栏吗?
+A: 有, 在你的 *game.project* 文件的 *Android* 部分的 *immersive_mode* 项. 这项可以使你获得全部的屏幕及屏幕触摸事件.
+
+
+#### Q: 在设备上安装 Defold 游戏时总是出现 "Failure [INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES]" 错误?
+A: 安卓系统发现你的更新app使用了新的证书. 打包调试版本时, 使用的是一个临时证书. 所以在更新版本前要删除旧版本:
+
+```
+$ adb uninstall com.defold.examples
+Success
+$ adb install Defold\ examples.apk
+4826 KB/s (18774344 bytes in 3.798s)
+      pkg: /data/local/tmp/Defold examples.apk
+Success
+```

+ 13 - 0
docs/zh/shared/blend-modes.md

@@ -0,0 +1,13 @@
+*Blend Mode* 属性定义了可视组件如何与其后面的图像混合. 以下列举了支持的混合模式及其混合算法:
+
+Alpha
+: 普通混合: a~0~ * rgb~0~ + (1 - a~0~) * rgb~1~
+
+Add
+: 使用相应的 sprite 像素颜色值提亮背景: rgb~0~ + rgb~1~
+
+Add Alpha (废弃!)
+: 使用相应的可见 sprite 像素颜色值提亮背景: a~0~ * rgb~0~ + rgb~1~
+
+Multiply
+: 使用相应的 sprite 像素颜色值调暗背景: rgb~0~ * rgb~1~

+ 24 - 0
docs/zh/shared/components.md

@@ -0,0 +1,24 @@
+组件是用来给与游戏对象各种功能与表现的程序. 组件位于游戏对象之下, 游戏对象受控于组件:
+
+![Components](../shared/images/components.png){srcset="../shared/images/[email protected] 2x"}
+
+许多组件含有某些属性是可以在运行时控制的, 根据组件属性的不同类型, 调用交换的函数也不一样:
+
+```lua
+-- 关闭 "body" 精灵
+msg.post("can#body", "disable")
+
+-- 1 秒以后在 "bean" 上播放 "hoohoo" 声音
+sound.play("bean#hoohoo", { delay = 1, gain = 0.5 } )
+```
+
+组件要么直接依附于游戏对象, 要么作为一个文件被游戏对象引用:
+
+<kbd>右键点击</kbd> *Outline* 视图里的游戏对象, 选择 <kbd>Add Component</kbd> (直接依附) 或者 <kbd>Add Component File</kbd> (引用文件).
+
+一般认为直接依附就够了, 但是以下组件类型必须保存为各种不同的文件以便被游戏对象引用:
+
+* Script
+* GUI
+* Particle FX
+* Tile Map

+ 11 - 0
docs/zh/shared/editor-versions.md

@@ -0,0 +1,11 @@
+## 1代编辑器与2代编辑器
+
+目前我们正关注于开发 Defold 编辑器的2代版本, 目前还是测试阶段. 我们发布的文档绝大多数都是针对2代编辑器的, 而且这些文档也会定期更新, 但不是短时间能做完的事. 看颜色就知道打开的是哪个版本.
+
+2代版本选用了漂亮的暗色主题:
+![editor 2](../shared/images/editor2.png)
+
+1代版本还是普通的白色窗口:
+![editor 1](../shared/images/editor1.png)
+
+欢迎 [尝试新版本](https://www.defold.com/editor-two/).

+ 0 - 0
docs/zh/shared/editor-views.md


+ 7 - 0
docs/zh/shared/html5-faq.md

@@ -0,0 +1,7 @@
+#### Q: 我的HTML5游戏在Chrome里一到溅射屏幕就卡死了?
+
+A: 很多浏览器不允许从本地磁盘文件来启动程序. 从编辑器里运行就能自动生成临时本地服务器. 另外, 你也可以使用 Python 之类的程序快速搭建本地服务器 SimpleHTTPServer:
+
+```sh
+$ python -m SimpleHTTPServer [port]
+```

+ 63 - 0
docs/zh/shared/install.md

@@ -0,0 +1,63 @@
+## 下载
+
+上 [Defold 下载页](https://defold.com/download/) 就能看到许多操作系统对应版本的下载按钮 macOS, Windows 还有 Linux (Ubuntu) 的:
+
+![download editor](../shared/images/editor_download.png)
+
+## 安装
+
+在 macOS 上安装
+: 下载完成后是一个 DMG 镜像文件.
+
+  1. 双击 "Defold-x86_64-darwin.dmg" 开启镜像打开文件夹.
+  2. 把 "Defold" 拖拽到 "Applications" 文件夹里去.
+
+  打开 "Applications" 文件夹 <kbd>双击</kbd> "Defold" 文件即可启动.
+
+  ![Defold macOS](../shared/images/macos_content.png)
+
+在 Windows 上安装
+: 下载完成后是一个 ZIP 压缩档案:
+
+  1. 在文件资源管理器中找到 "Defold-x86_64-win32.zip" (32位是 "Defold-x86-win32.zip") 文件, <kbd>右键点击</kbd> 选择 *解压到当前位置*, 就会解压缩出来一个 "Defold" 文件夹.
+  2. Move the folder "Defold" to "C:\Program Files (x86)\"
+
+  打开 "Defold" 文件夹, <kbd>双击</kbd> "Defold.exe" 文件即可启动.
+
+  ![Defold windows](../shared/images/windows_content.png)
+
+在 Linux 上安装
+: 下载完成后是一个 ZIP 压缩档案:
+
+  1. 在控制台里找到 "Defold-x86_64-linux.zip" 文件, 解压出 "Defold" 文件夹来.
+
+     ```bash
+     $ unzip Defold-x86_64-linux.zip -d Defold
+     ```
+
+  控制台进入文件夹直接启动 `Defold` 可执行文件, 或者在桌面程序上 <kbd>双击</kbd> 它即可启动.
+
+  ```bash
+  $ cd Defold
+  $ ./Defold
+  ```
+
+  如果遇到问题, 请参考 [FAQ 的 Linux 部分](/faq/faq#linux-issues).
+
+## 安装老版本
+
+### 从 Defold GitHub 发布页下载
+
+Defold 各版本也 [发布在 GitHub 上](https://github.com/defold/defold/releases).
+
+### 从 Defold 下载页下载
+
+下载链接遵循以下模式:
+
+* Windows: https://d.defold.com/archive/%sha1%/stable/editor2/Defold-x86_64-win32.zip
+* macOS: https://d.defold.com/archive/%sha1%/stable/editor2/Defold-x86_64-darwin.dmg
+* Linux: https://d.defold.com/archive/%sha1%/stable/editor2/Defold-x86_64-linux.zip
+
+把上面的 `%sha1%` 换成你需要的版本 hash. 这些 hash 可以在 https://d.defold.com/stable/ 上找到 (不要开头 # 号, 只要后面的字符):
+
+![download editor](../shared/images/old_version_sha1.png)

+ 55 - 0
docs/zh/shared/linux-faq.md

@@ -0,0 +1,55 @@
+#### Q: 在 GNOME 上使用 Defold 编辑器在 4k 或 HiDPI 显示器上显得特别小?
+
+A: 启动 Defold 之前修改缩放参数. [参见](https://unix.stackexchange.com/a/552411)
+
+```bash
+$ gsettings set org.gnome.desktop.interface scaling-factor 2
+```
+
+
+#### Q:在 Elementary OS 上使用 Defold 编辑器, 鼠标点选上的都是后面的东西?
+
+A: 尝试这样启动编辑器:
+
+```bash
+$ GTK_CSD=0 ./Defold
+```
+
+
+#### Q: 在新建, 打开项目时 Defold 编辑器崩溃?
+
+A: 某些版本 (比如 Ubuntu 18) 上 Defold 使用的 jogamp/jogl 版本与系统 Mesa 版本冲突.
+
+详情请见:
+
+  - https://github.com/defold/editor2-issues/issues/1905
+  - https://github.com/defold/editor2-issues/issues/1886
+
+使用如下代码可以绕过冲突:
+
+```bash
+$ export MESA_GL_VERSION_OVERRIDE=2.1
+$ ./Defold
+```
+
+如果问题没有解决可以尝试 (根据你自己的驱动匹配选取大于等于 2.1 的版本号):
+
+```bash
+$ export MESA_GL_VERSION_OVERRIDE=3.1
+$ ./Defold
+```
+
+
+#### Q: 在 Linux 上启动 Defold 游戏无效?
+
+A: 看看 Defold 编辑器控制台. 如果有下面这样的输出:
+
+```
+dmengine: error while loading shared libraries: libopenal.so.1: cannot open shared object file: No such file or directory
+```
+
+就需要安装 *libopenal1*. 不同版本包名不同, 另外某些用户也需要安装 *openal* 和 *openal-dev* 或者 *openal-devel* 包.
+
+```bash
+$ apt-get install libopenal-dev
+```

+ 13 - 0
docs/zh/shared/nintendo-switch-faq.md

@@ -0,0 +1,13 @@
+#### Q: 为什么开发任天堂游戏不免费?
+
+A: Defold 基金会的目标之一就是让 Defold 软件和代码面向全世界免费. 我们不会食言, 但是接入的任天堂 Switch SDK 是人家说了算. 也就是说对任天堂 Switch 的支持, 编辑器, 各种工具, 我们没法自己做出来. 同样 Defold 基金会的社区贡献者也没法自己做出来, 为了确保对任天堂平台的合法长远的技术支持, 就必须缴费了.
+
+
+#### Q: 做任天堂 Switch 游戏需要什么别的工具吗?
+
+A: 使用 Defold 编辑器和命令行工具都可以打包任天堂 Switch 游戏. 一旦你取得了任天堂平台开发资格, 关于如何调试游戏的方法也会发送给你.
+
+
+#### Q: 开发跨平台游戏加上任天堂 Switch 游戏, 代码库够用吗?
+
+A: 够用, 所有标准 Defold API 功能在任天堂 Switch 平台同样有效. 除此之外也许需要调用一些任天堂 Switch 的原生功能, 但总体上讲一套代码跨平台没问题.

+ 3 - 0
docs/zh/shared/platforms.md

@@ -0,0 +1,3 @@
+支持的系统有 `ios`, `android`, `osx`, `win32`, `linux`, `web`.
+
+支持的 `arc-platform` 平台架构有 `armv7-ios`, `arm64-ios`, `x86_64-ios`, `armv7-android`, `arm64-android`, `x86-osx`, `x86_64-osx`, `x86-win32`, `x86_64-win32`, `x86_64-linux`, `js-web` 和 `wasm-web`.

+ 5 - 0
docs/zh/shared/test.md

@@ -0,0 +1,5 @@
+This file can be used to test transclusion. This whole file will be transcluded as is, with whitespace preservation.
+
+Note that any file references need are relative to the document where the file is inserted.
+
+![shared image](../shared/images/logo.png)

+ 17 - 0
docs/zh/shared/url-shorthands.md

@@ -0,0 +1,17 @@
+  `.`
+  : 指代当前游戏对象.
+
+  `#`
+  : 指代当前组件.
+
+  举例:
+
+  ```lua
+   -- 使当前游戏对象获得输入焦点
+   msg.post(".", "acquire_input_focus")
+  ```
+
+  ```lua
+   -- 向当前脚本组件发出 "reset" 信息
+   msg.post("#", "reset")
+  ```

+ 8 - 0
docs/zh/shared/windows-faq.md

@@ -0,0 +1,8 @@
+#### Q: 为什么编辑器中无纹理的 GUI box 节点透明显示, 但是构建运行后能正常显示?
+
+A: 这个错误发生在 [使用 AMD Radeon GPU 的机器](https://github.com/defold/editor2-issues/issues/2723) 上. 注意更新显卡驱动.
+
+
+#### Q: 编辑器无法启动, 日志显示 "Caused by: java.awt.AWTError: Assistive Technology not found: com.sun.java.accessibility.AccessBridge" 错误
+
+A: 这个错误源于 Java 辅助技术, 比如 [NVDA screen reader](https://www.nvaccess.org/download/). 尝试删除用户文件夹下的 `.accessibility.properties` 文件. 参考 [Defold 论坛上的这个帖子](https://forum.defold.com/t/editor-endless-loading-windows-10-1-2-169-solved/65481/3?u=britzl).

+ 393 - 0
docs/zh/tutorials/15-puzzle.md

@@ -0,0 +1,393 @@
+---
+title: Building a 15 puzzle game in Defold
+brief: If you are new to Defold, this guide will help you to lab with a few of the building blocks in Defold and run script logic.
+---
+
+# The classic 15 puzzle
+
+This well-known puzzle became popular in America during the 1870s. The goal of the puzzle is to organize the tiles on the board by sliding them horizontally and vertically. The puzzle starts from a position where the tiles have been scrambled.
+
+The most common version of the puzzle shows the numbers 1--15 on the tiles. However, you can make the puzzle a bit more challenging by making the tiles part of an image. Before we begin, try to solve the puzzle. Click on a tile adjacent to the empty square to slide the tile to the empty position.
+
+## Creating the project
+
+1. Start Defold.
+2. Select *New Project* on the left.
+3. Select the *From Template* tab.
+4. Select *Empty Project*
+5. Select a location for the project on your local drive.
+6. Click *Create New Project*.
+
+Open the *game.project* settings file and set the dimensions of the game to 512⨉512. These dimensions will match the image you are going to use.
+
+![display settings](images/15-puzzle/display_settings.png)
+
+The next step is to download a suitable image for the puzzle. Pick any square image but make sure to scale it to 512 by 512 pixels. If you don't want to go out and search for an image, here's one:
+
+![Mona Lisa](images/15-puzzle/monalisa.png)
+
+Download the image, then drag it to the *main* folder of your project.
+
+## Representing the grid
+
+Defold contains a built-in *Tilemap* component that is perfect for visualizing the puzzle board. Tilemaps allow you to set and read individual tiles, which is all you need for this project.
+
+But before you create the tilemap, you need a *Tilesource* that the tilemap will pull its tile images from.
+
+<kbd>Right click</kbd> the *main* folder and select <kbd>New ▸ Tile Source</kbd>. Name the new file "monalisa.tilesource".
+
+Set the tile *Width* and *Height* properties to 128. This will split the 512⨉512 pixel image into 16 tiles. The tiles will be numbered 1--16 when you put them on the tilemap.
+
+![Tile source](images/15-puzzle/tilesource.png)
+
+Next, <kbd>Right click</kbd> the *main* folder and select <kbd>New ▸ Tile Map</kbd>. Name the new file "grid.tilemap".
+
+Defold needs you to initialize the grid. To do that, select the "layer1" layer and paint the 4⨉4 grid of tiles just to the top-right of origin. It does not really matter what you set the tiles to. You will write code in a bit that will set the content of these tiles automatically.
+
+![Tile map](images/15-puzzle/tilemap.png)
+
+## Putting the pieces together
+
+Open *main.collection*. <kbd>Right click</kbd> the root node in the *Outline* and select <kbd>Add Game Object</kbd>. Set the *Id* property of the new game object to "game".
+
+<kbd>Right click</kbd> the game object and select <kbd>Add Component File</kbd>. Select the file *grid.tilemap*.
+
+<kbd>Right click</kbd> the game object and select <kbd>Add Component ▸ Label</kbd>. Set the *Id* property of the label to "done" and its *Text* property to "Well done". Move the label to the center of the tilemap.
+
+Set the Z position of the label to 1 to make sure it's drawn on top of the grid.
+
+![Main collection](images/15-puzzle/main_collection.png)
+
+Next, create a Lua script file for the puzzle logic: <kbd>right click</kbd> the *main* folder and select <kbd>New ▸ Script</kbd>. Name the new file "game.script".
+
+Then <kbd>Right click</kbd> the game object called "game" in *main.collection* and select <kbd>Add Component File</kbd>. Select the file *game.script*.
+
+Run the game. You should see the grid as you drew it and the label with the "Well done" message on top.
+
+## The puzzle logic
+
+Now you have all the pieces in place so the rest of the tutorial will be spent putting together the puzzle logic.
+
+The script will carry its own representation of the board tiles, separate from the tilemap. That is because it is possible to make it easier to operate on. Instead of storing the tiles in a 2 dimensional array, the tiles are stored as a one dimensional list in a Lua table. The list contains the tile number in sequence, starting from the top left corner of the grid all the way to the bottom right:
+
+```lua
+-- The completed board looks like this:
+self.board = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0}
+```
+
+The code that takes such a list of tiles and draws it on our tilemap is pretty simple but needs to convert the position in the list to a x and y position:
+
+```lua
+-- Draw a table list of tiles onto a 4x4 tilemap
+local function draw(t)
+    for i=1, #t do
+        local y = 5 - math.ceil(i/4) -- <1>
+        local x = i - (math.ceil(i/4) - 1) * 4
+        tilemap.set_tile("#tilemap","layer1",x,y,t[i])
+    end
+end
+```
+1. In tilemaps, the tile with x-value 1 and y-value 1 is at the bottom left. Therefore the y position needs to be inverted.
+
+You can check that the function works as intended by creating a test `init()` function:
+
+```lua
+function init(self)
+    -- An inverted board, for test
+    self.board = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
+    draw(self.board)
+end
+```
+
+With the tiles in a Lua table list, scrambling the order is super easy. The code just runs through each element in the list and switches each tile with another randomly chosen tile:
+
+```lua
+-- Swap two items in a table list
+local function swap(t, i, j)
+    local tmp = t[i]
+    t[i] = t[j]
+    t[j] = tmp
+    return t
+end
+
+-- Randomize the order of a the elements in a table list
+local function scramble(t)
+    for i=1, #t do
+        t = swap(t, i, math.random(#t))
+    end
+    return t
+end
+```
+
+Before moving on, there's a thing about the 15 puzzle that you really need to consider: if you randomize the tile order like you are doing above, there is a 50% chance that the puzzle is *impossible* to solve.
+
+This is bad news since you definitely don't want to present the player with a puzzle that cannot be solved.
+
+Fortunately, it is possible to figure out whether a setup is solvable or not. Here's how:
+
+## Solvability
+
+In order to figure out if a position in a 4⨉4 puzzle is solvable, two pieces of information are needed:
+
+1. The number of "inversions" in the setup. An inversion is when a tile precedes another tile with a lower number on it. For example, given the list `{1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 11, 10, 13, 14, 15, 0}`, it has 3 inversions:
+
+    - the number 12 has 11 and 10 following it, giving 2 inversions.
+    - the number 11 has 10 following it, giving 1 more inversion.
+
+    (Note that the solved puzzle state has zero inversions)
+
+2. The row where the empty square is (denoted by `0` in the list).
+
+These two numbers can be calculated with the following functions:
+
+```lua
+-- Count the number of inversions in a list of tiles
+local function inversions(t)
+    local inv = 0
+    for i=1, #t do
+        for j=i+1, #t do
+            if t[i] > t[j] and t[j] ~= 0 then -- <1>
+                inv = inv + 1
+            end
+        end
+    end
+    return inv
+end
+```
+1. Note that the empty square does not count.
+
+```lua
+-- Find the x and y position of a given tile
+local function find(t, tile)
+    for i=1, #t do
+        if t[i] == tile then
+            local y = 5 - math.ceil(i/4) -- <1>
+            local x = i - (math.ceil(i/4) - 1) * 4
+            return x,y
+        end
+    end
+end
+```
+1. Y position from the bottom.
+
+Now, given these two numbers it is possible to tell if a puzzle state is solvable or not. A 4⨉4 board state is *solvable* if:
+
+- If the empty square is on an *odd* row (1 or 3 counting from the bottom) and the number of inversions is *even*.
+- If the empty square is on an *even* row (2 or 4 counting from the bottom) and the number of inversions is *odd*.
+
+## How does this work?
+
+Each legal move moves a piece by switching its place with the empty square either horizontally or vertically.
+
+Moving a piece horizontally does not change the number of inversions, nor does it change the row number where you find the empy square.
+
+Moving a piece vertically, however, changes the parity of the number of inversions (from odd to even, or from even to odd). It also changes the parity of the empty square row.
+
+For example:
+
+![sliding a piece](images/15-puzzle/slide.png)
+
+This move changes the tile order from:
+
+`{ ... 0, 11, 2, 13, 6 ... }`
+
+to
+
+`{ ... 6, 11, 2, 13, 0 ... }`
+
+The new state adds 3 inversions as follows:
+
+- The number 6 adds 1 inversion (the number 2 is now after 6)
+- The number 11 loses 1 inversion (the number 6 is now before 11)
+- The number 13 loses 1 inversion (the number 6 is now before 13)
+
+The possible ways the number of inversions can change by a vertical slide is by ±1 or ±3.
+
+The possible ways the empty square row can change by a vertical slide is by ±1.
+
+In the final state of the puzzle, the empty square is in the lower right corner (the *odd* row 1) and the number of inversions is the *even* value 0. Each legal move either leave these two values intact (horizontal move) or switches their polarity (vertical move). No legal move can ever make the polarity of the inversions and the empty square row *odd*, *odd* or *even*, *even*.
+
+Any puzzle state where the two numbers are both odd or both even is therefore impossible to solve.
+
+Here is the code that checks for solvability:
+
+```lua
+-- Is the given table list of 4x4 tiles solvable?
+local function solvable(t)
+    local x,y = find(t, 0)
+    if y % 2 == 1 and inversions(t) % 2 == 0 then
+        return true
+    end
+    if y % 2 == 0 and inversions(t) % 2 == 1 then
+        return true
+    end
+    return false    
+end
+```
+
+## User input
+
+The only thing left to do now is to make the puzzle interactive.
+
+Create an `init()` function that does all the runtime setup using the functions created above:
+
+```lua
+function init(self)
+    msg.post(".", "acquire_input_focus") -- <1>
+    math.randomseed(socket.gettime()) -- <2>
+    self.board = scramble({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0}) -- <3>
+    while not solvable(self.board) do -- <4>
+        self.board = scramble(self.board)
+    end
+    draw(self.board) -- <5>
+    self.done = false -- <6>
+    msg.post("#done", "disable") -- <7>
+end
+```
+1. Tell the engine that this game object should receive input.
+2. Seed the randomizer.
+3. Create an initial random state for the board.
+4. If the state is unsolvable, scramble again.
+5. Draw the board.
+6. Set a completion flag to track winning state.
+7. Disable the completion message label.
+
+Open */input/game.input_bindings* and add a new *Mouse Trigger*. Set the name of the action to "press":
+
+![input](images/15-puzzle/input.png)
+
+Go back to the script and create an `on_input()` function.
+
+```lua
+-- Deal with user input
+function on_input(self, action_id, action)
+    if action_id == hash("press") and action.pressed and not self.done then -- <1>
+        local x = math.ceil(action.x / 128) -- <2>
+        local y = math.ceil(action.y / 128)
+        local ex, ey = find(self.board, 0) -- <3>
+        if math.abs(x - ex) + math.abs(y - ey) == 1 then -- <4>
+            self.board = swap(self.board, (4-ey)*4+ex, (4-y)*4+x) -- <5>
+            draw(self.board) -- <6>
+        end
+        ex, ey = find(self.board, 0)
+        if inversions(self.board) == 0 and ex == 4 then -- <7>
+            self.done = true
+            msg.post("#done", "enable")
+        end
+    end
+end
+```
+1. If there is a mouse button press and the game is still running, do the following.
+2. Calculate the x and y square that the user has clicked.
+3. Find the current location of the empty (0) square.
+4. If the clicked square is on the square is right above, below, left or right of the empty one, do the following:
+5. Switch the tiles on the clicked square and the empty one.
+6. Redraw the updated board.
+7. If the number of inversions on the board is 0, meaning that everything is in the right order, and the empty square is at the rightmost column (it must be on the last row for the inversions to be 0) then the puzzle is solved so do the following:
+8. Set the completion flag.
+9. Enable/show the completion message.
+
+And that's it! You are done, the puzzle game is complete!
+
+## The complete script
+
+Here is the complete script code for reference:
+
+```lua
+local function inversions(t)
+    local inv = 0
+    for i=1, #t do
+        for j=i+1, #t do
+            if t[i] > t[j] and t[j] ~= 0 then
+                inv = inv + 1
+            end
+        end
+    end
+    return inv
+end
+
+local function find(t, tile)
+    for i=1, #t do
+        if t[i] == tile then
+            local y = 5 - math.ceil(i/4)
+            local x = i - (math.ceil(i/4) - 1) * 4
+            return x,y
+        end
+    end
+end
+
+local function solvable(t)
+    local x,y = find(t, 0)
+    if y % 2 == 1 and inversions(t) % 2 == 0 then
+        return true
+    end
+    if y % 2 == 0 and inversions(t) % 2 == 1 then
+        return true
+    end
+    return false    
+end
+
+local function scramble(t)
+    for i=1, #t do
+        local tmp = t[i]
+        local r = math.random(#t)
+        t[i] = t[r]
+        t[r] = tmp
+    end
+    return t
+end
+
+local function swap(t, i, j)
+    local tmp = t[i]
+    t[i] = t[j]
+    t[j] = tmp
+    return t
+end
+
+local function draw(t)
+    for i=1, #t do
+        local y = 5 - math.ceil(i/4)
+        local x = i - (math.ceil(i/4) - 1) * 4
+        tilemap.set_tile("#tilemap","layer1",x,y,t[i])
+    end
+end
+
+function init(self)
+    msg.post(".", "acquire_input_focus")
+    math.randomseed(socket.gettime())
+    self.board = scramble({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0})   
+    while not solvable(self.board) do
+        self.board = scramble(self.board)
+    end
+    draw(self.board)
+    self.done = false
+    msg.post("#done", "disable")
+end
+
+function on_input(self, action_id, action)
+    if action_id == hash("press") and action.pressed and not self.done then
+        local x = math.ceil(action.x / 128)
+        local y = math.ceil(action.y / 128)
+        local ex, ey = find(self.board, 0)
+        if math.abs(x - ex) + math.abs(y - ey) == 1 then
+            self.board = swap(self.board, (4-ey)*4+ex, (4-y)*4+x)
+            draw(self.board)
+        end
+        ex, ey = find(self.board, 0)
+        if inversions(self.board) == 0 and ex == 4 then
+            self.done = true
+            msg.post("#done", "enable")
+        end
+    end
+end
+
+function on_reload(self)
+    self.done = false
+    msg.post("#done", "disable")    
+end
+```
+
+## Further exercises
+
+1. Make a 5⨉5 puzzle, then a 6⨉5 one. Make sure the solvability checks work generally.
+2. Add sliding animations. Tiles cannot be moved separately from the tilemap so you will have to come up with a way of solving that. Perhaps a separate tilemap that only contains the sliding piece?

+ 27 - 0
docs/zh/tutorials/astronaut.md

@@ -0,0 +1,27 @@
+---
+title: Walking astronaut tutorial
+brief: In this beginner's tutorial you learn how to capture player input and make a character move and animate. You will also learn about game objects, components and collections
+github: https://github.com/defold/tutorial-astronaut
+---
+
+# Walking astronaut tutorial
+
+In this beginner's tutorial you learn how to capture player input and make a character move and animate. You will also learn about the core building blocks in Defold: game objects, components and collections.
+
+The tutorial is integrated with the Defold editor and easily accessible:
+
+1. Start Defold.
+2. Select *New Project* on the left.
+3. Select the *From Tutorial* tab.
+4. Select the "Walking astronaut tutorial"
+5. Select a location for the project on your local drive and click *Create New Project*.
+
+![new project](images/new-astronaut.png){srcset="images/[email protected] 2x"}
+
+The editor automatically opens the "README" file from the project root, containing the full tutorial text.
+
+![icon](images/icon-tutorial.svg){.icon} [You can also read the full tutorial text on Github](https://github.com/defold/tutorial-astronaut)
+
+If you get stuck, head over to the [Defold Forum](//forum.defold.com) where you will get help from the Defold team and many friendly users.
+
+Happy Defolding!

+ 226 - 0
docs/zh/tutorials/car.md

@@ -0,0 +1,226 @@
+---
+title: Building a simple car in Defold.
+brief: If you are new to Defold, this guide will help you getting your bearings right in the editor. It also explains the basic ideas and the most common building blocks in Defold - game objects, collections, scripts and sprites.
+---
+
+# Building a car
+
+If you are new to Defold, this guide will help you getting your bearings right in the editor. It also explains the basic ideas and the most common building blocks in Defold: Game objects, Collections, Scripts and Sprites.
+
+We're going to start from an empty project and work step by step to a very small, playable application. At the end you will hopefully have a feel for how Defold works and you will be ready to tackle a more extensive tutorial or dive right into the manuals.
+
+## The editor
+
+Start by creating a [new project](/manuals/project-setup/) and opening it in the editor. If you double-click the file *main/main.collection* the file will open up:
+
+![Editor overview](../manuals/images/editor/editor2_overview.png)
+
+The editor consists of the following main areas:
+
+Assets pane
+: This is a view of all files in your project. Different file types have different icons. Double click on a file to open in in a designated editor for that file type. The special read-only folder *builtins* is common for all projects and include useful items like a default render script, a font, materials for rendering various components and other things.
+
+Main Editor View
+: Depending on which filetype you're editing, this view will show an editor for that type. Most commonly used is the Scene editor that you see here. Each open file is shown in a separate tab.
+
+Changed Files
+: Contains a list of all the edits you have made in your branch since last synchronization. So if you see anything in this pane, you have changes that are not on the server yet. You can open a text-only diff and revert changes through this view.
+
+Outline
+: The content of the currently edited file in a hierarchical view. You can add, delete, modify and select objects and components through this view.
+
+Properties
+: The properties set on the currently selected object or component.
+
+Console
+: When running the game, this view captures output (logging, errors, debug info etc) coming from the game engine, and also any custom `print()` and `pprint()` debug messages from your scripts. If your app or game won't start the console is the first thing to check. Behind the console are a set of tabs displaying error information as well as a curve editor that is used when building particle effects.
+
+## Running the game
+
+The "Empty" project template actually isn't completely empty. As you've already seen, it contains one game object with a simple image. Select <kbd>Project ▸ Build and Launch</kbd> to build the project and launch the game.
+
+![Build and launch](images/car/start_build_and_launch.png)
+
+It's perhaps not very exciting, but it's a running Defold game application and we can easily modify it into something more interesting. So let's do that.
+
+First of all, let's clean the file *main.collection* of the one game object it contains. Select "logo" in the *Outline* view, right-click and select *Delete*. That's it. If you run the game again, the application window will be totally black.
+
+![Delete game object](images/car/start_delete_go.png)
+
+## Assembling the car
+
+The first thing we're going to do is to create a new collection. A collection is a container of game objects that you have placed and put into position. Collections are most commonly used to build game levels but they are very useful whenever you need to reuse groups and/or hierarchies of game objects that belong together. It might be helpful to think about collections as a kind of prefab.
+
+Click on the *main* folder in the *Assets pane*, then right-click and select <kbd>New ▸ Collection File</kbd>. You can also select <kbd>File ▸ New ▸ Collection File</kbd> from the main menu.
+
+![New Collection file](images/car/start_new_collection.png)
+
+Name the new collection file *car.collection* and open it. We're going to use this new, empty collection to build a small car out of a couple of game objects. A game object is a container of components (like sprites, sounds, logic scripts etc) that you use to build your game. Each game object is uniquely identified in the game by its id. Game objects can communicate with each other through message passing, but more on that later.
+
+Also, it's possible to create a game object in place in a collection, as we did here. That results in a one-of-a-kind object. You can copy that object but each copy is separate---changing one does not affect the others. This means that if you create 10 copies of a game object and realize that you want to change them all, you will need to edit all 10 instances of the object. Therefore, in place created game objects should be used for objects that you do not intend to make a lot of copies of.
+
+However, a game object that is stored in a _file_ works as a blueprint. When you place instances of a file stored game object in a collection each object is placed _by reference_---it is a clone based on the blueprint. If you decide you need to change the blueprint, every single placed game object based on that blueprint is instantly updated.
+
+![Add car gameobject](images/car/start_add_car_gameobject.png)
+
+Select the root "Collection" node in the *Outline* view, right-click and select <kbd>Add Game Object</kbd>. A new game object with the id "go" will appear in the collection. Mark it and set its id to "car" in the *Properties* view. So far, "car" is very uninteresting. It is empty, has neither visual representation nor any logic. To add a visual representation, we need to add a sprite _component_.
+
+Components are used to extend game objects with presence (graphics, sound) and functionality (spawn factories, collisions, scripted behaviors). A component can't exist by itself but has to reside inside a game object. Components are usually defined in place in the same file as the game object. However, if you want to reuse a component you can store it in a separate file (like you can with game objects) and include it as a reference in any game object file. Some component types (Lua scripts, for instance) has to be placed in a separate component file and then included as reference in your objects.
+
+Note that you do not manipulate components directly---you can move, rotate, scale and animate properties of game objects that in turn contain components.
+
+![Add car component](images/car/start_add_car_component.png)
+
+Select the "car" game object, right-click and select <kbd>Add Component</kbd>, then select *Sprite* and click *Ok*. If you mark the sprite in the *Outline* view you will see that it needs a few properties set:
+
+Image
+: This requires an image source for the sprite. Create an atlas image file by marking "main" in the *Assets pane* view, right-clicking and selecting <kbd>New ▸ Atlas File</kbd>. Name the new atlas file *sprites.atlas* and double click it to open it in the atlas editor. Save the following two image files to your computer and drag them into *main* in the *Assets pane* view. Now you can mark the Atlas root node in the atlas editor, right click and select <kbd>Add Images</kbd>. Add the car and the tire image to the atlas and save. Now you can select *sprites.atlas* as the image source for the sprite component in the "car" game object in the "car" collection.
+
+Images for our game:
+
+![Car image](images/car/start_car.png)
+![Tire image](images/car/start_tire.png)
+
+Add these images to the atlas:
+
+![Sprites atlas](images/car/start_sprites_atlas.png)
+
+![Sprite properties](images/car/start_sprite_properties.png)
+
+Default Animation
+: Set this to "car" (or whatever you named the car image). Each sprite needs a default animation that is played when it is shown in the game. When you add images to an atlas, Defold conveniently creates one-frame (still) animations for each image file.
+
+## Completing the car
+
+Continue by adding two more game objects in the collection. Call them "left_wheel" and "right_wheel" and put a sprite component in each, showing the tire image that we added to *sprites.atlas*. Then grab the wheel game objects and drop them onto "car" to make them children under "car". Game objects that are children under other game objects will be attached to their parent when the parent moves. They can be moved individually as well, but all motion happens relative to the parent object. For the tires this is perfect since we want them to stick to the car and we can just rotate them slightly left and right as we steer the car. A collection can contain any number of game objects, side by side or arranged into complex parent-child trees, or a mix.
+
+Move the tire game objects into place by selecting them and then choosing <kbd>Scene ▸ Move Tool</kbd>. Grab the arrow handlebars, or the center green square to move the object to a good spot. The final thing we need to do is to make sure that the tires are drawn below the car. We do that by setting the Z component of the position to -0.5. Every visual item in a game is drawn from the back to front, sorted on their Z value. An object with a Z-value of 0 will be drawn on top of an object with a Z-value of -0.5. Since the default Z-value of the car game object is 0, the new value on the tire objects will put them under the car image.
+
+![Car collection complete](images/car/start_car_collection_complete.png)
+
+The last piece of the puzzle is a _script_ to control the car. A script is a component that contains a program that defines game object behaviors. With scripts you can specify the rules of your game, how objects should respond to various interactions (with the player as well as other objects). All scripts are written in the Lua programming language. To be able to work with Defold, you or someone on your team needs to learn how to program in Lua.
+
+Mark "main" in the *Assets pane*, right-click and select <kbd>New ▸ Script File</kbd>. Name the new file *car.script*, then add it to the "car" game object by marking "car" in the *Outline* view, right click and select <kbd>Add Component File</kbd>. Select *car.script* and click *OK*. Save the collection file.
+
+Double click *car.script* and edit the script so it contains the following:
+
+```lua
+-- car.script
+-- Constants
+local turn_speed = 0.1                           -- Slerp factor
+local max_steer_angle_left = vmath.quat_rotation_z(math.pi / 6)     -- 30 degrees
+local max_steer_angle_right = vmath.quat_rotation_z(-math.pi / 6)   -- -30 degrees
+local wheels_vector = vmath.vector3(0, 72, 0)               -- Vector from center of back and front wheel pairs
+
+function init(self)
+    -- Send a message to the render script (see builtins/render/default.render_script) to set the clear color.
+    -- This changes the background color of the game. The vector4 contains color information
+    -- by channel from 0-1: Red = 0.2. Green = 0.2, Blue = 0.2 and Alpha = 1.0
+    msg.post("@render:", "clear_color", { color = vmath.vector4(0.2, 0.2, 0.2, 1.0) } )
+
+    -- Acquire input focus so we can react to input
+    msg.post(".", "acquire_input_focus")
+
+    -- Some variables
+    self.steer_angle = vmath.quat()
+    self.direction = vmath.quat()
+
+    -- Velocity and acceleration are car relative (not rotated)
+    self.velocity = vmath.vector3()
+    self.acceleration = vmath.vector3()
+end
+
+function update(self, dt)
+    -- Calculate new velocity based on current acceleration
+    self.velocity = self.velocity + self.acceleration * dt
+
+    -- Calculate the new positions of front and back wheels
+    local front_vel = vmath.rotate(self.steer_angle, self.velocity)
+    local new_front_pos = vmath.rotate(self.direction, wheels_vector + front_vel)
+    local new_back_pos = vmath.rotate(self.direction, self.velocity)
+
+    -- Calculate the car's new direction
+    local new_dir = vmath.normalize(new_front_pos - new_back_pos)
+    self.direction = vmath.quat_rotation_z(math.atan2(new_dir.y, new_dir.x) - math.pi / 2)
+
+    -- Update position based on current velocity and direction
+    local pos = go.get_position()
+    pos = pos + vmath.rotate(self.direction, self.velocity)
+    go.set_position(pos)
+
+    -- Set the game object's rotation to the direction
+    go.set_rotation(self.direction)
+end
+
+function on_message(self, message_id, message, sender)
+    if message_id == hash("left") then
+        -- Interpolate the steering angle.
+        self.steer_angle = vmath.slerp(turn_speed, self.steer_angle, max_steer_angle_left)
+        go.set_rotation(self.steer_angle, "left_wheel")
+        go.set_rotation(self.steer_angle, "right_wheel")
+    elseif message_id == hash("right") then
+        -- Interpolate the steering angle.
+        self.steer_angle = vmath.slerp(turn_speed, self.steer_angle, max_steer_angle_right)
+        go.set_rotation(self.steer_angle, "left_wheel")
+        go.set_rotation(self.steer_angle, "right_wheel")
+    elseif message_id == hash("set_acceleration") then
+        -- Set acceleration y component (car relative) to the message data field "acc".
+        self.acceleration.y = message.acc
+    end
+end
+
+function on_input(self, action_id, action)
+    if action_id == hash("left") then
+        msg.post("#", "left")
+    elseif action_id == hash("right") then
+        msg.post("#", "right")
+    elseif action_id == hash("accelerate") and action.value == 1 then
+        msg.post("#", "set_acceleration", { acc = 10 })
+    elseif action_id == hash("accelerate") and action.value == 0 then
+        msg.post("#", "set_acceleration", { acc = 0 })
+    elseif action_id == hash("brake") and action.value == 1 then
+        msg.post("#", "set_acceleration", { acc = -10 })
+    elseif action_id == hash("brake") and action.value == 0 then
+        msg.post("#", "set_acceleration", { acc = 0 })
+    end
+end
+```
+
+Don't forget to save your edits. The script contains 5 parts:
+
+Constants
+: At the top we define a couple of local variables that we use as constants throughout the script. This is optional but usually a good practice since it makes changes of the values easier.
+
+`init()`
+: The function `init()` is run when the game object that the script component exists in is brought to life in the game. This function is usually used to set up internal variables, that we add to the game object "self" that is passed to the function. Any variable added to "self" will be kept through the lifetime of the game object. This script sends two messages during initialization. The first is to the rendering system, which sets the background color for the game. The second message is sent to the game object harboring the script ("." is shorthand for that) asking the game object to start receiving input.
+
+`update()`
+: This function is called once each frame (i.e. 60 times a second) during the lifetime of the game object. We use the function to calculate the speed and direction of the car based on the rotation of the car and the tires. The parameter "dt" is the current timestep (1/60 of a second in this case) and we use that to scale the calculations right. The way steering is computed is an approximation but yields pretty good results if the steering angles are not too extreme. After the calculations, the script updates the position of the game object. This affects all components in the game object (the car body sprite) as well as any child game objects (the tires).
+
+`on_message()`
+: This function is called whenever a message arrives to the script component. We check what message is arriving and take proper action, setting game object variables to new values. If steering left or right, we interpolate with `vmath.slerp()` against the max values, if we are accelerating or decelerating both are handled by the message "set_acceleration" and a message value "acc" with the value of acceleration, positive or negative.
+
+`on_input()`
+: Since this game object listens to input (through the message "acquire_input_focus" in `init()` we receive input actions. Input are mapped from actual key, mouse, touch or game pad input to input "actions". We react to steering, accelerate and brake actions. When these actions arrive we send messages to the script component itself ("#" is shorthand for that) and through the logic in `on_message()` the car reacts. Now, we could just as well have skipped `on_message()` and put all logic straight into `on_input()` but there are benefits to using messages like we do. By allowing the car object to react to messages we can move the input handling to a different place, or perhaps add an AI driver somewhere that could drive the car through messages.
+
+## Input
+
+There is no input actions set up yet, so let's fix that. Open the file */input/game.input_bindings* and add *key_trigger* bindings for "accelerate", "brake", "left" and "right". We set them to the arrow keys (KEY_LEFT, KEY_RIGHT, KEY_UP and KEY_DOWN):
+
+![Input bindings](images/car/start_input_bindings.png)
+
+## Adding the car to the game
+
+Now the car is ready to roll. We have created it inside "car.collection" but it does not yet exist in the game. That is because the engine currently loads "main.collection" on startup. To fix that we simply have to add *car.collection* to *main.collection*. Open *main.collection*, mark the "Collection" root node in the *Outline* view, right-click and select <kbd>Add Collection From File</kbd>, select *car.collection* and click *OK*. Now the contents of the *car.collection* will be placed in *main.collection* as new instances. If you change the content of *car.collection*, each instance of the collection will be updated automatically when the game is built.
+
+![Adding the car collection](images/car/start_adding_car_collection.png)
+
+## Trying the final game
+
+Now, select <kbd>Project ▸ Build And Launch</kbd> from the main menu and take your new car for a spin!
+
+If you want you can try to add more instances of *car.collection* to *main.collection*. Each instance is a clone of what's inside *car.collection* with the exact same behavior. Each one listens to input and reacts to the same messages.
+
+That concludes this introductory tutorial. Now go ahead and dive into Defold. We have lots of [manuals and tutorials](/learn) prepared to guide you, and if you get stuck, you are very welcome to the [forum](//forum.defold.com).
+
+Happy Defolding!

+ 28 - 0
docs/zh/tutorials/colorslide.md

@@ -0,0 +1,28 @@
+---
+title: Colorslide tutorial
+brief: In this medium difficulty tutorial you build an in-game GUI, a GUI screen for level selection and a start screen for a simple multi level mobile game.
+github: https://github.com/defold/tutorial-colorslide
+---
+
+# Colorslide tutorial
+
+In this medium difficulty tutorial you build an in-game GUI, a GUI screen for level selection and a start screen for a simple multi level mobile game.
+
+The tutorial is integrated with the Defold editor and easily accessible:
+
+1. Start Defold.
+2. Select *New Project* on the left.
+3. Select the *From Tutorial* tab.
+4. Select the "Colorslide tutorial"
+5. Select a location for the project on your local drive and click *Create New Project*.
+
+![new project](images/new-colorslide.png){srcset="images/[email protected] 2x"}
+
+The editor automatically opens the "README" file from the project root, containing the full tutorial text.
+
+![icon](images/icon-tutorial.svg){.icon} [You can also read the full tutorial text on Github](https://github.com/defold/tutorial-colorslide)
+
+If you get stuck, head over to the [Defold Forum](//forum.defold.com) where you will get help from the Defold team and many friendly users.
+
+Happy Defolding!
+

+ 35 - 0
docs/zh/tutorials/getting-started.md

@@ -0,0 +1,35 @@
+---
+title: Getting started with Defold
+brief: This tutorial explains how to get started doing tutorials in Defold.
+---
+
+# Getting started
+
+The Defold engine and editor are powerful tools with a lot of features and functionality to learn. To help you on your way we have created a variety of tutorials. Many of the tutorials are available directly from within the editor which makes them very easy to get started with.
+
+## Starting a tutorial from the editor
+
+When you run the Defold editor, you are presented with a project selection and creation screen. From here you can easily select which tutorial you want to try out:
+
+1. Start Defold.
+2. Select *New Project* on the left.
+3. Select the *From Tutorial* tab.
+4. Select a tutorial that you are interested in.
+5. Select a location for the project on your local drive.
+6. Click *Create New Project*.
+
+![create project](images/getting-started/new-project.png){srcset="images/getting-started/[email protected] 2x"}
+
+The editor now automatically downloads the tutorial project, opens it in the editor and opens the tutorial text (the "README" file in the project root).
+
+![tutorial text](images/getting-started/tutorial-text.png)
+
+Now follow the tutorial text! If you want to get back to the text, <kbd>double click</kbd> the "README" file in the *Assets* view. You can also <kbd>right click</kbd> the tab of open files and select <kbd>Move to Other Tab Pane</kbd> to view the tutorial text side by side with the file you are working on.
+
+![side by side](images/getting-started/side-by-side.png)
+
+If you are totally new to Defold, you might also want to check out the [editor introduction](/manuals/editor).
+
+If you ever get stuck, please head over to the [Defold Forum](//forum.defold.com) where you will get help from the Defold developers and many friendly users.
+
+Happy Defolding!

+ 460 - 0
docs/zh/tutorials/grading.md

@@ -0,0 +1,460 @@
+---
+title: Grading shader tutorial
+brief: In this tutorial you will create a full screen post effect in Defold.
+---
+
+# Grading tutorial
+
+In this tutorial we are going to create a color grading  full screen post effect. The basic rendering method used is widely applicable for various types of post effects like blur, trails, glow, color adjustments and so on.
+
+It is assumed that you know your way around the Defold editor, and that you have basic understanding of GL shaders and the Defold rendering pipeline. If you need to read up on these subjects, check out [our Shader manual](/manuals/shader/) and the [Render manual](/manuals/render/).
+
+## Render targets
+
+With the default render script, each visual component (sprite, tilemap, particle effect, GUI etc) is rendered directly to the graphics card's *frame buffer*. The hardware then cause the graphics to appear on the screen. The actual drawing of a component's pixels is done by a GL *shader program*. Defold ships with a default shader program for each component type that draws the pixel data to the screen untouched. Normally, this is the behavior you want---your images should appear on the screen as they were originally conceived.
+
+You can replace a component's shader program with one that modifies the pixel data, or creates wholly new pixel colors programmatically. The [Shadertoy tutorial](/tutorials/shadertoy) teaches you how to do that.
+
+Now let's say that you want to render your whole game in black-and-white. One possible solution is to modify the individual shader program for each components type so that each shader desaturates pixel colors. Currently, Defold ships with 6 built-in materials and 6 vertex and fragment shader program pairs so it will take a fair amount of work. Furthermore, any subsequent changes or effect additions has to be made to each shader program.
+
+A much more flexible approach is to instead do the rendering in two separate steps:
+
+![Render target](images/grading/render_target.png)
+
+1. Draw all components as usual, but draw them to an off-screen buffer instead of the usual frame buffer. You do this by drawing to something called a *render target*.
+2. Draw a square polygon to the frame buffer and use the pixel data stored in the render target as the polygon's texture source. Also make sure that the square polygon is stretched to cover the whole screen.
+
+With this method, we are able to read the resulting visual data and modify it before it hits the screen. By adding shader programs to step 2 above, we can easily achieve full screen effects. Let's see how to set this up in Defold.
+
+## Setting up a custom renderer
+
+We need to modify the built-in render script and add the new rendering functionality. The default render script is a good starting point so start by copying it:
+
+1. Copy */builtins/render/default.render_script*: In the *Asset* view, right click *default.render_script*, select <kbd>Copy</kbd> then right click *main* and select <kbd>Paste</kbd>. Right click the copy and select <kbd>Rename...</kbd> and give it a suitable name, like "grade.render_script".
+2. Create a new render file called */main/grade.render* by right clicking *main* in the *Asset* view and selecting <kbd>New ▸ Render</kbd>.
+3. Open *grade.render* and set its *Script* property to "/main/grade.render_script".
+
+   ![grade.render](images/grading/grade_render.png)
+
+4. Open *game.project* and set *Render* to "/main/grade.render".
+
+   ![game.project](images/grading/game_project.png)
+
+Now the game is set up to run with a new render pipeline that we can modify. To test that our render script copy is used by the engine, run your game, then do a modification to the render script that will give a visual result, and then reload the script. For example, you can disable the drawing of tiles and sprites, then press <kbd>⌘ + R</kbd> to hot-relad the "broken" render script into the running game:
+
+```lua
+...
+
+render.set_projection(vmath.matrix4_orthographic(0, render.get_width(), 0, render.get_height(), -1, 1))
+
+-- render.draw(self.tile_pred) -- <1>
+render.draw(self.particle_pred)
+render.draw_debug3d()
+
+...
+```
+1. Comment out drawing of the "tile" predicate, which includes all sprites and tiles. This line of code can be found around line 33 in the render script file.
+
+If the sprites and tiles disappear by this simple test you know that the game runs your render script. If everything works as expected you can undo the change to the render script.
+
+## Drawing to an off-screen target
+
+Now, let's modify the render script so that it draws to the off-screen render target instead of the frame buffer. First we need to create the render target:
+
+```lua
+function init(self)
+    self.tile_pred = render.predicate({"tile"})
+    self.gui_pred = render.predicate({"gui"})
+    self.text_pred = render.predicate({"text"})
+    self.particle_pred = render.predicate({"particle"})
+
+    self.clear_color = vmath.vector4(0, 0, 0, 0)
+    self.clear_color.x = sys.get_config("render.clear_color_red", 0)
+    self.clear_color.y = sys.get_config("render.clear_color_green", 0)
+    self.clear_color.z = sys.get_config("render.clear_color_blue", 0)
+    self.clear_color.w = sys.get_config("render.clear_color_alpha", 0)
+
+    self.view = vmath.matrix4()
+
+    local color_params = { format = render.FORMAT_RGBA,
+                       width = render.get_width(),
+                       height = render.get_height() } -- <1>
+    local target_params = {[render.BUFFER_COLOR_BIT] = color_params }
+
+    self.target = render.render_target("original", target_params) -- <2>
+end
+```
+1. Set up color buffer parmeters for the render target. We use the game's target resolution.
+2. Create the render target with the color buffer parameters.
+
+Now we just need to wrap the original rendering code with `render.enable_render_target()` and `render.disable_render_target()`:
+
+```lua
+function update(self)
+  render.enable_render_target(self.target) -- <1>
+
+  render.set_depth_mask(true)
+  render.set_stencil_mask(0xff)
+  render.clear({[render.BUFFER_COLOR_BIT] = self.clear_color, [render.BUFFER_DEPTH_BIT] = 1, [render.BUFFER_STENCIL_BIT] = 0})
+
+  render.set_viewport(0, 0, render.get_width(), render.get_height()) -- <2>
+  render.set_view(self.view)
+  ...
+
+  render.disable_render_target(self.target) -- <3>
+end
+```
+1. Enable the render target. From now on, every call to `render.draw()` will draw to our off-screen render target's buffers.
+2. All original drawing code in `update()` is left as is, apart from the viewport which is set to the render target's resolution.
+3. At this point, all the game's graphics has been drawn to the render target. So it's time to disable it.
+
+That's all we need to do. If you run the game now it will draw everything to the render target. But since we now drawing nothing to the frame-buffer we will only see a black screen.
+
+## Something to fill the screen with
+
+To draw the pixels in the render target's color buffer onto the screen, we need to set something up that we can texture with the pixel data. For that purpose we are going to use a flat, quadratic 3D model.
+
+Create a quadratic plane mesh in Blender (or any other 3D modelling program). Set the vertex coordinates to -1 and 1 on the X-axis and -1 and 1 on the Y axis. Blender has the Z-axis up by default so you need to rotate the mesh 90° around the X-axis. You should also make sure that you generate correct UV-coordinates for the mesh. In Blender, enter Edit Mode with the mesh selected, then select <kbd>Mesh ▸ UV unwrap... ▸ Unwrap</kbd>.
+
+![game.project](images/grading/quad_blender.png)
+
+1. Export the model as a Collada file called *quad.dae* and drag it into your Defold project.
+2. Open *main.collection* and create a new game object called "grade".
+3. Add a Model component to the "grade" game object.
+3. Set the *Mesh* property of the model component to the *quad.dae* file.
+
+Leave the game object unscaled at origin. Later, when we render the quad we will project it so it fills the whole screen. But first we need a material and shader programs for the quad:
+
+1. Create a new material and call it *grade.material* by right clicking *main* in the *Asset* view and selecting <kbd>New ▸ Material</kbd>.
+2. Create a vertex shader program called *grade.vp* and a fragment shader program called *grade.fp* by right clicking *main* in the *Asset* view and selecting <kbd>New ▸ Vertex program</kbd> and <kbd>New ▸ Fragment program</kbd>.
+3. Open *grade.material* and set the *Vertex program* and *Fragment program* properties to the new shader program files.
+4. Add a *Vertex constant* named "view_proj" of type `CONSTANT_TYPE_VIEWPROJ`. This is the view and projection matrix used in the vertex program for the quad vertices.
+5. Add a *Sampler* called "original". This will be used to sample pixels from the off-screen render target color buffer.
+6. Add a *Tag* called "grade". We will make a new *render predicate* in the render script matching this tag to draw the quad.
+
+   ![grade.material](images/grading/grade_material.png)
+
+7. Open *main.collection*, select the model component in game object "grade" and set its *Material* property to "/main/grade.material".
+
+   ![model properties](images/grading/model_properties.png)
+
+8. The vertex shader program can be left as created from the base template:
+
+    ```glsl
+    // grade.vp
+    uniform mediump mat4 view_proj;
+
+    // positions are in world space
+    attribute mediump vec4 position;
+    attribute mediump vec2 texcoord0;
+
+    varying mediump vec2 var_texcoord0;
+
+    void main()
+    {
+      gl_Position = view_proj * vec4(position.xyz, 1.0);
+      var_texcoord0 = texcoord0;
+    }
+    ```
+
+9. In the fragment shader program, instead of setting `gl_FragColor` to the sampled color value directly, let's perform a simple color manipulation. We do this mainly to make sure everything works as expected so far:
+
+    ```glsl
+    // grade.fp
+    varying mediump vec4 position;
+    varying mediump vec2 var_texcoord0;
+
+    uniform lowp sampler2D original;
+
+    void main()
+    {
+      vec4 color = texture2D(original, var_texcoord0.xy);
+      // Desaturate the color sampled from the original texture
+      float grey = color.r * 0.3 + color.g * 0.59 + color.b * 0.11;
+      gl_FragColor = vec4(grey, grey, grey, 1.0);
+    }
+    ```
+
+Now we have the quad model in place with its material and shaders. We just have to draw it to the screen frame buffer.
+
+## Texturing with the off-screen buffer
+
+We need to add a render predicate to the render script so we can draw the quad model. Open *grade.render_script* and edit the `init()` function:
+
+```lua
+function init(self)
+    self.tile_pred = render.predicate({"tile"})
+    self.gui_pred = render.predicate({"gui"})
+    self.text_pred = render.predicate({"text"})
+    self.particle_pred = render.predicate({"particle"})
+    self.grade_pred = render.predicate({"grade"}) -- <1>
+
+    ...
+end
+```
+1. Add a new predicate matching the "grade" tag that we set in *grade.material*.
+
+After the render target's color buffer has been filled in `update()` we set up a view and a projection that make the quad model fill the whole screen. We then use the render target's color buffer as the quad's texture:
+
+```lua
+function update(self)
+  render.enable_render_target(self.target)
+
+  ...
+
+  render.disable_render_target(self.target)
+
+  render.clear({[render.BUFFER_COLOR_BIT] = self.clear_color}) -- <1>
+
+  render.set_viewport(0, 0, render.get_window_width(), render.get_window_height()) -- <2>
+  render.set_view(vmath.matrix4()) -- <3>
+  render.set_projection(vmath.matrix4())
+
+  render.enable_texture(0, self.target, render.BUFFER_COLOR_BIT) -- <4>
+  render.draw(self.grade_pred) -- <5>
+  render.disable_texture(0, self.target) -- <6>
+end
+```
+1. Clear the frame buffer. Note that the previous call to `render.clear()` affects the render target, not the screen frame buffer.
+2. Set the viewport to match the window size.
+3. Set the view to the identity matrix. This means camera is at origin looking straight along the Z axis. Also set the projection to the identity matrix causing the the quad to be projected flat across the whole screen.
+4. Set texture slot 0 to the color buffer of the render target. We have sampler "original" at slot 0 in our *grade.material* so the fragment shader will sample from the render target.
+5. Draw the predicate we created matching any material with the tag "grade". The quad model uses *grade.material* which sets that tag---thus the quad will be drawn.
+6. After drawing, disable texture slot 0 since we are done drawing with it.
+
+Now let's run the game and see the result:
+
+![desaturated game](images/grading/desaturated_game.png)
+
+## Color grading
+
+Colors are expressed as three component values where each component dictates the amount of red, green or blue a color consist of. The full color spectrum from black, through red, green, blue, yellow and pink to white can be fit into a cube shape:
+
+![color cube](images/grading/color_cube.png)
+
+Any color that can be displayed on screen can be found in this color cube. The basic idea of color grading is to use such a color cube, but with altered colors, as a 3D *lookup table*.
+
+For each pixel:
+
+1. Look up its color's position in the color cube (based on the red, green and blue values).
+2. *Read* what color the graded cube has stored in that location.
+3. Draw the pixel in the read color instead of the original color.
+
+We can do this in our fragment shader:
+
+1. Sample the color value for each pixel in the off-screen buffer.
+2. Look up the color position of the sampled pixel in a color-graded color cube.
+3. Set the output fragment color to the looked up value.
+
+![render target grading](images/grading/render_target_grading.png)
+
+## Representing the lookup table
+
+Open GL ES 2.0 does not support 3D textures so we need to figure out another way to represent the 3D color cube. A common way of doing that is to slice the cube along the Z-axis (blue) and lay each slice side by side in a 2-dimensional grid. Each of the 16 slices contains a 16⨉16 pixel grid. We store this in a texture that we can read from in the fragment shader with a sampler:
+
+![lookup texture](images/grading/lut.png)
+
+The resulting texture contains 16 cells (one for each blue color intensity) and within each cell 16 red colors along the X axis and 16 green colors along the Y axis. The texture represents the whole 16 million color RGB color space in just 4096 colors---merely 4 bits of color depth. By most standards this lousy but thanks to a feature of GL graphics hardware we can get very high color accuracy back. Let's see how.
+
+## Looking up colors
+
+To look up a color is a matter of checking the blue component and figure out which cell to pick the red and green values from. The formula for finding the cell with the right red-green color set is simple:
+
+$$
+cell = \left \lfloor{B \times (N - 1)} \right \rfloor
+$$
+
+Here `B` is the blue component value between 0 and 1 and `N` is the total number of cells. In our case the cell number will be in the range `0`--`15` where cell `0` contains all colors with the blue component at `0` and cell `15` all colors with the blue component at `1`.
+
+For example, the RGB value `(0.63, 0.83, 0.4)` is found in the cell containing all the colors with a blue value of `0.4`, which is cell number 6. Knowing that, the lookup of the final texture coordinates based on the green and red values is straightforward:
+
+![lut lookup](images/grading/lut_lookup.png)
+
+Note that we need to treat red and green values `(0, 0)` as being in the *center* of the bottom left pixel and the values `(1.0, 1.0)` as being in the *center* of the top right pixel.
+
+::: sidenote
+The reason we read starting at the center of the lower left pixel and up to the center of the top right one is that we don't want any pixels outside of the current cell to affect the sampled value. See below about filtering.
+:::
+
+When sampling at these specific coordinates on the texture we see that we end up right between 4 pixels. So what color value will GL tell us that point has?
+
+![lut filtering](images/grading/lut_filtering.png)
+
+The answer depends on how we have specified the sampler's *filtering* in the material.
+
+- If the sampler filtering is `NEAREST`, GL will get return the color value of the nearest pixel value (position value rounded down). In the above case GL will return the color value at position `(0.60, 0.80)`. For our 4 bit lookup texture it means that we will quantize the color values into just 4096 colors in total.
+
+- If the sampler filtering is `LINEAR`, GL will return the *interpolated* color value. GL will mix a color based on the distance to the pixels around the sample position. In the above case, GL will return a color that is 25% of each of the 4 pixels around the sample point.
+
+By using linear filtering we thus eliminate color quantization and get very good color precision out of a pretty small lookup table.
+
+## Implementing the lookup
+
+Let's implement the texture lookup in the fragment shader:
+
+1. Open *grade.material*.
+2. Add a second sampler called "lut" (for lookup table).
+3. Set the *Filter min* property to `FILTER_MODE_MIN_LINEAR` and the *Filter mag* property to `FILTER_MODE_MAG_LINEAR`.
+
+    ![lut sampler](images/grading/material_lut_sampler.png)
+
+4. Download the following lookup table texture (*lut16.png*) and add it to your project.
+
+    ![16 colors lut lookup table](images/grading/lut16.png)
+
+5. Open *main.collection* and set the *lut* texture property to the downloaded lookup texture.
+
+    ![quad model lut](images/grading/quad_lut.png)
+
+6. Finally, open *grade.fp* so we can add support for color lookup:
+
+    ```glsl
+    varying mediump vec4 position;
+    varying mediump vec2 var_texcoord0;
+
+    uniform lowp sampler2D original;
+    uniform lowp sampler2D lut; // <1>
+
+    #define MAXCOLOR 15.0 // <2>
+    #define COLORS 16.0
+    #define WIDTH 256.0
+    #define HEIGHT 16.0
+
+    void main()
+    {
+        vec4 px = texture2D(original, var_texcoord0.xy); // <3>
+
+        float cell = floor(px.b * MAXCOLOR); // <4>
+
+        float half_px_x = 0.5 / WIDTH; // <5>
+        float half_px_y = 0.5 / HEIGHT;
+
+        float x_offset = half_px_x + px.r / COLORS * (MAXCOLOR / COLORS);
+        float y_offset = half_px_y + px.g * (MAXCOLOR / COLORS); // <6>
+
+        vec2 lut_pos = vec2(cell / COLORS + x_offset, y_offset); // <7>
+
+        vec4 graded_color = texture2D(lut, lut_pos); // <8>
+
+        gl_FragColor = graded_color; // <9>
+    }
+    ```
+    1. Declare the sampler `lut`.
+    2. Constants for max color (15 since we start from 0), number of colors per channel and lookup texture width and height.
+    3. Sample a pixel color (called `px`) from the original texture (the off-screen render target color buffer).
+    4. Calculate which cell to read color from based on the blue channel value of `px`.
+    5. Calculate half pixel offsets so we read from pixel centers.
+    6. Calculate the X and Y offset on the texture based on the red and green values of `px`.
+    7. Calculate the final sample position on the lookup texture.
+    8. Sample the resulting color from the lookup texture.
+    9. Set the color on the quad's texture to the resulting color.
+
+Currently, the lookup table texture just returns the same color values that we look up. This means that the game should render with its original coloring:
+
+![world original look](images/grading/world_original.png)
+
+So far it looks like we have done everything right, but there is a problem lurking beneath the surface. Look what happens when we add a sprite with a gradient test texture:
+
+![blue banding](images/grading/blue_banding.png)
+
+The blue gradient shows some really ugly banding. Why is that?
+
+## Interpolating the blue channel
+
+The problem with banding in the blue channel is that GL is unable to perform any blue channel interpolation when reading the color from the texture. We preselect a particular cell to read from based on the blue color value, and that's it. For instance, if the blue channel contains a value anywhere in the range `0.400`--`0.466`, the value does not matter---we will always sample the final color from cell number 6 where the blue channel is set to `0.400`.
+
+To get better blue channel resolution, we can implement the interpolation ourselves. If the blue value is in between the value of two adjacent cells, we can sample from both of these cells and then mix the colors. For example, if the blue value is `0.420` we should sample from cell number 6 *and* from cell number 7 and then mix the colors.
+
+So, we should read from two cells:
+
+$$
+cell_{low} = \left \lfloor{B \times (N - 1)} \right \rfloor
+$$
+
+and:
+
+$$
+cell_{high} = \left \lceil{B \times (N - 1)} \right \rceil
+$$
+
+Then we sample color values from each of these cells and interpolate the colors linearly, according to the formula:
+
+$$
+color = color_{low} \times (1 - C_{frac}) + color_{high} \times C_{frac}
+$$
+
+Here `color`~low~ is the color sampled from the lower (leftmost) cell and `color`~high~ is the color sampled from the higher (rightmost) cell. The GLSL function `mix()` performs this linear interpolation for us.
+
+The value `C`~frac~ above is the fractional part of the blue channel value scaled to the `0`--`15` color range:
+
+$$
+C_{frac} = B \times (N - 1) - \left \lfloor{B \times (N - 1)} \right \rfloor
+$$
+
+Again, there is a GLSL function that gives us the fractional part of a value. It's called `frac()`. The final implementation in the fragment shader (*grade.fp*) is quite straightforward:
+
+```glsl
+varying mediump vec4 position;
+varying mediump vec2 var_texcoord0;
+
+uniform lowp sampler2D original;
+uniform lowp sampler2D lut;
+
+#define MAXCOLOR 15.0
+#define COLORS 16.0
+#define WIDTH 256.0
+#define HEIGHT 16.0
+
+void main()
+{
+  vec4 px = texture2D(original, var_texcoord0.xy);
+
+    float cell = px.b * MAXCOLOR;
+
+    float cell_l = floor(cell); // <1>
+    float cell_h = ceil(cell);
+
+    float half_px_x = 0.5 / WIDTH;
+    float half_px_y = 0.5 / HEIGHT;
+    float r_offset = half_px_x + px.r / COLORS * (MAXCOLOR / COLORS);
+    float g_offset = half_px_y + px.g * (MAXCOLOR / COLORS);
+
+    vec2 lut_pos_l = vec2(cell_l / COLORS + r_offset, g_offset); // <2>
+    vec2 lut_pos_h = vec2(cell_h / COLORS + r_offset, g_offset);
+
+    vec4 graded_color_l = texture2D(lut, lut_pos_l); // <3>
+    vec4 graded_color_h = texture2D(lut, lut_pos_h);
+
+    // <4>
+    vec4 graded_color = mix(graded_color_l, graded_color_h, fract(cell));
+
+    gl_FragColor = graded_color;
+}
+```
+1. Calculate the two adjacent cells to read from.
+2. Calculate two separate lookup positions, one for each cell.
+3. Sample the two colors from the cell positions.
+3. Mix the colors linearly according to the fraction of `cell`, which is the scaled blue color value.
+
+Running the game again with the test texture now yields much better results. The banding on the blue channel is gone:
+
+![blue no banding](images/grading/blue_no_banding.png)
+
+## Grading the lookup texture
+
+Okay, that was a lot of work to draw something that looks exactly like the original game world. But this setup allows us to do something really cool. Hang on now!
+
+1. Take a screenshot of the game in its unaffected form.
+2. Open the screenshot in your favorite image manipulation program.
+3. Apply any number of color adjustments (brightness, contrast, color curves, white balance, exposure etc, etc).
+
+    ![world in Affinity](images/grading/world_graded_affinity.png)
+
+4. Apply the same color adjustments to the lookup table texture file (*lut16.png*).
+5. Save the color adjusted lookup table texture file.
+6. Replace the texture *lut16.png* used in your Defold project with the color adjusted one.
+7. Run the game!
+
+![world graded](images/grading/world_graded.png)
+
+Joy!

+ 145 - 0
docs/zh/tutorials/hud.md

@@ -0,0 +1,145 @@
+---
+title: HUD code sample
+brief: In this sample, you learn effects for score counting.
+---
+# HUD
+
+<iframe width="560" height="315" src="https://www.youtube.com/embed/bcU9PCrPAeY" frameborder="0" allowfullscreen></iframe>
+
+In this sample, we demonstrate effects for score counting. The scores appear randomly over the screen, simulating a game where the player obtains scores at different positions.
+
+The scores float for a while after they appear. To achieve this, we set the scores to transparent and then fade in their color. We also animate them upwards. This is done in `on_message()` below.
+
+Then they move up to the total score in the top of the screen where they are summed up.
+They are also slightly fading out while moving up. This is done in `float_done()`.
+
+When they have reached the top score, their amounts are added to a target score that the total score counts up towards. This is done in `swoosh_done()`.
+
+When the script is updated, it checks if the target score has been increased and the total score needs to be counted up. When this is true, the total score is incremented by a smaller step.
+The scale of the total score is then animated to give a bouncing effect. This is done in `update()`.
+
+Each time the total is incremented, we spawn an amount of smaller stars and animate them out from the total score. The stars are spawned, animated and deleted in `spawn_stars()`, `fade_out_star()` and `delete_star()`.
+
+```lua
+-- file: hud.gui_script
+-- how fast the score counts up per second
+local score_inc_speed = 1000
+
+function init(self)
+    -- the target score is the current score in the game
+    self.target_score = 0
+    -- the current score being counted up towards the target score
+    self.current_score = 0
+    -- the score as displayed in the hud
+    self.displayed_score = 0
+    -- keep a reference to the node displaying the score for later use below
+    self.score_node = gui.get_node("score")
+end
+
+local function delete_star(self, star)
+    -- star has finished animation, delete it
+    gui.delete_node(star)
+end
+
+local function fade_out_star(self, star)
+    -- fade out the star before deletion
+    gui.animate(star, gui.PROP_COLOR, vmath.vector4(1, 1, 1, 0), gui.EASING_INOUT, 0.2, 0.0, delete_star)
+end
+
+local function spawn_stars(self, amount)
+    -- position of the score node, to be used for placing the stars
+    local p = gui.get_position(self.score_node)
+    -- distance from the position where the star is spawned
+    local start_distance = 0
+    -- distance where the star stops
+    local end_distance = 240
+    -- angle distance between each star in the star circle
+    local angle_step = 2 * math.pi / amount
+    -- randomize start angle
+    local angle = angle_step * math.random()
+    for i=1,amount do
+        -- increment the angle by the step to get an even distribution of stars
+        angle = angle + angle_step
+        -- direction of the star movement
+        local dir = vmath.vector3(math.cos(angle), math.sin(angle), 0)
+        -- start/end positions of the star
+        local start_p = p + dir * start_distance
+        local end_p = p + dir * end_distance
+        -- create the star node
+        local star = gui.new_box_node(vmath.vector3(start_p.x, start_p.y, 0), vmath.vector3(30, 30, 0))
+        -- set its texture
+        gui.set_texture(star, "star")
+        -- set to transparent
+        gui.set_color(star, vmath.vector4(1, 1, 1, 0))
+        -- fade in
+        gui.animate(star, gui.PROP_COLOR, vmath.vector4(1, 1, 1, 1), gui.EASING_OUT, 0.2, 0.0, fade_out_star)
+        -- animate position
+        gui.animate(star, gui.PROP_POSITION, end_p, gui.EASING_NONE, 0.55)
+    end
+end
+
+function update(self, dt)
+    -- check if the score needs to be updated
+    if self.current_score < self.target_score then
+        -- increment the score for this timestep to grow towards the target score
+        self.current_score = self.current_score + score_inc_speed * dt
+        -- clamp the score so it doesn't grow past the target score
+        self.current_score = math.min(self.current_score, self.target_score)
+        -- floor the score so it can be displayed without decimals
+        local floored_score = math.floor(self.current_score)
+        -- check if the displayed score should be updated
+        if self.displayed_score ~= floored_score then
+            -- update displayed score
+            self.displayed_score = floored_score
+            -- update the text of the score node
+            gui.set_text(self.score_node, string.format("%d p", self.displayed_score))
+            -- set the scale of the score node to be slightly bigger than normal
+            local s = 1.3
+            gui.set_scale(self.score_node, vmath.vector3(s, s, s))
+            -- then animate the scale back to the original value
+            s = 1.0
+            gui.animate(self.score_node, gui.PROP_SCALE, vmath.vector3(s, s, s), gui.EASING_OUT, 0.2)
+            -- spawn stars
+            spawn_stars(self, 4)
+        end
+    end
+end
+
+-- this function stores the added score so that the displayed score can be counted up in the update function
+local function swoosh_done(self, node)
+    -- retrieve score from node
+    local amount = tonumber(gui.get_text(node))
+    -- increase the target score, see the update function for how the score is updated to match the target score
+    self.target_score = self.target_score + amount
+    -- remove the temp score
+    gui.delete_node(node)
+end
+
+-- this function animates the node from having floated first to swoosh away towards the displayed total score
+local function float_done(self, node)
+    local duration = 0.2
+    -- swoosh away towards the displayed score
+    gui.animate(node, gui.PROP_POSITION, gui.get_position(self.score_node), gui.EASING_IN, duration, 0.0, swoosh_done)
+    -- also fade out partially during the swoosh
+    gui.animate(node, gui.PROP_COLOR, vmath.vector4(1, 1, 1, 0.6), gui.EASING_IN, duration)
+end
+
+function on_message(self, message_id, message, sender)
+    -- register added score, this message could be sent by anyone wanting to increment the score
+    if message_id == hash("add_score") then
+        -- create a new temporary score node
+        local node = gui.new_text_node(message.position, tostring(message.amount))
+        -- use the small font for it
+        gui.set_font(node, "small_score")
+        -- initially transparent
+        gui.set_color(node, vmath.vector4(1, 1, 1, 0))
+        gui.set_outline(node, vmath.vector4(0, 0, 0, 0))
+        -- fade in
+        gui.animate(node, gui.PROP_COLOR, vmath.vector4(1, 1, 1, 1), gui.EASING_OUT, 0.3)
+        gui.animate(node, gui.PROP_OUTLINE, vmath.vector4(0, 0, 0, 1), gui.EASING_OUT, 0.3)
+        -- float
+        local offset = vmath.vector3(0, 20, 0)
+        gui.animate(node, gui.PROP_POSITION, gui.get_position(node) + offset, gui.EASING_NONE, 0.5, 0.0, float_done)
+    end
+end
+```

BIN
docs/zh/tutorials/images/15-puzzle/display_settings.png


BIN
docs/zh/tutorials/images/15-puzzle/input.png


BIN
docs/zh/tutorials/images/15-puzzle/main_collection.png


BIN
docs/zh/tutorials/images/15-puzzle/monalisa.png


BIN
docs/zh/tutorials/images/15-puzzle/slide.png


BIN
docs/zh/tutorials/images/15-puzzle/tilemap.png


BIN
docs/zh/tutorials/images/15-puzzle/tilesource.png


BIN
docs/zh/tutorials/images/car/start_add_car_component.png


BIN
docs/zh/tutorials/images/car/start_add_car_gameobject.png


BIN
docs/zh/tutorials/images/car/start_adding_car_collection.png


BIN
docs/zh/tutorials/images/car/start_build_and_launch.png


BIN
docs/zh/tutorials/images/car/start_car.png


BIN
docs/zh/tutorials/images/car/start_car_collection_complete.png


BIN
docs/zh/tutorials/images/car/start_delete_go.png


Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff