incanto 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/incanto-check.mjs +6 -4
- package/dist/2d.d.ts +93 -3
- package/dist/2d.js +4 -4
- package/dist/3d.d.ts +45 -4
- package/dist/3d.js +4 -4
- package/dist/{audio-player-VSjk_vG8.d.ts → audio-player-Dyjg5k92.d.ts} +1 -1
- package/dist/audit-C6rMyict.js +58 -0
- package/dist/{behavior-e3kAmPGC.d.ts → behavior-Bod1AyJS.d.ts} +211 -174
- package/dist/{create-game-CEFoFN8d.js → create-game-66c4iYJE.js} +76 -6
- package/dist/{create-game-X5iRu6pf.js → create-game-BNDSbhy-.js} +88 -6
- package/dist/debug.d.ts +1 -1
- package/dist/debug.js +3 -0
- package/dist/{errors-BMFaY68Q.d.ts → errors-1dXlIwoR.d.ts} +7 -1
- package/dist/{gameplay-CDFgSG6z.js → gameplay-DPMgZk9W.js} +108 -1
- package/dist/gameplay.d.ts +44 -3
- package/dist/gameplay.js +2 -2
- package/dist/index.d.ts +151 -9
- package/dist/index.js +189 -4
- package/dist/{loader-y_X4zYO0.d.ts → loader-BcUDfNHn.d.ts} +1 -1
- package/dist/net.d.ts +46 -2
- package/dist/net.js +54 -2
- package/dist/particle-sim-CyUU7HVU.js +281 -0
- package/dist/{physics-2d-DmQ540uR.js → physics-2d-q2N362ph.js} +45 -4
- package/dist/{physics-3d-CDjuhtt_.js → physics-3d-CvHr31d4.js} +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/{register-CscQqB7V.js → register-Cbs7QxoV.js} +139 -4
- package/dist/{register-ClKnoILk.js → register-Cqjxrfq0.js} +254 -4
- package/dist/{register-C35HDZpm.js → register-CxmuI9FL.js} +1 -1
- package/dist/{particle-sim-CrTE7c02.js → register-DRPIjrKG.js} +1185 -278
- package/dist/test.d.ts +4 -10
- package/dist/test.js +11 -16
- package/editor/assets/{agent8-1WJU-yXr.js → agent8-B8QnWCeP.js} +1 -1
- package/editor/assets/{index-DzYFgZbl.js → index-CVhnNkb3.js} +81 -81
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/schemas/scene.schema.json +427 -0
- package/skills/incanto-3d-character.md +14 -0
- package/skills/incanto-audio.md +23 -0
- package/skills/incanto-building-2d-games.md +31 -0
- package/skills/incanto-building-3d-games.md +21 -0
- package/skills/incanto-gameplay-behaviors.md +28 -0
- package/skills/incanto-hud.md +24 -0
- package/skills/incanto-multiplayer.md +27 -0
- package/skills/incanto-node-reference.md +73 -0
- package/skills/incanto-physics-and-input.md +9 -0
- package/skills/incanto-verifying-your-game.md +40 -0
- package/dist/register-Dl_ixIJe.js +0 -834
package/editor/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Incanto Scene Editor</title>
|
|
7
7
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><rect width='16' height='16' rx='3' fill='%236ee7dc'/><text x='8' y='12' text-anchor='middle' font-size='11' font-family='monospace' fill='%230e1018'>i</text></svg>" />
|
|
8
|
-
<script type="module" crossorigin src="./assets/index-
|
|
8
|
+
<script type="module" crossorigin src="./assets/index-CVhnNkb3.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="./assets/GameServer-C56iOUgF.js">
|
|
10
10
|
<link rel="stylesheet" crossorigin href="./assets/index-DF3tMeKJ.css">
|
|
11
11
|
</head>
|
package/package.json
CHANGED
|
@@ -283,9 +283,15 @@
|
|
|
283
283
|
{
|
|
284
284
|
"$ref": "#/$defs/Terrain3D"
|
|
285
285
|
},
|
|
286
|
+
{
|
|
287
|
+
"$ref": "#/$defs/TileMap2D"
|
|
288
|
+
},
|
|
286
289
|
{
|
|
287
290
|
"$ref": "#/$defs/Timer"
|
|
288
291
|
},
|
|
292
|
+
{
|
|
293
|
+
"$ref": "#/$defs/Trail3D"
|
|
294
|
+
},
|
|
289
295
|
{
|
|
290
296
|
"$ref": "#/$defs/Tree3D"
|
|
291
297
|
},
|
|
@@ -298,6 +304,12 @@
|
|
|
298
304
|
{
|
|
299
305
|
"$ref": "#/$defs/UiBar"
|
|
300
306
|
},
|
|
307
|
+
{
|
|
308
|
+
"$ref": "#/$defs/UiButton"
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
"$ref": "#/$defs/UiDialogue"
|
|
312
|
+
},
|
|
301
313
|
{
|
|
302
314
|
"$ref": "#/$defs/UiText"
|
|
303
315
|
},
|
|
@@ -1753,6 +1765,10 @@
|
|
|
1753
1765
|
"skinYawOffset": {
|
|
1754
1766
|
"type": "number",
|
|
1755
1767
|
"default": 0
|
|
1768
|
+
},
|
|
1769
|
+
"animations": {
|
|
1770
|
+
"type": "object",
|
|
1771
|
+
"default": {}
|
|
1756
1772
|
}
|
|
1757
1773
|
},
|
|
1758
1774
|
"additionalProperties": false
|
|
@@ -4842,6 +4858,124 @@
|
|
|
4842
4858
|
},
|
|
4843
4859
|
"required": ["name", "type"]
|
|
4844
4860
|
},
|
|
4861
|
+
"TileMap2D": {
|
|
4862
|
+
"type": "object",
|
|
4863
|
+
"properties": {
|
|
4864
|
+
"name": {
|
|
4865
|
+
"type": "string"
|
|
4866
|
+
},
|
|
4867
|
+
"uid": {
|
|
4868
|
+
"type": "string"
|
|
4869
|
+
},
|
|
4870
|
+
"type": {
|
|
4871
|
+
"const": "TileMap2D"
|
|
4872
|
+
},
|
|
4873
|
+
"groups": {
|
|
4874
|
+
"type": "array",
|
|
4875
|
+
"items": {
|
|
4876
|
+
"type": "string"
|
|
4877
|
+
}
|
|
4878
|
+
},
|
|
4879
|
+
"tags": {
|
|
4880
|
+
"type": "object"
|
|
4881
|
+
},
|
|
4882
|
+
"props": {
|
|
4883
|
+
"type": "object",
|
|
4884
|
+
"properties": {
|
|
4885
|
+
"position": {
|
|
4886
|
+
"type": "array",
|
|
4887
|
+
"items": {
|
|
4888
|
+
"type": "number"
|
|
4889
|
+
},
|
|
4890
|
+
"minItems": 2,
|
|
4891
|
+
"maxItems": 2,
|
|
4892
|
+
"default": [0, 0]
|
|
4893
|
+
},
|
|
4894
|
+
"rotation": {
|
|
4895
|
+
"type": "number",
|
|
4896
|
+
"default": 0
|
|
4897
|
+
},
|
|
4898
|
+
"static": {
|
|
4899
|
+
"type": "boolean",
|
|
4900
|
+
"default": false
|
|
4901
|
+
},
|
|
4902
|
+
"scale": {
|
|
4903
|
+
"type": "array",
|
|
4904
|
+
"items": {
|
|
4905
|
+
"type": "number"
|
|
4906
|
+
},
|
|
4907
|
+
"minItems": 2,
|
|
4908
|
+
"maxItems": 2,
|
|
4909
|
+
"default": [1, 1]
|
|
4910
|
+
},
|
|
4911
|
+
"renderOrder": {
|
|
4912
|
+
"type": "number",
|
|
4913
|
+
"default": 0
|
|
4914
|
+
},
|
|
4915
|
+
"orderGroup": {
|
|
4916
|
+
"type": "string",
|
|
4917
|
+
"enum": ["background", "terrain", "default", "characters", "effects", "overlay"],
|
|
4918
|
+
"default": "default"
|
|
4919
|
+
},
|
|
4920
|
+
"visible": {
|
|
4921
|
+
"type": "boolean",
|
|
4922
|
+
"default": true
|
|
4923
|
+
},
|
|
4924
|
+
"texture": {
|
|
4925
|
+
"type": "string",
|
|
4926
|
+
"default": ""
|
|
4927
|
+
},
|
|
4928
|
+
"tileSize": {
|
|
4929
|
+
"type": "number",
|
|
4930
|
+
"default": 32
|
|
4931
|
+
},
|
|
4932
|
+
"columns": {
|
|
4933
|
+
"type": "number",
|
|
4934
|
+
"default": 0
|
|
4935
|
+
},
|
|
4936
|
+
"cells": {
|
|
4937
|
+
"type": "array",
|
|
4938
|
+
"default": []
|
|
4939
|
+
},
|
|
4940
|
+
"legend": {
|
|
4941
|
+
"type": "object",
|
|
4942
|
+
"default": {}
|
|
4943
|
+
},
|
|
4944
|
+
"solid": {
|
|
4945
|
+
"type": "array",
|
|
4946
|
+
"default": []
|
|
4947
|
+
},
|
|
4948
|
+
"opacity": {
|
|
4949
|
+
"type": "number",
|
|
4950
|
+
"default": 1
|
|
4951
|
+
}
|
|
4952
|
+
},
|
|
4953
|
+
"additionalProperties": false
|
|
4954
|
+
},
|
|
4955
|
+
"script": {
|
|
4956
|
+
"type": "object",
|
|
4957
|
+
"properties": {
|
|
4958
|
+
"name": {
|
|
4959
|
+
"type": "string"
|
|
4960
|
+
},
|
|
4961
|
+
"props": {
|
|
4962
|
+
"type": "object"
|
|
4963
|
+
}
|
|
4964
|
+
},
|
|
4965
|
+
"required": ["name"]
|
|
4966
|
+
},
|
|
4967
|
+
"network": {
|
|
4968
|
+
"type": "object"
|
|
4969
|
+
},
|
|
4970
|
+
"children": {
|
|
4971
|
+
"type": "array",
|
|
4972
|
+
"items": {
|
|
4973
|
+
"$ref": "#/$defs/node"
|
|
4974
|
+
}
|
|
4975
|
+
}
|
|
4976
|
+
},
|
|
4977
|
+
"required": ["name", "type"]
|
|
4978
|
+
},
|
|
4845
4979
|
"Timer": {
|
|
4846
4980
|
"type": "object",
|
|
4847
4981
|
"x-signals": ["timeout"],
|
|
@@ -4906,6 +5040,129 @@
|
|
|
4906
5040
|
},
|
|
4907
5041
|
"required": ["name", "type"]
|
|
4908
5042
|
},
|
|
5043
|
+
"Trail3D": {
|
|
5044
|
+
"type": "object",
|
|
5045
|
+
"properties": {
|
|
5046
|
+
"name": {
|
|
5047
|
+
"type": "string"
|
|
5048
|
+
},
|
|
5049
|
+
"uid": {
|
|
5050
|
+
"type": "string"
|
|
5051
|
+
},
|
|
5052
|
+
"type": {
|
|
5053
|
+
"const": "Trail3D"
|
|
5054
|
+
},
|
|
5055
|
+
"groups": {
|
|
5056
|
+
"type": "array",
|
|
5057
|
+
"items": {
|
|
5058
|
+
"type": "string"
|
|
5059
|
+
}
|
|
5060
|
+
},
|
|
5061
|
+
"tags": {
|
|
5062
|
+
"type": "object"
|
|
5063
|
+
},
|
|
5064
|
+
"props": {
|
|
5065
|
+
"type": "object",
|
|
5066
|
+
"properties": {
|
|
5067
|
+
"position": {
|
|
5068
|
+
"type": "array",
|
|
5069
|
+
"items": {
|
|
5070
|
+
"type": "number"
|
|
5071
|
+
},
|
|
5072
|
+
"minItems": 3,
|
|
5073
|
+
"maxItems": 3,
|
|
5074
|
+
"default": [0, 0, 0]
|
|
5075
|
+
},
|
|
5076
|
+
"rotation": {
|
|
5077
|
+
"type": "array",
|
|
5078
|
+
"items": {
|
|
5079
|
+
"type": "number"
|
|
5080
|
+
},
|
|
5081
|
+
"minItems": 3,
|
|
5082
|
+
"maxItems": 3,
|
|
5083
|
+
"default": [0, 0, 0]
|
|
5084
|
+
},
|
|
5085
|
+
"static": {
|
|
5086
|
+
"type": "boolean",
|
|
5087
|
+
"default": false
|
|
5088
|
+
},
|
|
5089
|
+
"scale": {
|
|
5090
|
+
"type": "array",
|
|
5091
|
+
"items": {
|
|
5092
|
+
"type": "number"
|
|
5093
|
+
},
|
|
5094
|
+
"minItems": 3,
|
|
5095
|
+
"maxItems": 3,
|
|
5096
|
+
"default": [1, 1, 1]
|
|
5097
|
+
},
|
|
5098
|
+
"visible": {
|
|
5099
|
+
"type": "boolean",
|
|
5100
|
+
"default": true
|
|
5101
|
+
},
|
|
5102
|
+
"renderOrder": {
|
|
5103
|
+
"type": "number",
|
|
5104
|
+
"default": 0
|
|
5105
|
+
},
|
|
5106
|
+
"orderGroup": {
|
|
5107
|
+
"type": "string",
|
|
5108
|
+
"enum": ["background", "terrain", "default", "characters", "effects", "overlay"],
|
|
5109
|
+
"default": "default"
|
|
5110
|
+
},
|
|
5111
|
+
"width": {
|
|
5112
|
+
"type": "number",
|
|
5113
|
+
"default": 0.3
|
|
5114
|
+
},
|
|
5115
|
+
"color": {
|
|
5116
|
+
"type": "string",
|
|
5117
|
+
"default": "#ffffff"
|
|
5118
|
+
},
|
|
5119
|
+
"opacity": {
|
|
5120
|
+
"type": "number",
|
|
5121
|
+
"default": 0.8
|
|
5122
|
+
},
|
|
5123
|
+
"seconds": {
|
|
5124
|
+
"type": "number",
|
|
5125
|
+
"default": 0.6
|
|
5126
|
+
},
|
|
5127
|
+
"emitting": {
|
|
5128
|
+
"type": "boolean",
|
|
5129
|
+
"default": true
|
|
5130
|
+
},
|
|
5131
|
+
"additive": {
|
|
5132
|
+
"type": "boolean",
|
|
5133
|
+
"default": false
|
|
5134
|
+
},
|
|
5135
|
+
"minDistance": {
|
|
5136
|
+
"type": "number",
|
|
5137
|
+
"default": 0.05
|
|
5138
|
+
}
|
|
5139
|
+
},
|
|
5140
|
+
"additionalProperties": false
|
|
5141
|
+
},
|
|
5142
|
+
"script": {
|
|
5143
|
+
"type": "object",
|
|
5144
|
+
"properties": {
|
|
5145
|
+
"name": {
|
|
5146
|
+
"type": "string"
|
|
5147
|
+
},
|
|
5148
|
+
"props": {
|
|
5149
|
+
"type": "object"
|
|
5150
|
+
}
|
|
5151
|
+
},
|
|
5152
|
+
"required": ["name"]
|
|
5153
|
+
},
|
|
5154
|
+
"network": {
|
|
5155
|
+
"type": "object"
|
|
5156
|
+
},
|
|
5157
|
+
"children": {
|
|
5158
|
+
"type": "array",
|
|
5159
|
+
"items": {
|
|
5160
|
+
"$ref": "#/$defs/node"
|
|
5161
|
+
}
|
|
5162
|
+
}
|
|
5163
|
+
},
|
|
5164
|
+
"required": ["name", "type"]
|
|
5165
|
+
},
|
|
4909
5166
|
"Tree3D": {
|
|
4910
5167
|
"type": "object",
|
|
4911
5168
|
"properties": {
|
|
@@ -5315,6 +5572,176 @@
|
|
|
5315
5572
|
},
|
|
5316
5573
|
"required": ["name", "type"]
|
|
5317
5574
|
},
|
|
5575
|
+
"UiButton": {
|
|
5576
|
+
"type": "object",
|
|
5577
|
+
"x-signals": ["pressed"],
|
|
5578
|
+
"properties": {
|
|
5579
|
+
"name": {
|
|
5580
|
+
"type": "string"
|
|
5581
|
+
},
|
|
5582
|
+
"uid": {
|
|
5583
|
+
"type": "string"
|
|
5584
|
+
},
|
|
5585
|
+
"type": {
|
|
5586
|
+
"const": "UiButton"
|
|
5587
|
+
},
|
|
5588
|
+
"groups": {
|
|
5589
|
+
"type": "array",
|
|
5590
|
+
"items": {
|
|
5591
|
+
"type": "string"
|
|
5592
|
+
}
|
|
5593
|
+
},
|
|
5594
|
+
"tags": {
|
|
5595
|
+
"type": "object"
|
|
5596
|
+
},
|
|
5597
|
+
"props": {
|
|
5598
|
+
"type": "object",
|
|
5599
|
+
"properties": {
|
|
5600
|
+
"anchor": {
|
|
5601
|
+
"type": "string",
|
|
5602
|
+
"enum": [
|
|
5603
|
+
"topLeft",
|
|
5604
|
+
"top",
|
|
5605
|
+
"topRight",
|
|
5606
|
+
"left",
|
|
5607
|
+
"center",
|
|
5608
|
+
"right",
|
|
5609
|
+
"bottomLeft",
|
|
5610
|
+
"bottom",
|
|
5611
|
+
"bottomRight"
|
|
5612
|
+
],
|
|
5613
|
+
"default": "topLeft"
|
|
5614
|
+
},
|
|
5615
|
+
"visible": {
|
|
5616
|
+
"type": "boolean",
|
|
5617
|
+
"default": true
|
|
5618
|
+
},
|
|
5619
|
+
"text": {
|
|
5620
|
+
"type": "string",
|
|
5621
|
+
"default": "OK"
|
|
5622
|
+
},
|
|
5623
|
+
"size": {
|
|
5624
|
+
"type": "number",
|
|
5625
|
+
"default": 16
|
|
5626
|
+
},
|
|
5627
|
+
"color": {
|
|
5628
|
+
"type": "string",
|
|
5629
|
+
"default": "#ffffff"
|
|
5630
|
+
},
|
|
5631
|
+
"background": {
|
|
5632
|
+
"type": "string",
|
|
5633
|
+
"default": "rgba(255,255,255,0.14)"
|
|
5634
|
+
},
|
|
5635
|
+
"disabled": {
|
|
5636
|
+
"type": "boolean",
|
|
5637
|
+
"default": false
|
|
5638
|
+
}
|
|
5639
|
+
},
|
|
5640
|
+
"additionalProperties": false
|
|
5641
|
+
},
|
|
5642
|
+
"script": {
|
|
5643
|
+
"type": "object",
|
|
5644
|
+
"properties": {
|
|
5645
|
+
"name": {
|
|
5646
|
+
"type": "string"
|
|
5647
|
+
},
|
|
5648
|
+
"props": {
|
|
5649
|
+
"type": "object"
|
|
5650
|
+
}
|
|
5651
|
+
},
|
|
5652
|
+
"required": ["name"]
|
|
5653
|
+
},
|
|
5654
|
+
"network": {
|
|
5655
|
+
"type": "object"
|
|
5656
|
+
},
|
|
5657
|
+
"children": {
|
|
5658
|
+
"type": "array",
|
|
5659
|
+
"items": {
|
|
5660
|
+
"$ref": "#/$defs/node"
|
|
5661
|
+
}
|
|
5662
|
+
}
|
|
5663
|
+
},
|
|
5664
|
+
"required": ["name", "type"]
|
|
5665
|
+
},
|
|
5666
|
+
"UiDialogue": {
|
|
5667
|
+
"type": "object",
|
|
5668
|
+
"x-signals": ["lineShown", "choiceMade", "dialogueFinished"],
|
|
5669
|
+
"properties": {
|
|
5670
|
+
"name": {
|
|
5671
|
+
"type": "string"
|
|
5672
|
+
},
|
|
5673
|
+
"uid": {
|
|
5674
|
+
"type": "string"
|
|
5675
|
+
},
|
|
5676
|
+
"type": {
|
|
5677
|
+
"const": "UiDialogue"
|
|
5678
|
+
},
|
|
5679
|
+
"groups": {
|
|
5680
|
+
"type": "array",
|
|
5681
|
+
"items": {
|
|
5682
|
+
"type": "string"
|
|
5683
|
+
}
|
|
5684
|
+
},
|
|
5685
|
+
"tags": {
|
|
5686
|
+
"type": "object"
|
|
5687
|
+
},
|
|
5688
|
+
"props": {
|
|
5689
|
+
"type": "object",
|
|
5690
|
+
"properties": {
|
|
5691
|
+
"anchor": {
|
|
5692
|
+
"type": "string",
|
|
5693
|
+
"enum": [
|
|
5694
|
+
"topLeft",
|
|
5695
|
+
"top",
|
|
5696
|
+
"topRight",
|
|
5697
|
+
"left",
|
|
5698
|
+
"center",
|
|
5699
|
+
"right",
|
|
5700
|
+
"bottomLeft",
|
|
5701
|
+
"bottom",
|
|
5702
|
+
"bottomRight"
|
|
5703
|
+
],
|
|
5704
|
+
"default": "bottom"
|
|
5705
|
+
},
|
|
5706
|
+
"visible": {
|
|
5707
|
+
"type": "boolean",
|
|
5708
|
+
"default": true
|
|
5709
|
+
},
|
|
5710
|
+
"charsPerSecond": {
|
|
5711
|
+
"type": "number",
|
|
5712
|
+
"default": 40
|
|
5713
|
+
},
|
|
5714
|
+
"width": {
|
|
5715
|
+
"type": "number",
|
|
5716
|
+
"default": 520
|
|
5717
|
+
}
|
|
5718
|
+
},
|
|
5719
|
+
"additionalProperties": false
|
|
5720
|
+
},
|
|
5721
|
+
"script": {
|
|
5722
|
+
"type": "object",
|
|
5723
|
+
"properties": {
|
|
5724
|
+
"name": {
|
|
5725
|
+
"type": "string"
|
|
5726
|
+
},
|
|
5727
|
+
"props": {
|
|
5728
|
+
"type": "object"
|
|
5729
|
+
}
|
|
5730
|
+
},
|
|
5731
|
+
"required": ["name"]
|
|
5732
|
+
},
|
|
5733
|
+
"network": {
|
|
5734
|
+
"type": "object"
|
|
5735
|
+
},
|
|
5736
|
+
"children": {
|
|
5737
|
+
"type": "array",
|
|
5738
|
+
"items": {
|
|
5739
|
+
"$ref": "#/$defs/node"
|
|
5740
|
+
}
|
|
5741
|
+
}
|
|
5742
|
+
},
|
|
5743
|
+
"required": ["name", "type"]
|
|
5744
|
+
},
|
|
5318
5745
|
"UiText": {
|
|
5319
5746
|
"type": "object",
|
|
5320
5747
|
"properties": {
|
|
@@ -97,6 +97,20 @@ shambling clip + glowing eyes for an enemy that reads as a different creature.
|
|
|
97
97
|
"animation": "$walk", "castShadow": true } }
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
+
## Animations without code
|
|
101
|
+
|
|
102
|
+
Map movement states straight in JSON — no behavior needed:
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{ "name": "Controller", "type": "CharacterController3D",
|
|
106
|
+
"props": { "view": "free",
|
|
107
|
+
"animations": { "idle": "$idle", "walk": "$walk", "run": "$run",
|
|
108
|
+
"fastRun": "$sprint", "airborne": "$jump" } } }
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The controller writes `skin.animation` on every state change (crossfaded by
|
|
112
|
+
the model). The `movementStateChanged` signal still fires for extras.
|
|
113
|
+
|
|
100
114
|
The controller also yaw-rotates the sibling at `skinPath` ('../Skin') toward
|
|
101
115
|
the move direction at `turnSpeed` rad/s (100 = instant snap) — the body
|
|
102
116
|
itself never rotates. The skin MOUNTS at 180° (facing away from the default
|
package/skills/incanto-audio.md
CHANGED
|
@@ -98,6 +98,29 @@ something up, `hurt` when Health takes damage:
|
|
|
98
98
|
> same unlock listener that retries `src` players also resumes the SFX context
|
|
99
99
|
> (see §2).
|
|
100
100
|
|
|
101
|
+
### Continuous voices — engine hum, wind, thrusters (`startVoice`)
|
|
102
|
+
|
|
103
|
+
One-shot presets can't do a sound that **lasts and retunes** — a motor that
|
|
104
|
+
follows the RPM, wind that rises with speed. `engine.sfx.startVoice(preset)`
|
|
105
|
+
starts a live synth voice you retune every frame:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
const motor = engine.sfx.startVoice('engine'); // presets: engine | wind | hum | noise
|
|
109
|
+
// per frame (e.g. in a script's update):
|
|
110
|
+
motor.set({ pitch: 0.8 + speed / maxSpeed, volume: throttle * 0.6 });
|
|
111
|
+
// on destroy / scene change:
|
|
112
|
+
motor.stop(); // fades out over 0.15s and frees the WebAudio nodes
|
|
113
|
+
motor.stop(1.2); // …or a slow custom fade
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
- **`pitch`** — 1 = the preset's base tone; drive it from speed/RPM/height.
|
|
117
|
+
- **`volume`** — 0..1; `startVoice(preset, gain)` sets an overall ceiling.
|
|
118
|
+
- Presets: `engine` (detuned-saw motor growl), `wind` (band-passed rush),
|
|
119
|
+
`hum` (soft pad — shields, auras, reactors), `noise` (thrusters, static).
|
|
120
|
+
- Headless the handle is **inert** (`set`/`stop` are no-ops) — keep the same
|
|
121
|
+
call sites, no `if (browser)` guards. Voices need the same first-gesture
|
|
122
|
+
unlock as everything else.
|
|
123
|
+
|
|
101
124
|
---
|
|
102
125
|
|
|
103
126
|
## 2. The AudioPlayer node (preset vs src file)
|
|
@@ -61,6 +61,37 @@ A solid-colored rectangle — no texture, no asset file. Props: `size [100,100]`
|
|
|
61
61
|
`color '#ffffff'`, `opacity 1`, `anchor [0.5,0.5]`. The prototyping workhorse
|
|
62
62
|
(paddles, walls, platforms, flashes); swap in a `Sprite2D` when art arrives.
|
|
63
63
|
|
|
64
|
+
### `TileMap2D` (a whole tile level in ONE node)
|
|
65
|
+
Grid render in a single draw call **plus** greedy-merged static colliders —
|
|
66
|
+
stop hand-placing dozens of ColorRect walls:
|
|
67
|
+
|
|
68
|
+
```jsonc
|
|
69
|
+
{ "name": "Level", "type": "TileMap2D", "props": {
|
|
70
|
+
"texture": "$tiles", // atlas: tileSize×tileSize squares, L→R, T→B
|
|
71
|
+
"tileSize": 32,
|
|
72
|
+
"cells": [
|
|
73
|
+
"..................",
|
|
74
|
+
"......GGG.........",
|
|
75
|
+
"000000000000000000"
|
|
76
|
+
],
|
|
77
|
+
"legend": { "G": 12 }, // chars → atlas tile index (digits 0-9 are free)
|
|
78
|
+
"solid": [0, 12] // these tile indices become static colliders
|
|
79
|
+
} }
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
- `.` / space = empty; digits `0-9` = atlas tile index directly; any OTHER char
|
|
83
|
+
must be in `legend` — unknown chars **hard-fail at load** (fix the map, not
|
|
84
|
+
the runtime).
|
|
85
|
+
- `solid` tiles are merged into a handful of `StaticBody2D` rect colliders
|
|
86
|
+
(greedy rectangles), so a 100×50 level costs a few bodies, not thousands.
|
|
87
|
+
- Cell (0,0) hangs its TOP-LEFT on the node's origin; position the node to
|
|
88
|
+
place the level. `columns: 0` (default) derives atlas columns from the
|
|
89
|
+
texture width.
|
|
90
|
+
- No texture yet? Colliders still work — pair with ColorRect2D placeholders or
|
|
91
|
+
just leave it invisible while you block out the level.
|
|
92
|
+
- Change the map at runtime by REPLACING `cells` (mutations are not watched):
|
|
93
|
+
`map.cells = [...rows]` — geometry and colliders rebuild next frame.
|
|
94
|
+
|
|
64
95
|
### `Sprite2D`
|
|
65
96
|
| Prop | Default | Notes |
|
|
66
97
|
|---|---|---|
|
|
@@ -358,6 +358,27 @@ paletteColors:[…saturated…], shimmer:8`), a lingering ember glitter
|
|
|
358
358
|
spreadDeg:180`) with `renderOrder:100`, each parented to a stable
|
|
359
359
|
node (NOT the collectible's container), self-removing on `finished`.
|
|
360
360
|
|
|
361
|
+
## Trails (`Trail3D` — motion ribbons)
|
|
362
|
+
|
|
363
|
+
A fading world-space ribbon behind whatever it's parented to — wingtip trails,
|
|
364
|
+
sword arcs, tyre streaks, dash effects. Cheaper and crisper than particles for
|
|
365
|
+
"where did it move" lines:
|
|
366
|
+
|
|
367
|
+
```jsonc
|
|
368
|
+
{ "name": "WingTrail", "type": "Trail3D",
|
|
369
|
+
"props": { "width": 0.4, "color": "#aaddff", "seconds": 0.8, "additive": true } }
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
Parent it to the MOVING node (it records that node's world position). The strip
|
|
373
|
+
faces the camera and tapers + fades toward the tail over `seconds`.
|
|
374
|
+
|
|
375
|
+
- `width` (m, default 0.3), `color`, `opacity` (0.8), `seconds` (0.6 lifetime).
|
|
376
|
+
- `additive: true` for glowing energy trails (dark backdrops); default normal
|
|
377
|
+
blending reads better in daylight.
|
|
378
|
+
- `emitting: false` stops laying NEW ribbon while the old tail fades out — flip
|
|
379
|
+
it from script for dash/boost effects (`trail.emitting = boosting`).
|
|
380
|
+
- `minDistance` (0.05 m) filters jitter when the parent is near-stationary.
|
|
381
|
+
|
|
361
382
|
## Terrain
|
|
362
383
|
|
|
363
384
|
`Terrain3D` is procedural heightfield terrain with biome texture splatting —
|
|
@@ -745,6 +745,10 @@ Terminal states ignore further transitions; the restart action (or
|
|
|
745
745
|
physics, input. Listen to the `flowChanged(state)` signal for custom UI.
|
|
746
746
|
`restartScene(engine)` is exported standalone.
|
|
747
747
|
|
|
748
|
+
Multi-scene games: `flow.goToScene(nextSceneJson, { fadeSeconds: 0.4 })`
|
|
749
|
+
fades to black, swaps, fades back (headless = instant). Title → level →
|
|
750
|
+
next level is three JSON files and this one call.
|
|
751
|
+
|
|
748
752
|
## Boot loading overlay
|
|
749
753
|
|
|
750
754
|
```ts
|
|
@@ -765,3 +769,27 @@ save.set('highScore', Math.max(score, save.get('highScore', 0)));
|
|
|
765
769
|
|
|
766
770
|
JSON round-tripped; headless/private-mode falls back to in-memory (never
|
|
767
771
|
throws). `clear()` wipes only your namespace.
|
|
772
|
+
|
|
773
|
+
## Pathfinding (grid A* + PathFollow)
|
|
774
|
+
|
|
775
|
+
```ts
|
|
776
|
+
import { findPath, gridFromRows } from 'incanto';
|
|
777
|
+
|
|
778
|
+
const grid = gridFromRows([ // or { width, height, solid(x,y) } over your map data
|
|
779
|
+
'..........',
|
|
780
|
+
'..######..',
|
|
781
|
+
'..........',
|
|
782
|
+
]);
|
|
783
|
+
const cells = findPath(grid, [0, 1], [9, 1]); // null = unreachable
|
|
784
|
+
(npc.behavior as PathFollow).setPath(
|
|
785
|
+
(cells ?? []).map(([cx, cy]) => [cx * TILE, cy * TILE]),
|
|
786
|
+
);
|
|
787
|
+
npc.on('arrived', () => attack());
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
`findPath` is pure and dimension-free (cells in, cells out; diagonals on by
|
|
791
|
+
default, corner-cutting forbidden; `{ diagonal: false }` for 4-way).
|
|
792
|
+
`PathFollow` (registered behavior) walks waypoints at constant `speed`
|
|
793
|
+
(units/sec — px in 2D, meters in 3D), emits `waypointReached(i)` /
|
|
794
|
+
`arrived`, and `loop: true` patrols. Corners never eat frame budget — the
|
|
795
|
+
speed is exact across bends.
|
package/skills/incanto-hud.md
CHANGED
|
@@ -56,3 +56,27 @@ banner.show('YOU DIED', { color: '#ef4444', seconds: 0 }); // sticky until next
|
|
|
56
56
|
|
|
57
57
|
Pair with the `Health` / `ScoreKeeper` gameplay behaviors: listen to their
|
|
58
58
|
signals and write the widget props — that is the whole HUD wiring.
|
|
59
|
+
|
|
60
|
+
## Interactive widgets: UiButton & UiDialogue
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{ "name": "Talk", "type": "UiDialogue" },
|
|
64
|
+
{ "name": "Start", "type": "UiButton",
|
|
65
|
+
"props": { "anchor": "center", "text": "START" } }
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
const talk = this.node.getNode('%Talk') as UiDialogue;
|
|
70
|
+
talk.say('Elder', 'Welcome to Lumina Village...');
|
|
71
|
+
talk.say('Elder', 'Will you help us?', ['Yes', 'No']);
|
|
72
|
+
talk.on('choiceMade', (i) => { if (i === 0) startQuest(); });
|
|
73
|
+
talk.on('dialogueFinished', () => player.frozen = false);
|
|
74
|
+
// while talk.active, skip player input — the box eats clicks to advance
|
|
75
|
+
|
|
76
|
+
(this.node.getNode('%Start') as UiButton).on('pressed', () => flow.restart());
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Typewriter reveal at `charsPerSecond` (0 = instant); clicking the box
|
|
80
|
+
reveals the line then advances; choice lines render buttons and wait for
|
|
81
|
+
`choose(i)`. Buttons opt into pointer events — the rest of the HUD stays
|
|
82
|
+
click-through.
|