Browse Source

Chinese manual up-to-date (#378)

* update physics

* update input

* update

* update code sharing in getting-help.md

* Export Compliance

* update on file i/o

* pi / 4

* inputs

* forum url

* read only user

* html5 gamepad

* sdk api update

* update

* image properties

* update editor

* defold sdk update

* animation updates

* animation fix

* run as admin

* update bob

* update about AndroidX support

* software render

* linux-faq.md update

* 4.28.2021 updates

* Basis Universal format

* sound & mesh

* gamepad event mapping

* admob url

* Minor edit to building blocks intro text

* update gamepad & ios

* project settings

* libffi version

* scaling

* image compression

* update gamepads

* increase memory

* caching assets

* update 2021/10/6

* update 2021/10/16
blend-modes.md

* update 2021/11/12

* allow dynamic transforms update

* Bundle update

* update faq

* bullet & bob

* script properties update

* editor-styling

* build server url

* editor templates

* spine extension update

* Fix typo in the "optimizations" word in Chinese docs

* Update to material.md - Constants buffers

* Verify Graphics Calls

* H5 parameters

* OpenJDK downloads

* cn update corresponds to [pull 259](https://github.com/defold/doc/pull/259)

* application security

* porting guidelines

* update for 8f1651f

* cn update for 094bf6f

* cn update for 20fdfc5 & 6263317

* cn update for 7/19/2022

* title

* profiling update

* update editor.md

* update bob.md

* update shortcuts

* update fixed update note

* Update properties.md

* Update material.md

* Updates links

* Update bob help with the latest info

* camera & renderer

* Updated android keystore info zh_cn

* bundling.md release vs debug zh_cn

* update bob.md & gui-clipping.md

* contentless bundle

* consoles update

* model animation link

* gamepad & faq

* remove a camera lib

* font shadow render mode fix

* updates about app-manifest and others

* Update script.md

* includes in shaders

* editor scripts

* material updates

* Added dynamic atlas and texture creation

* fixes for atlas and some others

* update screenshots and add explanations (CN)

* add a line about Dynamic Prototype (CN)

* remove "inline" marks in pics

* de-translate the subtitle "Running the debugger" & images fix

* bundle identifier restrictions

* node properties Enabled and Visible (CN)

* release checklist & slice-9

* Update project-settings.md (CN)

* Update camera.md (CN)

* Update project-settings.md (CN)

* culling of meshes (CN)

* Update project-settings.md (CN)

* gltf model file support (CN)

* updates about factory (CN)

* Update bob.md (CN)

* Update bob.jar help (CN)

* Update about renderer and other things

* Update PS4 development and other things

* Dynamic prototype part of the collection factory.

* sync to atlas.md

* sync to design.md

* sync to gpgs.md

* sync to hot-reload.md

* sync to linux.md

* sync to live-update.md

* sync to lua.md

* sync to networking.md

* sync to physics-shapes.md

* sync to push.md

* sync to test.md

* sync to working-offline.md

* update material.md

* update zerobrane.md

* all done
COCO 1 year ago
parent
commit
685694b604
64 changed files with 864 additions and 861 deletions
  1. 11 7
      docs/zh/manuals/bob.md
  2. 5 1
      docs/zh/manuals/building-blocks.md
  3. 9 0
      docs/zh/manuals/camera.md
  4. 3 1
      docs/zh/manuals/components.md
  5. 7 0
      docs/zh/manuals/debugging-game-logic.md
  6. 2 1
      docs/zh/manuals/debugging-native-code-android.md
  7. 5 1
      docs/zh/manuals/debugging-native-code.md
  8. 1 7
      docs/zh/manuals/dev-app.md
  9. 3 0
      docs/zh/manuals/editor-keyboard-shortcuts.md
  10. 32 4
      docs/zh/manuals/editor-preferences.md
  11. 1 0
      docs/zh/manuals/editor-scripts.md
  12. 3 1
      docs/zh/manuals/extensions-build-variants.md
  13. 1 77
      docs/zh/manuals/extensions-debugging-android.md
  14. 1 156
      docs/zh/manuals/extensions-debugging.md
  15. 1 6
      docs/zh/manuals/extensions-details.md
  16. 4 0
      docs/zh/manuals/file-access.md
  17. 0 4
      docs/zh/manuals/flipbook-animation.md
  18. 19 13
      docs/zh/manuals/getting-help.md
  19. 4 152
      docs/zh/manuals/graphics.md
  20. 4 0
      docs/zh/manuals/gui-box.md
  21. 7 2
      docs/zh/manuals/gui-clipping.md
  22. 6 6
      docs/zh/manuals/gui.md
  23. 19 12
      docs/zh/manuals/html5.md
  24. 1 0
      docs/zh/manuals/importing-models.md
  25. 1 1
      docs/zh/manuals/input-gamepads.md
  26. 9 7
      docs/zh/manuals/input-key-and-text.md
  27. 2 2
      docs/zh/manuals/input-mouse-and-touch.md
  28. 19 1
      docs/zh/manuals/ios.md
  29. 1 1
      docs/zh/manuals/label.md
  30. 2 2
      docs/zh/manuals/libraries.md
  31. 127 0
      docs/zh/manuals/live-update-aws.md
  32. 134 0
      docs/zh/manuals/live-update-scripting.md
  33. 47 285
      docs/zh/manuals/live-update.md
  34. 20 2
      docs/zh/manuals/lua.md
  35. 55 1
      docs/zh/manuals/material.md
  36. 1 0
      docs/zh/manuals/message-passing.md
  37. 1 1
      docs/zh/manuals/model.md
  38. 3 15
      docs/zh/manuals/nintendo-switch.md
  39. 27 1
      docs/zh/manuals/optimization.md
  40. 0 1
      docs/zh/manuals/physics-groups.md
  41. 1 0
      docs/zh/manuals/physics-joints.md
  42. 12 0
      docs/zh/manuals/physics-messages.md
  43. 11 11
      docs/zh/manuals/physics-objects.md
  44. 3 1
      docs/zh/manuals/physics-resolving-collisions.md
  45. 3 3
      docs/zh/manuals/physics-shapes.md
  46. 0 4
      docs/zh/manuals/physics.md
  47. 60 10
      docs/zh/manuals/porting-guidelines.md
  48. 9 4
      docs/zh/manuals/project-settings.md
  49. 1 0
      docs/zh/manuals/properties.md
  50. 0 1
      docs/zh/manuals/property-animation.md
  51. 1 1
      docs/zh/manuals/refactoring.md
  52. 8 4
      docs/zh/manuals/render.md
  53. 29 0
      docs/zh/manuals/script-properties.md
  54. 16 0
      docs/zh/manuals/script.md
  55. 4 0
      docs/zh/manuals/shader.md
  56. 6 24
      docs/zh/manuals/sony-playstation.md
  57. 12 0
      docs/zh/manuals/sprite.md
  58. 1 1
      docs/zh/manuals/texture-profiles.md
  59. 53 5
      docs/zh/manuals/writing-code.md
  60. 0 5
      docs/zh/shared/consoles-faq.md
  61. 9 6
      docs/zh/shared/editor-faq.md
  62. 5 8
      docs/zh/shared/linux-faq.md
  63. 5 1
      docs/zh/shared/slice-9-texturing.md
  64. 17 1
      docs/zh/shared/windows-faq.md

+ 11 - 7
docs/zh/manuals/bob.md

@@ -9,12 +9,16 @@ Bob 是一个用于Defold项目编辑器之外的命令行编译工具.
 
 Bob 用来编译操作 (对应编辑器里的 <kbd>Project ▸ Build</kbd>), 来创建数据档或者创建可独立发布的应用 (对应编辑器里的 <kbd>Project ▸ Bundle ▸ ...</kbd> 选项)
 
-Bob 集合了编译所需的一切, 作为Java包 _JAR_ 发布. 最新的 *bob.jar* 发布在 [Defold 下载页](http://d.defold.com) 和 [GitHub 发布页](https://github.com/defold/defold/releases) 上. 选择一个版本, 下载 *bob/bob.jar*. 运行这个工具, 您需要安装 OpenJDK 17.
+Bob 集合了编译所需的一切, 作为Java包 _JAR_ 发布. 最新的 *bob.jar* 发布在 [Defold 下载页](http://d.defold.com) 和 [GitHub 发布页](https://github.com/defold/defold/releases) 上. 选择一个版本, 下载 *bob/bob.jar*. 如果你使用的是 Defold 1.4.8, 您需要安装 OpenJDK 17. 对于 Defold 老版本, 你需要 openJDK 11.
 
-下载 OpenJDK 17 的地址:
+兼容 OpenJDK 17 镜像 (自从 Defold 1.4.8):
 * https://docs.microsoft.com/en-us/java/openjdk/download#openjdk-17
 * https://github.com/adoptium/temurin17-binaries/releases / https://adoptium.net/
 
+兼容 OpenJDK 11 镜像 (最高到 Defold 1.4.7):
+* https://docs.microsoft.com/en-us/java/openjdk/download#openjdk-11
+* https://github.com/adoptium/temurin11-binaries/releases / https://adoptium.net/
+
 比如在 Windows 平台上, 需要下载 OpenJDK 17 的 .msi 安装包.
 
 ## 用法
@@ -34,9 +38,8 @@ usage: bob [options] [commands]
 -bo,--bundle-output <arg>               打包输出目录
 -br,--build-report <arg>                自从 Defold 1.4.6 版本后已弃用! 
                                         使用 --build-report-json 代替
--brjson,--build-report-json <arg>       保存 JSON 编译报告的文件路径位置
-                                        (自从 Defold 1.4.6 版本启用)
 -brhtml,--build-report-html <arg>       指定编译生成的HTML报告的存放地址
+-brjson,--build-report-json <arg>       保存 JSON 编译报告的文件路径位置 (自从 Defold 1.4.6 版本启用)
     --build-artifacts <arg>             不指定的话默认为编译engine.
                                         可选项为 'engine', 'plugins'.
                                         以逗号分隔.
@@ -49,8 +52,8 @@ usage: bob [options] [commands]
     --defoldsdk <arg>                   指定 defold sdk (sha1) 使用版本
 -e,--email <arg>                        用户电邮
 -ea,--exclude-archive                   要从打包中排除的资源档案. 以此创建空应用用作编译目标
-    --exclude-build-folder              DEPRECATED from Defold 1.5.1! Use
-                                        '.defignore' file instead
+    --exclude-build-folder              自从 Defold 1.5.1 已弃用! 使用
+                                        '.defignore' 文件代替
 -h,--help                               该命令的帮助文档
 -i,--input <arg>                        指定源目录, 默认是当前目录
     --identity <arg>                    指定签名 (iOS)
@@ -140,7 +143,8 @@ usage: bob [options] [commands]
 `armv7-android`
 : Android 支持 32 bit `armv7-android` 和 64 bit `arm64-android` 架构. 默认情况下, `--architectures` 参数值为 `armv7-android,arm64-android`.
 
-`js-web` : HTML5 支持 `js-web` 和 `wasm-web` 架构. 默认情况下, `--architectures` 参数值为 `js-web,wasm-web`.
+`js-web`
+: HTML5 支持 `js-web` 和 `wasm-web` 架构. 默认情况下, `--architectures` 参数值为 `js-web,wasm-web`.
 
 默认情况下, Bob 在当前目录下寻找项目来编译. 切换到 Defold 项目目录下使用 bob, 它会把数据编译到默认输出 *build/default* 目录下.
 

+ 5 - 1
docs/zh/manuals/building-blocks.md

@@ -86,6 +86,10 @@ go.animate("can", "position.x", go.PLAYBACK_LOOP_PINGPONG, 100, go.EASING_LINEAR
 
 修改了原型文件, 那么它的所有实例都能一同被修改.
 
+![GO changing prototype](images/building_blocks/go_change_blueprint.png){srcset="images/building_blocks/[email protected] 2x"}
+
+这里原型的 sprite 图片被更改, 同时所有使用该文件的实例都被更新:
+
 ![GO instances updated](images/building_blocks/go_instance2.png){srcset="images/building_blocks/[email protected] 2x"}
 
 ## 游戏对象层级
@@ -107,6 +111,6 @@ local parent = go.get_id("bean")
 msg.post("child_bean", "set_parent", { parent_id = parent })
 ```
 
-::: sidenote
+::: important
 一个常见的误解是对象层级改变了那么它的定位地址也会改变. 但是, 这其实是两码事. 父子关系改变的是场景的层级. 集合嵌套关系才决定对象地址. 在对象整个生命周期中, 地址是不会变化的.
 :::

+ 9 - 0
docs/zh/manuals/camera.md

@@ -148,6 +148,15 @@ end
 `orthographic_zoom`
 : 平视摄像机缩放 (`number`).
 
+`aspect_ratio`
+: 自从 Defold 1.4.8 加入. 视口宽高比. 在计算透视摄像机投射时使用. (`number`).
+
+`view`
+: 自从 Defold 1.4.8 加入. 摄像机视口矩阵值. 只读. (`matrix4`).
+
+`projection`
+: 自从 Defold 1.4.8 加入. 摄像机投射矩阵值. 只读. (`matrix4`).
+
 
 ## 第三方摄像机解决方案
 

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

@@ -87,7 +87,7 @@ Defold 组件属性各不相同.在 [Outline 面板](/manuals/editor/#Outline 
 
 例如: 两个游戏对象 A 和 B. B 是 A 的子集. B 有一个sprite组件.
 
-| 元素     | z值      |
+| 元素      | z值     |
 |----------|---------|
 | A        | 2       |
 | B        | 1       |
@@ -103,3 +103,5 @@ Defold 组件属性各不相同.在 [Outline 面板](/manuals/editor/#Outline 
 渲染脚本为 z 值定义了极近端和极远端平面. z值在此范围之外的组件不会被渲染. 默认范围是 -1 到 1 但是 [可以任意修改](/manuals/render/#默认视口映射).
 Z 值得极近与极远坐标范围是 -1 到 1 的话, 需要很高的数值精度. 在处理 3D 资源时, 可能需要在你的自定义渲染脚本中修改极近和极远的坐标范围. 详情请见 [渲染教程](/manuals/render/).
 :::
+
+:[组件最大数配置](../shared/component-max-count-optimizations.md)

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

@@ -87,6 +87,13 @@ Step Out
 
   设置/清除断点, 可以在代码编辑器里行号右边右键点击. 还可以从菜单中选择 <kbd>Edit ▸ Toggle Breakpoint</kbd>.
 
+设置条件断点
+: 可以设置需要计算条件为真才触发的断点. 条件可以读取随着代码执行当前行的本地变量.
+
+  ![edit breakpoint](images/debugging/edit_breakpoint.png){srcset="images/debugging/[email protected] 2x"}
+
+  要编辑断电条件, 右键点击代码编辑器行号的右边的列, 或者从菜单栏点选 <kbd>Edit ▸ Edit Breakpoint</kbd>.
+
 执行Lua表达式
 : 调试器停在断点上时, 可以直接使用包含有当前上下文的 Lua 运行时. 在控制台底部输入表达式后按 <kbd>回车键</kbd> 来运行:
 

+ 2 - 1
docs/zh/manuals/debugging-native-code-android.md

@@ -7,6 +7,7 @@ brief: 本教程介绍了在使用 Android Studio 调试游戏的方法.
 
 下面介绍了如何使用 [Android Studio](https://developer.android.com/studio/), 即 Google 的 Android 操作系统的官方 IDE, 来调试游戏的方法.
 
+
 ## Android Studio
 
 * 在 *game.project* 中设置 `android.debuggable`
@@ -45,7 +46,7 @@ brief: 本教程介绍了在使用 Android Studio 调试游戏的方法.
 
 * 注意一定要获取与你所用版本完全一致的引擎版本
 
-		defold$ git checkout 1.2.148
+	defold$ git checkout 1.2.148
 
 * 点击 `Apply changes`
 

+ 5 - 1
docs/zh/manuals/debugging-native-code.md

@@ -49,6 +49,10 @@ Defold 几经测试鲜有崩溃情况出现. 但是崩溃这种事谁能保证
 
 可以使用 [崩溃模块](https://www.defold.com/ref/crash/) 帮助分析这个文件. 推荐你阅读, 收集信息, 打印信息到控制台, 然后把信息发送到 [第三方分析服务](/tags/stars/analytics/) 上去.
 
+::: important
+在 Windows 上还有个 `_crash.dmp` 文件被创建. 这个文件在调试崩溃时很有用.
+:::
+
 ### 从设备上获取崩溃日志
 
 手机上的崩溃日志可以下载到本地以便查看.
@@ -82,7 +86,7 @@ $ adb shell "run-as com.defold.example sh -c 'cat /data/data/com.defold.example/
 * HTML5 - 在 `build/js-web` 或 `build/wasm-web` 下的 `dmengine.js.symbols` 中包含有 HTML5 编译用 debug symbols.
 
 
-::: sidenote
+::: important
 对于游戏的每个发布版本一定要保留一套对应的调试数据. 不然的话原生扩展上线以后出错误就没法调试! 为了方便查看调用堆栈, 也要保存好对应的游戏引擎.
 :::
 

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

@@ -9,13 +9,7 @@ brief: 本教程介绍了如何在设备上安装开发用app以方便开发流
 
 ## 安装开发用app
 
-Debug  模式下编译的任何 iOS 或 Android 应用都可以作为开发用app. 事实上, 我们推荐这么做因为开发用app包含正确的项目配置而且拥有和开发时使用的相同的 [原生扩展](/manuals/extensions/). 还有 [Defold 的独立项目](https://github.com/defold/dev-app) (不包含原生扩展的项目) 也设计做为开发用app使用.
-
-![launch](images/dev-app/launch.png)
-
-::: sidenote
-只有在不使用 [原生扩展](/manuals/extensions/) 的项目可以使用我们提供的开发用apk. 否则你需要自己手动打debug包并且加入你所使用的原生扩展.
-:::
+Debug 模式下编译的任何 iOS 或 Android 应用都可以作为开发用app. 事实上, 我们推荐这么做因为开发用app包含正确的项目配置而且拥有和开发时使用的相同的 [原生扩展](/manuals/extensions/).
 
 从 Defold 1.4.0 版本开始可以给项目打空的 debug 包. 使用这个选项可以创建带原生扩展的应用版本, 适合于教程里提到的开发迭代.
 

+ 3 - 0
docs/zh/manuals/editor-keyboard-shortcuts.md

@@ -29,6 +29,7 @@ brief: 本教程介绍了当前编辑器快捷键以及如何自定义快捷键.
 | 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> |
+| Edit breakpoint | <kbd>Alt</kbd>+<kbd>F9</kbd> | <kbd>Alt</kbd>+<kbd>F9</kbd> | <kbd>Alt</kbd>+<kbd>F9</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> |
@@ -36,8 +37,10 @@ brief: 本教程介绍了当前编辑器快捷键以及如何自定义快捷键.
 | Escape | <kbd>Esc</kbd> | <kbd>Esc</kbd> | <kbd>Esc</kbd> |
 | Find next | <kbd>Ctrl</kbd>+<kbd>G</kbd>, <kbd>Enter</kbd> | <kbd>Cmd</kbd>+<kbd>G</kbd>, <kbd>Enter</kbd> | <kbd>Ctrl</kbd>+<kbd>G</kbd>, <kbd>Enter</kbd> |
 | Find prev | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>G</kbd>, <kbd>Shift</kbd>+<kbd>Enter</kbd> | <kbd>Shift</kbd>+<kbd>Cmd</kbd>+<kbd>G</kbd>, <kbd>Shift</kbd>+<kbd>Enter</kbd> | <kbd>Shift</kbd>+<kbd>Ctrl</kbd>+<kbd>G</kbd>, <kbd>Shift</kbd>+<kbd>Enter</kbd> |
+| Find references | <kbd>Shift</kbd>+<kbd>F12</kbd> | <kbd>Shift</kbd>+<kbd>F12</kbd> | <kbd>Shift</kbd>+<kbd>F12</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 definition | <kbd>F12</kbd> | <kbd>F12</kbd> | <kbd>F12</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> |

+ 32 - 4
docs/zh/manuals/editor-preferences.md

@@ -32,7 +32,7 @@ Path to custom keymap
 
 ## Code
 
-![](images/editor/preferences_code.png){srcset="images/editor/[email protected] 2x"}
+![](images/editor/preferences_code.png)
 
 Custom Editor
 : 自定义编辑器的绝对路径. 在 macOS 上应指向 .app 内的可执行程序 (比如 `/Applications/Atom.app/Contents/MacOS/Atom`).
@@ -47,12 +47,40 @@ Code editor font
 : 代码编辑器里要使用的系统上已安装的字体名称.
 
 
-## Extensions
+### 使用 Visual Studio Code 打开脚本文件
 
-![](images/editor/preferences_extensions.png){srcset="images/editor/[email protected] 2x"}
+![](images/editor/preferences_vscode.png)
+
+要从 Defold 编辑器里直接用 Visual Studio Code 打开脚本文件, 必须配置下列可执行文件地址:
+
+- MacOS: `/Applications/Visual Studio Code.app/Contents/MacOS/Electron`
+- Linux: `/usr/bin/code`
+- Windows: `C:\Program Files\Microsoft VS Code\Code.exe`
+
+ 配置打开指定文件和指定行号的参数:
+
+- 打开文件: `. {file}`
+- 打开到行: `. -g {file}:{line}`
+
+其中 `.` 符号代表打开整个项目, 而不是指定文件.
+
+
+## 扩展
+
+![](images/editor/preferences_extensions.png)
 
 Build Server
 : 编译包含 [原生扩展](/manuals/extensions) 项目时使用的编译服务器的 URL. 可以在编译服务器的请求 URL 中加入用户名和验证令牌. 使用格式举例: `username:[email protected]`. 在使用用户自己的编译服务器并开启认证时, 任天堂 Switch 编译需要这种用户认证 ([更多信息详见编译服务器文档](https://github.com/defold/extender/blob/dev/README_SECURITY.md)). 其中用户名和密码可以用系统环境变量 `DM_EXTENDER_USERNAME` 和 `DM_EXTENDER_PASSWORD` 来设置.
 
 Build Server Headers
-: 编译原生扩展时向服务器发送的额外的 header. 在使用 CloudFlare 服务或类似服务编译扩展时是很必要的.
+: 编译原生扩展时向服务器发送的额外的 header. 在使用 CloudFlare 服务或类似服务编译扩展时是很必要的.
+
+## 工具
+
+![](images/editor/preferences_tools.png)
+
+ADB path
+: 配置 [ADB](https://developer.android.com/tools/adb) 命令行工具的路径. 如果系统中安装了 ADB, 则 Defold 编辑器会使用它来安装和运行 Android APK 包到指定设备. 默认情况下, 编辑器会检查 ADB 是否安装在了默认位置, 如果需要手动指定路径则需配置该选项.
+
+ios-deploy path
+: 配置 [ios-deploy](https://github.com/ios-control/ios-deploy) 命令行工具的路径 (仅适用于 macOS). 与 ADB 路径类似, Defold 编辑器会使用该工具安装和运行 iOS 包到连接好的 iPhone 上. 默认情况下, 编辑器会检查 ios-deploy 是否安装在了默认位置, 如果需要手动指定路径则需配置该选项.

+ 1 - 0
docs/zh/manuals/editor-scripts.md

@@ -53,6 +53,7 @@ return M
     注意这些属性有的不是只读的, 而且基于上下文有些可能不可用, 所以要在读取之前执行 `editor.can_get`, 设置之前执行 `editor.can_set`. 属性面板里用鼠标悬停在属性名上会显示一个信息提示标明该属性在编辑器脚本里是如何命名的. 资源属性赋值为 `""` 代表 nil 值.
 - `editor.can_get(node_id, property)` — 检查属性是否可读, 确保 `editor.get()` 不会报错
 - `editor.can_set(node_id, property)` — 检查属性是否可写, 确保设置操作不会报错
+- `editor.create_directory(resource_path)` — 新建文件夹, 及其所有父文件夹
 
 ## Command
 

+ 3 - 1
docs/zh/manuals/extensions-build-variants.md

@@ -15,7 +15,9 @@ brief: 本教程介绍了 Defold 能创建的各种 Build variants 以及它们
 
 不同类型即是 `Build variants`
 
-注意: 使用 <kbd>Project ▸ Build</kbd> 时使用的是 debug 版引擎.
+::: sidenote
+使用 <kbd>Project ▸ Build</kbd> 时使用的是 debug 版引擎.
+:::
 
 ### Debug
 

+ 1 - 77
docs/zh/manuals/extensions-debugging-android.md

@@ -3,80 +3,4 @@ title: Android调试
 brief: 本教程介绍了如何调试运行在 Android 设备上的应用.
 ---
 
-# Android调试
-
-这里列举了一些在 Android 设备上调试应用的方法.
-
-## Android Studio
-
-* 打包前在  *game.project* 打开 `android.debuggable` 选项
-
-	![android.debuggable](images/extensions/debugging/android/game_project_debuggable.png)
-
-* 编译时选择 debug 模式.
-
-	![bundle_android](images/extensions/debugging/android/bundle_android.png)
-
-* 启动 [Android Studio](https://developer.android.com/studio/)
-
-* 选择 `Profile or debug APK`
-
-	![debug_apk](images/extensions/debugging/android/android_profile_or_debug.png)
-
-* 选择刚打包好的apk文件
-
-	![select_apk](images/extensions/debugging/android/android_select_apk.png)
-
-* 选择主 `.so` 文件, 确保其包含调试信息
-
-	![select_so](images/extensions/debugging/android/android_missing_symbols.png)
-
-* 如果没有调试信息, 提交一个带调试信息的 `.so` 文件. (文件大概 20mb 左右)
-
-* 路径映射帮助你重新把应用的各个路径从编译的地方 (在云端) 映射到你的本地目录下.
-
-* 选择 .so 文件, 再添加一个到本地的映射
-
-	![path_mapping1](images/extensions/debugging/android/path_mappings_android.png)
-
-	![path_mapping2](images/extensions/debugging/android/path_mappings_android2.png)
-
-* 如果你访问了引擎代码, 同样要添加一个对引擎代码的路径映射
-
-		* 确定checkout的是你正在调试的版本
-
-			defold$ git checkout 1.2.148
-
-* 点击 `Apply changes`
-
-* 现在你应该可以看到你的项目的代码映射了
-
-	![source](images/extensions/debugging/android/source_mappings_android.png)
-
-* 加入断点
-
-	![breakpoint](images/extensions/debugging/android/breakpoint_android.png)
-
-* 点击 `Run` -> `Debug "Appname"` 然后调用加入断点代码
-
-	![breakpoint](images/extensions/debugging/android/callstack_variables_android.png)
-
-* 现在你就可以在调用栈中步进调试和查看变量状态了
-
-
-## 注意
-
-### 原生扩展 job 目录
-
-目前, 工作流对于项目开发有点麻烦. 这是因为job目录名是随机的, 没法进行路径映射.
-
-但是对于调试来说还是可行的.
-
-路径映射保存在 Android Studio 项目的 <project>.iml 文件中.
-
-这样就能获得当前应用的job目录名
-
-	$ arm-linux-androideabi-readelf --string-dump=.debug_str build/armv7-android/libdmengine.so | grep /job
-
-job目录命名类似 `job1298751322870374150`, 每次编译都随机命名.
-
+教程移动至 [调试 Android 原生代码](/manuals/debugging-native-code-android)

+ 1 - 156
docs/zh/manuals/extensions-debugging.md

@@ -3,159 +3,4 @@ title: 调试原生扩展
 brief: 本教程介绍了一些调试包含原生扩展程序应用的方法.
 ---
 
-# 调试原生扩展
-
-开发原生扩展程序的时候总会碰到这样那样的问题,比如在编译服务器上编译不通过或者应用里扩展程序无效等等.
-
-## 报错调试
-
-通常一旦原生扩展程序在编译服务器上报错, 服务器控制台会给出所有的错误信息. 包括错误类型和哪个文件哪一行出的错. 同时 `log.txt` 日志文件也会被保存在编译文件夹当中.
-
-## 运行时调试
-
-一旦原生扩展的程序代码出了问题, 有一下途径可以找到问题所在.
-
-* Using a debugger
-* Using print debugging
-* Analyzing a crash log
-* Symbolicating a callstack
-
-### 使用调试器
-
-当你的代码出现问题时, 有一些方法可以找到问题的根源.
-
-最普通的就是使用 `调试器`.
-调试可以让你在代码中步进, 设置 `断点` 而且能在崩溃时冻结运行.
-
-各个平台都有一些调试器.
-
-* Visual studio - Windows
-* VSCode - Windows, macOS, Linux
-* Android Studio - Windows, macOS, Linux
-* Xcode - macOS
-* WinDBG - Windows
-* lldb / gdb - macOS, Linux, (Windows)
-* ios-deploy - macOS
-
-各个工具可以用来调试特定平台应用:
-
-* Visual studio - Windows + platforms supporting gdbserver (E.g. Linux/Android)
-* VSCode - Windows, macOS (lldb), Linux (lldb/gdb) + platforms supporting gdbserver
-* Xcode -  macOS, iOS
-* Android Studio - Android
-* WinDBG - Windows
-* lldb/gdb - macOS, Linux, (iOS)
-* ios-deploy - iOS (via lldb)
-
-
-### 打印调试信息
-
-有些时候, 需要在代码里加入 printf() 声明.
-之后, 你就可以从设备上获取日志文件来分析它.
-
-注意 Defold 的debug编译版本默认只输出 dmLog* 函数结果.
-
-#### [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)
-
-在 iOS 中, 你要使用 iTunes 或者 Xcode 来观察设备日志.
-
-### Defold 崩溃日志
-
-当 Defold 引擎硬崩溃时会保存一个 `_crash` 文件.
-它包含了关于系统和崩溃的信息.
-
-你可以使用 [crash module](https://www.defold.com/ref/crash/) 来读取这个文件.
-
-建议你读取这个文件, 收集信息然后放送到自己适用的服务器上来归集数据.
-
-
-#### Android
-
-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
-
-在 iTunes 中, 你可以 view/download 应用容器.
-
-在 `Xcode -> Devices` 窗口中, 也可以选择崩溃日志
-
-
-### Symbolication
-
-如果你从 `_crash` 文件或者日志文件获得了调用堆栈, 就可以开始解析它.
-也就是把各个调用堆栈的地址转化为文件名和代码行, 这样有助于找到出问题的原因.
-
-#### 获取正确的引擎
-
-使调用堆栈匹配正确的引擎是很重要的.
-否则很容易让你调试到不正确的地方.
-
-而且, 如果编译时使用了原生扩展, 确保添加了 [--with-symbols](https://www.defold.com/manuals/bob/) 选项
-以便从编译服务器获取所需信息. 比如, 可以在 iOS/macOS 的编译文件 `build.zip` 里找到 `dmengine.dSYM` 文件夹.
-
-Android/Linux 可运行文件已经包含了调试信息.
-
-还有, 你要持有引擎的完整版.
-这样有助于分析调试文件的调用堆栈.
-
-
-#### Android
-
-1. 从 build 文件夹获取
-
-	$ ls <project>/build/<platform>/[lib]dmengine[.exe|.so]
-
-1. 解压缩:
-
-	$ unzip dmengine.apk -d dmengine_1_2_105
-
-1. 找到调用堆栈地址
-
-	也就是分析前的调用堆栈, 类似这样
-
-	#00 pc 00257224 libmy_game_name.so
-
-	其中 *00257224* 就是地址
-
-1. 解析地址
-
-    $ arm-linux-androideabi-addr2line -C -f -e dmengine_1_2_105/lib/armeabi-v7a/libdmengine.so _address_
-
-#### iOS
-
-1. 如果使用了原生扩展, 服务器会提供解析文件 (.dSYM) 给你 (使用 bob.jar 加 "--with-symbols" 选项)
-
-	$ unzip <project>/build/arm64-darwin/build.zip
-	# 可以解压出 Contents/Resources/DWARF/dmengine
-
-1. 如果未使用原生扩展, 下载解析文件:
-
-	$ wget http://d.defold.com/archive/<sha1>/engine/arm64-darwin/dmengine.dSYM
-
-1. 使用载入地址进行解析
-
-	如果, 简单的输入调用堆栈地址不管用 (即 载入地址 0x0)
-
-		$ atos -arch arm64 -o Contents/Resources/DWARF/dmengine 0x1492c4
-
-	# 直接输入载入地址也不管用
-
-		$ atos -arch arm64 -o MyApp.dSYM/Contents/Resources/DWARF/MyApp -l0x100000000 0x1492c4
-
-	把载入地址加到地址里就管用了:
-
-		$ atos -arch arm64 -o MyApp.dSYM/Contents/Resources/DWARF/MyApp 0x1001492c4
-		dmCrash::OnCrash(int) (in MyApp) (backtrace_execinfo.cpp:27)
+详见 [调试原生代码教程](/manuals/debugging-native-code).

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

@@ -7,8 +7,7 @@ brief: 本教程介绍了有关编译系统用来编译原生扩展的一些细
 
 为了让你的扩展整合更加方便, 我们这里列举了一些编译相关的细节.
 
-在创建 Defold 引擎扩展的时候, 要考虑一些事情.
-对于更全面的如何开发跨平台原生代码以及扩展/Lua API的使用, 请参考 [原生扩展 - 最佳实践](/manuals/extensions-best-practices)
+在创建 Defold 引擎扩展的时候, 要考虑一些事情. 对于更全面的如何开发跨平台原生代码以及扩展/Lua API的使用, 请参考 [原生扩展 - 最佳实践](/manuals/extensions-best-practices)
 
 ## C++ 版本
 
@@ -18,10 +17,6 @@ brief: 本教程介绍了有关编译系统用来编译原生扩展的一些细
 
 ## 工具链
 
-
-
-
-
 ### SDK 版本
 
 * Android: NDK r25b, Build Tools 33.0.1, Api Level 19 for armv7 and Api level 21 for arm64

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

@@ -36,6 +36,7 @@ Defold 提供如下函数用以存取文件/文件夹:
  基于安全考虑浏览器 (及浏览器里运行的 JavaScript 插件) 不允许访问本地文件. 虽然 HTML5 游戏也能运行, 但是只能用浏览器提供的 IndexedDB API 在 "虚拟文件系统" 中存取数据. 也就是说不允许使用 `io.*` 和 `os.*` 下的函数. 但是可以用 `http.request()` 请求在线资源文件.
  :::
 
+
 #### 用户资源与打包资源对比
 
 | 特点              | 用户资源                          | 打包资源                              |
@@ -49,6 +50,9 @@ Defold 提供如下函数用以存取文件/文件夹:
 ### 操作系统文件处理
 基于安全考虑操作系统所管理的文件存取被严格限制. 可以使用 [`extension-directiories`](https://defold.com/assets/extensiondirectories/) 原生扩展来存取某些地方的绝对路径 (例如 documents, resource, temp). 然后用 `sys.*`, `io.*` 和 `os.*` 函数处理文件/文件夹 (见上文).
 
+::: sidenote
+出于安全考虑浏览器 (连同浏览器里运行的 JavaScript 扩展程序) 不可访问系统文件. Defold 的 HTML5 文件存取程序依然工作, 但只是在浏览器以 IndexedDB API 提供的 "虚拟文件系统" 上. 这意味着 HTML5 应用不能真正存取系统文件.
+:::
 
 ## 相关原生扩展
 在 [资源中心](https://defold.com/assets/) 里有些原生扩展能简化文件存取的工作. 例如:

+ 0 - 4
docs/zh/manuals/flipbook-animation.md

@@ -73,10 +73,6 @@ end
 给节点选择图片或者动画时, 实际上也同时指定了图片来源 (图集或者瓷砖图源) 以及默认动画. 节点图源是静态的, 但是当前播放的动画是可以在运行时指定的. 静态图片被视作单帧动画, 所以运行时切换图片相当于播放另一个动画:
 
 ```lua
-local function flipbook_done(self)
-    msg.post("#", "jump_completed")
-end
-
 function init(self)
     local character_node = gui.get_node("character")
     -- 新动画/图片播放时

+ 19 - 13
docs/zh/manuals/getting-help.md

@@ -19,35 +19,41 @@ brief: 本教程介绍了使用 Defold 遇到麻烦时该如何寻求帮助.
 **题目**
 简明扼要的标题. 像 "如何让游戏对象延面对方向前进?" 或者 "如何实现 Sprite 渐隐效果?" 就比较好. 像 "我需要 Defold 的帮助!" 或者 "我的游戏不动了!" 就不怎么好.
 
-* **问题的描述 (必须)** - 问题的简短描述.
+* **问题的描述 (必须)**
+问题的简短描述.
 
-* **问题的复现 (必须)** - 复现问题的步骤:
+* **问题的复现 (必须)**
+复现问题的步骤:
   1. 进入 '...'
   2. 点击 '....'
   3. 滑动到 '....'
   4. 错误出现
 
-* **期望行为 (必须)** - 期望实现的行为的简短描述.
+* **期望行为 (必须)**
+期望实现的行为的简短描述.
 
-* **Defold 版本 (必须)** - 版本 [例如 1.2.155]. 最好再加上引擎和编辑器的 SHA1, 可以从 <kbd>Help->About</kbd> 菜单项里看到.
+* **Defold 版本 (必须)**
+  - 版本 [例如 1.2.155].
 
-* **操作平台 (必须)** - 在哪个操作平台上出现的问题?
+* **操作平台 (必须)**
   - 平台: [比如 iOS, Android, Windows, macOS, Linux, HTML5]
   - 系统: [比如 iOS8.1, Windows 10, High Sierra]
   - 设备: [比如 iPhone6]
 
-* **详细系统信息 (可选)** - 有关错误出现系统平台的详细信息.
-  - HTML5: 提供关于 WebGL 的详细信息, 参考网站 https://webglreport.com/?v=1
+* **问题复现小项目 (可选)**
+请附加一个可以再现问题的最小项目包. 这可以对别人研究修复问题提供极大帮助.
 
-* **日志 (可选)** - 请附带相关 (云编译服务器, 引擎和编辑器) 日志. 参考 [下面关于日志文件获取的章节](#log-files).
+* **日志 (可选)**
+请附带相关 引擎, 编辑器或者云编译服务器的日志. 日志保存在哪请参考 [这里](#日志文件).
 
-* **问题复现小项目 (可选)** - 请附加一个可以再现问题的最小项目包. 这可以对别人研究修复问题提供极大帮助. 如果你把项目打成zip包请去掉其中的 `.git`, `.internal` 和 `build` 文件夹.
+* **绕过方法 (可选)**
+如果你找到了可以绕过问题的方案, 也请附加上.
 
-* **绕过方法 (可选)** - 如果你找到了可以绕过问题的方案, 也请附加上.
+* **屏幕截图 (可选)**
+如果可以, 附加屏幕截图有助于描述出现的问题.
 
-* **屏幕截图 (可选)** - 如果可以, 附加屏幕截图有助于描述出现的问题.
-
-* **其他 (可选)** - 还可以加入其他问题相关上下文信息.
+* **其他 (可选)**
+还可以加入其他问题相关上下文信息.
 
 
 ### 提交代码

+ 4 - 152
docs/zh/manuals/graphics.md

@@ -3,156 +3,8 @@ title: Defold 图像教程
 brief: 本教程简述了 Defold 支持的图像组件.
 ---
 
-# 图像
+该教程已废弃!
 
-Defold是一个全3D引擎, 但是设计上还是为2D提供强大支持的. 目前该引擎比较适用于开发2D游戏.
-
-## 图片资源
-
-Defold中, 可视组件使用两种图片资源:
-
-![atlas](images/icons/atlas.png){.icon} 图集
-: 图集由一组图片组成, 它们自动组成一张大图片. 图集中保存有图片和 *动画组*, 也就是逐帧动画的一组图片.
-
-  ![atlas](images/graphics/atlas.png){srcset="images/graphics/[email protected] 2x"}
-
-更多详情参见 [图集教程](/manuals/atlas).
-
-![tile source](images/icons/tilesource.png){.icon} Tile Source
-: 瓷砖图源是由一系列小图块按顺序拼贴而成的图片. 就像 _Sprite动画表_ 一样. 瓷砖图源可以包含逐帧动画, 只需指定动画的首尾帧. 瓷砖图块也可以自动生成其碰撞图形.
-
-  ![tile source](images/graphics/tilesource.png){srcset="images/graphics/[email protected] 2x"}
-
-更多详情参见 [Tile source manual](/manuals/tilesource).
-
-## 可视组件
-
-从图集或者瓷砖图源资源获得的数据可以用于几种可视组件:
-
-![sprite](images/icons/sprite.png){.icon}
-: Sprite是可以在屏幕上显示的图片或者逐帧动画.
-
-  ![sprite](images/graphics/sprite.png){srcset="images/graphics/[email protected] 2x"}
-
-Sprite更多详情请见 [Sprite manual](/manuals/sprite).
-
-![tile map](images/icons/tilemap.png){.icon} Tile Map
-: 瓷砖地图组件是由瓷砖图源中的瓷砖 (包括瓷砖图及其碰撞图形) 组成的地图. 瓷砖地图不能使用普通图集资源.
-
-  ![tilemap](images/graphics/tilemap.png){srcset="images/graphics/[email protected] 2x"}
-
-瓷砖地图更多详情请见 [Tilemap manual](/manuals/tilemap).
-
-![particle effect](images/icons/particlefx.png){.icon} Particle FX
-: 粒子是粒子发射器所发射出来的, 来自于图集或者瓷砖图源的一个个静态图片或者逐帧动画.
-
-  ![particles](images/graphics/particles.png){srcset="images/graphics/[email protected] 2x"}
-
-粒子特效更多详情请见 [Particle fx manual](/manuals/particlefx).
-
-![gui](images/icons/gui.png){.icon} GUI(图形用户界面)
-: GUI box 节点和 pie 节点同样使用来自图集和瓷砖图源的静态图片或者逐帧动画.
-
-  ![gui](images/graphics/gui.png){srcset="images/graphics/[email protected] 2x"}
-
-GUI更多详情请见 [GUI manual](/manuals/gui).
-
-![spine](images/icons/spine-model.png){.icon} Spine 模型
-: Spine 模型从 Spine 场景资源 中获取数据. 分为两部分:
-
-  1. 一个记录骨骼动画的Spine Json文件.
-  2. 一个由附加在骨骼上的图片组成的图集. Spine模型不能使用来自瓷砖地图的数据.
-
-  ![spine](images/graphics/spine.png){srcset="images/graphics/[email protected] 2x"}
-
-Spine模型更多详情请见 [Spine model manual](/manuals/spine-model).
-
-
-## 3D 图像
-
-模型直接从图片文件获取数据, 然后根据模型的UV映射到模型上:
-
-![model](images/icons/model.png){.icon} Model
-: 3D模型
-
-  ![model](images/graphics/model.png){srcset="images/graphics/[email protected] 2x"}
-
-模型更多详情请见 [Model manual](/manuals/model).
-
-Collada 支持
-: Defold's 3D 需要你保存或者导出模型, 骨骼和动画数据为 _Collada_ 格式. 这是绝大多数3D建模软件所支持的格式. 包括 _Maya_, _3D Max_, _Blender_, _Sketchup_ 等等, 都可以导入作品到 Defold.
-
-  Defold 目前只支持烘焙动画. 动画需要每帧每个骨骼的数据矩阵, 而不是仅仅是关键帧上的移动旋转缩放数据.
-
-  动画是线性插值的. 如果你想要曲线插值的动画, 记得先烘焙再导出.
-
-  不支持Collada中的动画剪辑. 要想一个模型多个动画, 就得分成多个 *.dae* 文件然后在Defold里合成一个 *.animationset* 文件.
-
-材质, 着色器和纹理
-: 3D软件一般可以在模型上设置属性, 比如颜色和纹理. 这些信息会保存在导出的 Collada *.dae* 文件中. 根据游戏需要你要选择创建合适的 _高效的_ 模型材质. 材质由 _着色器程序_ 和渲染时使用的一组参数组成.
-
-  你还需设计和实现一个合适的游戏摄像机.
-
-  built-in materials 文件夹下有一个简单的3D材质. 如果你需要为模型设计自定义材质, 详情请参考 [Material documentation](/manuals/material). [Shader manual](/manuals/shader)介绍了着色器程序是如何工作的.
-
-渲染模型
-: 默认的渲染器是为2D游戏而不是3D模型打造的. 但是参考它然后加入简单的几行代码就能实现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).
-
-
-## 纹理过滤和采样
-
-你可以控制在纹理采样时完成的过滤方法. 比如当一个 _纹素_ (纹理上的一个像素) 不是和屏幕完美的像素对齐时, 可以由过滤器决定显示结果 . 当你移动一个带纹理的图像元素少于一个像素时它就会发生. 下面的过滤方法是可选的:
-
-Nearest
-: 选取距离屏幕像素颜色最近的纹素. 如果你想要从纹理到屏幕显示完美的一对一像素映射就应该使用这种采样方法. 使用最近过滤方法所有物体移动的时候都是像素对齐的. 当 Sprite 慢慢移动时看起来可能会是一抽一抽的.
-
-Linear
-: 屏幕着色前纹素会和旁边的均值化. 当 Sprite 着色前会渗入像素, 呈现出一个慢慢的, 持续的动作 --从而使Sprite移动小于1个像素成为可能.
-
-采样的设置保存在 [Project Settings](/manuals/project-settings) 文件中. 有两个设置:
-
-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* 里的设置. 如果你为自定义材质指定了采样器, 你可以为每个采样器单独指定过滤方法. 详情请见 [Materials manual](/manuals/material/).
-
-## 材质和着色器
-
-默认材质和着色器文件位于项目的 "/builtins/materials/" 下. Sprite, 瓷砖, spine 模型 和 3D模型的默认材质从 *game.project* 中设置的采样和过滤中查找纹理. 片元着色器还使用与纹理颜色相乘的叫做 `tint` 的常量.
-
-当游戏运行时, 你可以使用 [`sprite.set_constant()`](/ref/sprite#sprite.set_constant) 和 [`sprite.reset_constant()`](/ref/sprite#sprite.reset_constant) 函数设置 `tint` 和其他着色常量设置 `tint` 和其他着色常量. sprite 以外的组件也有相应的函数.
-
-[Materials manual](/manuals/material/) 解释了如何创建自定义材质.
+* 参见 [如何导入和使用 2D 图片](/manuals/importing-graphics)
+* 参见 [贴图滤镜](/manuals/texture-filtering)
+* 参见 [材质](/manuals/material)

+ 4 - 0
docs/zh/manuals/gui-box.md

@@ -21,4 +21,8 @@ brief: 本教程介绍了如何使用 GUI 方块节点.
 
 即使没有纹理设置, 方块节点也会被渲染, 或者不论把 alpha 设置成 `0`, 还是把 sized 设置成 `0, 0, 0`. 方块节点应该设置纹理以便渲染器合批而减少 draw call.
 
+## 播放动画
+
+Box 节点可以由其图集或者瓷砖图源内容来播放动画. 详情请见 [逐帧动画教程](/manuals/flipbook-animation).
+
 :[Slice-9](../shared/slice-9-texturing.md)

+ 7 - 2
docs/zh/manuals/gui-clipping.md

@@ -65,6 +65,11 @@ Clipping Inverted
 
 ![Layers and clipping](images/gui-clipping/layers.png){srcset="images/gui-clipping/[email protected] 2x"}
 
-这里蒙版节点 "ocular" 层设置为 "layer3" 然后 "bean" 节点设置成 "layer1". 所以被 ocular 剪裁的纹理显示在了 bean 的上层.
+本例中, 节点 "Donut BG" 和 "BG" 都使用了 layer 1. 它们的渲染顺序遵循层级即 "Donut BG" 先于 "BG" 渲染. 然而, 子节点 "Donut Shadow" 归为 layer 2 即更高层级, 则它的渲染晚于这两个节点. 这种情况下, 渲染顺序为:
 
-节点 "shield" 设置为 "layer2", 但是在显示顺序上与 "ocular" 和 "bean" 并不冲突. 要更改 "shield" 的显示顺序, 设置层级顺序即可.
+- Donut BG
+- BG
+- BG Frame
+- Donut Shadow
+
+可见 "Donut Shadow" 对象基于层级被两个蒙版节点裁剪, 即使它是蒙版节点的唯一子节点.

+ 6 - 6
docs/zh/manuals/gui.md

@@ -302,24 +302,24 @@ end
 父节点先于子节点进行绘制. 使用层可以改变这个顺序还可以优化性能 (见下文).
 
 
-## 层与 drawcall
+## 层与 draw call
 
-Layers 可以方便控制节点绘制顺序以及减少drawcall. 引擎绘制界面前, 会根据以下规则合批渲染:
+Layers 可以方便控制节点绘制顺序以及减少draw call. 引擎绘制界面前, 会根据以下规则合批渲染:
 
 - 节点类型相同.
 - 节点纹理源自同一张图集或瓷砖图源.
 - 节点的渲染模式相同.
 - 节点使用的字体相同.
 
-如果有一条不符合, 就会破坏合批产生另一个drawcall. 蒙版和被蒙节点必然会破坏合批产生drawcall.
+如果有一条不符合, 就会破坏合批产生另一个 draw call. 蒙版和被蒙节点必然会破坏合批产生draw call.
 
 树形结构对于节点管理非常方便. 但是不同类型节点的混合一定会打破合批渲染:
 
 ![Breaking batch hierarchy](images/gui/break_batch.png){srcset="images/gui/[email protected] 2x"}
 
-渲染管线被迫为不同类型的节点建立不同的渲染批次. 这三个按钮就会产生6次drawcall.
+渲染管线被迫为不同类型的节点建立不同的渲染批次. 这三个按钮就会产生6次 draw call.
 
-要是使用层, 就可以重塑节点的绘制顺序, 渲染管线就能更好地进行合批减少drawcall. 第一步新建层. 在 *Outline* 的 "Layers" 文件夹上 <kbd>右键点击</kbd> 然后选择 <kbd>Add ▸ Layer</kbd>. 在 *Properties* 视图中填充 *Name* 属性给层命名.
+要是使用层, 就可以重塑节点的绘制顺序, 渲染管线就能更好地进行合批减少 draw call. 第一步新建层. 在 *Outline* 的 "Layers" 文件夹上 <kbd>右键点击</kbd> 然后选择 <kbd>Add ▸ Layer</kbd>. 在 *Properties* 视图中填充 *Name* 属性给层命名.
 
 ![Layers](images/gui/layers.png){srcset="images/gui/[email protected] 2x"}
 
@@ -337,6 +337,6 @@ Layers 可以方便控制节点绘制顺序以及减少drawcall. 引擎绘制界
   5. "button-text-2"
   6. "button-text-3"
 
-这样一来合批就成形了, 不再需要那么多drawcall了!
+这样一来合批就成形了, 不再需要那么多 draw call 了!
 
 注意如果子节点没有设置分配层默认继承分配父节点所在的层. 没有设置分配层的节点会被归为 "null" 层, 这个层最先被绘制.

+ 19 - 12
docs/zh/manuals/html5.md

@@ -34,21 +34,27 @@ Python 3:
 或者
 > python3 -m http.server
 
-::: sidenote
+::: important
 不能直接用浏览器打开 HTML5 游戏的 `index.html` 文件. 要通过服务器访问打开.
 :::
 
-::: sidenote
+::: important
 如果在控制台见到 "wasm streaming compile failed: TypeError: Failed to execute ‘compile’ on ‘WebAssembly’: Incorrect response MIME type. Expected ‘application/wasm’." 错误, 请确保你的服务器设置了 `application/wasm` MIME 类型对应 .wasm 文件.
 :::
 
 ## HTML5游戏打包
 
-Defold 打包 HTML5 游戏很简单, 跟其他平台一样: 从菜单栏选择 <kbd>Project ▸ Bundle...​ ▸ HTML5 Application...</kbd>:
+Defold 打包 HTML5 游戏很简单, 跟其他平台一样: 从菜单栏选择 <kbd>Project ▸ Bundle... ▸ HTML5 Application...</kbd> :
+
+![Create HTML5 bundle](images/html5/html5_bundle.png)
 
-![Application files](images/html5/html5_bundle.png)
+可以选择让 HTML5 包含 `asm.js` 和一个 Defold 引擎 WebAssembly (wasm) 双版本. 多数情况下选择 WebAssembly 版就够了, 因为 [所有主流浏览器都支持 WebAssembly](https://caniuse.com/wasm).
 
-会弹出提示框让你选择游戏存放位置. 打包结束后, 就可以看到输出的所有文件.
+::: important
+即使包含了 `asm.js` 和 `wasm` 双版本, 浏览器加载游戏时也只是下载其中一个. 如果浏览器支持 WebAssembly 则优先下载 WebAssembly 版, 否则回撤下载 asm.js 版.
+:::
+
+当点选 <kbd>Create bundle</kbd> 按钮会弹出目录对话框让你选择应用的保存位置. 等输出工作完成, 你会获得应用所需的所有文件.
 
 ## 已知问题和局限性
 
@@ -59,7 +65,7 @@ Defold 打包 HTML5 游戏很简单, 跟其他平台一样: 从菜单栏选择 <
   * Full screen - 全屏模式在浏览器中不可靠.
 * Chrome
   * Slow debug builds - 为了在 HTML5 平台更好地调试我们开启了校验所有 WebGL 图像调用来检测错误. 但是这样做在 Chrome 上会运行缓慢. 可以把 *game.project* 里的 *Engine Arguments* 部分设置为 `–-verify-graphics-calls=false` 来关闭图像调用校验.
-* 游戏手柄支持 - 对于 HTML5 平台的游戏手柄支持与配置参见[这篇教程](/manuals/input-gamepads/#gamepads-in-html5).
+* 游戏手柄支持 - 对于 HTML5 平台的游戏手柄支持与配置[参见手柄教程](/manuals/input-gamepads/#gamepads-in-html5).
 
 ## 自定义HTML5打包
 
@@ -71,18 +77,18 @@ Defold 打包 HTML5 游戏很简单, 跟其他平台一样: 从菜单栏选择 <
 
 关于每个选项详情请见 [形目设置教程](/manuals/project-settings/#HTML5).
 
-::: sidenote
+::: important
 `builtins` 文件夹下的默认 html/css 模板文件是不能直接修改的. 要先从 `builtins` 里把文件拷贝出来然后再在 *game.project* 文件里指明要使用的文件的位置.
 :::
 
-::: sidenote
+::: important
 网页 canvas 不能有 border 或者 padding. 否则的话, 鼠标输入坐标会产生偏差.
 :::
 
 可以在 *game.project* 文件里禁用 `Fullscreen` 按钮以及 `Made with Defold` 链接.
 Defold 提供了 index.html 文件的亮暗两种风格. 默认亮风格但是可以在 `Custom CSS` 修改成暗风格. 在 `Scale Mode` 部分还预定义了四种缩放模式可供选择.
 
-::: sidenote
+::: important
 各种缩放模式计算时考虑了当前屏幕 DPI 以支持 *game.project* 里的 `High Dpi` 选项 (在 `Display` 部分)
 :::
 
@@ -180,11 +186,12 @@ DEFOLD_ENGINE_ARGUMENTS
 ## 额外参数
 
 要创建自定义模板, 可以为引擎加载提供额外参数:
-```
-`Module.runApp("canvas", extra_params) - 通过指定canvas启动游戏
 
-'extra_params' 可选的额外参数, 如下:
+`Module.runApp("canvas", extra_params)` - 通过指定canvas启动游戏
 
+'extra_params' 可选的额外参数对象, 包含如下属性:
+
+```
 'archive_location_filter':
     包地址过滤.
 

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

@@ -8,6 +8,7 @@ Defold 目前支持 GL Transmission Format *.glTF* 和 Collada *.dae* 格式的
 
 ![Model in Blender](images/model/blender.png){srcset="images/model/[email protected] 2x"}
 
+
 ## 导入模型到 Defold
 要导入模型, 只需将 *.gltf* 文件或者 *.dae* 文件及其相应贴图拖拽至 *资源面板* 即可.
 

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

@@ -18,7 +18,7 @@ brief: 本教程介绍了游戏手柄输入的功能.
 
 ![](images/input/gamepad_bindings.png)
 
-::: sidenote
+::: important
 下面的例子中使用了上图的映射绑定配置. 映射与命名可以根据项目需要自由设置.
 :::
 

+ 9 - 7
docs/zh/manuals/input-key-and-text.md

@@ -33,13 +33,15 @@ end
 `text` 捕获一般字符输入. 事件 `text` 项保存了输入的字符. 动作由按下按钮时触发, 不存在 `release` 和 `repeated` 事件.
 
   ```lua
-  if action_id == hash("text") then
-    -- 收集输入字符填充 "user" 节点...
-    local node = gui.get_node("user")
-    local name = gui.get_text(node)
-    name = name .. action.text
-    gui.set_text(node, name)
-  end
+function on_input(self, action_id, action)
+    if action_id == hash("text") then
+        -- 收集输入字符填充 "user" 节点...
+        local node = gui.get_node("user")
+        local name = gui.get_text(node)
+        name = name .. action.text
+        gui.set_text(node, name)
+    end
+end 
   ```
 
 ## Marked text

+ 2 - 2
docs/zh/manuals/input-mouse-and-touch.md

@@ -16,7 +16,7 @@ brief: 本教程介绍了鼠标和触摸输入的功能.
 鼠标按键输入 `MOUSE_BUTTON_LEFT`, `MOUSE_BUTTON_RIGHT` 和 `MOUSE_BUTTON_MIDDLE` 等同于 `MOUSE_BUTTON_1`, `MOUSE_BUTTON_2` 和 `MOUSE_BUTTON_3`.
 :::
 
-::: sidenote
+::: important
 下面的例子中使用了上图的映射绑定配置. 映射与命名可以根据项目需要自由设置.
 :::
 
@@ -35,7 +35,7 @@ function on_input(self, action_id, action)
 end
 ```
 
-::: sidenote
+::: important
 单点触摸也会触发 `MOUSE_BUTTON_LEFT` (或 `MOUSE_BUTTON_1`) 事件.
 :::
 

+ 19 - 1
docs/zh/manuals/ios.md

@@ -59,6 +59,11 @@ Device identifier (UDID)
 3. 在 Xcode 注册并登录 Apple ID.
 4. 新建项目. 最简单的 "Single View App" 就好.
 5. 选择 "Team" (自动生成) 并为app设置 bundle identifier.
+
+::: important
+请牢记 bundle identifier 因为在 Defold 项目中需要配置同样的 bundle identifier.
+:::
+
 6. 确保 Xcode 为app生成了 *Provisioning Profile* 和 *Signing Certificate*.
 
    ![](images/ios/Xcode_certificates.png)
@@ -88,7 +93,7 @@ Device identifier (UDID)
 
 选择证书和档案. 设置架构 (32 bit, 64 bit 和 iOS 模拟器) 再选择打包模式 (Debug 或者 Release). 也可以取消选择 `Sign application` 跳过签名步骤留待后面完成.
 
-::: sidenote
+::: important
 要在模拟器中测试游戏 **必须取消** `Sign application` 选项. 否则的话游戏能安装却不能运行.
 :::
 
@@ -98,6 +103,19 @@ Device identifier (UDID)
 
 可以在 *game.project* 项目配置文件的 [iOS 部分](/manuals/project-settings/#iOS) 设置应用的图标, 启动屏幕 storyboard 等等.
 
+## 在已连接的 iPhone 上安装和运行应用
+
+选择编辑器中的 "Install on connected device" 和打包对话框的 "Launch installed app" 即可安装和运行应用:
+
+![Install and launch iOS bundle](images/ios/install_and_launch.png)
+
+这个特性需要你先安装好 [ios-deploy](https://github.com/ios-control/ios-deploy) 命令行工具. 最简单的方法是使用 Homebrew:
+```
+$ brew install ios-deploy
+```
+
+如果编辑器无法自动找到 ios-deploy 工具, 你需要在 [Preferences](/manuals/editor-preferences/#tools) 中手动指定. 
+
 ### 创建 storyboard
 
 使用 Xcode 创建 storyboard. 启动 Xcode 新建一个项目. 选择 iOS 和单视图应用:

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

@@ -128,4 +128,4 @@ end
 
 ## 相关项目配置
 
-在 *game.project* 文件里有些关于标签的 [置项目](/manuals/project-settings#label).
+在 *game.project* 文件里有些关于标签的 [置项目](/manuals/project-settings#label).

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

@@ -27,7 +27,7 @@ brief: 项目间可以使用库共享资源. 本教程解释了其工作方式.
 
 ![GitHub Library URL](images/libraries/libraries_library_url_github.png)
 
-::: sidenote
+::: important
 最好使用库项目的发布地址而不是主分支来引用库. 作为开发者你要决定什么时候该合并更新而不是时刻保持主分支最新代码 (使用主分支最新版可能引入潜在的不稳定性).
 :::
 
@@ -73,7 +73,7 @@ GitHub 具体步骤:
 
 此时这个只读用户的信息就可以放心公开在依赖库上. 这样就可以将私有库公开化而不用担心被恶意篡改.
 
-::: sidenote
+::: important
 使用这种只读用户的 token 可以访问所有依赖私有库的游戏.
 :::
 

+ 127 - 0
docs/zh/manuals/live-update-aws.md

@@ -0,0 +1,127 @@
+---
+title: Live update content uploads to AWS
+brief: This section will explain how to create a new user with limited access on Amazon Web Services that can be used together with the Defold editor to automatically upload Live update resources when you bundle your game.
+---
+
+# 创建 Amazon 网络服务器
+
+要使用 Defold 配合 Amazon 服务器进行热更新首先要有 Amazon Web Services 账户. 没有的话请在这里注册: https://aws.amazon.com/.
+
+这里介绍一下如何开通 Amazon 服务以配合 Defold 进行热更新, 在 Amazon S3 需要那些配置. 更多关于 Amazon S3 的信息, 请参考 [Amazon S3 文档](http://docs.aws.amazon.com/AmazonS3/latest/dev/Welcome.html).
+
+1. 开通服务
+
+    在 _Storage_ 类目 ([Amazon S3 Console](https://console.aws.amazon.com/s3)) 下打开 `Services` 菜单选择 `S3`. 页面上会列出已存在的所有服务器与开通新服务器的选项. 使用已存在的服务器是可以的, 但是建议为热更新资源创建一个新服务器,以便设置访问限制.
+    
+    ![Create a bucket](images/live-update/01-create-bucket.png)
+
+2. 服务配置
+
+    开通服务器, 打开 *Properties* 面板展开折叠的 *Permissions* 选项. 点击 *Add bucket policy* 按钮添加配置文件. 本例中的配置是允许任何客户端访问服务器资源, 以便热更新顺利工作. 更多配置信息, 请参考 [Amazon 文档](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html).
+
+    ```json
+    {
+        "Version": "2012-10-17",
+        "Statement": [
+            {
+                "Sid": "AddPerm",
+                "Effect": "Allow",
+                "Principal": "*",
+                "Action": "s3:GetObject",
+                "Resource": "arn:aws:s3:::defold-liveupdate-example/*"
+            }
+        ]
+    }
+    ```
+
+    ![Bucket policy](images/live-update/02-bucket-policy.png)
+
+3. 添加 CORS 配置 (可选)
+
+    [Cross-Origin Resource Sharing (CORS)](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) 是一种能让服务器使用 JavaScript 访问另一服务器资源的机制. 如果你发布的是 HTML5 游戏, 就需要给服务器添加 CORS 配置.
+
+    选择服务器, 打开 *Properties* 面板展开折叠的 *Permissions* 选项. 点击 *Add CORS Configuration* 按钮添加 CORS 配置. 本例中的配置是允许任何服务器访问本服务器资源, 如果需要可以做详细的限制. 更多 Amazon CORS 配置信息, 请参考 [Amazon 文档](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html).
+
+    ```xml
+    <?xml version="1.0" encoding="UTF-8"?>
+    <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
+        <CORSRule>
+            <AllowedOrigin>*</AllowedOrigin>
+            <AllowedMethod>GET</AllowedMethod>
+        </CORSRule>
+    </CORSConfiguration>
+    ```
+
+    ![CORS configuration](images/live-update/03-cors-configuration.png)
+
+4. 创建 IAM 配置
+
+    打开 *Services* 菜单, 在 _Security, Identity & Compliance_ 类目 ([Amazon IAM Console](https://console.aws.amazon.com/iam)) 下打开 *IAM*. 选择左边的 *Policies*, 页面会列出已存在的所有 IAM 配置与创建新配置的选项.
+
+    点击 *Create Policy* 按钮, 选择 _Create Your Own Policy_. 本例中的配置是允许用户获得服务器列表, 这是 Defold 热更新的必要配置. 这里还可以允许用户获得 Access Control List (ACL) 和把资源文件上传至服务器的权力. 关于 Amazon Identity and Access Management (IAM) 的更多信息, 详见 [Amazon 文档](http://docs.aws.amazon.com/IAM/latest/UserGuide/access.html).
+
+    ```json
+    {
+        "Version": "2012-10-17",
+        "Statement": [
+            {
+                "Effect": "Allow",
+                "Action": [
+                    "s3:ListAllMyBuckets"
+                ],
+                "Resource": "arn:aws:s3:::*"
+            },
+            {
+                "Effect": "Allow",
+                "Action": [
+                    "s3:GetBucketAcl"
+                ],
+                "Resource": "arn:aws:s3:::defold-liveupdate-example"
+            },
+            {
+                "Effect": "Allow",
+                "Action": [
+                    "s3:PutObject"
+                ],
+                "Resource": "arn:aws:s3:::defold-liveupdate-example/*"
+            }
+        ]
+    }
+    ```
+
+    ![IAM policy](images/live-update/04-create-policy.png)
+
+5. 创建管理账户
+
+    打开 *Services* 菜单, 在 _Security, Identity & Compliance_ 类目 ([Amazon IAM Console](https://console.aws.amazon.com/iam)) 下打开 *IAM*. 选择左边的 *Users*, 页面会列出已存在的所有用户与创建新用户的选项. 使用已存在的用户是可以的, 但是建议为热更新资源创建一个新用户,以便设置访问限制.
+
+    点击 *Add User* 按钮, 输入用户名选择 *Programmatic access* 作为 *Access type*, 然后点击 *Next: Permissions*. 选择 *Attach existing policies directly* 然后选择第4步中所作的配置.
+
+    完成之后你会得到 *Access key ID* 和 *Secret access key*.
+
+    ::: important
+    保存好密匙 *非常重要* 因为离开 Amazon 页面后就无法再次获得密匙了.
+    :::
+
+6. 创建档案文件
+
+    此时你已经开启了服务器, 做好了客户端访问配置, 添加了服务端方位配置, 新建了用户权限和一个新用户. 剩下的最后一件事是创建 [档案文件](https://aws.amazon.com/blogs/security/a-new-and-standardized-way-to-manage-credentials-in-the-aws-sdks) 以便让 Defold 也能访问服务器.
+
+    在本地新建一个 *.aws* 文件夹, 在里面新建一个 *credentials* 文件.
+
+    ```bash
+    $ mkdir ~/.aws
+    $ touch ~/.aws/credentials
+    ```
+
+    文件 *~/.aws/credentials* 要包含访问 Amazon 服务所需的凭证即标准 AWS 证书. 打开文件按照如下格式输入你的 *Access key ID* 和 *Secret access key*.
+
+    ```ini
+    [defold-liveupdate-example]
+    aws_access_key_id = <Access key ID>
+    aws_secret_access_key = <Secret access key>
+    ```
+
+    服务器名, 本例中是 _defold-liveupdate-example_, 在 Defold 编辑器热更新配置里也要提供.
+
+    ![Live update settings](images/live-update/05-liveupdate-settings.png)

+ 134 - 0
docs/zh/manuals/live-update-scripting.md

@@ -0,0 +1,134 @@
+---
+title: 热更新脚本
+brief: 使用热更新, 需要下载并挂载游戏数据. 本手册介绍了热更新脚本.
+---
+
+# 热更新脚本
+[live-update-scripting.md](live-update-scripting.md)
+热更新API只是如下几个函数:
+
+* `liveupdate.add_mount()`
+* `liveupdate.remove_mount()`
+* `liveupdate.get_mounts()`.
+
+## 得到 mounts
+
+如果使用一个以上的热更新卷, 推荐在启动时遍历每个 mount
+来检测这个 mount 是否还在使用中.
+
+这很重要因为内容可能对于引擎来说不在可用, 因为文件格式改变了.
+
+```lua
+local function remove_old_mounts()
+	local mounts = liveupdate.get_mounts() -- 得到 mounts 表
+
+    -- 每个 mount 包含: mount.uri, mount.priority, mount.name
+	for _,mount in ipairs(mounts) do
+
+        -- 这需要文件名是唯一的, 以便我们不会从不同卷里获得同名文件
+        -- 这里数据由开发者创建作为给卷指定元数据的方法
+		local version_data = sys.load_resource("/version_" .. mount.name .. ".json")
+
+		if version_data then
+			version_data = json.decode(version_data)
+		else
+			version_data = {version = 0} -- 没有版本文件的话, 很可能是老旧/不可用卷
+		end
+
+        -- 指定卷版本到游戏支持的版本
+        if version_data.version < sys.get_config_int("game.minimum_lu_version") then
+            -- 不可用的话, 卸载它!
+            liveupdate.remove_mount(mount.name)
+        end
+	end
+end
+```
+
+## 排除的集合代理脚本
+
+被打包排除的集合代理使用上跟普通集合代理类似, 但有一个重要区别. 当它还有资源没就位的时候给它发送 `load` 消息会直接报错.
+
+所以在给它发送 `load` 之前, 我们检查是否有遗漏的资源. 如果有, 我们需要下载包含这些资源的卷并保存起来.
+
+ 下例代码默认资源依照 `game.http_url` 的地址下可得到.
+
+```lua
+
+-- 你要跟踪哪个卷里有那些内容
+-- 本例中, 我们只用一个热更新卷, 包含所有遗漏资源.
+-- 如果需要用多个卷, 必须相应地构建好下载表
+local lu_infos = {
+    liveupdate = {
+        name = "liveupdate",
+        priority = 10,
+    }
+}
+
+local function get_lu_info_for_level(level_name)
+    if level_name == "level1" then
+        return lu_infos['liveupdate']
+    end
+end
+
+local function mount_zip(self, name, priority, path, callback)
+	liveupdate.add_mount(name, "zip:" .. path, priority, function(_uri, _path, _status) -- <1>
+		callback(_uri, _path, _status)
+	end)
+end
+
+function init(self)
+    self.http_url = sys.get_config_string("game.http_url", nil) -- <2>
+
+    local level_name = "level1"
+
+    local info = get_lu_archive_for_level(level_name) -- <3>
+
+    msg.post("#", "load_level", {level = "level1", info = info }) -- <4>
+end
+
+function on_message(self, message_id, message, sender)
+    if message_id == hash("load_level") then
+        local missing_resources = collectionproxy.missing_resources("#" .. message.level) -- <5>
+
+        if #missing_resources then
+            msg.post("#", "download_archive", message) -- <6>
+        else
+            msg.post("#" .. message.level, "load")
+        end
+
+    elseif message_id == hash("download_archive") then
+		local zip_filename = message.info.name .. ".zip"
+		local download_path = sys.get_save_file("mygame", zip_filename)
+        local url = self.http_url .. "/" .. zip_filename
+
+        -- 开始请求. 可以使用 credentials
+        http.request(url, "GET", function(self, id, response) -- <7>
+			if response.status == 200 or response.status == 304 then
+				mount_zip(self, message.info.name, message.info.priority, download_path, function(uri, path, status) -- <8>
+					msg.post("#", "load_level", message) -- 尝试重新加载 level
+				end)
+
+			else
+				print("Failed to download archive ", download_path, "from", url, ":", get_status_string(status))
+			end
+		end, nil, nil, {path=download_path})
+
+    elseif message_id == hash("proxy_loaded") then -- level 已加载, 可以 enable 了
+        msg.post(sender, "init")
+        msg.post(sender, "enable")
+    end
+end
+```
+
+1. 依照指定名称, 优先级和 zip 文件, 使用 `liveupdate.add_mount()` 挂载一个卷. 数据马上便可以用于加载 (不用重启引擎).
+mount 信息被保存然后下次引擎重启便会被自动读取 (同一 mount 不必再一次调用 liveupdate.add_mount())
+2. 线上保存卷 (比如放在 S3 上), 以便等待下载.
+3. 提供集合代理名, 要指出哪个卷需要下载, 然后如何挂载
+4. 游戏开始, 尝试载入 level.
+5. 检查集合代理的所有资源已就位.
+6. 如果有遗漏资源, 需要下载卷然后挂载它.
+7. 提出 http 请求, 下载卷到 `download_path`
+8. 数据已下载, 应该给当前引擎挂载它.
+
+
+载入代码完成后, 我们就可以测试游戏了. 然而, 从编辑器里运行游戏不会下载任何东西. 这是因为热更新是一个游戏包特性. 在编辑器环境运行游戏所有资源都就位. 为了测试该特性, 我们需要打游戏包.

+ 47 - 285
docs/zh/manuals/live-update.md

@@ -3,8 +3,6 @@ title: Defold 的热更新
 brief: 热更新允许游戏运行时获取和存储编译时并不存在的资源. 本教程介绍了热更新的用法.
 ---
 
-#### 目前热更新机制正在升级, 本教程可能随时变化
-
 # 热更新
 
 打包游戏时, Defold 把所有游戏资源装进游戏包当中. 多数情况下这样做很好因为游戏运行时引擎要快速找到加载所需要的各种资源. 但是, 有一些情况下需要将资源加载推迟到后续阶段. 比如:
@@ -15,6 +13,14 @@ brief: 热更新允许游戏运行时获取和存储编译时并不存在的资
 
 热更新扩展了集合代理的概念允许引擎在运行时获取和存储未被打入游戏包的资源数据.
 
+它可以把你的内容分成多个卷:
+
+* _基础卷_
+* Level 公共文件
+* Level 卷 1
+* Level 卷 2
+* ...
+
 ## 准备工作
 
 假设我们有个很大的, 高分辨率的图片. 图片放在sprite里, sprite放在游戏对象里, 游戏对象放在集合里:
@@ -25,6 +31,10 @@ brief: 热更新允许游戏运行时获取和存储编译时并不存在的资
 
 勾选集合代理属性 *Exclude* 即可, 打包时会把 *monalisa.collection* 的内容排除于包外.
 
+::: important
+基础游戏包所引用的任何资源都不会被排除.
+:::
+
 ![Collection proxy excluded](images/live-update/proxy-excluded.png)
 
 ## 热更新配置
@@ -35,91 +45,18 @@ brief: 热更新允许游戏运行时获取和存储编译时并不存在的资
 
 目前 Defold 支持两种包外资源的保存模式. 可以在设置窗口里的 *Mode* 下拉菜单中选择:
 
-`Amazon`
-: 让 Defold 自动把包外资源上传到 Amazon Web Service (AWS) S3 服务器上. 填写 AWS *凭证* 名, 选择合适的 *服务器* 在提供一个 *前缀* 名. [关于 AWS 账户注册请见下文](#setting_up_amazon_web_service).
-
 `Zip`
 : 让 Defold 把包外资源打成 zip 包. 并且在配置里 *Export path* 项指定存放路径.
 
-
-## 热更新脚本
-
-热更新集合代理和普通集合代理差不多, 只是有一个重要区别. 如果在资源还没下载好的时候发送 `load` 消息的话就会导致失败报错.
-
-所以发送 `load` 之前, 一定要确保资源的完整性. 把完整的资源下载并保存好. 一下代码假设资源保存在 Amazon S3, 一个叫做 "my-game-bucket" 的服务器上, 前缀为 `my-resources`.
-
-```lua
-function init(self)
-    self.resources_pending = 0 -- <1>
-    msg.post("#", "attempt_load_resources")
-end
-
--- 下载热更新用到的包外资源进行本地保存时会调用此函数
-local function resource_store_response(self, hexdigest, status)
-    if status == true then
-        -- 加载成功
-        print("Resource data stored: " .. hexdigest)
-
-        -- 还差一个资源
-        self.resources_pending = self.resources_pending - 1
-
-        -- 全部保存好了, 可以开始加载了
-        if self.resources_pending == 0 then
-            msg.post("#proxy", "load") -- <8>
-        end
-    else
-        -- 错误! 资源数据保存失败.
-        print("Failed to store resource data: " .. hexdigest)
-    end
-end
-
-function on_message(self, message_id, message, sender)
-    if message_id == hash("attempt_load_resources") then
-        local missing_resources = collectionproxy.missing_resources("#proxy") -- <2>
-
-        -- 为缺失的而且没被尝试下载过的资源初始化下载请求.
-        for _,resource_hash in ipairs(missing_resources) do
-            msg.post("#", "attempt_download", { resource_hash = resource_hash})
-        end
-
-        self.resources_pending = #missing_resources -- <3>
-
-        -- 如果游戏是从编辑器运行的, 那么全部资源都存在本地.
-        if self.resources_pending == 0 then
-            msg.post("#proxy", "load")
-        end
-    elseif message_id == hash("attempt_download") then
-        local manifest = resource.get_current_manifest() -- <4>
-        local base_url = "https://my-game-bucket.s3.amazonaws.com/my-resources/" -- <5>
-        http.request(base_url .. message.resource_hash, "GET", function(self, id, response)
-            if response.status == 200 or response.status == 304 then -- <6>
-                -- 得到ok响应.
-                print("storing " .. message.resource_hash)
-                resource.store_resource(manifest, response.response, message.resource_hash, resource_store_response) -- <7>
-            else
-                -- 错误! 资源下载失败.
-                print("Failed to download resource: " .. message.resource_hash)
-            end
-        end)
-    elseif message_id == hash("proxy_loaded") then
-        msg.post(sender, "init")
-        msg.post(sender, "enable")
-    end
-end
-```
-1. 一个计数器记录了还剩多少资源需要下载保存. 注意此处未做错误处理, 产品级游戏要跟踪好下载和保存的各种情况.
-2. 得到需要下载保存的资源.
-3. 计数器更新.
-4. 资源需求清单.
-5. 本例中资源保存于 Amazon S3. 如果使用zip包保存资源, 需要调用 `http.request()` 连同资源托管地址进行下载.
-6. 文件缓存好之后 Amazon 返回状态 304.
-7. 下载完成, 开始保存.
-8. 保存成功, 资源计数器清零. 此时可以放心发送 "load" 消息给集合代理. 注意如果下载保存任何地方出错, 计数器都不会清零.
-
-一切准备就绪, 我们可以尝试启动这个程序. 但是从编辑器运行并不会下载任何东西. 因为热更新是游戏包的功能. 编辑器运行时游戏未打包. 所以, 要测试热更新必须先给游戏打包.
+`Amazon`
+: 让 Defold 自动把包外资源上传到 Amazon Web Service (AWS) S3 服务器上. 填写 AWS *凭证* 名, 选择合适的 *服务器* 在提供一个 *前缀* 名. [关于 AWS 账户注册请见下文](#setting_up_amazon_web_service).
 
 ## 热更新应用打包
 
+::: important
+编辑器的编译运行 (<kbd>Project ▸ Build</kbd>) 不支持热更新. 要想测试热更新必须把项目打包.
+:::
+
 打包很简单. 选择 <kbd>Project ▸ Bundle ▸ ...</kbd> 然后选择目标平台. 此时会弹出对话框:
 
 ![Bundle Live application](images/live-update/bundle-app.png)
@@ -128,236 +65,61 @@ end
 
 点击 *Package* 然后指定保存位置. 打包好之后就能测试热更新功能了.
 
-## 清单文件
-
-清单是一种内部数据结构用来保存编译所需的所有资源列表连同每个资源的哈希值. 热更新使用清单来确定哪些资源是游戏的一部分, 哪些资源不在本地需要下载, 还要确定下载的资源是否完整.
-
-从用户角度来看, 清单是一个数字句柄, 将如何管理资源的细节留给引擎去做.
-
-## 清单更新
-
-每次热更新都会在本地保存一份更新的清单. 应用启动时会使用最新的清单代替包内的清单. 这对于游戏后续通过热更新来修改增添资源很重要, 尤其是第一版游戏打包时并不知道的资源.
-
-当把资源上传到 Amazon 服务器或打包成zip资源包的时候, 清单也会被加入到那些资源当中. 名称为 `liveupdate.game.dmanifest`.
-
-保存清单后首次启动引擎时会生成一个游戏包版本文件 `bundle.ver`. 用来判断保存清单之后游戏有无改动, 比如说一次完整的 app store 更新. 如果是这样的话清单将从文件系统中删除并使用更新版本游戏包中的清单代替. 也就是说完整 app store 更新会清除上次保存的清单. 而通过热更新下载到本地的资源不被清除.
-
-### 清单验证
-保存新版清单之前会对其进行验证. 验证包括如下内容:
+## .zip 卷
 
-* 二进制文件格式是否正确.
-* 引擎版本是否正确.
-* 清单签名是否正确.
-* 新旧文件签名所用的公钥私钥是否一致.
-* 清单列出的资源是否齐全.
+热更新的 .zip 文件包含了基础游戏包排除掉的文件.
 
-从用户角度来看, 验证过程不必深入了解, 但是要知道验证内容, 以便遇到错误时可以及时修复.
+我们目前的方法只支持单个 .zip 文件, 但是实际上把它分成若干小 .zip 文件是可行的. 这会让游戏下载更小的卷: level 包, 特典包等等. 每个 .zip 文件包含 manifest 文件描述了 .zip 文件里包含的资源的元数据.
 
-::: sidenote
-如果遇到 "ERROR:RESOURCE: Byte mismatch in decrypted manifest signature. Different keys used for signing?" 错误很有可能是因为你的服务器对包外资源和清单文件的 MIME 类型设置错误. 确保 MIME 类型为 `application/octet-stream`. 可以使用 `.htaccess` 文件加上一条 `AddType application/octet-stream .` 关联到资源和清单文件所在文件夹.
-:::
-
-### 引擎版本
-清单文件支持生成它的 Defold 版本. 如果希望它支持更多版本, 需要在热更新配置里手动添加. 如果你的游戏需要多版本客户端同时在线, 这一步设定很重要.
-
-![Manifest supported engine versions](images/live-update/engine-versions-settings.png)
-
-### 签名密钥
-清单签名用来保证游戏内容没有被恶意篡改, 还要确保新旧清单文件签名所用的密钥是相同的. 编译时签名自动生成.
-清单签名使用一对公私密钥. 用户需要提供 `.der` 格式 512/1024/2048-bit RSA 密钥. 可以使用 `openssl` 工具生成密钥:
-
-```sh
-$ openssl genrsa -out private_raw.key 1024
-$ openssl pkcs8 -topk8 -inform pem -in private_raw.key -outform der -nocrypt -out private.der
-$ openssl rsa -in private_raw.key -outform DER -RSAPublicKey_out -pubout -out public.der
-```
-输出文件为 `private_raw.key` (可以删除), `private.der` 和 `public.der`. 然后在热更新配置里指定密钥位置.
-
-![Manifest signature key-pair](images/live-update/manifest-keys.png)
-
-### 热更新清单脚本
-接上文热更新脚本, 加入以下回调函数:
-
-```lua
-local function store_manifest_cb(self, status)
-    if status == resource.LIVEUPDATE_OK then
-        print("Successfully stored manifest!")
-    else
-        print("Failed to store manifest, status: ", status)
-    end
-end
-```
-
-然后在 ```on_message``` 里加入处理 ```attempt_download_manifest``` 的代码:
-
-```lua
-...
-elseif message_id == hash("attempt_download_manifest") then
-    local base_url = "https://my-game-bucket.s3.amazonaws.com/my-resources/" -- <1>
-    http.request(base_url .. MANIFEST_FILENAME, "GET", function(self, id, response)
-        if response.status == 200 or response.status == 304 then
-            -- 响应 ok.
-            print("verifying and storing manifest " .. MANIFEST_FILENAME)
-            resource.store_manifest(response.response, store_manifest_cb) -- <2>
-        else
-            -- 错误! 清单下载失败.
-            print("Failed to download manifest: " .. MANIFEST_FILENAME)
-        end
-    end)
-end
-```
-1. 清单文件要跟热更新资源保存在一起. 无论是保存在S3服务器还是打zip包.
-2. 跟资源文件下载保存类似, 调用 `resource.store_manifest` 下载清单数据传入回调函数. 下载验证后保存在本地.
-
-如果 `resource.store_manifest` 成功, 清单已保存在本地. 下次游戏启动会自动使用新清单文件代替包内旧清单文件.
-
-### 注意事项
-更新清单文件要注意几个事项.
-
-* 只能添加或修改集合代理中被设置为 `Exclude` 的资源. 包内资源和集合代理未设置排除的资源不可更改. 比如清单列表要更新包内脚本, 但是因为包内资源不变 (只有清单更新了), 无法在包内找到新脚本, 更新肯定不会成功.
-
-* 热更新方便快捷, 但是使用时要多加留意. 热更新也是更新, 发布前也要做测试等工作.
-
-## 创建 Amazon 网络服务器
-
-要使用 Defold 配合 Amazon 服务器进行热更新首先要有 Amazon Web Services 账户. 没有的话请在这里注册: https://aws.amazon.com/.
-
-这里介绍一下如何开通 Amazon 服务以配合 Defold 进行热更新, 在 Amazon S3 需要那些配置. 更多关于 Amazon S3 的信息, 请参考 [Amazon S3 文档](http://docs.aws.amazon.com/AmazonS3/latest/dev/Welcome.html).
-
-1. 开通服务
-
-    在 _Storage_ 类目 ([Amazon S3 Console](https://console.aws.amazon.com/s3)) 下打开 `Services` 菜单选择 `S3`. 页面上会列出已存在的所有服务器与开通新服务器的选项. 使用已存在的服务器是可以的, 但是建议为热更新资源创建一个新服务器,以便设置访问限制.
-    
-    ![Create a bucket](images/live-update/01-create-bucket.png)
-
-2. 服务配置
-
-    开通服务器, 打开 *Properties* 面板展开折叠的 *Permissions* 选项. 点击 *Add bucket policy* 按钮添加配置文件. 本例中的配置是允许任何客户端访问服务器资源, 以便热更新顺利工作. 更多配置信息, 请参考 [Amazon 文档](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html).
-
-    ```json
-    {
-        "Version": "2012-10-17",
-        "Statement": [
-            {
-                "Sid": "AddPerm",
-                "Effect": "Allow",
-                "Principal": "*",
-                "Action": "s3:GetObject",
-                "Resource": "arn:aws:s3:::defold-liveupdate-example/*"
-            }
-        ]
-    }
-    ```
-
-    ![Bucket policy](images/live-update/02-bucket-policy.png)
-
-3. 添加 CORS 配置 (可选)
-
-    [Cross-Origin Resource Sharing (CORS)](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) 是一种能让服务器使用 JavaScript 访问另一服务器资源的机制. 如果你发布的是 HTML5 游戏, 就需要给服务器添加 CORS 配置.
+## 内容验证
 
-    选择服务器, 打开 *Properties* 面板展开折叠的 *Permissions* 选项. 点击 *Add CORS Configuration* 按钮添加 CORS 配置. 本例中的配置是允许任何服务器访问本服务器资源, 如果需要可以做详细的限制. 更多 Amazon CORS 配置信息, 请参考 [Amazon 文档](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html).
+热更新系统的一大特性, 是可以使用多个数据卷, 而不管它来自哪个版本的 Defold.
 
-    ```xml
-    <?xml version="1.0" encoding="UTF-8"?>
-    <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
-        <CORSRule>
-            <AllowedOrigin>*</AllowedOrigin>
-            <AllowedMethod>GET</AllowedMethod>
-        </CORSRule>
-    </CORSConfiguration>
-    ```
-
-    ![CORS configuration](images/live-update/03-cors-configuration.png)
+方法 `liveupdate.add_mount()` 的默认行为, 是添加 mount 时加入引擎版本校验.
+这意味着游戏基础卷和热更新卷需要用相同引擎版本同时建立, 使用一致的打包选项. 这将使客户端将以前下载的内容无效化, 强制重新下载内容.
 
-4. 创建 IAM 配置
+这个行为可以用一个可选参数关掉.
+关掉的话, 内容验证责任完全由开发者承担, 以保证每个热更新卷都能在当前运行的引擎下可用.
 
-    打开 *Services* 菜单, 在 _Security, Identity & Compliance_ 类目 ([Amazon IAM Console](https://console.aws.amazon.com/iam)) 下打开 *IAM*. 选择左边的 *Policies*, 页面会列出已存在的所有 IAM 配置与创建新配置的选项.
+我们建议给每个 mount 保存一些元数据, 以便 _在启动时_, 开发者能决定 mount/archive 是否应该删除.
+一个办法就是在游戏打包后给 zip 包里加入文件. 比如插入一个存有相关信息的 `metadata.json`. 然后, 在启动时, 游戏能用 `sys.load_resource("/metadata.json")` 取回信息. _注意每个 mount 的自定义数据要有唯一的名字, 否则 mount 将使用最高优先级的文件_
 
-    点击 *Create Policy* 按钮, 选择 _Create Your Own Policy_. 本例中的配置是允许用户获得服务器列表, 这是 Defold 热更新的必要配置. 这里还可以允许用户获得 Access Control List (ACL) 和把资源文件上传至服务器的权力. 关于 Amazon Identity and Access Management (IAM) 的更多信息, 详见 [Amazon 文档](http://docs.aws.amazon.com/IAM/latest/UserGuide/access.html).
+如果没做好, 你将面对内容与引擎不匹配的局面, 这将导致强制自动退出.
 
-    ```json
-    {
-        "Version": "2012-10-17",
-        "Statement": [
-            {
-                "Effect": "Allow",
-                "Action": [
-                    "s3:ListAllMyBuckets"
-                ],
-                "Resource": "arn:aws:s3:::*"
-            },
-            {
-                "Effect": "Allow",
-                "Action": [
-                    "s3:GetBucketAcl"
-                ],
-                "Resource": "arn:aws:s3:::defold-liveupdate-example"
-            },
-            {
-                "Effect": "Allow",
-                "Action": [
-                    "s3:PutObject"
-                ],
-                "Resource": "arn:aws:s3:::defold-liveupdate-example/*"
-            }
-        ]
-    }
-    ```
+## Mounts
 
-    ![IAM policy](images/live-update/04-create-policy.png)
+热更新同时使用多个内容卷.
+每个卷是 "挂载" 到引擎的资源系统的, 连同名字和优先级.
 
-5. 创建管理账户
+如果两个卷都有 `sprite.texturec` 文件, 则引擎将加载最高优先级的 mount 里的文件.
 
-    打开 *Services* 菜单, 在 _Security, Identity & Compliance_ 类目 ([Amazon IAM Console](https://console.aws.amazon.com/iam)) 下打开 *IAM*. 选择左边的 *Users*, 页面会列出已存在的所有用户与创建新用户的选项. 使用已存在的用户是可以的, 但是建议为热更新资源创建一个新用户,以便设置访问限制.
+引擎并不索引 mount 里的资源. 当资源被载入内存, 卷可能会被卸载. 资源会保留在内存中直到它们被卸载.
 
-    点击 *Add User* 按钮, 输入用户名选择 *Programmatic access* 作为 *Access type*, 然后点击 *Next: Permissions*. 选择 *Attach existing policies directly* 然后选择第4步中所作的配置.
+mounts 在引擎重启时会被自动重新读取.
 
-    完成之后你会得到 *Access key ID* 和 *Secret access key*.
-
-    ::: sidenote
-    保存好密匙 *非常重要* 因为离开 Amazon 页面后就无法再次获得密匙了.
-    :::
-
-6. 创建档案文件
-
-    此时你已经开启了服务器, 做好了客户端访问配置, 添加了服务端方位配置, 新建了用户权限和一个新用户. 剩下的最后一件事是创建 [档案文件](https://aws.amazon.com/blogs/security/a-new-and-standardized-way-to-manage-credentials-in-the-aws-sdks) 以便让 Defold 也能访问服务器.
-
-    在本地新建一个 *.aws* 文件夹, 在里面新建一个 *credentials* 文件.
-
-    ```bash
-    $ mkdir ~/.aws
-    $ touch ~/.aws/credentials
-    ```
-
-    文件 *~/.aws/credentials* 要包含访问 Amazon 服务所需的凭证即标准 AWS 证书. 打开文件按照如下格式输入你的 *Access key ID* 和 *Secret access key*.
-
-    ```ini
-    [defold-liveupdate-example]
-    aws_access_key_id = <Access key ID>
-    aws_secret_access_key = <Secret access key>
-    ```
+::: sidenote
+挂在卷不会拷贝或移动文件包. 引擎只保存包的路径. 这样, 开发者可以任意删除卷, mount 会在下次启动时被删除.
+:::
 
-    服务器名, 本例中是 _defold-liveupdate-example_, 在 Defold 编辑器热更新配置里也要提供.
+## 热更新脚本
 
-    ![Live update settings](images/live-update/05-liveupdate-settings.png)
+使用热更新更新内容, 必须下载并挂载游戏数据.
+参见 [这里的热更新脚本教程](/manuals/live-update-scripting.md).
 
-## 开发注意事项
+## 开发警告
 
 调试
-: 运行打包游戏, 不要直接接入控制台. 这在调试时会产生错误. 但是当你使用命令行或者双击启动的方式启动游戏:
+: 当运行游戏的某个版本, 没有对控制台的直接访问权. 这在调试时会出问题. 然而, 你可以用命令行启动游戏或者双击游戏的可执行文件:
 
   ![Running a bundle application](images/live-update/run-bundle.png)
 
-  这样游戏里的 `print()` 语句输出都会被打印到控制台上:
+  此时游戏连同控制台窗口启动并能显示所有 `print()` 内容:
 
   ![Console output](images/live-update/run-bundle-console.png)
 
 强制重新下载资源
-: 游戏保存资源时, 文件被保存在设备本地硬盘上. 重启游戏, 资源文件并不消失. 开发阶段可能会希望删掉这些文件然后强制重新下载.
+: 开发者可以把内容下载到任意文件/文件夹里, 但是通常是保存在游戏目录. 游戏目录取决于操作系统. 可以用 `print(sys.get_save_file("", ""))` 找到.
 
-  Defold 在设备上的应用文件夹下创建了一个以游戏包哈希值为名字的文件夹. 如果删除这个文件夹下的文件, 游戏会自动把清单资源作废然后就可以重新下载重新保存了.
+  文件 liveupdate.mounts 放在 "local storage" 下, 这个目录显示在控制台开头 "INFO:LIVEUPDATE: Live update folder located at: ..."
 
   ![Local storage](images/live-update/local-storage.png)
-
-  这个应用文件夹的位置基于操作系统有所不同. 可以运行 `print(sys.get_save_file("", ""))` 脚本查看其路径.
-  

+ 20 - 2
docs/zh/manuals/lua.md

@@ -12,10 +12,28 @@ Defold 引擎嵌入了 Lua 语言用以编写脚本. Lua 是一种轻量级脚
 ## Lua 版本
 我们力争让 Defold 在各个平台表现一致, 但是不同平台对于 Lua 版本使用略有不同. 对 HTML5 和 iOS 64 bit 平台我们使用 Lua 5.1 对其他平台我们使用 LuaJIT. LuaJIT 基于 5.1 还包含了一些特有功能.
 
-::: sidenote
+| Platform        | Lua version         | JIT Enabled |
+|-----------------|---------------------|-------------|
+| Windows         | LuaJIT 2.1.0-beta3  | Yes         |
+| macOS           | LuaJIT 2.1.0-beta3  | Yes         |
+| Linux           | LuaJIT 2.1.0-beta3  | Yes         |
+| Android         | LuaJIT 2.1.0-beta3  | Yes         |
+| iOS             | LuaJIT 2.1.0-beta3  | No*         |
+| Nintendo Switch | LuaJIT 2.1.0-beta3  | No*         |
+| HTML5           | Lua 5.1.4           | N/A         |
+
+*=JIT compiled code is not allowed
+
+[LuaJIT](https://luajit.org/) is a highly optimized version of Lua, suitable for use in games and other performance critical software. LuaJIT is fully upwards-compatible with Lua 5.1. It supports all standard Lua library functions and the full set of Lua/C API functions.
+
+LuaJIT also adds a number of [language extensions](https://luajit.org/extensions.html) and some features from Lua 5.2.
+
+::: important
 要真正做到跨所有平台建议只使用 Lua 5.1 功能.
 :::
 
+
+### 标准库和扩展
 Defold 包含所有 [Lua 5.1 标准库](http://www.lua.org/manual/5.1/manual.html#5) 连同 socket 和少量操作系统功能库:
 
   - base (`assert()`, `error()`, `print()`, `ipairs()`, `require()` 等等)
@@ -138,7 +156,7 @@ string
   print(my_string .. another_string) --> "helloworld"
 
   print("10.2" + 1) --> 11.2
-  print(my_string + 1) -- error, can't convert "hello"
+  print(my_string + 1) -- 报错, 不能转换为 "hello"
   print(my_string .. 1) --> "hello1"
 
   print("one\nstring") --> one

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

@@ -45,7 +45,58 @@ Samplers
 Tags
 : 标签与材质相关. 标签在引擎内部表现为 _bitmask_ 并由 [`render.predicate()`](/ref/render#render.predicate) 来收集需要渲染的组件. 如何渲染请见 [Render documentation](/manuals/render). 每个项目最多可以使用32个标签.
 
-## 着色器常量
+## Attributes
+
+Shader 属性 (也叫 vertex streams), 是一个 GPU 从内存获取顶点来渲染几何图形的机制. 顶点着色器使用 `attribute` 关键字指定一系列流而且多数情况下 Defold 在流名称上自动创建并绑定数据. 然而, 有些情况下你会想传递顶点数据来实现一个引擎没有的特效. 顶点属性有如下配置:
+
+Name
+: 属性名. 与着色器常量类似, 属性配置只在顶点程序里匹配指定属性的时候使用.
+
+Semantic type
+: 语义类型是指属性 *是什么* 或者 *如何* 在编辑器中显示的语义. 例如, 指定属性为 `SEMANTIC_TYPE_COLOR` 会在编辑器中显示一个颜色拾取器, 同时数据会从引擎原样发送至着色器.
+
+  - `SEMANTIC_TYPE_NONE` 默认语义类型. 除了给属性传送材质数据到顶点缓存以外没有其他效果.
+  - `SEMANTIC_TYPE_POSITION` 给属性创建每个顶点位置数据. 可以连同坐标空间一起告诉引擎位置应该如何计算.
+  - `SEMANTIC_TYPE_TEXCOORD` 给属性创建每个顶点的纹理坐标.
+  - `SEMANTIC_TYPE_PAGE_INDEX` 给属性创建每个顶点的页码.
+  - `SEMANTIC_TYPE_COLOR` 决定编辑器如何解释属性. 如果属性被配置为颜色语义, 则会在检视面板上显示一个颜色拾取器.
+
+::: sidenote
+材质系统会在运行时基于特定属性名给属性分配默认语义: position, texcoord0, page_index. 如果材质中有这些名字, 则默认语义类型会覆盖你在材质编辑器的手动配置!
+:::
+
+Data type
+: 属性数据类型.
+
+  - `TYPE_BYTE` 有符号 8 位值
+  - `TYPE_UNSIGNED_BYTE` 无符号 8 位值
+  - `TYPE_SHORT` 有符号 16 位短值
+  - `TYPE_UNSIGNED_SHORT` 无符号 16 位短值
+  - `TYPE_INT` 有符号整数
+  - `TYPE_UNSIGNED_INT` 无符号整数
+  - `TYPE_FLOAT` 浮点值
+
+Count
+: 属性的 *元素数*, 比如属性值的个数. 着色器里一个 `vec4` 有四个元素, 一个 `float` 有一个元素. 注意: 即使在着色器里制定了属性是一个 `vec4`, 你还是能给它指定元素更少的值, 这可以帮助减少内存占用.
+
+Normalize
+: 如果是 true, 属性值会被 GPU 驱动程序规范化. 当你不需要全精度, 又想在不知特定范围情况下计算时会很有用. 比如一个颜色向量一般只需 0..255 的 byte 值同时在着色器里被当作 0..1 的值.
+
+Coordinate space
+: 有些语义类型支持在不同坐标空间里提供数据. 要给 sprite 实现一个 billboarding 效果, 一般需要本地坐标系的位置属性加上世界坐标系的位置属性以实现更有效的合批.
+
+Value
+: 属性值. 可以基于每个组件覆盖属性值, 但除此之外, 这就是顶点属性的默认值. 注意: 对于 *默认* 属性 (position, texture coordinates 和 page indices) 该值被忽略.
+
+::: sidenote
+自定义属性也可以在 CPU 和 GPU 上帮助减少内存占用, 方法是重构流以使用更小的数据类型, 或更少的元素.
+:::
+
+::: important
+自定义属性从 Defold 1.4.8 版本开始可用!
+:::
+
+## 顶点和片元常量
 
 着色器常量, 或称 "uniforms" 是从引擎传输给顶点和片元着色器程序的数据. 要使用常量,您可以在材质文件中将其定义为一个 *顶点常量* 属性或 *片元常量* 属性.需要在着色器程序中定义相应的 `uniform` 变量.材质中可以设置以下常量:
 
@@ -64,6 +115,9 @@ CONSTANT_TYPE_VIEWPROJ
 CONSTANT_TYPE_WORLDVIEW
 : 世界与视口映射矩阵相乘后的矩阵.
 
+CONSTANT_TYPE_WORLDVIEWPROJ
+: 世界, 视口与映射矩阵相乘后的矩阵.
+
 CONSTANT_TYPE_NORMAL
 : 用于计算法方向的矩阵. 世界移动转换可能包含非等比缩放, 这样会打破世界-视口转换的正交性. 变换法线时使用发方向可以避免这个问题. (法矩阵是世界-视口矩阵的转置逆).
 

+ 1 - 0
docs/zh/manuals/message-passing.md

@@ -155,6 +155,7 @@ Defold 提供两种简化写法用来简化消息传递时需要输入的完整
 
 :[Shorthands](../shared/url-shorthands.md)
 
+
 ## 接收消息
 
 接收消息由 `on_message()` 函数完成. 函数接收4个参数:

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

@@ -125,4 +125,4 @@ go.animate("#model", "cursor", go.PLAYBACK_LOOP_PINGPONG, 1, go.EASING_LINEAR, 1
   end
   ```
 
-关于渲染脚本详情请见 [Render documentation](/manuals/render).
+关于渲染脚本详情请见 [渲染教程](/manuals/render).

+ 3 - 15
docs/zh/manuals/nintendo-switch.md

@@ -7,6 +7,7 @@ brief: 本教程介绍了 Nintendo Switch 开发许可
 
 基于 Nintendo 许可证限制, 支持 Nintendo Switch 平台的 Defold 版本不包括标准版. 要获取支持 Sony PlayStation® 的 Defold 特殊版本首先必须成为 Nintendo Switch 的正式开发者.
 
+
 ## 注册成为 Nintendo Switch 开发者
 
 可以在 [Nintendo Developer Portal](https://developer.nintendo.com/register) 注册成为 Nintendo Switch 开发者:
@@ -17,26 +18,13 @@ Nintendo 审核通过后就可以访问 Nintendo 开发者大厅里的 Defold 
 
 ## Nintendo Switch 的 Defold 访问
 
-当我们确定开发者是正式 Nintendo 开发者时, 我们会在 Defold 中提供对 Nintendo Switch 的两层访问:
-
-1. 标准访问 - Nintendo Switch 扩展, 编译工具及技术支持.
-2. 源码访问 - Nintendo Switch 扩展, 编译工具及技术支持连同 Defold 引擎用于访问 Nintendo Switch 那部分的源代码.
-
-
-### 标准访问
-
-Nintendo 批准的所有开发人员均可免费访问支持 Nintendo Switch 的 Defold 版本. 作为获得批准的开发人员, 我们将为您提供以下访问权限:
+当我们确定开发者是正式 Nintendo 开发者时, 我们会在 Defold 中提供对 Nintendo Switch 的访问:
 
 * Nintendo Switch 相关 API 整合的扩展程序.
+* Nintendo Switch 开启的 Defold 游戏引擎源码. 请注意, 为 Nintendo Switch 构建游戏不需要源代码访问权限, 但如果您希望对引擎核心做出源代码贡献, 我们会提供访问权限.
 * 用于编译打包 Nintendo Switch 应用的 [命令行工具](/manuals/bob).
 * 提供 Nintendo Switch 相关技术支持的论坛.
 
 
-### 源码访问
-
-只对 [活跃月度社区捐款](/community-donations/) 达到一定数额的开发者提供源码访问.
-
-![](images/nintendo-switch/register-defold.png)
-
 ## 问答
 :[Consoles FAQ](../shared/consoles-faq.md)

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

@@ -45,17 +45,36 @@ Defold 支持 .ogg 和 .wav 文件其中 .ogg 一般用于音乐 .wav 一般用
   * iPhone 4: 2048x2048
   * iPad 2, 3, Mini, Air, Pro: 4096x4096
   * iPhone 4s, 5, 6+, 6s: 4096x4096
-* Android 各不相同但是新设备基本都支持 4096x4096.
+* Android 最大纹理尺寸各不相同但是新设备基本都支持 4096x4096.
 
 如果图集太大就需要切分成小图集或者使用 texture profile 缩小整个图集. Defold 的 texture profile 系统不但可以缩小图集还可以通过应用压缩算法减小图集占用空间. 详见 [纹理档教程](/manuals/texture-profiles/).
 
+* mipmaps: false
+* premultiply_alpha: true
+* format: TEXTURE_FORMAT_RGBA
+* compression_level: NORMAL
+* compression_type: COMPRESSION_TYPE_BASIS_UASTC
+
 ::: sidenote
 优化和管理纹理可以参考 [这个帖子](https://forum.defold.com/t/texture-management-in-defold/8921).
 :::
 
+### 优化字体
+如果在 [Extra Characters](/manuals/font/#properties) 里指定文字而不是勾选包含所有字符, 字体大小就会减小.
+
+
 ### 排除内容按需下载
 另一个减小包体的办法是打包时把部分内容排除在外, 需要时再下载. 一开始被排除的东西可以是锁住的关卡, 未激活的角色, 皮肤, 武器或者是车辆. Defold 提供了叫做热更新的按需下载内容的方案. 详情请见 [热更新教程](/manuals/live-update/).
 
+### Android 大小优化
+Android 包必须支持 32-bit 和 64-bit CPU 架构. 当 [打包 Android](/manuals/android) 时你可以指定包含哪种 CPU 架构:
+
+![Signing Android bundle](images/android/sign_bundle.png)
+
+Google Play 支持同一个游戏的 [多 APKs 包](https://developer.android.com/google/play/publishing/multiple-apks), 所以你可以用生成连个 APKs 的方法减小包体, 每种 CPU 架构生成一个, 然后把这两个都上传至 Google Play.
+
+还有一种方法是结合 [APK 扩展文件](https://developer.android.com/google/play/expansion-files) 和 [热更新内容](/manuals/live-update). 谢谢 [资源大厅的 APKX 扩展](https://defold.com/assets/apkx/).
+
 
 ## 应用运行速度优化
 你要知道游戏运行效率瓶颈在哪才能进行优化. 每帧的什么操作最耗时间? 与渲染有关吗? 与游戏逻辑有关吗? 与场景图有关吗? 建议使用内置的分析工具分析这些事情. 使用 [屏幕或者网页分析器](/manuals/profiling/) 对游戏进行采样再分析哪里应该优化. 发现最耗时的操作就找到了优化方向.
@@ -144,6 +163,13 @@ end
 * [性能分析](/manuals/profiling/)
 
 
+### 微调组件计数
+检查 `game.project` 里的组件计数. 使用 [调试器](/manuals/profiling/) 获取准确的组件和资源使用情况, 并将游戏配置为使用更接近组件和资源实际计数的最大值. 这将减少游戏使用内存量 (参考组件 [最大数优化](/manuals/project-settings/#component-max-count-optimizations)).
+
+### Heap 大小 (仅 HTML5)
+确定给游戏设置最小的 heap 尺寸. 打开游戏玩最多 "资源展示" 的一关. 开启浏览器的开发者工具, 在控制台上写入 `HEAP8.length / 1024 / 1024`. 用这个数据加上 10-15% 来 `game.project` 里设置 [Heap 大小](/manuals/project-settings/#heap-size).
+
+
 ## 优化耗电
 此部分教程未完成. 讨论涵盖以下方面:
 

+ 0 - 1
docs/zh/manuals/physics-groups.md

@@ -13,6 +13,5 @@ brief: 物理引擎使用组来划分物理对象碰撞双方.
 
 *掩码* 可包含多个组名, 以实现复杂的碰撞控制.
 
-
 ## 碰撞检测
 当组码掩码都相匹配两个碰撞对象接触时, 游戏引擎就会发出 [碰撞消息](/manuals/physics-messages) 作为响应.

+ 1 - 0
docs/zh/manuals/physics-joints.md

@@ -12,6 +12,7 @@ Defold 支持物理关节. 一个关键基于某种限制连接两个物体. 支
 * **Weld (physics.JOINT_TYPE_WELD)** - 用於完全保持對象之間的位置關係的關節. 通過調整頻率和阻尼率軟化的焊接關節可以產生類似彈簧的效果. 在 Box2D 被称为焊接关节.
 * **Spring (physics.JOINT_TYPE_SPRING)** - 限制两个物体之间距离范围的弹簧关节. 弹簧关节通过设定其频率和阻尼比可以让物体像是被软弹簧连接. 在 Box2D 被称为距离关节.
 * **Slider (physics.JOINT_TYPE_SLIDER)** - 限制两物体只能在某个指定轴上相对移动而不允许相对转动的滑动关节. 在 Box2D 被称为活塞关节.
+* **Wheel (physics.JOINT_TYPE_WHEEL)** - 轮子关节从 bodyB 上的一个点约束到 bodyA 上的一条线. 轮子关节还提供了悬架弹簧. 在 Box2D 里称作焊接关节.
 
 ## 建立关节
 

+ 12 - 0
docs/zh/manuals/physics-messages.md

@@ -20,6 +20,9 @@ brief: 当两个碰撞对象接触, 引擎会向这两个对象上的所有组
 `other_group`
 : 另一个碰撞物所在的碰撞组 (`hash`过的)
 
+`own_group`
+: 碰撞物体的碰撞组 (`hash`过的)
+
 如果不需要很详细的信息, 碰撞响应消息就足够了, 比如检测子弹是否碰撞了敌人. 每帧每对碰撞物只有一个能收到此消息.
 
 ```Lua
@@ -69,6 +72,9 @@ end
 `group`
 : 另一个物体所处的碰撞组 (`hash`过的).
 
+`own_group`
+: 碰撞物体的碰撞组 (`hash`过的).
+
 要让相碰撞的物体好好分离, 用 `"contact_point_response"` 消息里的数据就够了. 注意每帧每对碰撞物可能不止收到一个 `"contact_point_response"` 消息, 这取决于接触的情况, 详见 [碰撞处理教程](/manuals/physics-resolving-collisions).
 
 ```Lua
@@ -94,6 +100,12 @@ end
 `enter`
 : 如果另一个物体进入触发器为 `true`, 离开为 `false`. (`boolean`类型).
 
+`other_group`
+: 另一个物体所处的碰撞组 (`hash`过的).
+
+`own_group`
+: 碰撞物体的碰撞组 (`hash`过的).
+
 ```Lua
 function on_message(self, message_id, message, sender)
     -- check for the message

+ 11 - 11
docs/zh/manuals/physics-objects.md

@@ -53,29 +53,29 @@ Type
 Friction
 : 摩擦可以做出一个物体在另一个物体上滑动的效果. 一般摩擦系数取值范围从 `0` (无摩擦---超级光滑) 到 `1` (强摩擦---超级粗糙) 之间. 但其实任何正数值都有效.
 
-摩擦力于法方向上的力成正比 (称为库伦摩擦). 计算两个物体 (`A` 和 `B`) 间的摩擦力时, 摩擦系数取两个物体的几何平均值:
+  摩擦力于法方向上的力成正比 (称为库伦摩擦). 计算两个物体 (`A` 和 `B`) 间的摩擦力时, 摩擦系数取两个物体的几何平均值:
 
-$$
-F_{combined} = \sqrt{ F_A \times F_B }
-$$
+  $$
+  F = sqrt( F_A * F_B )
+  $$
 
-也就是说只要有一个物体是0摩擦的, 两个物体之间就不会有摩擦力.
+  也就是说只要有一个物体是0摩擦的, 两个物体之间就不会有摩擦力.
 
 Restitution
 : 弹性是物体的 "反弹性能". 一般取值范围从 0 (非弹性碰撞—一点也不反弹) 到 1 (完全弹性碰撞---物体速度在碰撞后完全反向)
 
-两个物体 (`A` 和 `B`) 之间的弹性计算基于以下公式:
+  两个物体 (`A` 和 `B`) 之间的弹性计算基于以下公式:
 
-$$
-R = \max{ \left( R_A, R_B \right) }
-$$
+  $$
+  R = max( R_A, R_B )
+  $$
 
-当一个形状发生多处碰撞时, 弹性模拟并不精确因为 Box2D 使用的是迭代解算器. Box2D 在碰撞相对速度很小时也使用非弹性碰撞代替, 以防止反弹抖动.
+  当一个形状发生多处碰撞时, 弹性模拟并不精确因为 Box2D 使用的是迭代解算器. Box2D 在碰撞相对速度很小时也使用非弹性碰撞代替, 以防止反弹抖动.
 
 Linear damping
 : 线性阻尼会减小刚体的线性速度. 不像摩擦只在物体接触时产生, 线性阻尼始终应用与线性移动的物体上, 给人一种物体飘进比空气密度大的环境中的感觉. 取值范围 0 到 1.
 
-Box2D 并不精确计算阻尼. 值很小时阻尼与时间无关, 值很大时阻尼随时间变化. 如果时间步固定, 这不会造成问题.
+  Box2D 并不精确计算阻尼. 值很小时阻尼与时间无关, 值很大时阻尼随时间变化. 如果时间步固定, 这不会造成问题.
 
 Angular damping
 : 角阻尼与线性阻尼类似, 不同的是它减小的是刚体角速度. 取值范围 0 到 1.

+ 3 - 1
docs/zh/manuals/physics-resolving-collisions.md

@@ -40,7 +40,9 @@ end
 
 ![Projection](images/physics/projection.png){srcset="images/physics/[email protected] 2x"}
 
-$$l = vmath.project(A, B) \times vmath.length(B)$$
+```
+l = vmath.project(A, B) * vmath.length(B)
+```
 
 补偿向量等于 *B* 向量减去 *l* 向量. 所以计算位移的时候, 对于每个碰撞点, 可以引入矫正向量按以下步骤进行矫正:
 

+ 3 - 3
docs/zh/manuals/physics-shapes.md

@@ -27,11 +27,10 @@ brief: 碰撞对象的形状可以包含多个简单形状组成也可以由一
 
 ![Sphere shape](images/physics/capsule.png)
 
-::: sidenote
+::: important
 胶囊形仅用于 3D 物理 (在 *game.project* 文件的物理部分进行设置).
 :::
 
-
 ### 复杂形状
 复杂形状可以由瓷砖地图生成或者使用凸多边形.
 
@@ -47,7 +46,7 @@ Defold 包含一个功能就是从瓷砖地图中自动生成瓷磚圖源的物
 
 ![Tilesource collision](images/physics/collision_tilemap.png){srcset="images/physics/[email protected] 2x"}
 
-::: sidenote
+::: important
 这里的 *Group* 属性 **不会** 生效, 因为碰撞组已在瓷砖图源中定义好了.
 :::
 
@@ -71,5 +70,6 @@ Defold 有一个功能就是让你用3个或多个点建立凸多边形. 可以
 ## 在3D物理世界中旋转碰撞形状
 在3D物理中物体在各个轴上都可以进行旋转.
 
+
 ## 在2D物理世界中旋转碰撞形状
 在3D物理中物体只能在z轴上旋转. 其他轴旋转会造成错误结果, 即使旋转180度用于翻转形状也不行. 要翻转物理形状推荐使用 [`physics.set_hlip(url, flip)`](/ref/stable/physics/?#physics.set_hflip:url-flip) 和 [`physics.set_vlip(url, flip)`](/ref/stable/physics/?#physics.set_vflip:url-flip) 函数.

+ 0 - 4
docs/zh/manuals/physics.md

@@ -38,7 +38,3 @@ Defold 中的物理相关教程如下:
 
 碰撞漏检
 : 如果发现碰撞未检测或未处理请先阅读 [调试教程的物理调试部分](/manuals/debugging-game-logic/#物理引擎调试).
-
-
-
-

+ 60 - 10
docs/zh/manuals/porting-guidelines.md

@@ -5,25 +5,38 @@ brief: 本手册重点介绍了将游戏移植到新平台时需要考虑的一
 
 # 移植指南
 
-将 Defold 游戏移植到新平台通常是一个比较简单的过程. 理论上只要在 *game.project* 文件里配置好就行了, 但是处于对平台充分利用的考量还是推荐针对目标平台进行适配. 本教程包含一些通用移植的最佳实践和一些平台相关的细节.
+本教程包含了游戏跨平台发布的教程和步骤.
 
+将 Defold 游戏移植到新平台通常是一个比较简单的过程. 理论上只要在 *game.project* 文件里配置好就行了, 但是处于对平台充分利用的考量还是推荐针对目标平台进行适配. 本教程包含一些通用移植的最佳实践和一些平台相关的细节.
 
-## 最佳实践
 
-### 输入
+## 输入
 确保游戏适配平台的输入法. 只要支持 [游戏手柄](/manuals/input-gamepads) 的平台就做好手柄支持! 确保游戏有一个暂停菜单 - 万一输入控制器突然断掉, 游戏有必要暂停!
 
-
-### 本地化
+## 本地化
 本地化翻译游戏中的任何文本以及商店页面中的文本,因为这将对销售产生积极影响! 对于本地化, 确保玩家可以在游戏的不同语言之间轻松切换 (通过暂停菜单).
 
+::: important
+仅 iOS - 确保在 `game.project` 里指定了 [Localizations](/manuals/project-settings/#localizations), 因为语言不在列表中的话 sys.get_info() 会返回空值.
+:::
+
+翻译应用页面上的文字因为这样会对销售产生积极意义! 一些平台要求为游戏发售的每个国家翻译页面文字.
+
+## 商店资料
+
+### 应用图标
+确保您的游戏在竞争中脱颖而出. 图标通常是您与潜在玩家的第一个接触点. 要在充满游戏图标的页面上很容易找到才好.
+
+### 商店横幅和图像
+确保为您的游戏使用有影响力和令人兴奋的美术资源. 花一些钱与艺术家合作创作吸引玩家的图像可能是件值得的事.
 
-### 保存游戏进度
 
-#### 在桌面设备, 手机和 web 游戏里保存进度
+## 保存游戏进度
+
+### 在桌面设备, 手机和 web 游戏里保存进度
 保存游戏状态可以使用 Defold API 函数 `sys.save(filename, data)` 然后使用 `sys.load(filename)` 加载. 可以使用 `sys.get_save_file(application_id, name)` 获取不同系统上文件保存的路径, 一般就是登录用户的 home 文件夹.
 
-#### 在游戏主机里保存进度
+### 在游戏主机里保存进度
 用 `sys.get_save_file()` 和 `sys.save()` 能在大多数平台上顺利工作, 但是在游戏主机上推荐另一个方法. 游戏主机平台通常将用户与每个连接的手柄相关联, 这样当保存进度时, 成就和其他功能应与其各自的用户相关联.
 
 游戏手柄输入事件将包含一个用户 id, 可用于将手柄的操作与控制台上的用户关联起来.
@@ -46,15 +59,49 @@ end
 ```
 
 
-### 性能
+## Build artifacts
+
+确保为每个版本发布 [生成 debug symbols](/manuals/debugging-native-code/#symbolicate-a-callstack) 以便你能对它们进行崩溃调试. 将它们与应用包保存在一起.
+
+确保储存初次打包时在项目根目录生成的 `manifest.private.der` 和 `manifest.public.der` 文件. 它们是游戏包和 manifest 的公钥和私钥. 您需要这些文件才能重新创建游戏的上一个版本.
+
+
+## 应用优化
+
+参考 [优化教程](/manuals/optimizations) 优化应用的性能, 大小, 内存占用和耗电量.
+
+
+
+## 性能
 用真机进行调试! 必要的话查找性能瓶颈然后进行优化. 可以使用 [性能分析器](/manuals/profiling) 分析找出代码性能瓶颈.
 
 
-### 屏幕分辨率
+## 屏幕分辨率
 对于具有固定方向和屏幕分辨率的平台: 检查游戏能否在目标平台屏幕分辨率和长宽比上正常运行. 对于具有可变屏幕分辨率和长宽比的平台: 检查游戏是否适用于各种屏幕分辨率和长宽比. 考虑在渲染脚本和摄像机中使用什么样的 [视口映射](/manuals/render/#default-view-projection) 最好.
 
 移动平台可以在 *game.project* 配置中锁定屏幕方向, 或者做好适配确保游戏在横向和纵向模式下都能运行.
 
+* **Display sizes** - 在游戏设计宽高之外的大屏或者小屏上是否显示正常?
+  * 渲染脚本中使用的映射和 gui 中的布局会在这里发挥作用.
+* **Aspect ratios** - 在游戏设计屏幕比例之外的屏幕上是否显示正常?
+  * 渲染脚本中使用的映射和 gui 中的布局会在这里发挥作用.
+* **Refresh rate** - 在刷新率高于 60 Hz 的屏幕上是否显示正常?
+  * 调整配置 game.project 里 Display 部分的 vsync 和 swap interval.  
+
+
+## 手机刘海和打孔屏
+在显示屏上使用小切口 (也叫刘海或者打孔屏) 来安装前置摄像头和传感器变得越来越流行. 将游戏移植到移动设备时, 建议确保没有关键信息放置在刘海 (屏幕上边中间) 或打孔(屏幕左上角) 的位置. 还可以使用 [安全区域扩展](/extension-safearea) 将游戏视图限制在任何刘海或打孔摄像机之外的区域.
+
+
+## 平台相关指导
+
+### Android
+确保你的 [keystore](/manuals/android/#creating-a-keystore) 保存在安全的地方以便后面可以更新你的游戏.
+
+
+### Consoles
+保存每个版本的完整游戏包. 如果要给游戏发补丁就要用到这些文件.
+
 
 ### Nintendo Switch
 集成目标平台代码 - 对于 Nintendo Switch 就有一个特殊的扩展包以及很多工具供用户使用.
@@ -69,3 +116,6 @@ Defold 的 Nintendo Switch 使用 Vulkan 作为图形后端 - 要使用 [Vulkan
 ### HTML5
 在手机上玩网页游戏正越来越流行 - 当然前提是要确保游戏在手机浏览器可以流畅运行! 还要注意的是网页游戏要能快速载入! - 换句话说就是优化游戏体积. 同时还要考虑加载速度,以免造成不必要的玩家流失.
 
+2018 年, 浏览器引入了声音自动播放策略. 该策略阻止游戏和其他 Web 内容播放声音, 直到用户交互事件 (触摸, 按钮, 游戏手柄事件等) 发生. 在移植到 HTML5 时必须考虑到这一点, 仅在第一次用户交互时才开始播放声音和音乐. 尝试在任何用户交互之前就播放声音, 将在浏览器开发人员控制台中记录为错误, 但不会影响游戏运行.
+
+还要确保显示广告的时候暂停掉游戏里的所有声音.

+ 9 - 4
docs/zh/manuals/project-settings.md

@@ -358,6 +358,9 @@ GUI 组件最大数目, 默认是 `64`. [(参见最大组件数优化)](#compone
 #### Max Particle Count
 同一时间粒子最大数目, 默认是 `1024`.
 
+#### Max Animation Count
+gui 里最大活动动画数量, 默认是 `1024`.
+
 ---
 
 ### Label
@@ -409,9 +412,6 @@ label 最大数目, 默认是 `64`. [(参见最大组件数优化)](#component-m
 #### Launch Screen
 Storyboard 文件 (.storyboard). 其创建方法详情请见 [iOS 教程](/manuals/ios/#创建 storyboard).
 
-#### Launch Image 320x480--2436x1125
-用于应用启动图的图片 (.png) 文件, 宽高分辨率表示为 `W` &times; `H`. iOS 基于启动图选择分辨率.
-
 #### Pre Rendered Icons
 (iOS 6 及更早) 设置图标是否预渲染. 如果关闭则图标自动添加平滑高光效果.
 
@@ -492,6 +492,12 @@ Google Cloud Messaging Sender Id. 此值由 Google 签发, 设置后才能开启
 #### Bundle Identifier
 打包id使得 macOS 认识你的应用的版本更新. 你的打包 ID 必须在 Apple 注册且确保应用唯一性. iOS 与 macOS 应用不可以使用同一id. 它至少由两部分组成. 用点号连接. 每部分必须以字母开头, 由字母数字下划线或者连字符(-)组成.
 
+#### Default Language
+如果用户语言不在 `Localizations` 列表的话要使用的语言 (参见 [CFBundleDevelopmentRegion](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-130430)). 如果用户语言可用则使用两字母 ISO 639-1 标准或者三字母标准 ISO 639-2.
+
+#### Localizations
+该项包含以逗号分割的字符串代表了受支持的语言名或者本地 ISO 语言符号 (参见 [CFBundleLocalizations](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-109552)).
+
 ---
 
 ### Windows
@@ -560,7 +566,6 @@ Google Cloud Messaging Sender Id. 此值由 Google 签发, 设置后才能开启
 #### _App Manifest_
 如果设置了, 则在自定义引擎编译时使用指定的 manifest. 此设置可以让你移除引擎不必要的部分来减小包体.
 
-
 ![](images/app_manifest/create-app-manifest.png)
 
 ![](images/app_manifest/app-manifest.png)

+ 1 - 0
docs/zh/manuals/properties.md

@@ -105,6 +105,7 @@ local color = gui.get_color(node)
 | *material* | 文本标签所用材质. | `hash` | `get+set`{.mark}|
 | *font* | 文本标签所用字体. | `hash` | `get+set`{.mark}|
 
+
 ## GUI 节点属性
 
 GUI 节点也有属性, 但是要使用特定的读写函数. 每个属性都有对应的 get- 和 set- 函数. 还有一系列预定义常量可以用于属性动画. 引用属性可以使用属性名字符串, 或者属性名字符串hash.

+ 0 - 1
docs/zh/manuals/property-animation.md

@@ -32,7 +32,6 @@ go.cancel_animations(".", "euler.z")
 
 [属性教程](/manuals/properties) 涵盖游戏对象, 组件和 GUI 节点的所有属性.
 
-
 ## GUI 节点属性动画
 
 几乎所有 GUI 节点属性都可以制作动画. 比如说, 把一个节点的 `color` 设置成透明看不见然后制作属性动画到全白使其可见 (也就是没有染色).

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

@@ -9,7 +9,7 @@ brief: 本教程涉及了强大的自动重构功能.
 
 Defold 可以通过跟踪资源如何使用来帮助重构. 它能自动更新重命名或者被移动的引用和资源. 作为开发者, 你不用操心关注这些. 你的项目是一个动态结构所以不必害怕修改它会造成引用乱掉.
 
-::: sidenote
+::: important
 自动重构仅限于编辑器内的修改操作. 对于编辑器以外的重命名和移动, 引用不会自动更新.
 :::
 

+ 8 - 4
docs/zh/manuals/render.md

@@ -66,7 +66,7 @@ brief: 本教程介绍了 Defold 的渲染流程及其编程方法.
 msg.post("@render:", "use_stretch_projection", { near = -1, far = 1 })
 ```
 
-### Fixed Fit
+### Fixed Fit 映射
 
 跟 Stretch 一样 Fixed Fit 也是使用 *game.project* 里设置的分辨率, 不同的是一旦窗口大小改变游戏内容会缩放但是始终保持原比例, 这样一来本来不应被渲染的内容也可能会被显示出来:
 
@@ -88,7 +88,7 @@ msg.post("@render:", "use_stretch_projection", { near = -1, far = 1 })
 msg.post("@render:", "use_fixed_fit_projection", { near = -1, far = 1 })
 ```
 
-### Fixed
+### Fixed 映射
 
 以一个固定倍数按比例缩放视口. 也就是说倍数不是 100% 的话就会自行多显示或少显示内容, 而不按照 *game.project* 的设定分辨率渲染:
 
@@ -253,8 +253,6 @@ function on_message(self, message_id, message)
       -- 焦点摄像机每一帧都发送 set_view_projection
       -- 消息到 @render 端口. 使用摄像机发来的数据可以
       -- 设置渲染视口 (及映射).
-      -- 这里使用默认正交映射所以
-      -- 不使用消息传输映射.
       camera.view = message.view
       self.camera_projection = message.projection or vmath.matrix4()
       update_camera(camera, state)
@@ -269,6 +267,12 @@ GUI 脚本同样可以向 `@render` 端口发送消息:
 msg.post("@render:", "clear_color", { color = vmath.vector4(0.3, 0.4, 0.5, 0) })
 ```
 
+## 受支持的图像 API
+Defold 渲染脚本 API 把渲染操作转换为如下图像 API:
+
+:[Graphics API](../shared/graphics-api.md)
+
+
 ## 系统消息
 
 `"set_view_projection"`

+ 29 - 0
docs/zh/manuals/script-properties.md

@@ -108,3 +108,32 @@ local ids = collectionfactory.create("#cangang_factory", nil, nil, props)
 使用 `factory.create()` 和 `collectionfactory.create()` 创建的对象属性值会覆盖原型文件和脚本定义的初始值.
 
 如果一个游戏对象上附加了多个脚本组件定义了同名的属性, 每一个属性都会用提供给 `factory.create()` 或 `collectionfactory.create()` 的值来初始化.
+
+
+## 资源属性
+
+资源属性类似于脚本属性, 是为基础数据类型定义的:
+
+```lua
+go.property("my_atlas", resource.atlas("/atlas.atlas"))
+go.property("my_font", resource.font("/font.font"))
+go.property("my_material", resource.material("/material.material"))
+go.property("my_texture", resource.texture("/texture.png"))
+go.property("my_tile_source", resource.tile_source("/tilesource.tilesource"))
+```
+
+资源属性定义后像其他脚本属性一样会在 *Properties* 面板里展示出来, 但是是作为文件/资源浏览器项目:
+
+![Resource Properties](images/script-properties/resource-properties.png)
+
+你可以用 `go.get()` 或者通过 `self` 脚本实例引用并使用 `go.set()` 访问和存取资源属性:
+
+```lua
+function init(self)
+  go.set("#sprite", "image", self.my_atlas)
+  go.set("#label", "font", self.my_font)
+  go.set("#sprite", "material", self.my_material)
+  go.set("#model", "texture0", self.my_texture)
+  go.set("#tilemap", "tile_source", self.my_tile_source)
+end
+```

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

@@ -173,6 +173,22 @@ end
 这样就简单易懂多了. 不需要导出调整状态变量 --- 不小心就出错. 我们还完全离开了 `update()` 功能. 这样就不必让引擎每秒白白调用 60 次函数, 尽管里面没代码.
 
 
+## 预处理
+
+可以使用 Lua 预处理器特殊标记, 用于有条件地包含基于编译变体的代码. 例如:
+
+```lua
+-- 使用关键字: RELEASE, DEBUG 或 HEADLESS
+--#IF DEBUG
+local lives_num = 999
+--#ELSE 
+local lives_num = 3
+--#ENDIF
+```
+
+预处理器作为编译扩展存在. 详情请参见 [GitHub 上的扩展页面](https://github.com/defold/extension-lua-preprocessor).
+
+
 ## 编辑器支持
 
 Defold 编辑器支持 Lua 脚本编辑, 还提供语法高亮和自动补全功能. 要让 Defold 补全函数名, 按 *Ctrl+Space* 会弹出相关函名数列表.

+ 4 - 0
docs/zh/manuals/shader.md

@@ -112,6 +112,10 @@ Defold 中的 shader 支持引入项目文件内以 `.glsl` 为扩展名的着
 #include "../root-level-snippet.glsl"
 ```
 
+::: sidenote
+着色器导入语句自从 1.4.2 版本可用
+:::
+
 寻找引入文件注意以下几点:
 
   - 文件必须在基于项目目录的相对路径, 也就是说被引入文件必须存在于项目中. 基于项目目录的相对路径开头应该是 `/`

+ 6 - 24
docs/zh/manuals/sony-playstation.md

@@ -4,7 +4,6 @@ brief: 本教程介绍了如何访问 PlayStation®4
 ---
 
 # PlayStation®4 开发
-
 基于 Sony 许可证限制, 支持 Sony PlayStation® 平台的 Defold 版本不包括标准版. 要获取支持 Sony PlayStation® 的 Defold 特殊版本首先必须成为 Sony PlayStation® 的正式开发者.
 
 ::: sidenote
@@ -17,30 +16,13 @@ Defold 目前只提供 PS4™ 开发支持. 给 PlayStation 4 开发的游戏可
 
 Sony 审核通过后就可以访问 Playstation 4 DevNet. 导航到 Development > Tools & Middleware > Tools & Middleware directory > Defold. 点击 'Confirm Status' 按钮.
 
-
 ## PS4 的 Defold 访问
+当我们确定开发者是正式 PS4™ 开发者时, 我们会在 Defold 中提供如下访问:
 
-当我们确定开发者是正式 PS4™ 开发者时, 我们会在 Defold 中提供两层访问:
-
-1. 标准访问 - PS4™ 扩展, 编译工具及技术支持.
-2. 源码访问 - PS4™ 扩展, 编译工具及技术支持连同 Defold 引擎用于访问 PS4™ 那部分的源代码.
-
-
-### 标准访问
-
-PS4™ 的正式开发者可以免费访问支持 PS4™ 的 Defold 版本. 作为获得批准的开发人员, 我们将为您提供以下访问权限:
-
-* PS4™ 相关 API 整合的扩展程序.
-* 用于编译打包 PS4™ 应用的 [命令行工具](/manuals/bob).
-* 提供 PS4™ 相关技术支持的论坛.
-
-
-### 源码访问
-
-只对 [活跃月度社区捐款](/community-donations/) 达到一定数额的 PS4™ 开发者提供源码访问.
-
-![](images/nintendo-switch/register-defold.png)
-
+* PS4™ 扩展源码连同控制台 API 整合.
+* PS4™ 可用的 Defold 游戏引擎源码. 注意这些源码不用作 PS4™ 游戏编译, 如果你想对引擎核心做贡献可以使用这些源码.
+* 编译到 PS4™ 平台的 [命令行工具](/manuals/bob). 不支持从 Defold 编辑器进行编译.
+* PS4™ 特定论坛技术支持.
 
-## FAQ
+## 常见问题
 :[Consoles FAQ](../shared/consoles-faq.md)

+ 12 - 0
docs/zh/manuals/sprite.md

@@ -72,6 +72,18 @@ Sprite 组件使用 [图集](/manuals/atlas) 或者 [瓷砖图源](/manuals/tile
 `tint`
 : 3D网格颜色 (`vector4`). 四元数 x, y, z, 和 w 分别对应红, 绿, 蓝和不透明度.
 
+## 材质属性
+
+Sprite 可以覆盖当前分配材质中的顶点属性, 并将从组件传递到顶点着色器 (更多信息参见 [材质教程](/manuals/material/#attributes)).
+
+材质中指定的属性将在检查器中显示为常规属性, 并且可以在单个 Sprite 组件上设置. 如果任何属性被覆盖, 它将显示为被覆盖的属性, 并存储在磁盘上的 sprite 文件中:
+
+![sprite-attributes](../images/graphics/sprite-attributes.png)
+
+::: sidenote
+自定义属性自从 Defold 1.4.8 版本可用!
+:::
+
 ## 相关项目配置
 
 在 *game.project* 文件里有些关于Sprite的 [设置项目](/manuals/project-settings#sprite).

+ 1 - 1
docs/zh/manuals/texture-profiles.md

@@ -80,7 +80,7 @@ Defold 可以自动把图片数据处理成纹理并进行压缩 (称为 *Atlas*
 *Platforms*
 : 指定平台. `OS_ID_GENERIC` 匹配所有平台, `OS_ID_WINDOWS` 对应 Windows 平台, `OS_ID_IOS` 对应 iOS 平台. 注意如果使用 `OS_ID_GENERIC`, 设定将会对所有平台生效.
 
-::: sidenote
+::: important
 如果两个 [路径样式](#path-settings) 匹配一个文件并且这两个路径分别指定不同的平台, 那么这两个档案 **都会** 生效, 所以会生成 **两个** 纹理.
 :::
 

+ 53 - 5
docs/zh/manuals/writing-code.md

@@ -7,18 +7,66 @@ brief: 本教程简述了Defold中编写代码的事项.
 
 Defold 可以让你使用编辑器的可视工具来创建许多游戏必要的东西, 比如瓷砖地图和粒子特效, 但是对于游戏逻辑还是得写代码. 游戏逻辑使用 [Lua 语言](https://www.lua.org/) , 引擎扩展使用目标平台的原生开发语言.
 
-Defold 中内建编辑器可以打开和编辑 Lua 文件 (.lua), Defold 脚本文件 (.script, .gui_script 与 .render_script) 或者其他各类文件. 但只对Lua和脚本文件提供代码高亮.
-
 ## 编写Lua脚本
 
 Defold 使用 Lua 5.1 和 LuaJIT (与目标平台相关) 并且需要遵循 Lua 该版本的书写规范来编写代码. 关于 Defold 中 Lua 使用详情请见 [Defold中Lua使用教程](/manuals/lua).
 
-## 编写扩展代码
+## 编写原生代码
 
 Defold 允许使用原生代码来扩展游戏引擎以使用引擎所不具备的特定功能. 或者 Lua 性能不良时 (密集计算, 图像处理等) 考虑使用原生扩展. 详情请见 [原生扩展教程](/manuals/extensions/).
 
+## Using the built-in code editor
+
+Defold 中内建编辑器可以打开和编辑 Lua 文件 (.lua), Defold 脚本文件 (.script, .gui_script 与 .render_script) 或者其他各类文件. 但只对Lua和脚本文件提供代码高亮.
+
+![](/images/editor/code-editor.png)
+
+
+### 代码补全
+
+内置代码编辑器写代码时会出现代码补全功能:
+
+![](/images/editor/codecompletion.png)
+
+按 <kbd>CTRL</kbd> + <kbd>Space</kbd> 会出现函数, 参数和返回值的相关信息:
+
+![](/images/editor/apireference.png)
+
+
+### 使用 LSP 进行 Lua 代码 linting
+
+Defold 支持 [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) 的子集, 可用于分析代码并将程序语句和错误进行高光显示, 这个处理被叫做 linting.
+
+Lua language server 和 code linter 作为插件可用. 使用 [加入依赖](/manuals/libraries/#setting-up-library-dependencies) 的功能安装插件:
+
+```
+https://github.com/defold/lua-language-server/releases/download/v0.0.5/release.zip
+```
+
+可用的版本可以在插件的 [发布页面](https://github.com/defold/lua-language-server/releases) 上查看. 关于该插件详细信息参见 [Defold 论坛的插件支持页面](https://forum.defold.com/t/linting-in-the-code-editor/72465).
+
+
 ## 使用第三方代码编辑器
 
-尽管 Defold 提供了编写脚本的基本功能, 但是对于需求更多功能的专业开发者来说还是希望让 Defold 使用自己喜欢的第三方编辑器. 在 Code 页的 Preferences 窗口中可以指定使用第三方编辑器.
+尽管 Defold 提供了编写脚本的基本功能, 但是对于需求更多功能的专业开发者来说还是希望让 Defold 使用自己喜欢的第三方编辑器. 在 [Code 页下的 Preferences 窗口 ](/manuals/editor-preferences/#code) 中可以指定使用第三方编辑器.
+
+### Visual Studio Code - Defold Kit
+
+Defold Kit 是一个 Visual Studio Code 插件, 其包含如下功能:
+
+* 安装推荐扩展
+* Lua 高光, 自动补全和 linting
+* 将相关设置应用于工作区
+* Defold API 的 Lua 提示
+* 依赖库的 Lua 提示
+* 编译和运行
+* 断点和调试
+* 跨平台编译
+* 在连接的设备上运行应用
+
+安装 Defold Kit 详情参考 [Visual Studio 商店页面](https://marketplace.visualstudio.com/items?itemName=astronachos.defold).
+
+
+## 文档工具
 
-Defold 社区为许多编辑器提供了代码提示支持, 如 [Atom](https://atom.io/packages/defold-ide), [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=selimanac.defold-vsc-snippets) 和 [Sublime](https://forum.defold.com/t/full-autocomplete-defold-api-for-sublime-text-3/10910). 此外还有API参照表 [Dash and Zeal](https://forum.defold.com/t/defold-docset-for-dash/2417).
+社区创建的 API 参考包可用于 [Dash 和 Zeal](https://forum.defold.com/t/defold-docset-for-dash/2417).

+ 0 - 5
docs/zh/shared/consoles-faq.md

@@ -1,8 +1,3 @@
-#### Q: 为什么访问主机源码不免费?
-
-A: Defold 基金会的目标之一就是让 Defold 软件和代码面向全世界免费. 我们不会食言, 但是接入 Nintendo Switch 和 PlayStation®4 的 SDK 是人家说了算. 也就是说对 Nintendo 和 Sony 的支持, 编辑器, 各种工具, 我们没法自己做出来. 同样 Defold 基金会的社区贡献者也没法自己做出来, 为了确保对主机平台的合法长远的技术支持, 就必须缴费了. 访问主机源码所需的费用将用于确保基金会拥有支持主机的必要资源.
-
-
 #### Q: 开发主机游戏需要什么别的工具吗?
 
 A: 使用 Defold 编辑器和命令行工具都可以打包主机游戏. 一旦你取得了相应开发资格, 关于如何调试 Nintendo Switch 和 PlayStation®4 游戏的方法也会发送给你.

+ 9 - 6
docs/zh/shared/editor-faq.md

@@ -1,27 +1,30 @@
 
 #### 问: 运行编辑器需要什么硬件系统?
-
 答: 编辑器最多占用 75% 的空闲系统内存. 一般 4 GB 内存的电脑就可以运行 Defold 小项目了. 中大型项目建议配备 6 GB 或更多内存.
 
 
 #### 问: Defold 测试版会自动更新吗?
-
 答: Defold 测试版编辑器会在启动时检查并自动更新, 正式版也是.
 
-#### 问: 编辑器不启动, 项目不加载?
 
+#### Q: 打开编辑器报错 "java.awt.AWTError: Assistive Technology not found"?
+A: 该报错与 Java 辅助技术比如 [NVDA screen reader](https://www.nvaccess.org/download/) 相关. 在你的 home 文件夹下可能有个 `.accessibility.properties` 文件. 删除该文件尝试重新启动编辑器. (注意: 如果你确实用了辅助技术需要保留这个文件请发消息至 [email protected] 来探讨其他解决办法).
+
+在 [Defold 论坛这里](https://forum.defold.com/t/editor-endless-loading-windows-10-1-2-169-solved/65481/3) 讨论过.
+
+
+#### 问: 编辑器不启动, 项目不加载?
 答: 检查 Defold 安装路径里是否有空格. 比如, 把编辑器放在mac系统 *Applications* 中的 *Defold-macosx* 文件夹里, 就能运行.  改成 *Defold macosx* 就无法运行. 在 Windows 上, 像 *C:\\Program Files\\* 这样的路径都不行. 这归因于 Eclipse 框架的一个已知 bug.
 
 
 #### 问: 启动 Defold 时报了 "sun.security.validator.ValidatorException: PKIX path building failed" 的错?
-
 答: 这个错是由于编辑器尝试建立 https 连接而服务器证书无法验证导致.
 
 详情请见 [这里](https://github.com/defold/defold/blob/master/editor/README_TROUBLESHOOTING_PKIX.md).
 
 
-#### Q: 操作中遇到 "java.lang.OutOfMemoryError: Java heap space" 报错?
-A: Defold 编辑器基于 Java, 所以某种情况下可能会造成内存不足. 可以尝试手动编辑配置文件来增加内存使用量. 配置文件叫做 `config`, 在 macOS 位于 `Defold.app/Contents/Resources/` 文件夹下. 在 Windows 位于 `Defold.exe` 可执行文件同一个文件夹下, 在 Linux 位于 `Defold` 可执行文件同一个文件夹下. 打开 `config` 文件, 在 `vmargs` 后顶头加入 `-Xmx6gb` 参数. 加入 `-Xmx6gb` 的意思是使用 6 GB 内存 (默认 4GB). 如下所示:
+#### : 操作中遇到 "java.lang.OutOfMemoryError: Java heap space" 报错?
+: Defold 编辑器基于 Java, 所以某种情况下可能会造成内存不足. 可以尝试手动编辑配置文件来增加内存使用量. 配置文件叫做 `config`, 在 macOS 位于 `Defold.app/Contents/Resources/` 文件夹下. 在 Windows 位于 `Defold.exe` 可执行文件同一个文件夹下, 在 Linux 位于 `Defold` 可执行文件同一个文件夹下. 打开 `config` 文件, 在 `vmargs` 后顶头加入 `-Xmx6gb` 参数. 加入 `-Xmx6gb` 的意思是使用 6 GB 内存 (默认 4GB). 如下所示:
 
 ```
 vmargs = -Xmx6gb,-Dfile.encoding=UTF-8,-Djna.nosys=true,-Ddefold.launcherpath=${bootstrap.launcherpath},-Ddefold.resourcespath=${bootstrap.resourcespath},-Ddefold.version=${build.version},-Ddefold.editor.sha1=${build.editor_sha1},-Ddefold.engine.sha1=${build.engine_sha1},-Ddefold.buildtime=${build.time},-Ddefold.channel=${build.channel},-Ddefold.archive.domain=${build.archive_domain},-Djava.net.preferIPv4Stack=true,-Dsun.net.client.defaultConnectTimeout=30000,-Dsun.net.client.defaultReadTimeout=30000,-Djogl.texture.notexrect=true,-Dglass.accessible.force=false,--illegal-access=warn,--add-opens=java.base/java.lang=ALL-UNNAMED,--add-opens=java.desktop/sun.awt=ALL-UNNAMED,--add-opens=java.desktop/sun.java2d.opengl=ALL-UNNAMED,--add-opens=java.xml/com.sun.org.apache.xerces.internal.jaxp=ALL-UNNAMED

+ 5 - 8
docs/zh/shared/linux-faq.md

@@ -17,7 +17,6 @@ vmargs = -Dglass.gtk.uiScale=192dpi,-Dfile.encoding=UTF-8,...
 
 此值的意义参见 [Arch Linux HiDPI wiki 文章](https://wiki.archlinux.org/title/HiDPI#JavaFX).
 
-
 #### Q:在 Elementary OS 上使用 Defold 编辑器, 鼠标点选上的都是后面的东西?
 
 A: 尝试这样启动编辑器:
@@ -29,9 +28,7 @@ $ GTK_CSD=0 ./Defold
 
 #### Q: 在 Defold 编辑器里打开集合或者游戏对象时崩溃报关于 "com.jogamp.opengl" 的错误.
 
-A: 某些Linux版本 (如 Ubuntu 18) 下 [Mesa](https://docs.mesa3d.org/) 版所使用的 jogamp/jogl Defold 版本有冲突.
-可以在调用 `glGetString(GL_VERSION)` 是设置`MESA_GL_VERSION_OVERRIDE` 为2.1或者更高的值以覆盖 GL 默认的驱动版本.
-可以使用如下命令查看系统上支持 `glxinfo` 的最高 OpenGL 版本:
+A: 某些Linux版本 (如 Ubuntu 18) 下 [Mesa](https://docs.mesa3d.org/) 版所使用的 jogamp/jogl Defold 版本有冲突. 可以在调用 `glGetString(GL_VERSION)` 是设置`MESA_GL_VERSION_OVERRIDE` 为2.1或者更高的值以覆盖 GL 默认的驱动版本. 可以使用如下命令查看系统上支持 `glxinfo` 的最高 OpenGL 版本:
 
 ```bash
 glxinfo | grep version
@@ -67,18 +64,18 @@ $ MESA_GL_VERSION_OVERRIDE=4.6 ./Defold
 ```
 
 
+#### Q: 打开 Defold 时报错 "com.jogamp.opengl.GLException: Graphics configuration failed"?
+
 A: 某些Linux版本 (如 Ubuntu 20.04) 在運行 Defold 時會出現新的 [Mesa](https://docs.mesa3d.org/) 驅動程序 (Iris) 的問題. 可以嘗試使用舊版本驅動程序:
 
 ```bash
-$ export MESA_LOADER_DRIVER_OVERRIDE=i965
-$ ./Defold
+$ export MESA_LOADER_DRIVER_OVERRIDE=i965 ./Defold
 ```
 
 
 #### Q: 在 Defold 编辑器里打开集合或者游戏对象时崩溃报关于 "libffi.so" 的错误.
 
-A: 这是由于Linux系统的 [libffi](https://sourceware.org/libffi/) 版本与 Defold (版本 6 或 7) 需要的版本不一致.
-确保 `libffi.so.6` 或 `libffi.so.7` 已安装在 `/usr/lib/x86_64-linux-gnu` 路径下. 可以使用如下命令下载 `libffi.so.7`:
+A: 这是由于Linux系统的 [libffi](https://sourceware.org/libffi/) 版本与 Defold (版本 6 或 7) 需要的版本不一致. 确保 `libffi.so.6` 或 `libffi.so.7` 已安装在 `/usr/lib/x86_64-linux-gnu` 路径下. 可以使用如下命令下载 `libffi.so.7`:
 
 ```bash
 $ wget http://ftp.br.debian.org/debian/pool/main/libf/libffi/libffi7_3.3-6_amd64.deb

+ 5 - 1
docs/zh/shared/slice-9-texturing.md

@@ -6,7 +6,7 @@ GUIs 对于其元素的大小改变是积极的: 面板和对话框总是应该
 
 ![GUI 缩放](images/gui-box/scaling.png){srcset="images/gui-box/[email protected] 2x"}
 
-九宫格方块节点包含4个像素数值分别代表左, 上, 右, 下有多少边缘不参与缩放:
+*九宫格* 方块节点包含4个像素数值分别代表左, 上, 右, 下有多少边缘不参与缩放:
 
 ![九宫格属性](images/gui-box/slice9_properties.png){srcset="images/gui-box/[email protected] 2x"}
 
@@ -28,6 +28,10 @@ GUIs 对于其元素的大小改变是积极的: 面板和对话框总是应该
 如果更改 sprite 或方块节点的缩放属性 (或者游戏对象自身的缩放属性) - sprite 或节点和纹理的缩放都不会带 *Slice9* 效果.
 :::
 
+::: important
+要在 Sprite 上启用九宫格 [Sprite 图片的 Trim Mode](https://defold.com/manuals/atlas/#image-properties) 必须关闭.
+:::
+
 
 ### Mipmaps 和 slice-9
 因为渲染器里 mipmapping 的工作方式, 部分缩放纹理可能会造成小问题. 当你把纹理一部分 _缩小_ 到比本身小的时候. 渲染器会自动选择一个低分辨率的 mipmap 来渲染这部分, 导致了这个小问题.

+ 17 - 1
docs/zh/shared/windows-faq.md

@@ -8,4 +8,20 @@ A: 试试以管理员身份打开 Defold. 右键点击 Defold 可执行程序选
 
 #### Q: 爲什麽在 Windows 上使用 Intel UHD 集成 GPU 渲染不正常 (但是 HTML5 版本正常)?
 
-A: 確保你的驅動版本大於等於 27.20.100.8280. 參見 [Intel Driver Support Asistant](https://www.intel.com/content/www/us/en/search.html?ws=text#t=Downloads&layout=table&cf:Downloads=%5B%7B%22actualLabel%22%3A%22Graphics%22%2C%22displayLabel%22%3A%22Graphics%22%7D%2C%7B%22actualLabel%22%3A%22Intel%C2%AE%20UHD%20Graphics%20Family%22%2C%22displayLabel%22%3A%22Intel%C2%AE%20UHD%20Graphics%20Family%22%7D%2C%7B%22actualLabel%22%3A%22Intel%C2%AE%20UHD%20Graphics%20630%22%2C%22displayLabel%22%3A%22Intel%C2%AE%20UHD%20Graphics%20630%22%7D%5D). 更多信息請見 [這個帖子](https://forum.defold.com/t/sprite-game-object-is-not-rendering/69198/35?u=britzl).
+A: 確保你的驅動版本大於等於 27.20.100.8280. 參見 [Intel Driver Support Asistant](https://www.intel.com/content/www/us/en/search.html?ws=text#t=Downloads&layout=table&cf:Downloads=%5B%7B%22actualLabel%22%3A%22Graphics%22%2C%22displayLabel%22%3A%22Graphics%22%7D%2C%7B%22actualLabel%22%3A%22Intel%C2%AE%20UHD%20Graphics%20Family%22%2C%22displayLabel%22%3A%22Intel%C2%AE%20UHD%20Graphics%20Family%22%7D%2C%7B%22actualLabel%22%3A%22Intel%C2%AE%20UHD%20Graphics%20630%22%2C%22displayLabel%22%3A%22Intel%C2%AE%20UHD%20Graphics%20630%22%7D%5D). 更多信息請見 [這個帖子](https://forum.defold.com/t/sprite-game-object-is-not-rendering/69198/35?u=britzl).
+
+#### Q: Defold 编辑器崩溃, 日志显示 AWTError: Assistive Technology not found
+
+如果编辑器崩溃, 日志提示 `Caused by: java.awt.AWTError: Assistive Technology not found: com.sun.java.accessibility.AccessBridge` 请参考如下步骤:
+
+* 打开 `C:\Users\<username>`
+* 使用标准文本编辑器 (Notepad is fine) 打开名为 `.accessibility.properties` 的文件
+* 在 config 下找到如下几行:
+
+```
+assistive_technologies=com.sun.java.accessibility.AccessBridge
+screen_magnifier_present=true
+```
+
+* 在这几行的行首加入井号 (`#``)
+* 保存文件重启 Defold