@lampdotdev/lamp 0.0.0-stage → 0.35.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.
Files changed (464) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +357 -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 +1646 -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/scaffold/Game/game.cpp +142 -0
  29. package/Resources/GameKit/scaffold/Game/scene.glsl +49 -0
  30. package/Resources/GameKit/scaffold-web/Web/game.js +31 -0
  31. package/Resources/GameKit/scaffold-web/Web/index.html +13 -0
  32. package/Resources/GameKit/scaffold-web/Web/making.js +33 -0
  33. package/Resources/GameKit/scaffold-web/Web/world.js +33 -0
  34. package/Resources/GameKit/web/lamp-game.js +3036 -0
  35. package/Resources/GameKit/web/lamp-phaser.js +128 -0
  36. package/Resources/WebHost/App.exe +0 -0
  37. package/Resources/WebHost/Microsoft.Web.WebView2.Core.dll +0 -0
  38. package/Resources/WebHost/WebView2-LICENSE.txt +27 -0
  39. package/Resources/WebHost/lamp_controllers.h +1506 -0
  40. package/Resources/WebHost/lamp_web_host.cpp +1173 -0
  41. package/Resources/WebLibraries/earlier.txt +318 -0
  42. package/Resources/WebLibraries/phaser/LICENSE.md +20 -0
  43. package/Resources/WebLibraries/phaser/NOTICE.md +2 -0
  44. package/Resources/WebLibraries/phaser/phaser.esm.min.js +1 -0
  45. package/Resources/WebLibraries/qrcode/LICENSE +21 -0
  46. package/Resources/WebLibraries/qrcode/NOTICE.md +4 -0
  47. package/Resources/WebLibraries/qrcode/qrcode.js +2297 -0
  48. package/Resources/WebLibraries/rapier/LICENSE +201 -0
  49. package/Resources/WebLibraries/rapier/NOTICE.md +3 -0
  50. package/Resources/WebLibraries/rapier/rapier.js +2 -0
  51. package/Resources/WebLibraries/three/LICENSE +21 -0
  52. package/Resources/WebLibraries/three/NOTICE.md +4 -0
  53. package/Resources/WebLibraries/three/addons/animation/AnimationClipCreator.js +168 -0
  54. package/Resources/WebLibraries/three/addons/animation/CCDIKSolver.js +607 -0
  55. package/Resources/WebLibraries/three/addons/controls/ArcballControls.js +3543 -0
  56. package/Resources/WebLibraries/three/addons/controls/DragControls.js +452 -0
  57. package/Resources/WebLibraries/three/addons/controls/FirstPersonControls.js +512 -0
  58. package/Resources/WebLibraries/three/addons/controls/FlyControls.js +384 -0
  59. package/Resources/WebLibraries/three/addons/controls/MapControls.js +116 -0
  60. package/Resources/WebLibraries/three/addons/controls/OrbitControls.js +1985 -0
  61. package/Resources/WebLibraries/three/addons/controls/PointerLockControls.js +264 -0
  62. package/Resources/WebLibraries/three/addons/controls/TrackballControls.js +1106 -0
  63. package/Resources/WebLibraries/three/addons/controls/TransformControls.js +2003 -0
  64. package/Resources/WebLibraries/three/addons/curves/CurveExtras.js +694 -0
  65. package/Resources/WebLibraries/three/addons/curves/NURBSCurve.js +169 -0
  66. package/Resources/WebLibraries/three/addons/curves/NURBSSurface.js +98 -0
  67. package/Resources/WebLibraries/three/addons/curves/NURBSUtils.js +532 -0
  68. package/Resources/WebLibraries/three/addons/curves/NURBSVolume.js +82 -0
  69. package/Resources/WebLibraries/three/addons/effects/AnaglyphEffect.js +274 -0
  70. package/Resources/WebLibraries/three/addons/effects/AsciiEffect.js +323 -0
  71. package/Resources/WebLibraries/three/addons/effects/OutlineEffect.js +489 -0
  72. package/Resources/WebLibraries/three/addons/effects/ParallaxBarrierEffect.js +155 -0
  73. package/Resources/WebLibraries/three/addons/effects/StereoEffect.js +91 -0
  74. package/Resources/WebLibraries/three/addons/environments/ColorEnvironment.js +59 -0
  75. package/Resources/WebLibraries/three/addons/environments/DebugEnvironment.js +102 -0
  76. package/Resources/WebLibraries/three/addons/environments/RoomEnvironment.js +185 -0
  77. package/Resources/WebLibraries/three/addons/geometries/BoxLineGeometry.js +92 -0
  78. package/Resources/WebLibraries/three/addons/geometries/ConvexGeometry.js +72 -0
  79. package/Resources/WebLibraries/three/addons/geometries/DecalGeometry.js +420 -0
  80. package/Resources/WebLibraries/three/addons/geometries/LoftGeometry.js +355 -0
  81. package/Resources/WebLibraries/three/addons/geometries/ParametricFunctions.js +100 -0
  82. package/Resources/WebLibraries/three/addons/geometries/ParametricGeometry.js +172 -0
  83. package/Resources/WebLibraries/three/addons/geometries/RoundedBoxGeometry.js +216 -0
  84. package/Resources/WebLibraries/three/addons/geometries/TeapotGeometry.js +689 -0
  85. package/Resources/WebLibraries/three/addons/geometries/TextGeometry.js +102 -0
  86. package/Resources/WebLibraries/three/addons/helpers/AnimationPathHelper.js +302 -0
  87. package/Resources/WebLibraries/three/addons/helpers/LightProbeGridHelper.js +166 -0
  88. package/Resources/WebLibraries/three/addons/helpers/LightProbeGridHelperWebGL.js +221 -0
  89. package/Resources/WebLibraries/three/addons/helpers/LightProbeHelper.js +166 -0
  90. package/Resources/WebLibraries/three/addons/helpers/LightProbeHelperGPU.js +102 -0
  91. package/Resources/WebLibraries/three/addons/helpers/OctreeHelper.js +109 -0
  92. package/Resources/WebLibraries/three/addons/helpers/PositionalAudioHelper.js +169 -0
  93. package/Resources/WebLibraries/three/addons/helpers/RapierHelper.js +59 -0
  94. package/Resources/WebLibraries/three/addons/helpers/RectAreaLightHelper.js +118 -0
  95. package/Resources/WebLibraries/three/addons/helpers/TextureHelper.js +265 -0
  96. package/Resources/WebLibraries/three/addons/helpers/TextureHelperGPU.js +214 -0
  97. package/Resources/WebLibraries/three/addons/helpers/VertexNormalsHelper.js +155 -0
  98. package/Resources/WebLibraries/three/addons/helpers/VertexTangentsHelper.js +133 -0
  99. package/Resources/WebLibraries/three/addons/helpers/ViewHelper.js +529 -0
  100. package/Resources/WebLibraries/three/addons/interactive/HTMLMesh.js +617 -0
  101. package/Resources/WebLibraries/three/addons/interactive/InteractiveGroup.js +224 -0
  102. package/Resources/WebLibraries/three/addons/interactive/SelectionBox.js +324 -0
  103. package/Resources/WebLibraries/three/addons/interactive/SelectionHelper.js +150 -0
  104. package/Resources/WebLibraries/three/addons/libs/fflate.module.js +2699 -0
  105. package/Resources/WebLibraries/three/addons/libs/lil-gui.module.min.js +8 -0
  106. package/Resources/WebLibraries/three/addons/libs/meshopt_decoder.module.js +196 -0
  107. package/Resources/WebLibraries/three/addons/libs/potpack.module.js +125 -0
  108. package/Resources/WebLibraries/three/addons/libs/stats.module.js +167 -0
  109. package/Resources/WebLibraries/three/addons/libs/tween.module.js +876 -0
  110. package/Resources/WebLibraries/three/addons/lighting/ClusteredLighting.js +153 -0
  111. package/Resources/WebLibraries/three/addons/lighting/DynamicLighting.js +82 -0
  112. package/Resources/WebLibraries/three/addons/lighting/LightMapper.js +295 -0
  113. package/Resources/WebLibraries/three/addons/lighting/LightProbeGrid.js +923 -0
  114. package/Resources/WebLibraries/three/addons/lighting/LightProbeGridUtils.js +107 -0
  115. package/Resources/WebLibraries/three/addons/lighting/LightProbeGridWebGL.js +846 -0
  116. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIConeTracer.js +243 -0
  117. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIIrradiance.js +43 -0
  118. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGINode.js +617 -0
  119. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGISceneCollector.js +793 -0
  120. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIVolume.js +1440 -0
  121. package/Resources/WebLibraries/three/addons/lights/LightProbeGenerator.js +337 -0
  122. package/Resources/WebLibraries/three/addons/lights/RectAreaLightTexturesLib.js +127 -0
  123. package/Resources/WebLibraries/three/addons/lights/RectAreaLightUniformsLib.js +40 -0
  124. package/Resources/WebLibraries/three/addons/lights/SunLight.js +100 -0
  125. package/Resources/WebLibraries/three/addons/lights/SunLightNode.js +56 -0
  126. package/Resources/WebLibraries/three/addons/lights/SunLightShadow.js +319 -0
  127. package/Resources/WebLibraries/three/addons/lights/SunShadowNode.js +312 -0
  128. package/Resources/WebLibraries/three/addons/lines/Line2.js +56 -0
  129. package/Resources/WebLibraries/three/addons/lines/LineGeometry.js +157 -0
  130. package/Resources/WebLibraries/three/addons/lines/LineMaterial.js +742 -0
  131. package/Resources/WebLibraries/three/addons/lines/LineSegments2.js +434 -0
  132. package/Resources/WebLibraries/three/addons/lines/LineSegmentsGeometry.js +298 -0
  133. package/Resources/WebLibraries/three/addons/lines/Wireframe.js +108 -0
  134. package/Resources/WebLibraries/three/addons/lines/WireframeGeometry2.js +49 -0
  135. package/Resources/WebLibraries/three/addons/lines/webgpu/Line2.js +46 -0
  136. package/Resources/WebLibraries/three/addons/lines/webgpu/LineSegments2.js +419 -0
  137. package/Resources/WebLibraries/three/addons/lines/webgpu/Wireframe.js +86 -0
  138. package/Resources/WebLibraries/three/addons/loaders/EXRLoader.js +3411 -0
  139. package/Resources/WebLibraries/three/addons/loaders/FBXLoader.js +4660 -0
  140. package/Resources/WebLibraries/three/addons/loaders/FontLoader.js +262 -0
  141. package/Resources/WebLibraries/three/addons/loaders/GLTFLoader.js +5006 -0
  142. package/Resources/WebLibraries/three/addons/loaders/HDRLoader.js +463 -0
  143. package/Resources/WebLibraries/three/addons/loaders/MTLLoader.js +601 -0
  144. package/Resources/WebLibraries/three/addons/loaders/OBJLoader.js +961 -0
  145. package/Resources/WebLibraries/three/addons/loaders/PLYLoader.js +992 -0
  146. package/Resources/WebLibraries/three/addons/loaders/RGBELoader.js +18 -0
  147. package/Resources/WebLibraries/three/addons/loaders/STLLoader.js +423 -0
  148. package/Resources/WebLibraries/three/addons/loaders/SVGLoader.js +3297 -0
  149. package/Resources/WebLibraries/three/addons/loaders/TGALoader.js +539 -0
  150. package/Resources/WebLibraries/three/addons/loaders/UltraHDRLoader.js +757 -0
  151. package/Resources/WebLibraries/three/addons/math/Capsule.js +159 -0
  152. package/Resources/WebLibraries/three/addons/math/ColorConverter.js +62 -0
  153. package/Resources/WebLibraries/three/addons/math/ColorSpaces.js +147 -0
  154. package/Resources/WebLibraries/three/addons/math/ConvexHull.js +1695 -0
  155. package/Resources/WebLibraries/three/addons/math/ImprovedNoise.js +88 -0
  156. package/Resources/WebLibraries/three/addons/math/Lut.js +317 -0
  157. package/Resources/WebLibraries/three/addons/math/MeshSurfaceSampler.js +315 -0
  158. package/Resources/WebLibraries/three/addons/math/OBB.js +535 -0
  159. package/Resources/WebLibraries/three/addons/math/Octree.js +825 -0
  160. package/Resources/WebLibraries/three/addons/math/SimplexNoise.js +470 -0
  161. package/Resources/WebLibraries/three/addons/misc/ConvexObjectBreaker.js +539 -0
  162. package/Resources/WebLibraries/three/addons/misc/GPUComputationRenderer.js +508 -0
  163. package/Resources/WebLibraries/three/addons/misc/Gyroscope.js +78 -0
  164. package/Resources/WebLibraries/three/addons/misc/MorphAnimMesh.js +119 -0
  165. package/Resources/WebLibraries/three/addons/misc/MorphBlendMesh.js +425 -0
  166. package/Resources/WebLibraries/three/addons/misc/ProgressiveLightMap.js +370 -0
  167. package/Resources/WebLibraries/three/addons/misc/ProgressiveLightMapGPU.js +322 -0
  168. package/Resources/WebLibraries/three/addons/misc/RollerCoaster.js +661 -0
  169. package/Resources/WebLibraries/three/addons/misc/Sculptor.js +1679 -0
  170. package/Resources/WebLibraries/three/addons/misc/SculptorMesh.js +1504 -0
  171. package/Resources/WebLibraries/three/addons/misc/SculptorTools.js +1180 -0
  172. package/Resources/WebLibraries/three/addons/misc/SculptorUtils.js +345 -0
  173. package/Resources/WebLibraries/three/addons/misc/TileCreasedNormalsPlugin.js +270 -0
  174. package/Resources/WebLibraries/three/addons/misc/TubePainter.js +611 -0
  175. package/Resources/WebLibraries/three/addons/misc/Volume.js +520 -0
  176. package/Resources/WebLibraries/three/addons/misc/VolumeSlice.js +275 -0
  177. package/Resources/WebLibraries/three/addons/modifiers/CurveModifier.js +374 -0
  178. package/Resources/WebLibraries/three/addons/modifiers/CurveModifierGPU.js +256 -0
  179. package/Resources/WebLibraries/three/addons/modifiers/EdgeSplitModifier.js +299 -0
  180. package/Resources/WebLibraries/three/addons/modifiers/TessellateModifier.js +340 -0
  181. package/Resources/WebLibraries/three/addons/objects/GroundedSkybox.js +69 -0
  182. package/Resources/WebLibraries/three/addons/objects/Lensflare.js +489 -0
  183. package/Resources/WebLibraries/three/addons/objects/LensflareMesh.js +376 -0
  184. package/Resources/WebLibraries/three/addons/objects/MarchingCubes.js +1261 -0
  185. package/Resources/WebLibraries/three/addons/objects/Reflector.js +390 -0
  186. package/Resources/WebLibraries/three/addons/objects/ReflectorForSSRPass.js +393 -0
  187. package/Resources/WebLibraries/three/addons/objects/Refractor.js +389 -0
  188. package/Resources/WebLibraries/three/addons/objects/ShadowMesh.js +130 -0
  189. package/Resources/WebLibraries/three/addons/objects/Sky.js +342 -0
  190. package/Resources/WebLibraries/three/addons/objects/SkyMesh.js +403 -0
  191. package/Resources/WebLibraries/three/addons/objects/Water.js +374 -0
  192. package/Resources/WebLibraries/three/addons/objects/Water2.js +403 -0
  193. package/Resources/WebLibraries/three/addons/objects/Water2Mesh.js +199 -0
  194. package/Resources/WebLibraries/three/addons/objects/WaterMesh.js +194 -0
  195. package/Resources/WebLibraries/three/addons/postprocessing/AfterimagePass.js +187 -0
  196. package/Resources/WebLibraries/three/addons/postprocessing/BloomPass.js +274 -0
  197. package/Resources/WebLibraries/three/addons/postprocessing/BokehPass.js +218 -0
  198. package/Resources/WebLibraries/three/addons/postprocessing/ClearPass.js +97 -0
  199. package/Resources/WebLibraries/three/addons/postprocessing/CubeTexturePass.js +146 -0
  200. package/Resources/WebLibraries/three/addons/postprocessing/DotScreenPass.js +114 -0
  201. package/Resources/WebLibraries/three/addons/postprocessing/EffectComposer.js +365 -0
  202. package/Resources/WebLibraries/three/addons/postprocessing/FXAAPass.js +40 -0
  203. package/Resources/WebLibraries/three/addons/postprocessing/FilmPass.js +113 -0
  204. package/Resources/WebLibraries/three/addons/postprocessing/GTAOPass.js +735 -0
  205. package/Resources/WebLibraries/three/addons/postprocessing/GlitchPass.js +177 -0
  206. package/Resources/WebLibraries/three/addons/postprocessing/HalftonePass.js +134 -0
  207. package/Resources/WebLibraries/three/addons/postprocessing/LUTPass.js +138 -0
  208. package/Resources/WebLibraries/three/addons/postprocessing/MaskPass.js +195 -0
  209. package/Resources/WebLibraries/three/addons/postprocessing/OutlinePass.js +776 -0
  210. package/Resources/WebLibraries/three/addons/postprocessing/OutputPass.js +148 -0
  211. package/Resources/WebLibraries/three/addons/postprocessing/Pass.js +191 -0
  212. package/Resources/WebLibraries/three/addons/postprocessing/RenderPass.js +193 -0
  213. package/Resources/WebLibraries/three/addons/postprocessing/RenderPixelatedPass.js +314 -0
  214. package/Resources/WebLibraries/three/addons/postprocessing/RenderTransitionPass.js +267 -0
  215. package/Resources/WebLibraries/three/addons/postprocessing/SAOPass.js +407 -0
  216. package/Resources/WebLibraries/three/addons/postprocessing/SMAAPass.js +230 -0
  217. package/Resources/WebLibraries/three/addons/postprocessing/SSAARenderPass.js +313 -0
  218. package/Resources/WebLibraries/three/addons/postprocessing/SSAOPass.js +527 -0
  219. package/Resources/WebLibraries/three/addons/postprocessing/SSRPass.js +858 -0
  220. package/Resources/WebLibraries/three/addons/postprocessing/SavePass.js +132 -0
  221. package/Resources/WebLibraries/three/addons/postprocessing/ShaderPass.js +135 -0
  222. package/Resources/WebLibraries/three/addons/postprocessing/TAARenderPass.js +243 -0
  223. package/Resources/WebLibraries/three/addons/postprocessing/TexturePass.js +131 -0
  224. package/Resources/WebLibraries/three/addons/postprocessing/UnrealBloomPass.js +541 -0
  225. package/Resources/WebLibraries/three/addons/shaders/ACESFilmicToneMappingShader.js +96 -0
  226. package/Resources/WebLibraries/three/addons/shaders/AfterimageShader.js +63 -0
  227. package/Resources/WebLibraries/three/addons/shaders/BasicShader.js +36 -0
  228. package/Resources/WebLibraries/three/addons/shaders/BleachBypassShader.js +68 -0
  229. package/Resources/WebLibraries/three/addons/shaders/BlendShader.js +56 -0
  230. package/Resources/WebLibraries/three/addons/shaders/BokehShader.js +151 -0
  231. package/Resources/WebLibraries/three/addons/shaders/BokehShader2.js +404 -0
  232. package/Resources/WebLibraries/three/addons/shaders/BrightnessContrastShader.js +62 -0
  233. package/Resources/WebLibraries/three/addons/shaders/ColorCorrectionShader.js +59 -0
  234. package/Resources/WebLibraries/three/addons/shaders/ColorifyShader.js +57 -0
  235. package/Resources/WebLibraries/three/addons/shaders/ConvolutionShader.js +74 -0
  236. package/Resources/WebLibraries/three/addons/shaders/CopyShader.js +52 -0
  237. package/Resources/WebLibraries/three/addons/shaders/DOFMipMapShader.js +63 -0
  238. package/Resources/WebLibraries/three/addons/shaders/DepthLimitedBlurShader.js +183 -0
  239. package/Resources/WebLibraries/three/addons/shaders/DigitalGlitch.js +104 -0
  240. package/Resources/WebLibraries/three/addons/shaders/DotScreenShader.js +75 -0
  241. package/Resources/WebLibraries/three/addons/shaders/ExposureShader.js +51 -0
  242. package/Resources/WebLibraries/three/addons/shaders/FXAAShader.js +298 -0
  243. package/Resources/WebLibraries/three/addons/shaders/FilmShader.js +73 -0
  244. package/Resources/WebLibraries/three/addons/shaders/FocusShader.js +94 -0
  245. package/Resources/WebLibraries/three/addons/shaders/FreiChenShader.js +103 -0
  246. package/Resources/WebLibraries/three/addons/shaders/GTAOShader.js +437 -0
  247. package/Resources/WebLibraries/three/addons/shaders/GammaCorrectionShader.js +52 -0
  248. package/Resources/WebLibraries/three/addons/shaders/HalftoneShader.js +332 -0
  249. package/Resources/WebLibraries/three/addons/shaders/HorizontalBlurShader.js +68 -0
  250. package/Resources/WebLibraries/three/addons/shaders/HorizontalTiltShiftShader.js +70 -0
  251. package/Resources/WebLibraries/three/addons/shaders/HueSaturationShader.js +74 -0
  252. package/Resources/WebLibraries/three/addons/shaders/KaleidoShader.js +65 -0
  253. package/Resources/WebLibraries/three/addons/shaders/LuminosityHighPassShader.js +68 -0
  254. package/Resources/WebLibraries/three/addons/shaders/LuminosityShader.js +54 -0
  255. package/Resources/WebLibraries/three/addons/shaders/MirrorShader.js +62 -0
  256. package/Resources/WebLibraries/three/addons/shaders/NormalMapShader.js +60 -0
  257. package/Resources/WebLibraries/three/addons/shaders/OutputShader.js +103 -0
  258. package/Resources/WebLibraries/three/addons/shaders/PoissonDenoiseShader.js +230 -0
  259. package/Resources/WebLibraries/three/addons/shaders/RGBShiftShader.js +61 -0
  260. package/Resources/WebLibraries/three/addons/shaders/SAOShader.js +201 -0
  261. package/Resources/WebLibraries/three/addons/shaders/SMAAShader.js +489 -0
  262. package/Resources/WebLibraries/three/addons/shaders/SSAOShader.js +331 -0
  263. package/Resources/WebLibraries/three/addons/shaders/SSRShader.js +396 -0
  264. package/Resources/WebLibraries/three/addons/shaders/SepiaShader.js +57 -0
  265. package/Resources/WebLibraries/three/addons/shaders/SobelOperatorShader.js +98 -0
  266. package/Resources/WebLibraries/three/addons/shaders/SubsurfaceScatteringShader.js +95 -0
  267. package/Resources/WebLibraries/three/addons/shaders/TechnicolorShader.js +51 -0
  268. package/Resources/WebLibraries/three/addons/shaders/ToonShader.js +349 -0
  269. package/Resources/WebLibraries/three/addons/shaders/TriangleBlurShader.js +79 -0
  270. package/Resources/WebLibraries/three/addons/shaders/UnpackDepthRGBAShader.js +60 -0
  271. package/Resources/WebLibraries/three/addons/shaders/VelocityShader.js +137 -0
  272. package/Resources/WebLibraries/three/addons/shaders/VerticalBlurShader.js +66 -0
  273. package/Resources/WebLibraries/three/addons/shaders/VerticalTiltShiftShader.js +70 -0
  274. package/Resources/WebLibraries/three/addons/shaders/VignetteShader.js +56 -0
  275. package/Resources/WebLibraries/three/addons/shaders/VolumeShader.js +285 -0
  276. package/Resources/WebLibraries/three/addons/shaders/WaterRefractionShader.js +106 -0
  277. package/Resources/WebLibraries/three/addons/textures/FlakesTexture.js +54 -0
  278. package/Resources/WebLibraries/three/addons/tsl/WebGLNodesHandler.js +607 -0
  279. package/Resources/WebLibraries/three/addons/tsl/display/AfterImageNode.js +256 -0
  280. package/Resources/WebLibraries/three/addons/tsl/display/AnaglyphPassNode.js +550 -0
  281. package/Resources/WebLibraries/three/addons/tsl/display/BilateralBlurNode.js +377 -0
  282. package/Resources/WebLibraries/three/addons/tsl/display/BleachBypass.js +33 -0
  283. package/Resources/WebLibraries/three/addons/tsl/display/BloomNode.js +599 -0
  284. package/Resources/WebLibraries/three/addons/tsl/display/CRT.js +150 -0
  285. package/Resources/WebLibraries/three/addons/tsl/display/ChromaticAberrationNode.js +163 -0
  286. package/Resources/WebLibraries/three/addons/tsl/display/DenoiseNode.js +354 -0
  287. package/Resources/WebLibraries/three/addons/tsl/display/DepthOfFieldNode.js +572 -0
  288. package/Resources/WebLibraries/three/addons/tsl/display/DotScreenNode.js +104 -0
  289. package/Resources/WebLibraries/three/addons/tsl/display/FSR1Node.js +481 -0
  290. package/Resources/WebLibraries/three/addons/tsl/display/FXAANode.js +357 -0
  291. package/Resources/WebLibraries/three/addons/tsl/display/FilmNode.js +101 -0
  292. package/Resources/WebLibraries/three/addons/tsl/display/GTAONode.js +727 -0
  293. package/Resources/WebLibraries/three/addons/tsl/display/GaussianBlurNode.js +412 -0
  294. package/Resources/WebLibraries/three/addons/tsl/display/GodraysNode.js +604 -0
  295. package/Resources/WebLibraries/three/addons/tsl/display/ImportanceSampledEnvironment.js +564 -0
  296. package/Resources/WebLibraries/three/addons/tsl/display/LensflareNode.js +282 -0
  297. package/Resources/WebLibraries/three/addons/tsl/display/Lut3DNode.js +109 -0
  298. package/Resources/WebLibraries/three/addons/tsl/display/MotionBlur.js +33 -0
  299. package/Resources/WebLibraries/three/addons/tsl/display/OITPassNode.js +341 -0
  300. package/Resources/WebLibraries/three/addons/tsl/display/OutlineNode.js +916 -0
  301. package/Resources/WebLibraries/three/addons/tsl/display/ParallaxBarrierPassNode.js +90 -0
  302. package/Resources/WebLibraries/three/addons/tsl/display/PixelationPassNode.js +227 -0
  303. package/Resources/WebLibraries/three/addons/tsl/display/RGBShiftNode.js +96 -0
  304. package/Resources/WebLibraries/three/addons/tsl/display/RecurrentDenoiseNode.js +812 -0
  305. package/Resources/WebLibraries/three/addons/tsl/display/RetroPassNode.js +263 -0
  306. package/Resources/WebLibraries/three/addons/tsl/display/SMAANode.js +729 -0
  307. package/Resources/WebLibraries/three/addons/tsl/display/SSAAPassNode.js +344 -0
  308. package/Resources/WebLibraries/three/addons/tsl/display/SSAONode.js +422 -0
  309. package/Resources/WebLibraries/three/addons/tsl/display/SSGINode.js +698 -0
  310. package/Resources/WebLibraries/three/addons/tsl/display/SSRNode.js +1430 -0
  311. package/Resources/WebLibraries/three/addons/tsl/display/SSSNode.js +479 -0
  312. package/Resources/WebLibraries/three/addons/tsl/display/Sepia.js +24 -0
  313. package/Resources/WebLibraries/three/addons/tsl/display/Shape.js +29 -0
  314. package/Resources/WebLibraries/three/addons/tsl/display/SharpenNode.js +284 -0
  315. package/Resources/WebLibraries/three/addons/tsl/display/SobelOperatorNode.js +168 -0
  316. package/Resources/WebLibraries/three/addons/tsl/display/StereoCompositePassNode.js +190 -0
  317. package/Resources/WebLibraries/three/addons/tsl/display/StereoPassNode.js +117 -0
  318. package/Resources/WebLibraries/three/addons/tsl/display/TAAUNode.js +700 -0
  319. package/Resources/WebLibraries/three/addons/tsl/display/TRAANode.js +609 -0
  320. package/Resources/WebLibraries/three/addons/tsl/display/TemporalReprojectNode.js +1024 -0
  321. package/Resources/WebLibraries/three/addons/tsl/display/TransitionNode.js +141 -0
  322. package/Resources/WebLibraries/three/addons/tsl/display/boxBlur.js +65 -0
  323. package/Resources/WebLibraries/three/addons/tsl/display/depthAwareBlend.js +80 -0
  324. package/Resources/WebLibraries/three/addons/tsl/display/depthAwareBlur.js +63 -0
  325. package/Resources/WebLibraries/three/addons/tsl/display/hashBlur.js +55 -0
  326. package/Resources/WebLibraries/three/addons/tsl/display/lensDirt.js +30 -0
  327. package/Resources/WebLibraries/three/addons/tsl/display/radialBlur.js +68 -0
  328. package/Resources/WebLibraries/three/addons/tsl/lighting/ClusteredLightsNode.js +994 -0
  329. package/Resources/WebLibraries/three/addons/tsl/lighting/DynamicLightsNode.js +201 -0
  330. package/Resources/WebLibraries/three/addons/tsl/lighting/LightProbeGridNode.js +183 -0
  331. package/Resources/WebLibraries/three/addons/tsl/lighting/data/AmbientLightDataNode.js +67 -0
  332. package/Resources/WebLibraries/three/addons/tsl/lighting/data/DirectionalLightDataNode.js +117 -0
  333. package/Resources/WebLibraries/three/addons/tsl/lighting/data/HemisphereLightDataNode.js +105 -0
  334. package/Resources/WebLibraries/three/addons/tsl/lighting/data/PointLightDataNode.js +140 -0
  335. package/Resources/WebLibraries/three/addons/tsl/lighting/data/SpotLightDataNode.js +167 -0
  336. package/Resources/WebLibraries/three/addons/tsl/math/Bayer.js +84 -0
  337. package/Resources/WebLibraries/three/addons/tsl/math/curlNoise.js +107 -0
  338. package/Resources/WebLibraries/three/addons/tsl/math/voronoiNoise.js +112 -0
  339. package/Resources/WebLibraries/three/addons/tsl/shadows/TileShadowNode.js +542 -0
  340. package/Resources/WebLibraries/three/addons/tsl/shadows/TileShadowNodeHelper.js +212 -0
  341. package/Resources/WebLibraries/three/addons/tsl/utils/GroundedSkybox.js +62 -0
  342. package/Resources/WebLibraries/three/addons/tsl/utils/RNoise.js +51 -0
  343. package/Resources/WebLibraries/three/addons/tsl/utils/Raymarching.js +70 -0
  344. package/Resources/WebLibraries/three/addons/tsl/utils/SoftParticles.js +53 -0
  345. package/Resources/WebLibraries/three/addons/tsl/utils/SpecularHelpers.js +302 -0
  346. package/Resources/WebLibraries/three/addons/tsl/utils/TAAUtils.js +184 -0
  347. package/Resources/WebLibraries/three/addons/utils/BufferGeometryUtils.js +1523 -0
  348. package/Resources/WebLibraries/three/addons/utils/CameraUtils.js +82 -0
  349. package/Resources/WebLibraries/three/addons/utils/ColorUtils.js +76 -0
  350. package/Resources/WebLibraries/three/addons/utils/GaussianSplatUtils.js +229 -0
  351. package/Resources/WebLibraries/three/addons/utils/GeometryCompressionUtils.js +547 -0
  352. package/Resources/WebLibraries/three/addons/utils/GeometryUtils.js +226 -0
  353. package/Resources/WebLibraries/three/addons/utils/LDrawUtils.js +211 -0
  354. package/Resources/WebLibraries/three/addons/utils/SceneOptimizer.js +459 -0
  355. package/Resources/WebLibraries/three/addons/utils/SceneUtils.js +363 -0
  356. package/Resources/WebLibraries/three/addons/utils/ShadowMapViewer.js +244 -0
  357. package/Resources/WebLibraries/three/addons/utils/ShadowMapViewerGPU.js +233 -0
  358. package/Resources/WebLibraries/three/addons/utils/SkeletonUtils.js +496 -0
  359. package/Resources/WebLibraries/three/addons/utils/SortUtils.js +175 -0
  360. package/Resources/WebLibraries/three/addons/utils/UVsDebug.js +173 -0
  361. package/Resources/WebLibraries/three/addons/utils/WebGLTextureUtils.js +115 -0
  362. package/Resources/WebLibraries/three/addons/utils/WebGPUTextureUtils.js +81 -0
  363. package/Resources/WebLibraries/three/addons/utils/WorkerPool.js +167 -0
  364. package/Resources/WebLibraries/three/addons/utils/unwrapUVs.js +865 -0
  365. package/Resources/WebLibraries/three/three.core.js +61162 -0
  366. package/Resources/WebLibraries/three/three.module.js +19537 -0
  367. package/Resources/WebLibraries/three/three.tsl.js +41903 -0
  368. package/Resources/WebLibraries/three/three.webgpu.js +53714 -0
  369. package/Resources/skills/2d-game/SKILL.md +305 -0
  370. package/Resources/skills/3d-game/SKILL.md +274 -0
  371. package/Resources/skills/accounts/SKILL.md +41 -0
  372. package/Resources/skills/android-design/SKILL.md +159 -0
  373. package/Resources/skills/app-ai/SKILL.md +154 -0
  374. package/Resources/skills/app-intents/SKILL.md +31 -0
  375. package/Resources/skills/app-kinds/SKILL.md +122 -0
  376. package/Resources/skills/apple-watch/SKILL.md +43 -0
  377. package/Resources/skills/assets/SKILL.md +183 -0
  378. package/Resources/skills/building-blocks/SKILL.md +97 -0
  379. package/Resources/skills/device-control/SKILL.md +56 -0
  380. package/Resources/skills/device-integrations/SKILL.md +278 -0
  381. package/Resources/skills/finder-files/SKILL.md +19 -0
  382. package/Resources/skills/game/SKILL.md +414 -0
  383. package/Resources/skills/game-3d/SKILL.md +12 -0
  384. package/Resources/skills/game-art/SKILL.md +11 -0
  385. package/Resources/skills/game-feel/SKILL.md +13 -0
  386. package/Resources/skills/game-levels/SKILL.md +12 -0
  387. package/Resources/skills/game-live/SKILL.md +12 -0
  388. package/Resources/skills/game-physics/SKILL.md +13 -0
  389. package/Resources/skills/game-playtest/SKILL.md +26 -0
  390. package/Resources/skills/game-ui/SKILL.md +278 -0
  391. package/Resources/skills/github-projects/SKILL.md +59 -0
  392. package/Resources/skills/icloud-sync/SKILL.md +30 -0
  393. package/Resources/skills/iphone-hardware/SKILL.md +57 -0
  394. package/Resources/skills/iphone-widgets/SKILL.md +53 -0
  395. package/Resources/skills/lg-developer-mode/SKILL.md +152 -0
  396. package/Resources/skills/mac-widgets/SKILL.md +60 -0
  397. package/Resources/skills/maps/SKILL.md +8 -0
  398. package/Resources/skills/menu-bar/SKILL.md +36 -0
  399. package/Resources/skills/more-apps/SKILL.md +53 -0
  400. package/Resources/skills/phone-controllers/SKILL.md +79 -0
  401. package/Resources/skills/phone-pages/SKILL.md +173 -0
  402. package/Resources/skills/roku-developer-mode/SKILL.md +106 -0
  403. package/Resources/skills/scene-3d/SKILL.md +27 -0
  404. package/Resources/skills/scripting/SKILL.md +17 -0
  405. package/Resources/skills/share-extension/SKILL.md +22 -0
  406. package/Resources/skills/tv-design/SKILL.md +72 -0
  407. package/Resources/skills/web-app/SKILL.md +136 -0
  408. package/Resources/skills/web-game/SKILL.md +95 -0
  409. package/Resources/skills/web-or-native/SKILL.md +103 -0
  410. package/Resources/skills/wish-links/SKILL.md +156 -0
  411. package/THIRD_PARTY_NOTICES.md +170 -0
  412. package/cli/android.mjs +941 -0
  413. package/cli/browser.mjs +268 -0
  414. package/cli/calls.mjs +390 -0
  415. package/cli/dev.mjs +773 -0
  416. package/cli/devices.mjs +984 -0
  417. package/cli/lamp.mjs +1016 -0
  418. package/cli/lampapp.mjs +332 -0
  419. package/cli/lamps/android-host/LampPageGateway.kt +345 -0
  420. package/cli/lamps/android-host/app/build.gradle.kts +40 -0
  421. package/cli/lamps/android-host/build.gradle.kts +4 -0
  422. package/cli/lamps/android-host/game/AndroidManifest.xml +33 -0
  423. package/cli/lamps/android-host/game/MainActivity.kt +173 -0
  424. package/cli/lamps/android-host/gradle/libs.versions.toml +39 -0
  425. package/cli/lamps/android-host/gradle.properties +8 -0
  426. package/cli/lamps/android-host/page/AndroidManifest.xml +35 -0
  427. package/cli/lamps/android-host/page/MainActivity.kt +193 -0
  428. package/cli/lamps/android-host/settings.gradle.kts +30 -0
  429. package/cli/lamps/android-host/tools.json +43 -0
  430. package/cli/lamps/lamp-controllers.js +2 -0
  431. package/cli/lamps/lamp-for-games.js +6863 -0
  432. package/cli/lamps/lamp.js +7023 -0
  433. package/cli/lamps/mac-starter/.lamp/meta.json +1 -0
  434. package/cli/lamps/mac-starter/APP.md +12 -0
  435. package/cli/lamps/mac-starter/Package.swift +8 -0
  436. package/cli/lamps/mac-starter/Sources/App.swift +11 -0
  437. package/cli/lamps/mac-starter/Sources/ContentView.swift +17 -0
  438. package/cli/lamps/mac-starter/Sources/LampSupport.swift +18097 -0
  439. package/cli/lamps/mac-starter/build.sh +336 -0
  440. package/cli/lamps/mac-starter/gitignore +3 -0
  441. package/cli/lamps/mac-starter/lamp-starter.json +6 -0
  442. package/cli/lamps/web-starter/APP.md +8 -0
  443. package/cli/lamps/web-starter/app.js +1 -0
  444. package/cli/lamps/web-starter/index.html +17 -0
  445. package/cli/lamps/web-starter/lamp-starter.json +5 -0
  446. package/cli/lamps/web-starter/lamp.js +7023 -0
  447. package/cli/lamps/web-starter/style.css +25 -0
  448. package/cli/link.mjs +138 -0
  449. package/cli/mac.mjs +621 -0
  450. package/cli/mdns.mjs +205 -0
  451. package/cli/msix.mjs +413 -0
  452. package/cli/network.mjs +209 -0
  453. package/cli/outside.mjs +140 -0
  454. package/cli/page.js +165 -0
  455. package/cli/place.mjs +298 -0
  456. package/cli/png.mjs +184 -0
  457. package/cli/share.mjs +202 -0
  458. package/cli/skill/SKILL.md +255 -0
  459. package/cli/skills.mjs +71 -0
  460. package/cli/state.mjs +173 -0
  461. package/cli/update.mjs +57 -0
  462. package/package.json +20 -4
  463. package/site/lib/quota.js +59 -0
  464. package/site/lib/shared-wishes.js +996 -0
@@ -0,0 +1,19 @@
1
+ ---
2
+ name: finder-files
3
+ description: A Mac app that takes files or folders from Finder - dropped on its icon, Open With, a Quick Action - with what it declares in capabilities.json, how to try it, and Quick Actions that survive a move. Read before writing any of it.
4
+ ---
5
+
6
+ # Files and folders from Finder
7
+
8
+ An app that takes files or folders from Finder (dropped on its icon, Open With, a Quick Action) says what it opens in
9
+ `capabilities.json` at the app's root: `{"opens": ["folder", "png", "public.image"]}`, with "folder", "file" for any
10
+ file, file extensions or type identifiers. Lamp declares them for the app; without that macOS hands it nothing. It is
11
+ only ever offered for a kind another app opens, never put in that app's place; a kind nothing else opens (your own
12
+ extension) is the app's to open.
13
+
14
+ To try it, make test files in the app's folder or a temporary folder and hand them over with the `open` command
15
+ `look_at_app` then gives you, which does what Finder does.
16
+
17
+ A Finder Quick Action is a workflow the app writes into ~/Library/Services, and it stores the app's full path: it
18
+ stops working when the app is moved or renamed, until the app runs again and rewrites it. So have the app write it at
19
+ every launch from `Bundle.main.bundlePath`, never once.
@@ -0,0 +1,414 @@
1
+ ---
2
+ name: game
3
+ description: Games, 2D or 3D, made either way - what makes one fun and playtesting it, the frame loop, controls (a controller, keys, touch, a TV remote), sound, saves, keeping every frame smooth and light rendering - with the tools for each (Lamp's game runtime in a web page, a Samsung or LG TV app's page, in 2D or with three.js, for a game played with phones, SpriteKit and Lamp's blocks in Swift, an integration's own), and turning an app into a game. Read before writing or changing a game; a new web game at home on the Mac starts from the web-game guide and game-feel instead, and the parts of this it needs come as the skills that guide names.
4
+ ---
5
+
6
+ # Games
7
+
8
+ A game is something played in real time, rather than used. What follows holds for every game, whichever way it's
9
+ made; each part then names the tools for each make. For a game in 2D, open the 2d-game skill too (Phaser or SpriteKit,
10
+ and which to choose); for one in 3D, the 3d-game skill (or scene-3d for RealityKit in Swift). Before designing its
11
+ opening, title, menus, level select, HUD, pause or results, read the game-ui skill: a new game picks its screen flow
12
+ there before any screen is drawn, however it's made.
13
+
14
+ The tools Lamp has for games:
15
+
16
+ - **Web**: Lamp's game runtime, `Web/lamp-game.js`, with Phaser for 2D (through `Web/lamp-phaser.js`) or three.js for
17
+ 3D, in a game `make_app_for` made with `kind` "game". It's a game's default make, 2D or 3D, wherever Lamp has a host
18
+ for a page, and the same on every one of them. Read lamp-game.js first, all of it (and lamp-phaser.js for 2D): their
19
+ comments are the whole interface. (A new game at home on the Mac starts from the web-game guide, which needs neither read whole.) Below, "Web" means this runtime.
20
+ - **TypeScript**: a game whose source is TypeScript (one brought in from a Vite project, or when the person asks for
21
+ it) keeps it in `src/` with `src/main.ts` as its entry, and Lamp bundles it into `Web/app/` before every build and
22
+ look (types stripped, not checked): `Web/index.html` loads `app/main.js` (and `app/main.css` when the source imports
23
+ CSS), and its import map names the bare imports, `three` and `lamp-game` (`./lamp-game.js`) among them. As in a
24
+ Vite build, `import.meta.env` reads as a published build's, and a worker is a `src/**/*.worker.ts` file, started with
25
+ `new Worker(new URL("./<name>.worker.js", import.meta.url), { type: "module" })` (`.js`: every file is bundled flat
26
+ into `Web/app/`; a module worker, since what it shares with the page comes as an import). Edit `src/`,
27
+ never `Web/app/`. A game in plain JavaScript stays as it is, its modules in `Web/`.
28
+ - **Phones as players**: a game on the runtime takes phones on the Wi‑Fi with `Lamp.controllers` (Web/lamp.js) and
29
+ its page for them in Phone/ (the phone-controllers and phone-pages skills), on the Mac, in the TV preview, on a
30
+ Samsung or LG TV and on the Xbox; elsewhere `Lamp.controllers` says it can't start, so the game stays whole with a controller,
31
+ the keys or touch. Lamp plays the game with a controller of its own, never as a phone: only the person's phones
32
+ join. Read a phone's buttons in `frame(f)` from `f.phones`, as the pads are read (`frame().phones`
33
+ in a Phaser scene): one `{ player, down, pressed, released }` for each phone joined, each button by the name the phone
34
+ page gave it, so `for (const p of f.phones) if (p.pressed.go) start()`. `pressed` and `released` last the one frame after
35
+ it happened, and a press let go again between two frames is still a press. `onButton` runs between frames, so a flag
36
+ it sets and `frame` clears is lost: keep it for what can't wait for a frame. Sticks and messages still come by
37
+ `onAxis` and `onMessage`, so the game keeps its own queue for them (the phone-pages skill's "Views and moves").
38
+ - **A TV app's page**: a game made as a Samsung or LG TV app before games took phones (`kind` "app") has no
39
+ lamp-game.js: it follows the TV rules and lamp.js instead, with its own `requestAnimationFrame`. The rest of this
40
+ skill holds for it wherever it doesn't name the runtime.
41
+ - **Native Apple** (Mac, iPhone, iPad, Apple TV): SpriteKit for 2D, SwiftUI for menus and scores, and Lamp's blocks
42
+ in LampSupport.swift: a game made natively, where the person asked for that, it needs what only Apple's apps have
43
+ (Game Center, a widget, a place inside an app of theirs) or the device has no host for a page (an Apple TV). It stays
44
+ on Apple's devices: it can't go to Android, the Xbox, a TV's browser or the web later. For 3D in Swift, LampSceneView (the scene-3d skill) is for a Mac app made natively; a native 3D game
45
+ on iPhone, iPad or Apple TV writes its own 3D with that device's frameworks (RealityKit or SceneKit).
46
+ - **Native Android**: Lamp has no game help in Kotlin yet: write the game's own frame loop on a SurfaceView or a
47
+ Canvas, and its controls, sound and saves with Android's own APIs.
48
+ - **An integration's device** (Roku…): what its integration declares; read the device-integrations skill.
49
+ - **Apple Watch**: Lamp has no game help there.
50
+
51
+ ## Fun
52
+
53
+ A game is for fun, and fun is designed from the first build, not added at the end:
54
+
55
+ - **A clear core loop.** One thing the player does again and again (jump, aim, steer, match) that feels good on its
56
+ own, and a reason to do it once more: a score to beat, the next level, something new just ahead.
57
+ - **Quick feedback.** Every action answers at once, in sight and sound: a hit flashes and pops, a coin chimes and
58
+ leaps to the score, a landing squashes. This is the game's juice: particles, a little screen shake on the big
59
+ moments (never on every frame, and less on a TV across the room), a tween in place of a jump cut, a short freeze on
60
+ a big hit.
61
+ - **A learning curve.** The first minute teaches by playing, never by a page of rules; then it gets harder in steps the
62
+ player feels coming, with a breather after each rise.
63
+ - **Variety.** New enemies, places, rules or tools keep coming, so the tenth minute isn't the first again.
64
+ - **Surprise and delight the player frequently.** Small things nobody asked for: a character that waves back, a
65
+ secret, a joke in a name, a combo that does something special, weather that changes, a celebration that's over the
66
+ top. Many small ones beat one big one.
67
+
68
+ What's in it is made in code (3D models from three.js shapes, the 3d-game skill; pictures drawn in code or painted with
69
+ `make_art`) or ready-made from Lamp's free assets: models, characters with their animations, sprite sheets, tilesets,
70
+ textures, sound effects and music, fetched and credited by the `assets` tool (the assets skill says when each suits and
71
+ how to keep one style). Sound looks in those assets first ("Sound", below). Either way it's the person's to share. Any other file only when the person gives it or names where it comes from and its license allows sharing; it goes into the game's own
72
+ folder, credited as the rules say. The game never loads anything from the network while it's played.
73
+
74
+ When asked to make a game more fun, look at it first and find what's flat (a loop that doesn't pull, a curve that's
75
+ too easy or too hard, an action that answers with nothing), then work on those four: the loop and the curve, the
76
+ juice, the surprises, and the variety. Keep what the person likes about it, and its controls.
77
+
78
+ ## The frame loop
79
+
80
+ Everything that moves is moved by the time since the last frame, never by a fixed step per frame: devices draw at
81
+ different rates, and a slow frame must not slow the game.
82
+
83
+ - Web (the runtime): `game({ renderer, init, frame })` from lamp-game.js, moving by `f.dt`; in 2D, Phaser's scenes
84
+ through `phaser({ scenes })` from lamp-phaser.js, moving by `update`'s `delta`, on the same one loop. Never requestAnimationFrame, timers, the
85
+ clock, Math.random or localStorage: `random()`, `save()` and `load()` from the runtime, which keep through a change
86
+ of the code.
87
+ Physics is the one exception to moving by `f.dt`: it steps at a fixed 1/60 s inside the frame, through `fixedStep`
88
+ from lamp-game.js, so it behaves the same at any frame rate (Rapier for 3D, in the 3d-game skill).
89
+ - SpriteKit: in a SpriteView, one SKScene subclass for each screen with `scaleMode = .resizeFill`; movement in
90
+ `update(_:)` scaled by the time since the last frame; collisions with SKPhysicsBody, its category and contact masks,
91
+ and an SKPhysicsContactDelegate. An SKCameraNode follows the player through a world bigger than the screen.
92
+
93
+ ## Controls
94
+
95
+ Controls follow the input the player has, not the device: the same player may pick up an Xbox, PlayStation or
96
+ Switch controller, the keyboard or the touch screen, and switch while playing.
97
+
98
+ - **Web**: lamp-game.js reads all of them as one pad, `f.pads[0]` (`pad()` in a Phaser scene). Write the controls once, as actions mapped to the
99
+ pad (`const CONTROLS = { jump: BUTTON.A, pause: BUTTON.MENU, move: STICK.LEFT, gas: TRIGGER.RT }`), and read the pad
100
+ through them. `input()` says what the player holds (`kind` is `controller`, with its `family`: `xbox`,
101
+ `playstation`, `switch` or `other`; or `keyboard`, or `touch`); `onInput(draw)` draws now and again each time they
102
+ take up another. Build every prompt and help screen inside it from the actions: `label(CONTROLS.jump)` is the
103
+ button's name on that input ("A", "✕", "Space") and `glyph(CONTROLS.jump)` its badge, an element to put in the text.
104
+ Both are null where the input has nothing for that action: leave the line out. Never write a key's or a button's
105
+ name yourself; a page that reads the keys itself (`keyboard: false`) names its own keys by their codes,
106
+ `label('KeyH')`. When the person names the keys to move with, the hints use them: `keyboardHints: { leftStick:
107
+ 'arrows' }` to `game()` or `phaser()` makes `label(STICK.LEFT)` and `glyph(STICK.LEFT)` name the arrow keys (`'wasd'`
108
+ is the default). Both sets of keys still move the player.
109
+ - **Swift**: GameController's `GCController` for a controller, with the button's name from the controller itself
110
+ (`localizedName`, `sfSymbolsName`) rather than a fixed letter; keys on a Mac with
111
+ `NSEvent.addLocalMonitorForEvents`.
112
+ - **Touch**: big targets for thumbs, and few of them. Web: the runtime draws a stick and the buttons `touch` names;
113
+ keep the game playable with those few.
114
+ - **A TV remote**: arrows and OK, and a back key; a game that needs more wants a controller, or phones (the
115
+ phone-controllers skill).
116
+
117
+ B (or Esc, or Back) is the game's own back or cancel; Menu pauses.
118
+
119
+ ## Sound
120
+
121
+ Every game has sound: a short effect (under a second) for each thing the player does or meets, and music only when it
122
+ suits, quiet (0.3 to 0.4) under effects at 0.6 to 0.8. Settings or the pause menu turn sound and music on and off.
123
+
124
+ **Look in the `assets` tool before writing any sound.** List what the game needs to sound like (each thing the player
125
+ does or meets, and its music), then see the whole catalog: `assets` with `kind: sound`, `limit: 30` and no `find` lists
126
+ every effect, and `kind: music` every loop. Fetch one for every moment it can serve, by name and notes (the assets
127
+ skill's "Sounds and music" has more). Only files the person gave come before this. Write a sound in code only for a
128
+ moment nothing in those lists fits, or one that has to follow the game as it's played (an engine's pitch, notes on a
129
+ scale), and name each of those in your report. They're chosen as the game is made, and every one ships inside it.
130
+
131
+ - Web: `sound` in lamp-game.js. A file loads with `await sound.load('assets/…')`. Written in code, effects come from
132
+ `sound.tone`, and music from a loop of a few bars written out note by note into `sound.samples` (a bass line, chords,
133
+ a melody, in one key). Either way `sound.play` plays an effect and `sound.music` a loop, a calmer one for menus and a
134
+ livelier one for play.
135
+ - Swift: files in Assets/ (.wav, .m4a or .mp3, and what the `assets` tool brought in) play with an
136
+ `AVAudioPlayer(contentsOf: LampAssets.url(name)!)` made once and `prepareToPlay()`ed, a few of them for an effect
137
+ that overlaps itself; music is one looping (`numberOfLoops = -1`). Written in code, effects come from one
138
+ `AVAudioEngine` started at launch with an `AVAudioPlayerNode`, each effect a few hundredths of a second of a wave
139
+ written once into an `AVAudioPCMBuffer`, with soft ends so it doesn't click. On iPhone set the session to
140
+ `.ambient`, so the silent switch mutes the game and the person's own music keeps playing.
141
+
142
+ ## Saves
143
+
144
+ Scores, progress and settings are kept on the device, and only ever added to: a new field gets a default where it's
145
+ read, so an update never loses a player's progress. Web: `save(name, value)` and `load(name)` from lamp-game.js.
146
+ Swift: LampStore.
147
+
148
+ ## Changes while it's played
149
+
150
+ Lamp puts each change into the game while the person plays it (Web: lamp-game.js, "Changes while it's played"), so a
151
+ game is written to keep the player's place through one:
152
+
153
+ - **Everything that has to last is registered, by name, once.** That's how every new game is written, and the scaffold
154
+ starts that way. Web, with `const live = hot(import.meta)` from lamp-game.js:
155
+
156
+ ```js
157
+ const renderer = live.renderer(() => new THREE.WebGLRenderer({ antialias: true }));
158
+ const camera = live.camera('main', () => {
159
+ const c = new THREE.PerspectiveCamera(60, 16 / 9, 0.1, 500);
160
+ c.position.set(0, 4, 12); // its starting pose and lens are made here, and nowhere else
161
+ return c;
162
+ }, { target: () => controls.target });
163
+ const play = live.state('play', {
164
+ version: 1,
165
+ start: () => ({ mode: 'opening', menu: null, level: 1, score: 0, lives: 3, player: { x: 0, z: 0, heading: 0, speed: 0 } }),
166
+ });
167
+ ```
168
+
169
+ - `live.renderer(build)`: new code gets the renderer the game has before it could make another, so there's one, with
170
+ its compiled shaders. It's made again only when `build` itself changes. An async build (the 3d-game skill's
171
+ WebGPU) is awaited.
172
+ - `live.camera(id, build, { target })`: keeps the camera's pose, lens and what it looks at (`target` gives anything
173
+ with x, y and z that new code makes again, as OrbitControls' `target`). At the first frame it's where the player
174
+ left it, whatever the start set. A change to `build` gives the new lens at the old pose.
175
+ - `live.state(id, { version, start, migrate })`: everything that says where the game is goes in one plain object,
176
+ the mode (playing, paused, a menu), which menu, overlay or card is open, the level, the player's position, heading
177
+ and speed, what they ride or hold, the score, lives, the clock, the time of day. Change its fields and never
178
+ replace it. Lamp snapshots it as plain JSON by itself, so it holds no objects of three.js or Phaser, and nothing
179
+ derived from it is kept elsewhere. A field added to `start()` takes its start value, and every other field keeps its value.
180
+ Raise `version` when a field changes its meaning, with `migrate(old, oldVersion)` to carry the old state over; with
181
+ none, that state starts over from `start()`.
182
+ - Each part of the world is kept with `live.keep` (below).
183
+
184
+ Only what's registered is kept. A renderer or camera the game's code makes for itself, or a variable of its own,
185
+ starts again with the code.
186
+ - **One start path.** Everything registered is back before `init` runs and before the first frame, at a fresh start
187
+ it's `start()`, and the same object stays the whole time. So `init` (in a 2D game, the first scene's `init` or
188
+ `create`) reads the state and builds exactly that screen: that mode, that menu or overlay open, and nothing a fresh
189
+ start shows (a title card, an intro, a tutorial prompt, a fade in) built or shown at all. Never start fresh and then
190
+ put the place back, which leaves the opening over the game and input in the opening's mode. A later restart (a new
191
+ round, a death) sets the state's fields back itself. A 2D game registers its state; Phaser's game and cameras are made
192
+ again from it.
193
+ - **A game from before this**, or one brought in, may use `snapshot()` in game() (or phaser()), plain JSON of where it
194
+ is, with `pendingRestore()` (the state while it starts, null for a fresh start and once it has started) or
195
+ `restore(state)` (called after init when it didn't read pendingRestore()). They're still taken, and a change keeps
196
+ its place through them. Without either it starts again, from its saves. When you're asked to change such a game, register what your change
197
+ touches as you make it, and leave the rest for the changes that touch it: move its renderer into `live.renderer` first, its
198
+ main camera into `live.camera`, then its state, field by field out of snapshot() into `live.state`.
199
+ - **Lamp checks and says.** With your request comes what the game hasn't registered. A change that would start play over
200
+ (no state registered, and no snapshot() it reads back) waits for the person's Reload rather than going in, and the
201
+ look names what's missing: register it in the same turn, and Reload takes both in. Those are the one change a game
202
+ needs to adopt this: after that, changes go in as it's played. After a run of the code, a look says what was kept, built again and reset,
203
+ and what isn't registered. Anything reset that you didn't mean to reset is the place the person lost: register it
204
+ now, so the next change keeps it.
205
+ - A game with phones keeps them through all of this: they stay joined with their numbers, and the code never stops or
206
+ starts `Lamp.controllers` for a change. So the state holds which player owns which slot (the seat, side, color or
207
+ team each player number has), and the new code restores those slots before it sits anyone down. As its first frame
208
+ nears, `onLeave` and `onJoin` are called again for who left and who is here, so `onJoin` for a player who already has
209
+ a slot leaves the slot alone, and only a new player takes a free one. What a phone has held down stays in
210
+ `f.phones`' `down`; a press or message from before the new code started isn't sent again and isn't in `pressed`, so
211
+ anything read while held is read from `down` (or `isHeld`), not remembered from `onButton`.
212
+ - Pictures, models, sounds and data load through the runtime (`texture()`, `model()`, `sound.load()`, `asset()`), never
213
+ by a URL of the game's own: a new copy of one of those goes into the running game with no reload. What the game makes
214
+ of a file itself (a material from shader source, clones of a model, a mixer for its animations, a level from JSON) is
215
+ made again in `assetChanged(path)`, which returns true when it has.
216
+ - Code goes into the running game too, never by opening the page again, in one of two ways, and the log says which,
217
+ what was kept and how long it took:
218
+ - **Swapped**, at once: a change to the methods of a class in a module that ends with `hot(import.meta).accept()`
219
+ from lamp-game.js. Every object the game made of that class runs the new methods with its fields kept.
220
+ - **Run again in place**, for anything else (the HTML, the module that starts the game, a class's constructor or
221
+ fields, an exported function, a new module): the page is put back as the new HTML has it, every module of the game
222
+ runs again, and the game starts straight from what it registered, as a reload would but without one. What's
223
+ registered stays: the renderer and its compiled shaders, the cameras, the state, and each part kept with
224
+ `hot(import.meta).keep(key, build, { inputs, from, background })`, and so do the files the runtime loaded, so the change costs only
225
+ what's built again, and a part built in the background costs the person nothing. The listeners,
226
+ timers, sound contexts and workers the old code started are taken away by Lamp, and so are its `Lamp.controllers`
227
+ callbacks, which the new code sets again as it starts; `dispose` in game() is for anything else it must let go of,
228
+ and never stops the phones (a `stop()` there is ignored).
229
+
230
+ So a game is written in parts, each in a module of its own:
231
+
232
+ - **The module that starts the game only puts the parts together** (`game.js`; New York's `main.js`). It registers
233
+ the renderer, the cameras and the state, and keeps each part of the world:
234
+
235
+ ```js
236
+ import { game, hot } from './lamp-game.js';
237
+ const live = hot(import.meta);
238
+ const renderer = live.renderer(() => new THREE.WebGLRenderer({ antialias: true }));
239
+ const ground = live.keep('ground', () => buildGround());
240
+ const trees = live.keep('trees', () => buildTrees(ground.heights), { inputs: [ground] });
241
+ scene.add(ground.group, trees.group);
242
+ ```
243
+
244
+ A kept part is built again only when its own module (or one it imports) changed, its build function changed, one
245
+ of its `inputs` (the parts it's built from) was built again, or a file it read as it was built changed. So build
246
+ each part of the world (the ground, the buildings, the trees and street details, the props, the traffic) in a
247
+ module of its own, into a group of its own that's added to the scene at each start, and do everything to it
248
+ (setting it on the ground, cutting it for culling) inside its build, never to a kept part afterwards. The build
249
+ function in the starting module names the module it builds from (`buildTrees`), since that's how Lamp tells which
250
+ change is its own. Declare the data each part is built from in its `from` (files beside the page, a module of
251
+ generated data, or a folder ending in /), so a change to that data builds the part again in place, with the rest
252
+ of the world and the player's place kept:
253
+
254
+ ```js
255
+ const streets = live.keep('streets', () => buildStreets(), { from: ['js/map-data.js'] });
256
+ const paint = live.keep('roadPaint', () => buildRoadPaint(streets.network), { inputs: [streets], from: ['js/map-data.js'] });
257
+ ```
258
+
259
+ A part that takes more than a frame or two to build (a city from its map data, a terrain, a road network, the
260
+ traffic on it) is built in the background with `background: true`, so a change to it never holds the game still:
261
+ the person plays on with the part they have, "Building…" shows over the game, and once the new part is built its
262
+ shaders are compiled and it swaps in, in about a frame. Until then the game's logic and the controller use the old
263
+ part, so code that reads a part works with either. Its build is either a generator that yields every few
264
+ milliseconds of work (a row of blocks, a chunk of terrain), which Lamp steps between frames, or an async function
265
+ that hands the pure data work (parsing, the arrays geometry is made from) to a worker with `work()` from
266
+ lamp-game.js and makes only the three.js objects from what comes back:
267
+
268
+ ```js
269
+ const city = live.keep('city', function* () {
270
+ const group = new THREE.Group();
271
+ for (const block of MAP.blocks) { group.add(buildBlock(block)); yield; }
272
+ return { group };
273
+ }, { from: ['js/map-data.js'], background: true });
274
+
275
+ const ground = live.keep('ground', async () => {
276
+ const { positions, normals } = await work('js/ground-worker.js', { size: MAP.size }); // posted back with their buffers as transfer
277
+ return { group: groundMesh(positions, normals) };
278
+ }, { from: ['js/elevation.js'], background: true });
279
+ ```
280
+
281
+ Data the person asked to come live from the network (today's weather, road closures, a feed) is fetched inside the
282
+ build of the part made from it, and declared in its `from` when a file stands in for it offline, never awaited on its
283
+ own in the module that starts the game: a part keeps what it fetched when the code runs again, while a fetch outside
284
+ every part is waited for again at each change, with the game standing still. The log after each run says how long
285
+ the game's own start took outside its kept parts.
286
+
287
+ The first build, as the game starts, is built whole. A part built from one being built (its `inputs`) is built
288
+ again from the new one once that's in, so parts that must change together are one part. Keep a part's three.js
289
+ objects in the value it returns (one object, or a plain object of them, as `{ group }`), so Lamp can compile them
290
+ ahead and let go of the old ones. Make a part's materials once, in a kept part of their own
291
+ (`live.keep('cityMaterials', () => makeCityMaterials())`), and build only its geometry in the background: a
292
+ material made anew is a shader to compile, which holds the frames on screen while it compiles (about a third of a
293
+ second each in WebKit), and the old part goes without taking the materials the new one still uses.
294
+
295
+ After a run, the look says which parts were built again, how long each took, which are still being built in the
296
+ background, how long the game stood still, and what of the change nothing read again, which shows only after
297
+ Reload. A look shows the person's open game as it is: a change built into a part that was kept isn't in it until
298
+ that part is built again.
299
+
300
+ A big 3D world on three.js's `WebGPURenderer` keeps its scene and lights the same way, as its camera is. For a new one of
301
+ them it works out how to draw every object again, which holds a big world still for a second at each change. Empty
302
+ the kept scene at each start (`scene.clear()`), then add back the kept lights and each part's group, so what the
303
+ last run added doesn't stay.
304
+ - **The HUD and menus are made at each start**, from the page's HTML or built in code, and their elements found
305
+ there (in init, or the function that starts the game), never once at a module's top level: the page they find is
306
+ the one the new HTML put back.
307
+ - **What changes as the person plays is a class the game makes an object of** (a vehicle and its tuning, the
308
+ player's moves, missions, enemies, the HUD's code, the camera, a shader's settings), its state in the object and
309
+ the module ending with `hot(import.meta).accept()`, so most changes are swapped:
310
+
311
+ ```js
312
+ import { hot } from '../lamp-game.js';
313
+ const CAR = { topSpeed: 36, acceleration: 4.5 }; // tuning, read where it's used
314
+ export class Car {
315
+ constructor(scene) { this.mesh = buildCar(); scene.add(this.mesh); this.speed = 0; }
316
+ update(dt, pad) { this.speed = Math.min(CAR.topSpeed, this.speed + pad.rt * CAR.acceleration * dt); … }
317
+ }
318
+ hot(import.meta).accept();
319
+ ```
320
+
321
+ Export every class a module defines and the game calls (one kept to itself keeps its old methods), read tuning
322
+ where it's used rather than copying it into fields in the constructor, and keep state in the objects, not in
323
+ variables at the module's top. An exported plain object (`export const TUNING = {…}`) takes the values a change
324
+ changed and keeps the rest. What a constructor built once stays as built through a swap: give
325
+ `accept((next, { changed }) => …)` the rebuild, or have it return false to run the code again.
326
+ **What's at a module's top level outlives it.** The page keeps every version of a module for as long as it's open,
327
+ with whatever its variables point at, so a list of objects or a memo at a module's top level holds the old run's
328
+ world, and each run of the code gets slower. Release what the module gathered in `hot(import.meta).dispose(…)`, and
329
+ have the run or the part that owns a system drop it where it's registered (the game's `dispose` for what a run made,
330
+ a part's own `dispose` for what it keeps, which stays registered while the part is kept). A kept renderer doesn't
331
+ manage what a run builds around it: every render pipeline, pass and effect made in a run gets an explicit teardown in
332
+ the game's `dispose`, the pipeline first and the scene pass it reads last, each step safe if an earlier one throws,
333
+ and never `renderer.dispose()`. A build hands on only the data a later consumer needs: one closure kept at a module's
334
+ top level holds everything the function that made it gathered. A reusable generated texture needs an explicit kept
335
+ owner and what invalidates it (a `keep` with `from`, or the kept object it's made from); a transient one needs
336
+ teardown, and not every texture at a module's top level belongs in `keep`. Keeping a compound object doesn't dispose
337
+ what's nested in it, so its `keep` takes a `dispose`, and a custom `dispose` spares what another owner still uses,
338
+ since it replaces the runtime's own. A big table that doesn't
339
+ change as it's played is built inside `keep`, with what it's read from in `from`, so a run reuses it; what changes
340
+ as it's played stays out of `keep`. Name the file's address outside the build (`const address = new URL('./x.bin',
341
+ import.meta.url)`): the runtime writes `import.meta` out differently each run, so a build that names it is built
342
+ again every time.
343
+ `hot(import.meta).dispose(data => …)` takes away what a version made at its top level, keeping in `data` what the
344
+ next version reads as `hot(import.meta).data`.
345
+
346
+ A stylesheet is swapped by itself. Where running again can't be done (a change to the import map or to a script that
347
+ isn't a module, modules that import each other in a circle) the change waits for the person's Reload, which opens the
348
+ page again from what's registered; so does new code that fails as it starts, before its first frame or in its first
349
+ second, at once. A game bundled from TypeScript is one
350
+ file, so its changes run it again, and what it keeps is built again with each change.
351
+ - `busy()` is true while a match, race or round is on: a change that runs the code again then waits for the next
352
+ pause, and the person can put it in at once with Reload. A swap goes in at once.
353
+ - On a phone, Android, a TV or the Xbox a change arrives when Lamp installs the game again, and the runtime puts what's
354
+ registered back then, once, as it does the last snapshot.
355
+
356
+ Swift: a change reopens the app; what it keeps is what it saved.
357
+
358
+ ## Keeping every frame smooth
359
+
360
+ A frame has about 16 ms, and anything that runs during play takes from it, so a slow piece is a stutter:
361
+
362
+ - load each picture, model and sound once and reuse it; prepare a level before it starts;
363
+ - reuse what comes and goes (bullets, enemies, particles) rather than making new ones each time;
364
+ - allocate nothing per frame, and keep per-frame work to what moves;
365
+ - many copies of one thing are one draw (THREE.InstancedMesh, `LampScene.copies` in a Mac-only app).
366
+
367
+ The request's device line names the slowest device the game is played on and its budget; the log says how frames kept
368
+ to time. When frames are late, draw less.
369
+
370
+ ## The look
371
+
372
+ Sprites, characters and backgrounds are art from `make_art` or one ready-made pack (the assets skill), all in one
373
+ style, on a transparent background where they move. Shapes and colors made in code, well lit, look better than
374
+ mismatched models. Score, pause and menus are large and easy to read, over the game (SwiftUI over a SpriteView; HTML
375
+ over the canvas in a page), and made for its world: the game-ui skill says how to choose the screens a game needs and
376
+ give them its theme.
377
+
378
+ After changing anything that moves, look_at_app with `motion` shows what changes frame to frame and catches flicker a
379
+ single picture hides.
380
+
381
+ ## Playtesting
382
+
383
+ `use_app` plays the game in front of the person, so play it only when they ask you to try, play or test it; then play it
384
+ the way they would, since a game that only looks right isn't done. For a request to change it, build and look, and say
385
+ in your report what you didn't play rather than calling it checked. On Lamp's game runtime, `use_app` plays the game in its window on this Mac, the one the person has open, with Lamp's own controller (`stick`,
386
+ `button` and `wait`), in plain sight and from wherever the game is: a menu, a pause screen, the middle of a level. A
387
+ button or field the game's page shows (a menu, a mode switch, a name) is used with `click`, `double_click` or `type` by
388
+ its id from the screen as text; `key` isn't taken there, so what a key does in play is a `button` or a `stick`. A click
389
+ is only sent: the next picture and the log say whether the game took it. Read
390
+ the last picture first and get to what you mean to check; to begin again, look with `reopen` (which asks the person
391
+ first while they play). Play a whole round: start, learn the controls, score, get hit, lose, win, pause. Ask of each
392
+ stretch whether it's fun: is there always something to do, does each action answer, is it too easy or too hard, does
393
+ anything surprise. Fix what isn't, and play it again.
394
+
395
+ A fix goes into the open game as you save it (or with a look), so play on after one with `use_app`; nothing replays the
396
+ moves before it, and the game's random numbers differ each time, so play to the same place again rather than expecting
397
+ the same frames. The person playing takes the game back at once: then use_app is off until their next message.
398
+
399
+ A C++ game (played on the Xbox), SpriteKit in a Swift app and a page with a loop of its own take no controller from Lamp:
400
+ `use_app` there acts as that place takes it, where the person sees it, so it waits for them to ask. Without that, keep to
401
+ what `look_at_app` shows, and say what you didn't play rather than calling it checked.
402
+
403
+ ## A game and the project's other apps
404
+
405
+ When the person wants an app to become a game ("actually, make it a game"), change its code in place: the same app,
406
+ now played. If they might want both (the app they use and a game beside it), ask once whether to keep the app as well
407
+ or replace it. Turning it into a game is a change to that app: `make_app_for` with its folder in `app` and `kind`
408
+ "game" (made as the table's defaults say unless the person names a make: web wherever Lamp has a host for a page),
409
+ keeping its folder and data, and its code changed into a
410
+ game. A game beside
411
+ the app is one more app, only when they say they want both and the game is of another kind than the app:
412
+ `make_app_for` with `another` and `kind` "game", in a folder of its own, once they chose that when you asked. Two apps
413
+ of one kind can't be in one project yet (the `more-apps` skill), and a game is never made web only to get around that. A
414
+ game that becomes an app again is the same in reverse.
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: game-3d
3
+ description: For a web game at home on the Mac that's drawn in 3D (a world with depth, a camera that moves through or around it, models and light) - three.js on Lamp's game runtime, models, light and materials, and what costs the most. Choose it by how the game is drawn, not by the word 3D. Not for a flat game with depth effects. Things that move as bodies are game-physics.
4
+ sections: 3d-game#; 3d-game#A game on Lamp's runtime; 3d-game#Models, light and materials; 3d-game#What costs the most
5
+ ---
6
+
7
+ # A web game in 3D on the Mac
8
+
9
+ The web-game guide and game-feel hold for a game in 3D as for one in 2D; this is how it draws. Where it names Physics,
10
+ that's the game-physics skill.
11
+
12
+ {{sections}}
@@ -0,0 +1,11 @@
1
+ ---
2
+ name: game-art
3
+ description: For a web game at home on the Mac whose look is part of what's asked - a style the person named (pixel art, hand-drawn, neon, cozy), a game that's mostly its look, or drawn art beyond shapes - authored screens and titles, a theme carried into how screens are built, and drawing the art. Not for every game: the guide's How it looks and game-feel's feedback are the baseline.
4
+ sections: game-ui#Authored, not defaulted; game-ui#Theme in the composition; 2d-game#Drawing the art; 2d-game#Pixel art or smooth
5
+ ---
6
+
7
+ # A look that's this game's own
8
+
9
+ The web-game guide and game-feel hold; this is for when the look itself is asked for.
10
+
11
+ {{sections}}
@@ -0,0 +1,13 @@
1
+ ---
2
+ name: game-feel
3
+ description: What makes a web game at home on the Mac good to play, beside the web-game guide's runtime rules - fun and feedback, sound, saves that never lose progress, a flow that starts and restarts cleanly, a finished look, and teaching in play. Playing it, checking it and judging it are the game-playtest skill's, when the person asks. Lamp hands it over with the guide when the game is made; open it in a later conversation before changing how the game plays, teaches or looks.
4
+ sections: game#Fun; game#Sound; game#Saves; game-ui#What every flow keeps; game-ui#A finished look; game-ui#Teaching and input; game-ui#Feedback and layout
5
+ ---
6
+
7
+ # What makes the game good to play
8
+
9
+ The web-game guide says how the game runs on Lamp's runtime; this says what makes it worth playing, and every game
10
+ needs it. Where the two touch the runtime (files, input, how sound loads), the guide holds. A section below that points
11
+ to the game or game-ui skill means the part that's here; open another skill only when the guide says the game needs it.
12
+
13
+ {{sections}}
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: game-levels
3
+ description: For a web game at home on the Mac with more than one round to it - levels, stages or worlds, unlocks and a level select, a menu that's a place to walk through, a story, a pause menu with options - choosing the flow before drawing the screens. Not for one round with a score: title, play and results are the guide's flow, and game-feel keeps what every flow needs.
4
+ sections: game-ui#A short brief; game-ui#Pick the flow first; game-ui#A menu that's a place, where it suits
5
+ ---
6
+
7
+ # Levels and the screens between them
8
+
9
+ The web-game guide and game-feel hold; this is for a game whose rounds add up to more. Saves that keep each unlocked
10
+ level are game-feel's Saves.
11
+
12
+ {{sections}}
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: game-live
3
+ description: For a web game at home on the Mac that's open while you change it, when the change is structural - new or split modules, a world that streams in parts, what has to last moved or renamed, or a change that won't go in, needs Reload or loses the player's place. Not for a color, a number, text or a tweak to how something moves: those go in as they are, with the guide's rules for keeping the player's place.
4
+ sections: game#Changes while it's played
5
+ ---
6
+
7
+ # Structural changes to a game that's open
8
+
9
+ The web-game guide's "Keeping the player's place" is what every change keeps; this is the whole of how changes go into
10
+ a running game, for the ones that move its structure.
11
+
12
+ {{sections}}
@@ -0,0 +1,13 @@
1
+ ---
2
+ name: game-physics
3
+ description: For a web game at home on the Mac whose fun is things behaving as bodies - they fall, roll, stack, topple, bounce off each other, ride on wheels, swing on joints, or a board tilts under them - with Rapier in 3D, or Phaser's Matter in a flat game. Choose it by the mechanics, not the words: a car that drives on its wheels needs it, stars that fall to be caught don't. Not for steering, simple gravity or checking what touches what: the guide's setup does those.
4
+ sections: 3d-game#Physics
5
+ ---
6
+
7
+ # Things that behave like things
8
+
9
+ The web-game guide and game-feel hold; this is the physics a game of bodies needs, with Rapier, which Lamp ships for a
10
+ game drawn in 3D. A flat game whose things must tumble, stack or swing on joints uses Phaser's Matter instead
11
+ (`physics: { default: 'matter' }` to `phaser()`), with the same reasons for when it's worth it.
12
+
13
+ {{sections}}
@@ -0,0 +1,26 @@
1
+ ---
2
+ name: game-playtest
3
+ description: For a web game at home on the Mac, only when the person asks to play it, test it, check that it works or judge how it looks - playing a round in its window, seeing the real opening, proving a flow and its screens, and one short critique. Open it then, and do only what was asked. Never for a request that only changes the game.
4
+ sections: game#Playtesting; game-ui#Check the real opening; game-ui#Proof; 3d-game#Checking it
5
+ ---
6
+
7
+ # Playing and checking the game, when asked
8
+
9
+ Lamp builds this game and opens it at the end of every turn, and says whether its window drew. Playing it, looking at
10
+ it and judging it happen only when the person asks, and only as far as they asked:
11
+
12
+ - **Play it, test it, check it works:** one `use_app` round as the person would play it: start, steer both ways,
13
+ take a hit, wait out the round to the results, press A to restart. Fix what fails and play that part again.
14
+ - **How it looks:** one `look_at_app` (with `reopen` for the opening, `motion` for what moves), without playing a
15
+ round. It's the game's window as the person has it; how it fits a smaller window is checked by reading its layout
16
+ against the stage's (the web-game guide).
17
+ - **Check the code:** read it, without opening or playing the game.
18
+ - **A critique:** look at the opening, a moment of play and the results in the pictures you already have, against
19
+ what the person asked for. Name at most one thing a player would trip on or that reads as a template, and fix it,
20
+ or say nothing is worth changing. A screen that works isn't restyled for this.
21
+
22
+ A request to check once doesn't reach later changes: the next change is written and finished as the guide says. The
23
+ sections below hold for this game only inside what the person asked; where one says "before you finish", read "when
24
+ asked". Say what you didn't try.
25
+
26
+ {{sections}}