@lampdotdev/lamp 0.0.0-stage → 0.36.2-nightly.16

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.
Files changed (470) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +397 -2
  3. package/Resources/Devices/roku.json +410 -0
  4. package/Resources/Devices/xbox-one.json +367 -0
  5. package/Resources/GameKit/NOTICE.md +63 -0
  6. package/Resources/GameKit/apple/LampPage.swift +1813 -0
  7. package/Resources/GameKit/apple/LampPlayer.swift +46 -0
  8. package/Resources/GameKit/apple/LampWebApp.swift +63 -0
  9. package/Resources/GameKit/apple/LampWebGame.swift +87 -0
  10. package/Resources/GameKit/apple/Native.swift +12 -0
  11. package/Resources/GameKit/build.sh +55 -0
  12. package/Resources/GameKit/lamp_game.h +116 -0
  13. package/Resources/GameKit/lamp_host.h +19 -0
  14. package/Resources/GameKit/lamp_kit.cpp +61 -0
  15. package/Resources/GameKit/lamp_sound.cpp +455 -0
  16. package/Resources/GameKit/lamp_xbox.cpp +374 -0
  17. package/Resources/GameKit/libraries/HandmadeMath.h +3940 -0
  18. package/Resources/GameKit/libraries/cgltf.h +7240 -0
  19. package/Resources/GameKit/libraries/dr_mp3.h +5430 -0
  20. package/Resources/GameKit/libraries/dr_wav.h +9209 -0
  21. package/Resources/GameKit/libraries/sokol_debugtext.h +4754 -0
  22. package/Resources/GameKit/libraries/sokol_gfx.h +29558 -0
  23. package/Resources/GameKit/libraries/sokol_gl.h +4538 -0
  24. package/Resources/GameKit/libraries/sokol_log.h +335 -0
  25. package/Resources/GameKit/libraries/sokol_shape.h +1531 -0
  26. package/Resources/GameKit/libraries/stb_image.h +7988 -0
  27. package/Resources/GameKit/libraries/stb_vorbis.c +5584 -0
  28. package/Resources/GameKit/page/lamp-live.js +672 -0
  29. package/Resources/GameKit/scaffold/Game/game.cpp +142 -0
  30. package/Resources/GameKit/scaffold/Game/scene.glsl +49 -0
  31. package/Resources/GameKit/scaffold-web/Web/game.js +31 -0
  32. package/Resources/GameKit/scaffold-web/Web/index.html +13 -0
  33. package/Resources/GameKit/scaffold-web/Web/making.js +33 -0
  34. package/Resources/GameKit/scaffold-web/Web/world.js +33 -0
  35. package/Resources/GameKit/web/lamp-game.js +3042 -0
  36. package/Resources/GameKit/web/lamp-phaser.js +128 -0
  37. package/Resources/WebHost/App.exe +0 -0
  38. package/Resources/WebHost/Microsoft.Web.WebView2.Core.dll +0 -0
  39. package/Resources/WebHost/WebView2-LICENSE.txt +27 -0
  40. package/Resources/WebHost/lamp_controllers.h +1506 -0
  41. package/Resources/WebHost/lamp_web_host.cpp +1173 -0
  42. package/Resources/WebLibraries/earlier.txt +318 -0
  43. package/Resources/WebLibraries/phaser/LICENSE.md +20 -0
  44. package/Resources/WebLibraries/phaser/NOTICE.md +2 -0
  45. package/Resources/WebLibraries/phaser/phaser.esm.min.js +1 -0
  46. package/Resources/WebLibraries/qrcode/LICENSE +21 -0
  47. package/Resources/WebLibraries/qrcode/NOTICE.md +4 -0
  48. package/Resources/WebLibraries/qrcode/qrcode.js +2297 -0
  49. package/Resources/WebLibraries/rapier/LICENSE +201 -0
  50. package/Resources/WebLibraries/rapier/NOTICE.md +3 -0
  51. package/Resources/WebLibraries/rapier/rapier.js +2 -0
  52. package/Resources/WebLibraries/three/LICENSE +21 -0
  53. package/Resources/WebLibraries/three/NOTICE.md +4 -0
  54. package/Resources/WebLibraries/three/addons/animation/AnimationClipCreator.js +168 -0
  55. package/Resources/WebLibraries/three/addons/animation/CCDIKSolver.js +607 -0
  56. package/Resources/WebLibraries/three/addons/controls/ArcballControls.js +3543 -0
  57. package/Resources/WebLibraries/three/addons/controls/DragControls.js +452 -0
  58. package/Resources/WebLibraries/three/addons/controls/FirstPersonControls.js +512 -0
  59. package/Resources/WebLibraries/three/addons/controls/FlyControls.js +384 -0
  60. package/Resources/WebLibraries/three/addons/controls/MapControls.js +116 -0
  61. package/Resources/WebLibraries/three/addons/controls/OrbitControls.js +1985 -0
  62. package/Resources/WebLibraries/three/addons/controls/PointerLockControls.js +264 -0
  63. package/Resources/WebLibraries/three/addons/controls/TrackballControls.js +1106 -0
  64. package/Resources/WebLibraries/three/addons/controls/TransformControls.js +2003 -0
  65. package/Resources/WebLibraries/three/addons/curves/CurveExtras.js +694 -0
  66. package/Resources/WebLibraries/three/addons/curves/NURBSCurve.js +169 -0
  67. package/Resources/WebLibraries/three/addons/curves/NURBSSurface.js +98 -0
  68. package/Resources/WebLibraries/three/addons/curves/NURBSUtils.js +532 -0
  69. package/Resources/WebLibraries/three/addons/curves/NURBSVolume.js +82 -0
  70. package/Resources/WebLibraries/three/addons/effects/AnaglyphEffect.js +274 -0
  71. package/Resources/WebLibraries/three/addons/effects/AsciiEffect.js +323 -0
  72. package/Resources/WebLibraries/three/addons/effects/OutlineEffect.js +489 -0
  73. package/Resources/WebLibraries/three/addons/effects/ParallaxBarrierEffect.js +155 -0
  74. package/Resources/WebLibraries/three/addons/effects/StereoEffect.js +91 -0
  75. package/Resources/WebLibraries/three/addons/environments/ColorEnvironment.js +59 -0
  76. package/Resources/WebLibraries/three/addons/environments/DebugEnvironment.js +102 -0
  77. package/Resources/WebLibraries/three/addons/environments/RoomEnvironment.js +185 -0
  78. package/Resources/WebLibraries/three/addons/geometries/BoxLineGeometry.js +92 -0
  79. package/Resources/WebLibraries/three/addons/geometries/ConvexGeometry.js +72 -0
  80. package/Resources/WebLibraries/three/addons/geometries/DecalGeometry.js +420 -0
  81. package/Resources/WebLibraries/three/addons/geometries/LoftGeometry.js +355 -0
  82. package/Resources/WebLibraries/three/addons/geometries/ParametricFunctions.js +100 -0
  83. package/Resources/WebLibraries/three/addons/geometries/ParametricGeometry.js +172 -0
  84. package/Resources/WebLibraries/three/addons/geometries/RoundedBoxGeometry.js +216 -0
  85. package/Resources/WebLibraries/three/addons/geometries/TeapotGeometry.js +689 -0
  86. package/Resources/WebLibraries/three/addons/geometries/TextGeometry.js +102 -0
  87. package/Resources/WebLibraries/three/addons/helpers/AnimationPathHelper.js +302 -0
  88. package/Resources/WebLibraries/three/addons/helpers/LightProbeGridHelper.js +166 -0
  89. package/Resources/WebLibraries/three/addons/helpers/LightProbeGridHelperWebGL.js +221 -0
  90. package/Resources/WebLibraries/three/addons/helpers/LightProbeHelper.js +166 -0
  91. package/Resources/WebLibraries/three/addons/helpers/LightProbeHelperGPU.js +102 -0
  92. package/Resources/WebLibraries/three/addons/helpers/OctreeHelper.js +109 -0
  93. package/Resources/WebLibraries/three/addons/helpers/PositionalAudioHelper.js +169 -0
  94. package/Resources/WebLibraries/three/addons/helpers/RapierHelper.js +59 -0
  95. package/Resources/WebLibraries/three/addons/helpers/RectAreaLightHelper.js +118 -0
  96. package/Resources/WebLibraries/three/addons/helpers/TextureHelper.js +265 -0
  97. package/Resources/WebLibraries/three/addons/helpers/TextureHelperGPU.js +214 -0
  98. package/Resources/WebLibraries/three/addons/helpers/VertexNormalsHelper.js +155 -0
  99. package/Resources/WebLibraries/three/addons/helpers/VertexTangentsHelper.js +133 -0
  100. package/Resources/WebLibraries/three/addons/helpers/ViewHelper.js +529 -0
  101. package/Resources/WebLibraries/three/addons/interactive/HTMLMesh.js +617 -0
  102. package/Resources/WebLibraries/three/addons/interactive/InteractiveGroup.js +224 -0
  103. package/Resources/WebLibraries/three/addons/interactive/SelectionBox.js +324 -0
  104. package/Resources/WebLibraries/three/addons/interactive/SelectionHelper.js +150 -0
  105. package/Resources/WebLibraries/three/addons/libs/fflate.module.js +2699 -0
  106. package/Resources/WebLibraries/three/addons/libs/lil-gui.module.min.js +8 -0
  107. package/Resources/WebLibraries/three/addons/libs/meshopt_decoder.module.js +196 -0
  108. package/Resources/WebLibraries/three/addons/libs/potpack.module.js +125 -0
  109. package/Resources/WebLibraries/three/addons/libs/stats.module.js +167 -0
  110. package/Resources/WebLibraries/three/addons/libs/tween.module.js +876 -0
  111. package/Resources/WebLibraries/three/addons/lighting/ClusteredLighting.js +153 -0
  112. package/Resources/WebLibraries/three/addons/lighting/DynamicLighting.js +82 -0
  113. package/Resources/WebLibraries/three/addons/lighting/LightMapper.js +295 -0
  114. package/Resources/WebLibraries/three/addons/lighting/LightProbeGrid.js +923 -0
  115. package/Resources/WebLibraries/three/addons/lighting/LightProbeGridUtils.js +107 -0
  116. package/Resources/WebLibraries/three/addons/lighting/LightProbeGridWebGL.js +846 -0
  117. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIConeTracer.js +243 -0
  118. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIIrradiance.js +43 -0
  119. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGINode.js +617 -0
  120. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGISceneCollector.js +793 -0
  121. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIVolume.js +1440 -0
  122. package/Resources/WebLibraries/three/addons/lights/LightProbeGenerator.js +337 -0
  123. package/Resources/WebLibraries/three/addons/lights/RectAreaLightTexturesLib.js +127 -0
  124. package/Resources/WebLibraries/three/addons/lights/RectAreaLightUniformsLib.js +40 -0
  125. package/Resources/WebLibraries/three/addons/lights/SunLight.js +100 -0
  126. package/Resources/WebLibraries/three/addons/lights/SunLightNode.js +56 -0
  127. package/Resources/WebLibraries/three/addons/lights/SunLightShadow.js +319 -0
  128. package/Resources/WebLibraries/three/addons/lights/SunShadowNode.js +312 -0
  129. package/Resources/WebLibraries/three/addons/lines/Line2.js +56 -0
  130. package/Resources/WebLibraries/three/addons/lines/LineGeometry.js +157 -0
  131. package/Resources/WebLibraries/three/addons/lines/LineMaterial.js +742 -0
  132. package/Resources/WebLibraries/three/addons/lines/LineSegments2.js +434 -0
  133. package/Resources/WebLibraries/three/addons/lines/LineSegmentsGeometry.js +298 -0
  134. package/Resources/WebLibraries/three/addons/lines/Wireframe.js +108 -0
  135. package/Resources/WebLibraries/three/addons/lines/WireframeGeometry2.js +49 -0
  136. package/Resources/WebLibraries/three/addons/lines/webgpu/Line2.js +46 -0
  137. package/Resources/WebLibraries/three/addons/lines/webgpu/LineSegments2.js +419 -0
  138. package/Resources/WebLibraries/three/addons/lines/webgpu/Wireframe.js +86 -0
  139. package/Resources/WebLibraries/three/addons/loaders/EXRLoader.js +3411 -0
  140. package/Resources/WebLibraries/three/addons/loaders/FBXLoader.js +4660 -0
  141. package/Resources/WebLibraries/three/addons/loaders/FontLoader.js +262 -0
  142. package/Resources/WebLibraries/three/addons/loaders/GLTFLoader.js +5006 -0
  143. package/Resources/WebLibraries/three/addons/loaders/HDRLoader.js +463 -0
  144. package/Resources/WebLibraries/three/addons/loaders/MTLLoader.js +601 -0
  145. package/Resources/WebLibraries/three/addons/loaders/OBJLoader.js +961 -0
  146. package/Resources/WebLibraries/three/addons/loaders/PLYLoader.js +992 -0
  147. package/Resources/WebLibraries/three/addons/loaders/RGBELoader.js +18 -0
  148. package/Resources/WebLibraries/three/addons/loaders/STLLoader.js +423 -0
  149. package/Resources/WebLibraries/three/addons/loaders/SVGLoader.js +3297 -0
  150. package/Resources/WebLibraries/three/addons/loaders/TGALoader.js +539 -0
  151. package/Resources/WebLibraries/three/addons/loaders/UltraHDRLoader.js +757 -0
  152. package/Resources/WebLibraries/three/addons/math/Capsule.js +159 -0
  153. package/Resources/WebLibraries/three/addons/math/ColorConverter.js +62 -0
  154. package/Resources/WebLibraries/three/addons/math/ColorSpaces.js +147 -0
  155. package/Resources/WebLibraries/three/addons/math/ConvexHull.js +1695 -0
  156. package/Resources/WebLibraries/three/addons/math/ImprovedNoise.js +88 -0
  157. package/Resources/WebLibraries/three/addons/math/Lut.js +317 -0
  158. package/Resources/WebLibraries/three/addons/math/MeshSurfaceSampler.js +315 -0
  159. package/Resources/WebLibraries/three/addons/math/OBB.js +535 -0
  160. package/Resources/WebLibraries/three/addons/math/Octree.js +825 -0
  161. package/Resources/WebLibraries/three/addons/math/SimplexNoise.js +470 -0
  162. package/Resources/WebLibraries/three/addons/misc/ConvexObjectBreaker.js +539 -0
  163. package/Resources/WebLibraries/three/addons/misc/GPUComputationRenderer.js +508 -0
  164. package/Resources/WebLibraries/three/addons/misc/Gyroscope.js +78 -0
  165. package/Resources/WebLibraries/three/addons/misc/MorphAnimMesh.js +119 -0
  166. package/Resources/WebLibraries/three/addons/misc/MorphBlendMesh.js +425 -0
  167. package/Resources/WebLibraries/three/addons/misc/ProgressiveLightMap.js +370 -0
  168. package/Resources/WebLibraries/three/addons/misc/ProgressiveLightMapGPU.js +322 -0
  169. package/Resources/WebLibraries/three/addons/misc/RollerCoaster.js +661 -0
  170. package/Resources/WebLibraries/three/addons/misc/Sculptor.js +1679 -0
  171. package/Resources/WebLibraries/three/addons/misc/SculptorMesh.js +1504 -0
  172. package/Resources/WebLibraries/three/addons/misc/SculptorTools.js +1180 -0
  173. package/Resources/WebLibraries/three/addons/misc/SculptorUtils.js +345 -0
  174. package/Resources/WebLibraries/three/addons/misc/TileCreasedNormalsPlugin.js +270 -0
  175. package/Resources/WebLibraries/three/addons/misc/TubePainter.js +611 -0
  176. package/Resources/WebLibraries/three/addons/misc/Volume.js +520 -0
  177. package/Resources/WebLibraries/three/addons/misc/VolumeSlice.js +275 -0
  178. package/Resources/WebLibraries/three/addons/modifiers/CurveModifier.js +374 -0
  179. package/Resources/WebLibraries/three/addons/modifiers/CurveModifierGPU.js +256 -0
  180. package/Resources/WebLibraries/three/addons/modifiers/EdgeSplitModifier.js +299 -0
  181. package/Resources/WebLibraries/three/addons/modifiers/TessellateModifier.js +340 -0
  182. package/Resources/WebLibraries/three/addons/objects/GroundedSkybox.js +69 -0
  183. package/Resources/WebLibraries/three/addons/objects/Lensflare.js +489 -0
  184. package/Resources/WebLibraries/three/addons/objects/LensflareMesh.js +376 -0
  185. package/Resources/WebLibraries/three/addons/objects/MarchingCubes.js +1261 -0
  186. package/Resources/WebLibraries/three/addons/objects/Reflector.js +390 -0
  187. package/Resources/WebLibraries/three/addons/objects/ReflectorForSSRPass.js +393 -0
  188. package/Resources/WebLibraries/three/addons/objects/Refractor.js +389 -0
  189. package/Resources/WebLibraries/three/addons/objects/ShadowMesh.js +130 -0
  190. package/Resources/WebLibraries/three/addons/objects/Sky.js +342 -0
  191. package/Resources/WebLibraries/three/addons/objects/SkyMesh.js +403 -0
  192. package/Resources/WebLibraries/three/addons/objects/Water.js +374 -0
  193. package/Resources/WebLibraries/three/addons/objects/Water2.js +403 -0
  194. package/Resources/WebLibraries/three/addons/objects/Water2Mesh.js +199 -0
  195. package/Resources/WebLibraries/three/addons/objects/WaterMesh.js +194 -0
  196. package/Resources/WebLibraries/three/addons/postprocessing/AfterimagePass.js +187 -0
  197. package/Resources/WebLibraries/three/addons/postprocessing/BloomPass.js +274 -0
  198. package/Resources/WebLibraries/three/addons/postprocessing/BokehPass.js +218 -0
  199. package/Resources/WebLibraries/three/addons/postprocessing/ClearPass.js +97 -0
  200. package/Resources/WebLibraries/three/addons/postprocessing/CubeTexturePass.js +146 -0
  201. package/Resources/WebLibraries/three/addons/postprocessing/DotScreenPass.js +114 -0
  202. package/Resources/WebLibraries/three/addons/postprocessing/EffectComposer.js +365 -0
  203. package/Resources/WebLibraries/three/addons/postprocessing/FXAAPass.js +40 -0
  204. package/Resources/WebLibraries/three/addons/postprocessing/FilmPass.js +113 -0
  205. package/Resources/WebLibraries/three/addons/postprocessing/GTAOPass.js +735 -0
  206. package/Resources/WebLibraries/three/addons/postprocessing/GlitchPass.js +177 -0
  207. package/Resources/WebLibraries/three/addons/postprocessing/HalftonePass.js +134 -0
  208. package/Resources/WebLibraries/three/addons/postprocessing/LUTPass.js +138 -0
  209. package/Resources/WebLibraries/three/addons/postprocessing/MaskPass.js +195 -0
  210. package/Resources/WebLibraries/three/addons/postprocessing/OutlinePass.js +776 -0
  211. package/Resources/WebLibraries/three/addons/postprocessing/OutputPass.js +148 -0
  212. package/Resources/WebLibraries/three/addons/postprocessing/Pass.js +191 -0
  213. package/Resources/WebLibraries/three/addons/postprocessing/RenderPass.js +193 -0
  214. package/Resources/WebLibraries/three/addons/postprocessing/RenderPixelatedPass.js +314 -0
  215. package/Resources/WebLibraries/three/addons/postprocessing/RenderTransitionPass.js +267 -0
  216. package/Resources/WebLibraries/three/addons/postprocessing/SAOPass.js +407 -0
  217. package/Resources/WebLibraries/three/addons/postprocessing/SMAAPass.js +230 -0
  218. package/Resources/WebLibraries/three/addons/postprocessing/SSAARenderPass.js +313 -0
  219. package/Resources/WebLibraries/three/addons/postprocessing/SSAOPass.js +527 -0
  220. package/Resources/WebLibraries/three/addons/postprocessing/SSRPass.js +858 -0
  221. package/Resources/WebLibraries/three/addons/postprocessing/SavePass.js +132 -0
  222. package/Resources/WebLibraries/three/addons/postprocessing/ShaderPass.js +135 -0
  223. package/Resources/WebLibraries/three/addons/postprocessing/TAARenderPass.js +243 -0
  224. package/Resources/WebLibraries/three/addons/postprocessing/TexturePass.js +131 -0
  225. package/Resources/WebLibraries/three/addons/postprocessing/UnrealBloomPass.js +541 -0
  226. package/Resources/WebLibraries/three/addons/shaders/ACESFilmicToneMappingShader.js +96 -0
  227. package/Resources/WebLibraries/three/addons/shaders/AfterimageShader.js +63 -0
  228. package/Resources/WebLibraries/three/addons/shaders/BasicShader.js +36 -0
  229. package/Resources/WebLibraries/three/addons/shaders/BleachBypassShader.js +68 -0
  230. package/Resources/WebLibraries/three/addons/shaders/BlendShader.js +56 -0
  231. package/Resources/WebLibraries/three/addons/shaders/BokehShader.js +151 -0
  232. package/Resources/WebLibraries/three/addons/shaders/BokehShader2.js +404 -0
  233. package/Resources/WebLibraries/three/addons/shaders/BrightnessContrastShader.js +62 -0
  234. package/Resources/WebLibraries/three/addons/shaders/ColorCorrectionShader.js +59 -0
  235. package/Resources/WebLibraries/three/addons/shaders/ColorifyShader.js +57 -0
  236. package/Resources/WebLibraries/three/addons/shaders/ConvolutionShader.js +74 -0
  237. package/Resources/WebLibraries/three/addons/shaders/CopyShader.js +52 -0
  238. package/Resources/WebLibraries/three/addons/shaders/DOFMipMapShader.js +63 -0
  239. package/Resources/WebLibraries/three/addons/shaders/DepthLimitedBlurShader.js +183 -0
  240. package/Resources/WebLibraries/three/addons/shaders/DigitalGlitch.js +104 -0
  241. package/Resources/WebLibraries/three/addons/shaders/DotScreenShader.js +75 -0
  242. package/Resources/WebLibraries/three/addons/shaders/ExposureShader.js +51 -0
  243. package/Resources/WebLibraries/three/addons/shaders/FXAAShader.js +298 -0
  244. package/Resources/WebLibraries/three/addons/shaders/FilmShader.js +73 -0
  245. package/Resources/WebLibraries/three/addons/shaders/FocusShader.js +94 -0
  246. package/Resources/WebLibraries/three/addons/shaders/FreiChenShader.js +103 -0
  247. package/Resources/WebLibraries/three/addons/shaders/GTAOShader.js +437 -0
  248. package/Resources/WebLibraries/three/addons/shaders/GammaCorrectionShader.js +52 -0
  249. package/Resources/WebLibraries/three/addons/shaders/HalftoneShader.js +332 -0
  250. package/Resources/WebLibraries/three/addons/shaders/HorizontalBlurShader.js +68 -0
  251. package/Resources/WebLibraries/three/addons/shaders/HorizontalTiltShiftShader.js +70 -0
  252. package/Resources/WebLibraries/three/addons/shaders/HueSaturationShader.js +74 -0
  253. package/Resources/WebLibraries/three/addons/shaders/KaleidoShader.js +65 -0
  254. package/Resources/WebLibraries/three/addons/shaders/LuminosityHighPassShader.js +68 -0
  255. package/Resources/WebLibraries/three/addons/shaders/LuminosityShader.js +54 -0
  256. package/Resources/WebLibraries/three/addons/shaders/MirrorShader.js +62 -0
  257. package/Resources/WebLibraries/three/addons/shaders/NormalMapShader.js +60 -0
  258. package/Resources/WebLibraries/three/addons/shaders/OutputShader.js +103 -0
  259. package/Resources/WebLibraries/three/addons/shaders/PoissonDenoiseShader.js +230 -0
  260. package/Resources/WebLibraries/three/addons/shaders/RGBShiftShader.js +61 -0
  261. package/Resources/WebLibraries/three/addons/shaders/SAOShader.js +201 -0
  262. package/Resources/WebLibraries/three/addons/shaders/SMAAShader.js +489 -0
  263. package/Resources/WebLibraries/three/addons/shaders/SSAOShader.js +331 -0
  264. package/Resources/WebLibraries/three/addons/shaders/SSRShader.js +396 -0
  265. package/Resources/WebLibraries/three/addons/shaders/SepiaShader.js +57 -0
  266. package/Resources/WebLibraries/three/addons/shaders/SobelOperatorShader.js +98 -0
  267. package/Resources/WebLibraries/three/addons/shaders/SubsurfaceScatteringShader.js +95 -0
  268. package/Resources/WebLibraries/three/addons/shaders/TechnicolorShader.js +51 -0
  269. package/Resources/WebLibraries/three/addons/shaders/ToonShader.js +349 -0
  270. package/Resources/WebLibraries/three/addons/shaders/TriangleBlurShader.js +79 -0
  271. package/Resources/WebLibraries/three/addons/shaders/UnpackDepthRGBAShader.js +60 -0
  272. package/Resources/WebLibraries/three/addons/shaders/VelocityShader.js +137 -0
  273. package/Resources/WebLibraries/three/addons/shaders/VerticalBlurShader.js +66 -0
  274. package/Resources/WebLibraries/three/addons/shaders/VerticalTiltShiftShader.js +70 -0
  275. package/Resources/WebLibraries/three/addons/shaders/VignetteShader.js +56 -0
  276. package/Resources/WebLibraries/three/addons/shaders/VolumeShader.js +285 -0
  277. package/Resources/WebLibraries/three/addons/shaders/WaterRefractionShader.js +106 -0
  278. package/Resources/WebLibraries/three/addons/textures/FlakesTexture.js +54 -0
  279. package/Resources/WebLibraries/three/addons/tsl/WebGLNodesHandler.js +607 -0
  280. package/Resources/WebLibraries/three/addons/tsl/display/AfterImageNode.js +256 -0
  281. package/Resources/WebLibraries/three/addons/tsl/display/AnaglyphPassNode.js +550 -0
  282. package/Resources/WebLibraries/three/addons/tsl/display/BilateralBlurNode.js +377 -0
  283. package/Resources/WebLibraries/three/addons/tsl/display/BleachBypass.js +33 -0
  284. package/Resources/WebLibraries/three/addons/tsl/display/BloomNode.js +599 -0
  285. package/Resources/WebLibraries/three/addons/tsl/display/CRT.js +150 -0
  286. package/Resources/WebLibraries/three/addons/tsl/display/ChromaticAberrationNode.js +163 -0
  287. package/Resources/WebLibraries/three/addons/tsl/display/DenoiseNode.js +354 -0
  288. package/Resources/WebLibraries/three/addons/tsl/display/DepthOfFieldNode.js +572 -0
  289. package/Resources/WebLibraries/three/addons/tsl/display/DotScreenNode.js +104 -0
  290. package/Resources/WebLibraries/three/addons/tsl/display/FSR1Node.js +481 -0
  291. package/Resources/WebLibraries/three/addons/tsl/display/FXAANode.js +357 -0
  292. package/Resources/WebLibraries/three/addons/tsl/display/FilmNode.js +101 -0
  293. package/Resources/WebLibraries/three/addons/tsl/display/GTAONode.js +727 -0
  294. package/Resources/WebLibraries/three/addons/tsl/display/GaussianBlurNode.js +412 -0
  295. package/Resources/WebLibraries/three/addons/tsl/display/GodraysNode.js +604 -0
  296. package/Resources/WebLibraries/three/addons/tsl/display/ImportanceSampledEnvironment.js +564 -0
  297. package/Resources/WebLibraries/three/addons/tsl/display/LensflareNode.js +282 -0
  298. package/Resources/WebLibraries/three/addons/tsl/display/Lut3DNode.js +109 -0
  299. package/Resources/WebLibraries/three/addons/tsl/display/MotionBlur.js +33 -0
  300. package/Resources/WebLibraries/three/addons/tsl/display/OITPassNode.js +341 -0
  301. package/Resources/WebLibraries/three/addons/tsl/display/OutlineNode.js +916 -0
  302. package/Resources/WebLibraries/three/addons/tsl/display/ParallaxBarrierPassNode.js +90 -0
  303. package/Resources/WebLibraries/three/addons/tsl/display/PixelationPassNode.js +227 -0
  304. package/Resources/WebLibraries/three/addons/tsl/display/RGBShiftNode.js +96 -0
  305. package/Resources/WebLibraries/three/addons/tsl/display/RecurrentDenoiseNode.js +812 -0
  306. package/Resources/WebLibraries/three/addons/tsl/display/RetroPassNode.js +263 -0
  307. package/Resources/WebLibraries/three/addons/tsl/display/SMAANode.js +729 -0
  308. package/Resources/WebLibraries/three/addons/tsl/display/SSAAPassNode.js +344 -0
  309. package/Resources/WebLibraries/three/addons/tsl/display/SSAONode.js +422 -0
  310. package/Resources/WebLibraries/three/addons/tsl/display/SSGINode.js +698 -0
  311. package/Resources/WebLibraries/three/addons/tsl/display/SSRNode.js +1430 -0
  312. package/Resources/WebLibraries/three/addons/tsl/display/SSSNode.js +479 -0
  313. package/Resources/WebLibraries/three/addons/tsl/display/Sepia.js +24 -0
  314. package/Resources/WebLibraries/three/addons/tsl/display/Shape.js +29 -0
  315. package/Resources/WebLibraries/three/addons/tsl/display/SharpenNode.js +284 -0
  316. package/Resources/WebLibraries/three/addons/tsl/display/SobelOperatorNode.js +168 -0
  317. package/Resources/WebLibraries/three/addons/tsl/display/StereoCompositePassNode.js +190 -0
  318. package/Resources/WebLibraries/three/addons/tsl/display/StereoPassNode.js +117 -0
  319. package/Resources/WebLibraries/three/addons/tsl/display/TAAUNode.js +700 -0
  320. package/Resources/WebLibraries/three/addons/tsl/display/TRAANode.js +609 -0
  321. package/Resources/WebLibraries/three/addons/tsl/display/TemporalReprojectNode.js +1024 -0
  322. package/Resources/WebLibraries/three/addons/tsl/display/TransitionNode.js +141 -0
  323. package/Resources/WebLibraries/three/addons/tsl/display/boxBlur.js +65 -0
  324. package/Resources/WebLibraries/three/addons/tsl/display/depthAwareBlend.js +80 -0
  325. package/Resources/WebLibraries/three/addons/tsl/display/depthAwareBlur.js +63 -0
  326. package/Resources/WebLibraries/three/addons/tsl/display/hashBlur.js +55 -0
  327. package/Resources/WebLibraries/three/addons/tsl/display/lensDirt.js +30 -0
  328. package/Resources/WebLibraries/three/addons/tsl/display/radialBlur.js +68 -0
  329. package/Resources/WebLibraries/three/addons/tsl/lighting/ClusteredLightsNode.js +994 -0
  330. package/Resources/WebLibraries/three/addons/tsl/lighting/DynamicLightsNode.js +201 -0
  331. package/Resources/WebLibraries/three/addons/tsl/lighting/LightProbeGridNode.js +183 -0
  332. package/Resources/WebLibraries/three/addons/tsl/lighting/data/AmbientLightDataNode.js +67 -0
  333. package/Resources/WebLibraries/three/addons/tsl/lighting/data/DirectionalLightDataNode.js +117 -0
  334. package/Resources/WebLibraries/three/addons/tsl/lighting/data/HemisphereLightDataNode.js +105 -0
  335. package/Resources/WebLibraries/three/addons/tsl/lighting/data/PointLightDataNode.js +140 -0
  336. package/Resources/WebLibraries/three/addons/tsl/lighting/data/SpotLightDataNode.js +167 -0
  337. package/Resources/WebLibraries/three/addons/tsl/math/Bayer.js +84 -0
  338. package/Resources/WebLibraries/three/addons/tsl/math/curlNoise.js +107 -0
  339. package/Resources/WebLibraries/three/addons/tsl/math/voronoiNoise.js +112 -0
  340. package/Resources/WebLibraries/three/addons/tsl/shadows/TileShadowNode.js +542 -0
  341. package/Resources/WebLibraries/three/addons/tsl/shadows/TileShadowNodeHelper.js +212 -0
  342. package/Resources/WebLibraries/three/addons/tsl/utils/GroundedSkybox.js +62 -0
  343. package/Resources/WebLibraries/three/addons/tsl/utils/RNoise.js +51 -0
  344. package/Resources/WebLibraries/three/addons/tsl/utils/Raymarching.js +70 -0
  345. package/Resources/WebLibraries/three/addons/tsl/utils/SoftParticles.js +53 -0
  346. package/Resources/WebLibraries/three/addons/tsl/utils/SpecularHelpers.js +302 -0
  347. package/Resources/WebLibraries/three/addons/tsl/utils/TAAUtils.js +184 -0
  348. package/Resources/WebLibraries/three/addons/utils/BufferGeometryUtils.js +1523 -0
  349. package/Resources/WebLibraries/three/addons/utils/CameraUtils.js +82 -0
  350. package/Resources/WebLibraries/three/addons/utils/ColorUtils.js +76 -0
  351. package/Resources/WebLibraries/three/addons/utils/GaussianSplatUtils.js +229 -0
  352. package/Resources/WebLibraries/three/addons/utils/GeometryCompressionUtils.js +547 -0
  353. package/Resources/WebLibraries/three/addons/utils/GeometryUtils.js +226 -0
  354. package/Resources/WebLibraries/three/addons/utils/LDrawUtils.js +211 -0
  355. package/Resources/WebLibraries/three/addons/utils/SceneOptimizer.js +459 -0
  356. package/Resources/WebLibraries/three/addons/utils/SceneUtils.js +363 -0
  357. package/Resources/WebLibraries/three/addons/utils/ShadowMapViewer.js +244 -0
  358. package/Resources/WebLibraries/three/addons/utils/ShadowMapViewerGPU.js +233 -0
  359. package/Resources/WebLibraries/three/addons/utils/SkeletonUtils.js +496 -0
  360. package/Resources/WebLibraries/three/addons/utils/SortUtils.js +175 -0
  361. package/Resources/WebLibraries/three/addons/utils/UVsDebug.js +173 -0
  362. package/Resources/WebLibraries/three/addons/utils/WebGLTextureUtils.js +115 -0
  363. package/Resources/WebLibraries/three/addons/utils/WebGPUTextureUtils.js +81 -0
  364. package/Resources/WebLibraries/three/addons/utils/WorkerPool.js +167 -0
  365. package/Resources/WebLibraries/three/addons/utils/unwrapUVs.js +865 -0
  366. package/Resources/WebLibraries/three/three.core.js +61162 -0
  367. package/Resources/WebLibraries/three/three.module.js +19537 -0
  368. package/Resources/WebLibraries/three/three.tsl.js +41903 -0
  369. package/Resources/WebLibraries/three/three.webgpu.js +53714 -0
  370. package/Resources/share-rules.json +64 -0
  371. package/Resources/skills/2d-game/SKILL.md +305 -0
  372. package/Resources/skills/3d-game/SKILL.md +274 -0
  373. package/Resources/skills/accounts/SKILL.md +41 -0
  374. package/Resources/skills/android-design/SKILL.md +159 -0
  375. package/Resources/skills/app-ai/SKILL.md +154 -0
  376. package/Resources/skills/app-intents/SKILL.md +31 -0
  377. package/Resources/skills/app-kinds/SKILL.md +122 -0
  378. package/Resources/skills/apple-watch/SKILL.md +43 -0
  379. package/Resources/skills/assets/SKILL.md +183 -0
  380. package/Resources/skills/building-blocks/SKILL.md +97 -0
  381. package/Resources/skills/device-control/SKILL.md +56 -0
  382. package/Resources/skills/device-integrations/SKILL.md +278 -0
  383. package/Resources/skills/finder-files/SKILL.md +19 -0
  384. package/Resources/skills/game/SKILL.md +416 -0
  385. package/Resources/skills/game-3d/SKILL.md +12 -0
  386. package/Resources/skills/game-art/SKILL.md +11 -0
  387. package/Resources/skills/game-feel/SKILL.md +13 -0
  388. package/Resources/skills/game-levels/SKILL.md +12 -0
  389. package/Resources/skills/game-live/SKILL.md +12 -0
  390. package/Resources/skills/game-physics/SKILL.md +13 -0
  391. package/Resources/skills/game-playtest/SKILL.md +26 -0
  392. package/Resources/skills/game-ui/SKILL.md +278 -0
  393. package/Resources/skills/github-projects/SKILL.md +62 -0
  394. package/Resources/skills/icloud-sync/SKILL.md +30 -0
  395. package/Resources/skills/iphone-hardware/SKILL.md +57 -0
  396. package/Resources/skills/iphone-widgets/SKILL.md +53 -0
  397. package/Resources/skills/lg-developer-mode/SKILL.md +152 -0
  398. package/Resources/skills/mac-widgets/SKILL.md +60 -0
  399. package/Resources/skills/maps/SKILL.md +8 -0
  400. package/Resources/skills/menu-bar/SKILL.md +36 -0
  401. package/Resources/skills/more-apps/SKILL.md +53 -0
  402. package/Resources/skills/phone-controllers/SKILL.md +79 -0
  403. package/Resources/skills/phone-pages/SKILL.md +173 -0
  404. package/Resources/skills/roku-developer-mode/SKILL.md +106 -0
  405. package/Resources/skills/scene-3d/SKILL.md +27 -0
  406. package/Resources/skills/scripting/SKILL.md +17 -0
  407. package/Resources/skills/share-extension/SKILL.md +22 -0
  408. package/Resources/skills/tv-design/SKILL.md +72 -0
  409. package/Resources/skills/web-app/SKILL.md +170 -0
  410. package/Resources/skills/web-game/SKILL.md +95 -0
  411. package/Resources/skills/web-or-native/SKILL.md +108 -0
  412. package/Resources/skills/wish-links/SKILL.md +156 -0
  413. package/THIRD_PARTY_NOTICES.md +170 -0
  414. package/cli/ai.mjs +237 -0
  415. package/cli/android.mjs +941 -0
  416. package/cli/app-ai.mjs +473 -0
  417. package/cli/browser.mjs +284 -0
  418. package/cli/calls.mjs +594 -0
  419. package/cli/dev.mjs +820 -0
  420. package/cli/devices.mjs +984 -0
  421. package/cli/lamp.mjs +1326 -0
  422. package/cli/lampapp.mjs +332 -0
  423. package/cli/lamps/android-host/LampPageGateway.kt +345 -0
  424. package/cli/lamps/android-host/app/build.gradle.kts +40 -0
  425. package/cli/lamps/android-host/build.gradle.kts +4 -0
  426. package/cli/lamps/android-host/game/AndroidManifest.xml +33 -0
  427. package/cli/lamps/android-host/game/MainActivity.kt +173 -0
  428. package/cli/lamps/android-host/gradle/libs.versions.toml +39 -0
  429. package/cli/lamps/android-host/gradle.properties +8 -0
  430. package/cli/lamps/android-host/page/AndroidManifest.xml +35 -0
  431. package/cli/lamps/android-host/page/MainActivity.kt +193 -0
  432. package/cli/lamps/android-host/settings.gradle.kts +30 -0
  433. package/cli/lamps/android-host/tools.json +43 -0
  434. package/cli/lamps/lamp-controllers.js +2 -0
  435. package/cli/lamps/lamp-for-games.js +6922 -0
  436. package/cli/lamps/lamp.js +7082 -0
  437. package/cli/lamps/mac-starter/.lamp/meta.json +1 -0
  438. package/cli/lamps/mac-starter/APP.md +12 -0
  439. package/cli/lamps/mac-starter/Package.swift +8 -0
  440. package/cli/lamps/mac-starter/Sources/App.swift +11 -0
  441. package/cli/lamps/mac-starter/Sources/ContentView.swift +17 -0
  442. package/cli/lamps/mac-starter/Sources/LampSupport.swift +18215 -0
  443. package/cli/lamps/mac-starter/build.sh +336 -0
  444. package/cli/lamps/mac-starter/gitignore +3 -0
  445. package/cli/lamps/mac-starter/lamp-starter.json +6 -0
  446. package/cli/lamps/web-starter/APP.md +8 -0
  447. package/cli/lamps/web-starter/app.js +1 -0
  448. package/cli/lamps/web-starter/index.html +17 -0
  449. package/cli/lamps/web-starter/lamp-starter.json +5 -0
  450. package/cli/lamps/web-starter/lamp.js +7082 -0
  451. package/cli/lamps/web-starter/style.css +25 -0
  452. package/cli/link.mjs +202 -0
  453. package/cli/local-ai.mjs +193 -0
  454. package/cli/mac.mjs +621 -0
  455. package/cli/mdns.mjs +205 -0
  456. package/cli/msix.mjs +413 -0
  457. package/cli/network.mjs +209 -0
  458. package/cli/openrouter.mjs +133 -0
  459. package/cli/outside.mjs +203 -0
  460. package/cli/page.js +317 -0
  461. package/cli/place.mjs +298 -0
  462. package/cli/png.mjs +184 -0
  463. package/cli/share.mjs +270 -0
  464. package/cli/skill/SKILL.md +280 -0
  465. package/cli/skills.mjs +71 -0
  466. package/cli/state.mjs +176 -0
  467. package/cli/update.mjs +162 -0
  468. package/package.json +20 -4
  469. package/site/lib/quota.js +59 -0
  470. package/site/lib/shared-wishes.js +1727 -0
@@ -0,0 +1,183 @@
1
+ ---
2
+ name: assets
3
+ description: Ready-made models, sprites, tilesets, UI, icons, textures, sound effects and music from Lamp's free index (the `assets` tool) - when to use them rather than making things in code or with make_art, keeping one style, loading them so a change shows in the running game, glTF scale, orientation, copies and animations in three.js, sprite sheets and tilesets in Phaser, sounds and music, pictures for apps, and their credit. Read before choosing how a game's or app's things will look or sound.
4
+ ---
5
+
6
+ # Ready-made assets
7
+
8
+ The `assets` tool searches Lamp's index of free work by people who publish it for anyone to use: low-poly 3D packs
9
+ (Kenney's city, houses, furniture and survival kits, Quaternius's cars, nature, animals, people and monsters, KayKit's
10
+ city bits, a few single models such as a taxi or a bus), Kenney's 2D packs (a platformer, a space shooter, a top-down
11
+ racer, pixel-art towns and dungeons, cartoon characters, animals), UI pieces, icons, ambientCG's tileable materials,
12
+ Kenney's interface sounds and SubspaceAudio's retro effects and music loops. Each is CC0, or CC-BY, which asks for
13
+ credit. Lamp fetches what you choose into the app, checks it, makes its pictures smaller where the slowest place it's
14
+ shown needs that, and writes its credit in credits.json. Nothing is
15
+ loaded from the network while the app runs.
16
+
17
+ ## Ready-made or made yourself
18
+
19
+ Ready-made, when the person wants things that look like real things and there are many of them, or that move in
20
+ ways code can't easily give: a city of different buildings, real-looking cars, people and animals that walk and run
21
+ (their skeletons and animations come with them, which code can't make), a forest of varied trees, a platformer's
22
+ character with its run and jump frames, a tileset for a whole level, a UI that looks finished. And whenever the person
23
+ asks for "the same game with different models" or another look for a game that exists (below).
24
+
25
+ Made yourself, when the thing is simple or abstract (blocks, balls, a neon track), when the game moves its parts itself
26
+ (a robot whose arms the player aims, a car whose doors open), when it must match something the person described or
27
+ gave, when only one or two things are needed and code makes them well, or when nothing in the index fits the style.
28
+ Three.js shapes or Phaser graphics for shapes; `make_art` for a picture in the app's own style (a hero, a boss, a
29
+ backdrop, an illustration in an app). The two mix well when the code-made things take the pack's palette.
30
+
31
+ Sounds and music have a rule of their own, below: the index comes first.
32
+
33
+ Look first with `find` (and `kind`), `show: true` to see the candidates together, before deciding: it costs nothing.
34
+
35
+ ## One style
36
+
37
+ Things seen together come from one pack, or from one author's packs, whose `style` matches: Kenney with Kenney,
38
+ Quaternius with Quaternius. Different authors' low-poly flat-color work can sit together, but look at them side by side
39
+ (`show`) first: a pastel KayKit house beside a sharp Google Poly taxi reads as two games. Fill what the pack lacks in
40
+ code, in its colors and proportions, rather than with a third style. In 2D, pixel art at one size (16 px) never mixes
41
+ with smooth vector art.
42
+
43
+ ## Bringing them in
44
+
45
+ 1. `assets` with `find` ("taxi", "low-poly tree", "platformer player") and `kind`, and `show: true`. Each line has an
46
+ id, its triangles, its box in its own units, its animations, its size, its pack, author, license and style.
47
+ 2. `assets` with `fetch` and the ids. They land in Web/assets/<pack>/ for a game or another page, or Assets/<pack>/ for
48
+ a Swift app (app/src/main/assets/<pack>/ for a native Android app, read with `LampAssets`), and the answer gives each
49
+ file's path as the app loads it.
50
+ 3. Load each through the runtime (below), then `look_at_app`: a model's size and the way it faces are only certain once
51
+ seen.
52
+
53
+ The answer leaves out what's too heavy for the slowest place the app is shown (an Xbox One, a TV, a cheap Android
54
+ phone): what's listed fits one copy. The scene's total is still yours to keep within the device line's budget: twenty
55
+ cars of 3,000 triangles are 60,000.
56
+
57
+ Keep every asset's path in one table at the top of the game (`const MODELS = { taxi: 'assets/poly-quaternius/car.glb', … }`),
58
+ with each thing's real size beside it. Changing the look is then that table, which is also how "the same game with
59
+ different models" is made: find a set in another style, fetch it, and point the table at it; the game's code stays.
60
+
61
+ ## In a three.js game
62
+
63
+ Load with lamp-game.js, never a loader of your own, so a new copy of a file goes into the running game:
64
+ `const taxi = await model(MODELS.taxi)` in `init` gives a `THREE.Group` holding the file's scene, with
65
+ `taxi.animations`. Pictures: `texture(path, t => { t.colorSpace = THREE.SRGBColorSpace; })`.
66
+
67
+ - **Scale.** Units differ by author: Kenney's are tiles (a building about 1 unit wide), Quaternius's and KayKit's are
68
+ near meters, Google Poly's are often centimeters (a taxi 90 units long). Scale each to its real size from its box,
69
+ once: a car is about 4.5 m long, a person 1.75 m tall, a door 2 m, a street lamp 5 m.
70
+
71
+ ```js
72
+ function fitted(group, meters, axis = 'longest') {
73
+ const size = new THREE.Box3().setFromObject(group).getSize(new THREE.Vector3());
74
+ const now = axis === 'height' ? size.y : Math.max(size.x, size.z);
75
+ group.scale.setScalar(meters / now);
76
+ return group;
77
+ }
78
+ ```
79
+
80
+ - **Standing on the ground.** A model's origin may be at its center or its feet: after scaling, lift it by the box's
81
+ bottom (`group.position.y = -box.min.y`), inside a holder group that the game moves.
82
+ - **Facing.** glTF is y up; most models face +z, some -z or +x. Find out by looking, then turn the holder (or the
83
+ group) once: `holder.add(taxi); taxi.rotation.y = Math.PI`. Never change the meshes inside the group: a new copy of
84
+ the file replaces them.
85
+ - **Many copies.** The same model many times: `clone()` shares its geometry and materials (cheap in memory, one draw
86
+ per mesh per copy); for a whole street of one building or a forest of one tree, an `InstancedMesh` per mesh of the
87
+ model (walk it with `traverse`, take each mesh's `geometry` and `material` and its matrix within the model) is one
88
+ draw for all of them. A rigged character (one with `SkinnedMesh`es) is copied with `SkeletonUtils.clone` from
89
+ `three/addons/utils/SkeletonUtils.js`; a plain clone shares one skeleton and every copy moves as one. Copies and
90
+ instances are made again in `assetChanged(path)` (the game skill, "Changes while it's played").
91
+ - **Animations.** One `THREE.AnimationMixer` per character, its clips found by the end of their names, which carry
92
+ the rig's name ("CharacterArmature|Walk"):
93
+
94
+ ```js
95
+ const clip = name => model.animations.find(a => a.name.split('|').pop() === name);
96
+ const mixer = new THREE.AnimationMixer(character);
97
+ const walk = mixer.clipAction(clip('Walk')), run = mixer.clipAction(clip('Run'));
98
+ walk.play();
99
+ // switching: run.reset().play(); walk.crossFadeTo(run, 0.25, false);
100
+ // in frame(f): mixer.update(f.dt);
101
+ ```
102
+
103
+ The fetch answer lists each model's animations. Mixers are made again in `assetChanged(path)`.
104
+ - **Materials.** Packs come lit for MeshStandardMaterial. Where the device line names a slow place, swap each mesh's
105
+ material for a `MeshLambertMaterial` with the same `color` and `map` as the game starts. Shadows only where the budget
106
+ allows them: `castShadow` on each mesh through `traverse`.
107
+ - **Textures** (ambientCG): color in sRGB, the normal and roughness maps as they are, all with
108
+ `wrapS = wrapT = THREE.RepeatWrapping` and `repeat` set so a tile is about its real size (a 1K brick map covers about
109
+ two meters).
110
+
111
+ ## In a Phaser game
112
+
113
+ Load in a Boot scene's `preload`, by the path the fetch gave:
114
+
115
+ - **A sprite sheet with an XML atlas** (most of Kenney's 2D packs):
116
+ `this.load.atlasXML('players', 'assets/kenney-platformer/spritesheet_players.png', 'assets/kenney-platformer/spritesheet_players.xml')`.
117
+ Its frames are named as the XML says ("alienBeige_walk1.png"); an animation is
118
+ `this.anims.create({ key: 'walk', frames: this.anims.generateFrameNames('players', { prefix: 'alienBeige_walk', start: 1, end: 2, suffix: '.png' }), frameRate: 8, repeat: -1 })`.
119
+ Read the XML (the fetch put it beside the sheet) for the frame names before writing them.
120
+ - **A tilesheet** (the pixel-art packs): `this.load.spritesheet('tiles', path, { frameWidth: 16, frameHeight: 16, spacing: 1 })`
121
+ with the size and spacing the fetch answer gives, and in a tilemap
122
+ `map.addTilesetImage('tiles', 'tiles', 16, 16, 0, 1)` (margin, then spacing). Its tiles are numbered left to right,
123
+ top to bottom, from 0: look at the sheet before writing the level's rows.
124
+ - **Pixel art** at 16 px wants `pixelArt: true` and a whole-number camera zoom (the 2d-game skill); smooth art is drawn
125
+ at its own size or smaller, never scaled up.
126
+
127
+ A picture Phaser's loader read goes in again through `assetChanged(path)` in phaser() (the 2d-game skill).
128
+
129
+ ## Sounds and music
130
+
131
+ Kinds `sound` (short effects) and `music` (loops). Each line has its length and says when it loops. `show` has nothing
132
+ to show: a sound's name and notes are all you can judge it by, so try it in the game, and say in your report that you
133
+ haven't heard it, since Lamp hears nothing of what plays.
134
+
135
+ A game's sounds start here, whatever else it makes in code. List them all before writing any: `kind: sound`, `limit: 30`
136
+ and no `find`, then `kind: music`, since one search stops at its own words. Go through each moment (a click, a flip, a
137
+ coin, a hit, a win, a loss) and the music against those lists: "Coin", "Impact" or "Jump" may do for a flip. Make one in
138
+ code (the game skill, "Sound") only when nothing here fits that moment, or when it must follow the game as it's played
139
+ (an engine's pitch, notes on a scale), and say which and why in your report.
140
+
141
+ Most sounds here are retro and chiptune. That's no reason to skip them, since a tone written in code is no less
142
+ synthetic; a clip that's wrong for the moment is. One game keeps to one sound family as it keeps to one art style.
143
+
144
+ Choose them as the game is made, and fetch them then: they ship inside it, so the game works offline. Load each once, as
145
+ the game sets itself up, through the runtime, and play it with what the game skill names:
146
+
147
+ ```js
148
+ const SOUNDS = { click: 'assets/subspace-retro-sfx/sfx_menu_select1.wav', coin: 'assets/subspace-retro-sfx/sfx_coin_single1.wav' };
149
+ const click = await sound.load(SOUNDS.click);
150
+ const theme = await sound.load('assets/subspace-music-loops/menu-relaxed.ogg');
151
+ sound.play(click, { volume: 0.7 });
152
+ sound.music(theme, 0.35);
153
+ ```
154
+
155
+ Keep them in one table, as with models, and keep the mute setting and `sound.volume` as the game skill says: a fetched
156
+ sound follows them like any other. A loop is decoded whole, about 20 MB of memory a minute: one or two on a phone or a
157
+ TV, and the shortest that does. Native games read the same files: `lamp_sound_load` and `lamp_music` take
158
+ `"<pack>/<file>"` from Assets/, and a Swift app `LampAssets.url("<pack>/<file>")`.
159
+
160
+ Kenney's interface sounds and the music are Ogg Vorbis, which a page or `AVAudioPlayer` on Apple's devices decodes only
161
+ from about macOS 15.4 and iOS 18.4: on an older one such a sound stays silent, and the page's log says it couldn't be
162
+ loaded. SubspaceAudio's effects are WAV and play everywhere, so they carry a game's menus and what the player needs to
163
+ hear; use them for those on an older Mac or iPhone.
164
+
165
+ ## In an app
166
+
167
+ On Apple's devices, an SF Symbol comes before any icon file. Kenney's icons and UI pieces suit a game's menus, a web
168
+ app or a page on a TV. An illustration in an app is `make_art`'s, in the app's own style. In a Swift app a fetched file
169
+ is in Assets/<pack>/, read with `LampAssets.url("<pack>/<file>")` or `LampAssets.image(…)`; a .glb in a Mac app's
170
+ RealityKit scene is turned into USD as the scene-3d skill says.
171
+
172
+ ## Credit
173
+
174
+ Lamp writes each fetched asset, sounds and music included, into credits.json (its pack, author, license and files), which the app's info, its About
175
+ window, a shared copy, a published page and its repository's README all show: never take an entry out. CC-BY work asks
176
+ for more: name it where the game or app shows its credits too (a Credits line in the pause menu or the About screen:
177
+ "Taxi by Poly by Google, CC BY 3.0"), which the fetch answer reminds you of. CC0 needs nothing, though a line thanking
178
+ the pack's author is kind.
179
+
180
+ ## When nothing fits
181
+
182
+ Make it in code, in the style of what's there, or with `make_art` for a picture. Lamp has no way to make a new model
183
+ from words yet: don't promise one.
@@ -0,0 +1,97 @@
1
+ ---
2
+ name: building-blocks
3
+ description: How to call LampSupport.swift's tested building blocks - notifications, schedules and work while the app is closed, text from documents and pictures, dropped files, folders, global shortcuts, the clipboard, login items, photos, location, weather, music, Spotlight, the home, the devices on the home network and a Roku. Read before using any of them.
4
+ ---
5
+
6
+ # Lamp's building blocks
7
+
8
+ LampSupport.swift has tested building blocks for common jobs, the same ones on a Mac and an iPhone where both have
9
+ them. Use them instead of writing your own.
10
+
11
+ ## On both
12
+
13
+ - `LampNotifications.send("Title", body: "…")`, also `at: date` to show it later, even with the app closed, `id:` to
14
+ replace or `cancel(id)` one, `actions: ["Done", "Snooze"]` for buttons that work without opening the app, handled by
15
+ `LampNotifications.onAction { action, id in … }` set where the app starts, and on iPhone `timeSensitive: true`,
16
+ with `{"timeSensitive": true}` in capabilities.json, for what can't wait, sparingly.
17
+ - `LampSchedule.daily("briefing", hour: 7) { }` and `LampSchedule.every("inbox", minutes: 15) { }`: work at a time or
18
+ every so often, catching up after sleep; keep it alive. On an iPhone see "Work while the app is closed" below.
19
+ - `await LampText.read(url)`: text from PDFs, scanned PDFs, images and screenshots via Live Text, RTF, Word, HTML,
20
+ plain text, all on the device and free; use it before sending documents to LampAI. `await LampText.recognize(in:
21
+ image)` for an `NSImage` on the Mac, a `UIImage` on iPhone.
22
+ - `.lampDropFiles { urls in }` on any view and `LampDropZone("Drop screenshots here") { urls in }` for an empty state
23
+ (Finder files, images from other apps, links; on iPad, files and images dragged in from another app).
24
+ - Photos: `LampPhotos` (`authorize()`, `photos(days:)`, `photos(near:_:km:)`, `favorites()`, `albums()`,
25
+ `photos(in:)`, `image(_:size:)`, `tags(of:)` for what a picture shows (empty in the simulator), `save(_:)`;
26
+ choosing one is SwiftUI's `PhotosPicker`).
27
+ - Location: `LampLocation` (`current()` with a name from the map, `find(address)`, `distance(from:to:)`,
28
+ `shared.watch()` for big moves, `shared.watchVisits()` on the iPhone for where the person stops and for how long,
29
+ which needs `"backgroundModes": ["location"]`).
30
+ - Weather: `LampWeather` (`now(latitude:longitude:)`, `hours`, `days`, `here()`), after `{"weather": true}` in
31
+ capabilities.json, for apps with an iPhone half only; the team also turns WeatherKit on for the app at
32
+ developer.apple.com once, and the call's message says so until then (otherwise, Open-Meteo through `connectors`).
33
+ Apple's terms ask for `LampWeatherAttribution()` (its Weather mark, linking to its sources) wherever its weather is
34
+ shown, allow forecasts to be kept only briefly (never saved with the app's data), and rule out apps meant for
35
+ emergencies or safety.
36
+ - Music: `LampMusic` (`authorize()`, `recentlyPlayed()`, `library()`, `search(_:)`, `play(_:)`, `pause()`, and on the
37
+ iPhone `nowPlaying`), Apple Music only, with MusicKit turned on for the app at developer.apple.com the same way.
38
+ - Spotlight: for the app's own things people would look for by name (notes, recipes, people, trips),
39
+ `LampSpotlight.index(id:title:details:keywords:)` when one is added or changed and `LampSpotlight.remove(id)` when
40
+ it's deleted, and `.lampSpotlightOpen { id in … }` on the view that shows them, to show the one tapped in Spotlight.
41
+
42
+ - The home network: `LampNetwork`, for an app on the Mac or a phone that controls, plays to or reads the person's
43
+ devices (a remote for the TV and speakers, what's playing, a light). The system asks the person about the local
44
+ network before anything answers, so the app says why first, in its own words and on its own screen, and asks with
45
+ `await LampNetwork.requestAccess()` (`.allowed`, `.denied` with `LampNetwork.allowHint` saying where to turn it on,
46
+ or `.unknown` off a home network), never at launch. Then `await LampNetwork.find()`: every device that answers, each
47
+ with `address`, `name`, `maker`, `model`, what it answered SSDP for (`ssdp`, `server`, `location`) and its Bonjour
48
+ services (`bonjour`). An iPhone app sees only the Bonjour types in capabilities.json's `bonjourServices` (add the
49
+ types of the devices the app is for: `"_sonos._tcp"`, `"_googlecast._tcp"`), and the system's question shows
50
+ `"localNetwork"` there, the app's own reason ("TV Remote finds your TV and speakers to control them."). Work out how
51
+ to reach each device from what it says of itself; a Roku is `LampRoku`'s. Its maker and model say what a device is;
52
+ its services say only what it can do: a console and a TV both answer as media renderers, and a Mac offers AirPlay,
53
+ so none of them is a speaker for that.
54
+ - Roku: `LampRoku`, for an app on the Mac or a phone that controls the person's Roku (a remote of its own, buttons
55
+ that open Netflix or a show, what's playing, a Roku TV's power, volume and input), with nothing installed on the
56
+ Roku. An app that runs on the Roku itself is a Roku app instead. `await LampRoku.find()` (every Roku that answers,
57
+ each with `name`, `isTV` and `canBeControlled`), then `launch(named:)` or `launch(appID:contentID:mediaType:)` for a
58
+ deep link, `press(.home)` and the other keys, `type(_:)` into its on-screen keyboard, `activeApp()`, `playing()`,
59
+ `apps()`, and on a Roku TV `power(on:)`, `press(.volumeUp)` and `input(.hdmi1)`. The one setup is on the Roku:
60
+ Settings, System, Advanced system settings, Control by mobile apps, Network access set to Enabled
61
+ (`LampRoku.setUp` says it); show that when `canBeControlled` is false or a call says so, and never suggest
62
+ Permissive. The first `find()` makes the system ask about the local network, so give the person a way to look
63
+ again; remember the Roku they chose by its `id`, and offer a choice when more than one answers.
64
+
65
+ ## On the Mac only
66
+
67
+ These exist only in a Mac app's copy of the library (in an app for both, only under `#if os(macOS)`):
68
+
69
+ - `LampFolderWatcher(folder) { changedURLs in }`: files added or changed in a folder; keep it alive.
70
+ - `LampFolders`: downloads, desktop, documents, screenshots, `files(in:)` newest first.
71
+ - `LampHotKey("cmd+shift+space") { }`: a shortcut that works from any app; keep it alive.
72
+ - `LampLoginItem.isEnabled`: open at login. Offer it as a toggle in Settings, never turn it on yourself; an app that
73
+ declares `"background": true` is opened at login by Lamp.
74
+ - `LampClipboardWatcher { item in }` (item.text / image / fileURLs; keep it alive) and
75
+ `LampClipboardWatcher.copy(text)`.
76
+
77
+ ## On iPhone only
78
+
79
+ An iPhone app's copy of the library has none of the Mac-only blocks above, nor Mail, other apps, the menu bar or the
80
+ permission screens: never call them there.
81
+
82
+ - Home: `LampHome` (after `{"homekit": true}` in capabilities.json): `accessories()` (lights, locks, thermostats,
83
+ sensors, switches, each with its room and state), `set(_:on:)`, `set(_:brightness:)`, `set(_:locked:)`,
84
+ `read(_:)`. Apple's terms allow it only in an app whose job is controlling the home, and what it reads never
85
+ leaves the phone: not to LampAI, a server, LampSync or the Mac.
86
+
87
+ ### Work while the app is closed
88
+
89
+ When the app should do something while it's closed (fetch the news before breakfast, check a price, tidy up,
90
+ remind), declare `{"background": true}` in capabilities.json, put `.lampBackground()` on its WindowGroup, and make
91
+ `@State private var check = LampSchedule.every("prices", minutes: 60) { … }` or
92
+ `LampSchedule.daily("briefing", hour: 7) { … }` in the App, the same calls as on a Mac. iOS runs them while the app
93
+ is closed when it judges best: near the time, not on the dot, at most a few times an hour, and less for an app the
94
+ person rarely opens; while the app is open they run on time. Keep each run short (seconds) and tell the person what
95
+ came of it with a notification. Something that must happen at an exact time and only needs to tell the person is a
96
+ notification sent with `at:`, not a schedule. The simulator never wakes a closed app by itself, so try the work by
97
+ running it from the app.
@@ -0,0 +1,56 @@
1
+ ---
2
+ name: device-control
3
+ description: How an app controls, plays to or reads the person's own devices on their home network (a TV, speakers, a console, lights) when Lamp has no block for them - finding each one, working out its local API, writing it into the app, and asking the person before changing anything on a real device. Read before writing code that reaches one of their devices.
4
+ ---
5
+
6
+ # Controlling the person's devices
7
+
8
+ A remote for the TV and speakers, buttons that open the family's apps, what's playing in the menu bar: the app talks
9
+ to devices that are really in the person's home. Work out each one from what it says about itself, and never change
10
+ anything on a real one until the person has said you may.
11
+
12
+ ## What's there
13
+
14
+ - Call `network_devices` first: what Lamp's own look found, with what it already has for each device. Start from
15
+ that, not from a question about what the person owns, and ask only about what it can't tell you.
16
+ - In the app, find devices with `LampNetwork` (the building-blocks skill): `requestAccess()` after the app has said
17
+ why, then `find()`. Give capabilities.json a `localNetwork` reason in the app's own words, and the Bonjour types
18
+ of the devices it's for in `bonjourServices` (an iPhone app can look for no others).
19
+ - A Roku is `LampRoku`'s. Use it rather than writing ECP yourself.
20
+ - A device's maker and model say what it is. Its services say only what it can do: a console and a TV both answer as
21
+ media renderers, and a Mac offers AirPlay, so none of them is a speaker for that.
22
+
23
+ ## Working out a device
24
+
25
+ For a device Lamp has no block for, find how its maker's own phone app talks to it on the home network, from what it
26
+ says about itself: its SSDP answer and UPnP description (`location`), its Bonjour services and TXT record, its model.
27
+ Most have a local API: an HTTP or SOAP service (Sonos on port 1400, UPnP's AVTransport and RenderingControl), a
28
+ WebSocket (Samsung's remote channel, LG's second-screen socket), or a documented REST API. Read it from the device
29
+ (its description, a status endpoint) before relying on it. Some can't be reached this way: pairing that needs
30
+ cryptography of the maker's own (Apple TV, a Google TV's remote), or control only through the maker's cloud account.
31
+ Say so plainly in a sentence instead of half-building it.
32
+
33
+ ## Writing it
34
+
35
+ - One file per kind of device, behind one small protocol the rest of the app uses, so a new kind is one more file:
36
+ what it can do (keys, apps, text, volume, power, what's playing) and how. The screen asks a device what it can do,
37
+ never which kind it is: a TV without volume over the network shows no volume buttons.
38
+ - Reach only addresses that discovery found, or one the person typed.
39
+ - A device that signs its own secure socket (an LG's 3001, a Samsung's 8002) is trusted for that address alone,
40
+ never every certificate the app meets.
41
+ - A token a device hands back after the person allows the app on its screen is kept with the device in LampStore:
42
+ it only lets an app on this network reach that one device, and the remote must work with Lamp closed, which
43
+ `LampSecrets` on a Mac doesn't. A sign-in to the maker's account is the person's: `LampSecrets`, never LampStore.
44
+ - When the device asks the person on its own screen (Allow on a TV), the app says so while it waits, and what to do
45
+ if they missed it.
46
+ - Example devices for exploring with nothing found, clearly marked, sending nothing.
47
+
48
+ ## Asking before changing a device
49
+
50
+ Reading a device is always fine: what it is, its apps, what's playing, its volume. Changing one is the person's to
51
+ allow: a key press, opening an app, the volume, the input, power, a setting. Before the first change on a device, by
52
+ a command or by using the app (`use_app`), call `device_permission` with the device as the person knows it, its address,
53
+ and what you'd do, and end your turn. Lamp shows the card and keeps the answer: "Allow once" covers this request, "Always for"
54
+ the device covers the wish. Lamp refuses `use_app` on an app that reaches devices unless its `device` names one the person allowed,
55
+ and every engine's check refuses a command that changes a device without it. When the answer is "Not now", leave the
56
+ device alone and say how the person can try it themselves.
@@ -0,0 +1,278 @@
1
+ ---
2
+ name: device-integrations
3
+ description: A device Lamp has no kit for (a streaming stick, a photo frame, a TV, an appliance), described as data for device_integration - how Lamp finds it, reads who it is, sets it up step by step, and puts software on it. Read before writing or fixing an integration.
4
+ ---
5
+
6
+ # Device integrations
7
+
8
+ An integration is a JSON object handed to Lamp with `device_integration`. It is data, never code: Lamp acts on it with
9
+ its own primitives, fills every value itself, draws every card the person sees, and checks each step on the device.
10
+ Write it from the device's own documentation (its developer docs, its local API's reference). Lamp answers with what's
11
+ wrong; fix exactly that and send it again.
12
+
13
+ You never reach the device: no command, request or scan of yours. Lamp does that. You never walk the person through
14
+ steps in the chat: the steps are cards Lamp draws from what you write here.
15
+
16
+ ## Shape
17
+
18
+ ```json
19
+ {
20
+ "id": "roku", // lowercase letters, digits, dashes
21
+ "name": "Roku", "maker": "Roku", "kind": "streaming stick",
22
+ "sources": ["https://developer.roku.com/docs/developer-program/debugging/external-control-api.md"],
23
+ "find": [{ "ssdp": "roku:ecp" }],
24
+ "identity": { ... },
25
+ "steps": [ ... ],
26
+ "bridge": { ... }, // how an app goes on it, opens, is seen and is used
27
+ "app": { ... } // what's built for it; needs bridge.install
28
+ }
29
+ ```
30
+
31
+ ### find
32
+
33
+ How the device announces itself; any one that matches finds it. Each entry has exactly one of:
34
+
35
+ - `"ssdp": "<search target>"`, optionally `"contains"` for what the answer's SERVER line holds.
36
+ - `"bonjour": "_service._tcp"`, optionally `"contains"` for the name.
37
+ - `"http": {"port": 8060, "path": "/query/device-info", "contains": "<device-info>"}`: asked of every address that
38
+ answered Lamp's own SSDP scan.
39
+
40
+ ### identity
41
+
42
+ Where each field of the device's record is read from its own answers. `os` is said once; the rest are reads. `id`
43
+ (unique to this one device: a serial, a UDN) and `model` are required.
44
+
45
+ ```json
46
+ "identity": {
47
+ "os": "Roku OS",
48
+ "id": { "http": { "port": 8060, "path": "/query/device-info" }, "xml": "serial-number" },
49
+ "model": { "http": { "port": 8060, "path": "/query/device-info" }, "xml": "model-name" },
50
+ "name": { "http": { "port": 8060, "path": "/query/device-info" }, "xml": "user-device-name" },
51
+ "modelID": { "http": { "port": 8060, "path": "/query/device-info" }, "xml": "model-number" },
52
+ "osVersion": { "http": { "port": 8060, "path": "/query/device-info" }, "xml": "software-version" }
53
+ }
54
+ ```
55
+
56
+ A read has `json` (a dotted path: `device.modelName`, `items.0.id`) or `xml` (an element, or `parent/child`). Reads are
57
+ GETs. In place of `http`, `"description": true` reads the device's UPnP description wherever its SSDP answer points now
58
+ (with `xml`), for a device whose description moves with its mode, as an Xbox's does. `contains` on a read says what the
59
+ value must hold for the device to be this kind (`"contains": "Xbox"` on the model), when other devices answer the same
60
+ search.
61
+
62
+ ### Requests
63
+
64
+ Every request goes to the address the device was found at; you give only the port and path.
65
+
66
+ ```json
67
+ { "method": "POST", "port": 80, "path": "/plugin_install",
68
+ "auth": { "digest": true, "user": "rokudev", "password": "{field:password}" },
69
+ "form": { "mysubmit": "Install", "archive": "@{package}" } }
70
+ ```
71
+
72
+ `https: true` for a device that only speaks HTTPS with a certificate of its own (Xbox's Device Portal): Lamp
73
+ trusts that certificate the first time and holds the device to it after. `method` (GET, POST, PUT, DELETE), `headers`, `body` or `form` (a value `"@{package}"` sends the package file), `auth`
74
+ (`digest` true or false for basic; the password is always one `{field:…}`), and `keep`: `"picture"` in `bridge.look`
75
+ for the answer that is the screen's picture, `"screen"` in `bridge.screen` for the answer that is the screen as text (the
76
+ tree of what the app shows, where the device describes it), `"log"` in `bridge.log` for the answer that is the app's log, `"key"` in a
77
+ step's `run` for an SSH key the device gives this Mac.
78
+ `poll` (seconds) asks again every two seconds while the device answers 204 (still working on an install), and `expect`
79
+ (`json` or `xml`, with `equals` or `contains`) is what the answer must say for the step to count, else it fails with the
80
+ device's words. In a `json` path, `*` is every element of a list, and the answer counts when any of them says it
81
+ (`"InstalledPackages.*.PackageFullName"`); `equals` and `contains` may hold Lamp's values (`"{packageFullName}"`).
82
+ `until` (seconds, with `expect`) asks again every two seconds until the answer says it: for a device that's done with an
83
+ install a while before the app can be opened, end `install` with a request that waits until the device lists the app. A form value `"@{certificate}"` sends Lamp's certificate for a wrapped package (below).
84
+ `restore` (a JSON field's name) on a PUT or POST that changes a setting only for its sequence: Lamp first reads the
85
+ same path with a GET, takes that field's value, and when the sequence ends (in `bridge.install`, once the app has been
86
+ launched after it), however it ends, sends `{"<field>": "<that value>"}` back the same way. For a device-wide setting an install needs (an Xbox installs a package as a game only while
87
+ `/ext/settings/DefaultUWPContentTypeToGame` is `{"Value":"{isGame}"}`), so the person's own choice is left as it was.
88
+
89
+ ### Values Lamp fills
90
+
91
+ Write `{name}`; Lamp fills it, checked to a safe alphabet. You never write a value yourself.
92
+
93
+ - `{address}` the device's address, `{mac}` this Mac's address on that network, `{deviceID}` the device's id
94
+ - `{package}` the built package's file, `{appID}` the app's id, `{key}` a remote key from `bridge.keys`, `{text}` one character being typed (only in `bridge.type`, in a path, form or body; in a path Lamp percent-encodes it)
95
+ - `{callback}` the sign-in's address back (only in `vendorSignIn.page`), `{signIn}` what that sign-in returned
96
+ - `{sshKey}` Lamp's public SSH key, for a device that must be told it
97
+ - `{field:<key>}` what the person typed in a step's field: only in a sign-in, a form, a header or a body, never in a path
98
+ or command
99
+ - `{read:<step>}` the value a step's check read
100
+ - `{cookie:<name>}` a cookie the device set earlier in the same sequence, only in a header (a CSRF token: a GET first,
101
+ then `"X-CSRF-Token": "{cookie:CSRF-Token}"` on the POST)
102
+ - `{packageFullName}` and `{appUserModelID}` a wrapped Windows package's names, and `{base64:<one of Lamp's values>}`
103
+ any of Lamp's values in base64, as some devices take an id in a query
104
+ - `{isGame}` "true" when the app is a game (Lamp's native games, or `{"game": true}` in the app's capabilities.json or its icon.json),
105
+ else "false", for a device that installs games differently from apps
106
+
107
+ ### steps
108
+
109
+ The setup, in order. Each step is done when its `check` passes, never because anyone said so.
110
+
111
+ ```json
112
+ {
113
+ "id": "developer-mode",
114
+ "title": "Turn on developer mode", // at most 8 words
115
+ "lines": ["Press Home three times on the remote", "Then Up, Up, Right, Left, Right, Left, Right",
116
+ "Choose Enable installer and restart", "Set a developer password when it asks"], // at most 8 lines, 16 words each
117
+ "wait": true, // hands on the device: Lamp checks again until it passes
118
+ "accepts": ["softwareRisk"],
119
+ "check": [{ "http": { "port": 8060, "path": "/query/device-info" }, "xml": "developer-enabled", "equals": "true" },
120
+ { "tcp": 80 }],
121
+ "known": { "how": "read", "source": "https://developer.roku.com/docs/developer-program/getting-started/developer-setup.md" }
122
+ }
123
+ ```
124
+
125
+ - `show`: `[{"label": "This Mac", "value": "{mac}"}]`, Lamp's values shown large. `qr`: a value shown as a QR code.
126
+ - `field`: `{"key": "password", "label": "Developer password", "secret": true}`, what the person types; kept for that
127
+ device only and sent only to it.
128
+ - `link`: an https page to read. A step that roots, jailbreaks or unlocks a device is only ever a link the person
129
+ follows themselves.
130
+ - `run`: what Lamp does when the person presses the step's button, in order (primitives below).
131
+ - `check`: every condition must hold. Each is one of `http` (answers 2xx; with `json` or `xml`, the value `equals` or
132
+ `contains` something), `tcp` (a port that accepts a connection), `field` (the person typed it), `signedIn` (a
133
+ `vendorSignIn` came back).
134
+ - `model`: `true` when the value the check reads is the device's model, finer than what it says before it's set up
135
+ (an Xbox's description says Xbox One on every console; Device Portal's `/api/os/info` names the console).
136
+ - Every setting of the device's that the bridge needs is a step of its own, checked on the device, so it's found in
137
+ setup rather than when a builder first uses it: a Roku answers key presses only with Settings → System → Advanced
138
+ system settings → Control by mobile apps set to Enabled, which its device-info says
139
+ (`{"http": {"port": 8060, "path": "/query/device-info"}, "xml": "ecp-setting-mode", "equals": "enabled"}`; Roku's ECP
140
+ page doesn't list that field, but Rokus report it: enabled, limited, disabled or permissive). Never ask for a setting
141
+ looser than the bridge needs (a Roku's Permissive).
142
+ - `accepts`: what doing it may cost, from Lamp's list; Lamp writes the sentences. `account` (an account with the
143
+ maker), `softwareRisk` (it may stop working until reset), `warranty`, `dataWiped`, `updatesStop`, `protectionsOff`,
144
+ `commandRuns` (required by any step that runs `ssh` or a downloaded `tool`).
145
+ - `known`: only `{"how": "read", "source": "<https page>"}`. Lamp marks a step checked or done once it passes on a
146
+ device; the person sees "Not tried yet" until then.
147
+
148
+ ### Primitives
149
+
150
+ A step's `run` and each bridge sequence are lists of these, one key each:
151
+
152
+ - `http`: a request (above).
153
+ - `probe`: `"tcp:8060"`, `"ssdp:<target>"` or `"bonjour:<type>"`; fails the sequence when the device doesn't answer.
154
+ - `stream`: `{"port": 8085}`, the device's log read line by line into the app's log (bridge.logs only).
155
+ - `ssh`: `{"user": "prisoner", "port": 9922, "command": "luna-send-pub -n 1 luna://… '{…}'", "explanation": "…"}`.
156
+ The person approves the exact command for that device first, with your explanation (plain words, at most 30). One
157
+ line; values are quoted by Lamp. Lamp pins the device's host key and forwards nothing.
158
+ - `tool`: `{"name": "<Lamp's tool>"}`, from Lamp's list (`unlock-device-key`: unlocks a key kept with `keep: "key"`
159
+ with the field `passphrase`), or `{"download": "https://…", "sha256": "<64 hex>", "arguments": […], "explanation": "…"}`
160
+ for another program, which runs confined to its own folder and the network after the person approves it.
161
+ - `vendorSignIn`: `{"page": "https://account.vendor.com/…?redirect_uri={callback}"}`, the vendor's page in the
162
+ browser; what comes back is `{signIn}`. Setup steps only.
163
+ - `wait`: seconds to wait, 1 to 30.
164
+
165
+ ### bridge
166
+
167
+ How software goes on the device once it's set up. Each is a sequence of primitives. With `app`, this is all Lamp has
168
+ to make apps for the device with, and the builder of each app gets it as Lamp's own: `install` then `launch` when
169
+ the person presses Play (and at the end of a turn, or Reload, while the app is on the device), `look` for a picture of
170
+ its screen, `use` once for each of the remote's keys pressed (`{key}` is the device's name for it, from `keys`), `logs`
171
+ read into the app's log while it's open. The builder of an app never looks at or presses anything on the device itself,
172
+ only in its `preview` (below), so `look` and `use` are what Lamp's own test run of the integration (from the device's
173
+ setup window) goes through. What the device answers to `install` is shown to the builder, so a device that says there what it
174
+ made of the package (a compile error) needs nothing more. `stop` ends the app when the person stops it (Lamp presses
175
+ `home` when there's no `stop`, or the device refuses it), and for a wrapped package it also ends the copy on the device
176
+ before an update goes over it, with the values of the copy that's there. `running` says whether the app `launch` opened
177
+ is running: a request whose `expect` finds it among the device's processes, with `until` a few seconds. Lamp launches
178
+ again, with growing pauses, while the device refuses the launch or the app isn't running, and says so plainly when it
179
+ never opens. `type` types into a keyboard on the device's
180
+ screen, run once per character with `{text}` that character (a Roku's `/keypress/Lit_{text}`). `log` reads a log the app keeps on the device (a file) for the
181
+ builder, for a device with no log to stream. `remove` takes the app off the device when its project is deleted. With `app`,
182
+ each of `stop`, `remove` and `type` is there or named in `"lacks": ["type"]` when the device has no way to do it, so
183
+ Lamp can tell one forgotten from one that can't be; and every picture the scaffold names is in `files` or `icons`, and
184
+ `rules` names each library in `support`. `known` is Lamp's: once the device is set up, the person can have Lamp try the
185
+ integration on it (a test app put on, opened, pictured, pressed, typed into, stopped, put on again while open, and taken
186
+ off), and a run that passes marks the bridge with the device's model. What the run found comes back to you with the
187
+ next request in the device's setup conversation: fix the integration from the device's own words and send it again.
188
+
189
+ ```json
190
+ "bridge": {
191
+ "install": [{ "http": { "method": "POST", "port": 80, "path": "/plugin_install",
192
+ "auth": { "digest": true, "user": "rokudev", "password": "{field:password}" },
193
+ "form": { "mysubmit": "Install", "archive": "@{package}" } } }],
194
+ "launch": [{ "http": { "method": "POST", "port": 8060, "path": "/launch/dev" } }, { "wait": 3 }],
195
+ "look": [{ "http": { "method": "POST", "port": 80, "path": "/plugin_inspect",
196
+ "auth": { "digest": true, "user": "rokudev", "password": "{field:password}" },
197
+ "form": { "mysubmit": "Screenshot" } } },
198
+ { "http": { "port": 80, "path": "/pkgs/dev.jpg", "keep": "picture",
199
+ "auth": { "digest": true, "user": "rokudev", "password": "{field:password}" } } }],
200
+ "use": [{ "http": { "method": "POST", "port": 8060, "path": "/keypress/{key}" } }],
201
+ "type": [{ "http": { "method": "POST", "port": 8060, "path": "/keypress/Lit_{text}" } }],
202
+ "stop": [{ "http": { "method": "POST", "port": 8060, "path": "/exit-app/dev" } }],
203
+ "remove": [{ "http": { "method": "POST", "port": 80, "path": "/plugin_install",
204
+ "auth": { "digest": true, "user": "rokudev", "password": "{field:password}" },
205
+ "form": { "mysubmit": "Delete", "archive": "" } } }],
206
+ "logs": [{ "stream": { "port": 8085 } }],
207
+ "keys": { "home": "Home", "up": "Up", "down": "Down", "left": "Left", "right": "Right", "select": "Select", "back": "Back" }
208
+ }
209
+ ```
210
+
211
+ ### app
212
+
213
+ What's built for it: `{"lamp": "tv-web"}` for Lamp's own TV web app, or a kind you declare. A declared kind becomes
214
+ a kind of app people can wish for ("a Roku app that…"): `files` is each new app's scaffold, where `{{NAME}}` is the
215
+ app's name; `rules` is what its builder is told about writing for the device (the language, the layout, the screen,
216
+ how input arrives, where its output is printed, and how it plays sound: the device's own way for short effects and
217
+ for music, the formats it plays, and that a game keeps both quiet with a way to turn them off), as the only guide
218
+ they get; `package` is the shell command that
219
+ makes the package from the app's folder, run there in the app's sandbox with the system's own tools (`zip`, `tar`),
220
+ never anything to download; `output` is where it leaves it, which `"@{package}"` sends.
221
+
222
+ ```json
223
+ "app": { "declared": {
224
+ "files": { "manifest": "title={{NAME}}\nmajor_version=1\nmm_icon_focus_hd=pkg:/images/icon_focus_hd.png\n…", "source/main.brs": "sub Main()\n…\nend sub\n" },
225
+ "rules": "What a builder needs to know to write apps for it, in a few sentences.",
226
+ "package": "rm -f build/app.zip && mkdir -p build images && zip -qr build/app.zip manifest source components images",
227
+ "output": "build/app.zip",
228
+ "icons": { "images/icon_focus_hd.png": "290x218", "images/icon_focus_fhd.png": "540x405" }
229
+ } }
230
+ ```
231
+
232
+ The package step runs in the app's sandbox like every build.
233
+
234
+ `"support"` gives the app Lamp's building blocks (AI through the person's Mac, saved data, the package's own files),
235
+ by library to where they go in the app's folder: `"web": "Web/lamp.js"` for an app that's a web page (a script its
236
+ `index.html` loads before the app's own), `"brightscript": "components/Lamp"` for a Roku channel (a folder its
237
+ components include). Lamp writes them before every build, so keep them out of `files`, and make sure the package step
238
+ takes them into the package. Lamp tells the app where it is and gives it its token on the device itself.
239
+
240
+ `"icons"` gives the app its icon on the device, wherever the device shows one (a channel's poster on a Roku's home
241
+ screen, a tile, a splash screen, a launcher): by path in the app's folder to its size in pixels,
242
+ `"images/icon_focus_hd.png": "290x218"`, one for each picture the device's manifest names, at the sizes its maker
243
+ documents. Lamp draws the icon it made for the app at each path before every build (a dark tile until there is one), so name those paths in the scaffold's manifest, keep them out of `files`, and make
244
+ sure the package step takes them in. Never draw an icon in the scaffold or the package step. A device that shows no icon
245
+ for an app needs none.
246
+
247
+ `"support"` may also name `"three"`, three.js (the 3D library, with its light addons), as a folder in the app's web
248
+ folder (`"three": "Web/three"`): for a device whose web view runs WebGL 2 and ES modules and whose apps may be games or 3D
249
+ scenes. Lamp writes it with the others; say in the rules to load it through an import map (`"three"` to
250
+ `./three/three.module.js`, `"three/addons/"` to `./three/addons/`) from a module script.
251
+
252
+ `"preview": "Web"` is for a web app: the folder whose `index.html` Lamp opens at 1920x1080 in a window on the person's Mac,
253
+ for the builder to look at and try as it works (a TV app's preview), since the device's own screen can only be pictured,
254
+ not played. Play still puts the app on the device. Give one whenever the app is a web page; the rules should then say the
255
+ app must also work with the keyboard (arrows, Enter, Escape for the device's Back), which is how the preview is used.
256
+
257
+ `"wrap": "msix"` is for a device that takes Windows app packages (an Xbox in Developer Mode, through its Device
258
+ Portal): the package step leaves a `.zip` of the app's files, and Lamp makes the package itself, writing its manifest
259
+ (started at `start`, `index.html` unless said), its logos from the app's icon, and its signature with a certificate of
260
+ Lamp's. Install it with the package and `"@{certificate}"` in one form, and launch it by `{base64:appUserModelID}` and
261
+ `{base64:packageFullName}`. Never write a manifest or sign anything in the package step. With `"host": "webview2"` beside it, the
262
+ pages are shown in Lamp's own host for Chromium's WebView2 rather than the system's older EdgeHTML: much faster, WebGL 2
263
+ and current JavaScript, with the app's console in its log. Use it for a web app on an Xbox; `start` is then `index.html`.
264
+
265
+ `"purpose"` says in a few words what the kind is for ("an app with menus and pages"), for a device that takes more than
266
+ one kind. The integrations Lamp ships may offer more kinds beside `app` in `kinds` (the Xbox's native 3D games,
267
+ `{"lamp": "native-game"}`); an integration you write has only `app`.
268
+
269
+ `"runs"`, beside `app`, says in one plain sentence what the device runs ("Only its own channels, written in BrightScript
270
+ and driven by the remote: no web pages, no 3D"). Lamp gives it as the reason when something the device can't run is asked
271
+ of it, so write it for the person, from the device's documentation.
272
+
273
+ ## Checking it before you send
274
+
275
+ - Every step has a check that asks the device (or a field the step itself asks for).
276
+ - Every `{…}` is one of Lamp's values above, and a field is only in a sign-in, form, header or body.
277
+ - Titles and lines are short and in plain words, for someone who has never done this.
278
+ - A step written from documentation says where (`known.source`).