@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.
- package/LICENSE +21 -0
- package/README.md +397 -2
- package/Resources/Devices/roku.json +410 -0
- package/Resources/Devices/xbox-one.json +367 -0
- package/Resources/GameKit/NOTICE.md +63 -0
- package/Resources/GameKit/apple/LampPage.swift +1813 -0
- package/Resources/GameKit/apple/LampPlayer.swift +46 -0
- package/Resources/GameKit/apple/LampWebApp.swift +63 -0
- package/Resources/GameKit/apple/LampWebGame.swift +87 -0
- package/Resources/GameKit/apple/Native.swift +12 -0
- package/Resources/GameKit/build.sh +55 -0
- package/Resources/GameKit/lamp_game.h +116 -0
- package/Resources/GameKit/lamp_host.h +19 -0
- package/Resources/GameKit/lamp_kit.cpp +61 -0
- package/Resources/GameKit/lamp_sound.cpp +455 -0
- package/Resources/GameKit/lamp_xbox.cpp +374 -0
- package/Resources/GameKit/libraries/HandmadeMath.h +3940 -0
- package/Resources/GameKit/libraries/cgltf.h +7240 -0
- package/Resources/GameKit/libraries/dr_mp3.h +5430 -0
- package/Resources/GameKit/libraries/dr_wav.h +9209 -0
- package/Resources/GameKit/libraries/sokol_debugtext.h +4754 -0
- package/Resources/GameKit/libraries/sokol_gfx.h +29558 -0
- package/Resources/GameKit/libraries/sokol_gl.h +4538 -0
- package/Resources/GameKit/libraries/sokol_log.h +335 -0
- package/Resources/GameKit/libraries/sokol_shape.h +1531 -0
- package/Resources/GameKit/libraries/stb_image.h +7988 -0
- package/Resources/GameKit/libraries/stb_vorbis.c +5584 -0
- package/Resources/GameKit/page/lamp-live.js +672 -0
- package/Resources/GameKit/scaffold/Game/game.cpp +142 -0
- package/Resources/GameKit/scaffold/Game/scene.glsl +49 -0
- package/Resources/GameKit/scaffold-web/Web/game.js +31 -0
- package/Resources/GameKit/scaffold-web/Web/index.html +13 -0
- package/Resources/GameKit/scaffold-web/Web/making.js +33 -0
- package/Resources/GameKit/scaffold-web/Web/world.js +33 -0
- package/Resources/GameKit/web/lamp-game.js +3042 -0
- package/Resources/GameKit/web/lamp-phaser.js +128 -0
- package/Resources/WebHost/App.exe +0 -0
- package/Resources/WebHost/Microsoft.Web.WebView2.Core.dll +0 -0
- package/Resources/WebHost/WebView2-LICENSE.txt +27 -0
- package/Resources/WebHost/lamp_controllers.h +1506 -0
- package/Resources/WebHost/lamp_web_host.cpp +1173 -0
- package/Resources/WebLibraries/earlier.txt +318 -0
- package/Resources/WebLibraries/phaser/LICENSE.md +20 -0
- package/Resources/WebLibraries/phaser/NOTICE.md +2 -0
- package/Resources/WebLibraries/phaser/phaser.esm.min.js +1 -0
- package/Resources/WebLibraries/qrcode/LICENSE +21 -0
- package/Resources/WebLibraries/qrcode/NOTICE.md +4 -0
- package/Resources/WebLibraries/qrcode/qrcode.js +2297 -0
- package/Resources/WebLibraries/rapier/LICENSE +201 -0
- package/Resources/WebLibraries/rapier/NOTICE.md +3 -0
- package/Resources/WebLibraries/rapier/rapier.js +2 -0
- package/Resources/WebLibraries/three/LICENSE +21 -0
- package/Resources/WebLibraries/three/NOTICE.md +4 -0
- package/Resources/WebLibraries/three/addons/animation/AnimationClipCreator.js +168 -0
- package/Resources/WebLibraries/three/addons/animation/CCDIKSolver.js +607 -0
- package/Resources/WebLibraries/three/addons/controls/ArcballControls.js +3543 -0
- package/Resources/WebLibraries/three/addons/controls/DragControls.js +452 -0
- package/Resources/WebLibraries/three/addons/controls/FirstPersonControls.js +512 -0
- package/Resources/WebLibraries/three/addons/controls/FlyControls.js +384 -0
- package/Resources/WebLibraries/three/addons/controls/MapControls.js +116 -0
- package/Resources/WebLibraries/three/addons/controls/OrbitControls.js +1985 -0
- package/Resources/WebLibraries/three/addons/controls/PointerLockControls.js +264 -0
- package/Resources/WebLibraries/three/addons/controls/TrackballControls.js +1106 -0
- package/Resources/WebLibraries/three/addons/controls/TransformControls.js +2003 -0
- package/Resources/WebLibraries/three/addons/curves/CurveExtras.js +694 -0
- package/Resources/WebLibraries/three/addons/curves/NURBSCurve.js +169 -0
- package/Resources/WebLibraries/three/addons/curves/NURBSSurface.js +98 -0
- package/Resources/WebLibraries/three/addons/curves/NURBSUtils.js +532 -0
- package/Resources/WebLibraries/three/addons/curves/NURBSVolume.js +82 -0
- package/Resources/WebLibraries/three/addons/effects/AnaglyphEffect.js +274 -0
- package/Resources/WebLibraries/three/addons/effects/AsciiEffect.js +323 -0
- package/Resources/WebLibraries/three/addons/effects/OutlineEffect.js +489 -0
- package/Resources/WebLibraries/three/addons/effects/ParallaxBarrierEffect.js +155 -0
- package/Resources/WebLibraries/three/addons/effects/StereoEffect.js +91 -0
- package/Resources/WebLibraries/three/addons/environments/ColorEnvironment.js +59 -0
- package/Resources/WebLibraries/three/addons/environments/DebugEnvironment.js +102 -0
- package/Resources/WebLibraries/three/addons/environments/RoomEnvironment.js +185 -0
- package/Resources/WebLibraries/three/addons/geometries/BoxLineGeometry.js +92 -0
- package/Resources/WebLibraries/three/addons/geometries/ConvexGeometry.js +72 -0
- package/Resources/WebLibraries/three/addons/geometries/DecalGeometry.js +420 -0
- package/Resources/WebLibraries/three/addons/geometries/LoftGeometry.js +355 -0
- package/Resources/WebLibraries/three/addons/geometries/ParametricFunctions.js +100 -0
- package/Resources/WebLibraries/three/addons/geometries/ParametricGeometry.js +172 -0
- package/Resources/WebLibraries/three/addons/geometries/RoundedBoxGeometry.js +216 -0
- package/Resources/WebLibraries/three/addons/geometries/TeapotGeometry.js +689 -0
- package/Resources/WebLibraries/three/addons/geometries/TextGeometry.js +102 -0
- package/Resources/WebLibraries/three/addons/helpers/AnimationPathHelper.js +302 -0
- package/Resources/WebLibraries/three/addons/helpers/LightProbeGridHelper.js +166 -0
- package/Resources/WebLibraries/three/addons/helpers/LightProbeGridHelperWebGL.js +221 -0
- package/Resources/WebLibraries/three/addons/helpers/LightProbeHelper.js +166 -0
- package/Resources/WebLibraries/three/addons/helpers/LightProbeHelperGPU.js +102 -0
- package/Resources/WebLibraries/three/addons/helpers/OctreeHelper.js +109 -0
- package/Resources/WebLibraries/three/addons/helpers/PositionalAudioHelper.js +169 -0
- package/Resources/WebLibraries/three/addons/helpers/RapierHelper.js +59 -0
- package/Resources/WebLibraries/three/addons/helpers/RectAreaLightHelper.js +118 -0
- package/Resources/WebLibraries/three/addons/helpers/TextureHelper.js +265 -0
- package/Resources/WebLibraries/three/addons/helpers/TextureHelperGPU.js +214 -0
- package/Resources/WebLibraries/three/addons/helpers/VertexNormalsHelper.js +155 -0
- package/Resources/WebLibraries/three/addons/helpers/VertexTangentsHelper.js +133 -0
- package/Resources/WebLibraries/three/addons/helpers/ViewHelper.js +529 -0
- package/Resources/WebLibraries/three/addons/interactive/HTMLMesh.js +617 -0
- package/Resources/WebLibraries/three/addons/interactive/InteractiveGroup.js +224 -0
- package/Resources/WebLibraries/three/addons/interactive/SelectionBox.js +324 -0
- package/Resources/WebLibraries/three/addons/interactive/SelectionHelper.js +150 -0
- package/Resources/WebLibraries/three/addons/libs/fflate.module.js +2699 -0
- package/Resources/WebLibraries/three/addons/libs/lil-gui.module.min.js +8 -0
- package/Resources/WebLibraries/three/addons/libs/meshopt_decoder.module.js +196 -0
- package/Resources/WebLibraries/three/addons/libs/potpack.module.js +125 -0
- package/Resources/WebLibraries/three/addons/libs/stats.module.js +167 -0
- package/Resources/WebLibraries/three/addons/libs/tween.module.js +876 -0
- package/Resources/WebLibraries/three/addons/lighting/ClusteredLighting.js +153 -0
- package/Resources/WebLibraries/three/addons/lighting/DynamicLighting.js +82 -0
- package/Resources/WebLibraries/three/addons/lighting/LightMapper.js +295 -0
- package/Resources/WebLibraries/three/addons/lighting/LightProbeGrid.js +923 -0
- package/Resources/WebLibraries/three/addons/lighting/LightProbeGridUtils.js +107 -0
- package/Resources/WebLibraries/three/addons/lighting/LightProbeGridWebGL.js +846 -0
- package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIConeTracer.js +243 -0
- package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIIrradiance.js +43 -0
- package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGINode.js +617 -0
- package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGISceneCollector.js +793 -0
- package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIVolume.js +1440 -0
- package/Resources/WebLibraries/three/addons/lights/LightProbeGenerator.js +337 -0
- package/Resources/WebLibraries/three/addons/lights/RectAreaLightTexturesLib.js +127 -0
- package/Resources/WebLibraries/three/addons/lights/RectAreaLightUniformsLib.js +40 -0
- package/Resources/WebLibraries/three/addons/lights/SunLight.js +100 -0
- package/Resources/WebLibraries/three/addons/lights/SunLightNode.js +56 -0
- package/Resources/WebLibraries/three/addons/lights/SunLightShadow.js +319 -0
- package/Resources/WebLibraries/three/addons/lights/SunShadowNode.js +312 -0
- package/Resources/WebLibraries/three/addons/lines/Line2.js +56 -0
- package/Resources/WebLibraries/three/addons/lines/LineGeometry.js +157 -0
- package/Resources/WebLibraries/three/addons/lines/LineMaterial.js +742 -0
- package/Resources/WebLibraries/three/addons/lines/LineSegments2.js +434 -0
- package/Resources/WebLibraries/three/addons/lines/LineSegmentsGeometry.js +298 -0
- package/Resources/WebLibraries/three/addons/lines/Wireframe.js +108 -0
- package/Resources/WebLibraries/three/addons/lines/WireframeGeometry2.js +49 -0
- package/Resources/WebLibraries/three/addons/lines/webgpu/Line2.js +46 -0
- package/Resources/WebLibraries/three/addons/lines/webgpu/LineSegments2.js +419 -0
- package/Resources/WebLibraries/three/addons/lines/webgpu/Wireframe.js +86 -0
- package/Resources/WebLibraries/three/addons/loaders/EXRLoader.js +3411 -0
- package/Resources/WebLibraries/three/addons/loaders/FBXLoader.js +4660 -0
- package/Resources/WebLibraries/three/addons/loaders/FontLoader.js +262 -0
- package/Resources/WebLibraries/three/addons/loaders/GLTFLoader.js +5006 -0
- package/Resources/WebLibraries/three/addons/loaders/HDRLoader.js +463 -0
- package/Resources/WebLibraries/three/addons/loaders/MTLLoader.js +601 -0
- package/Resources/WebLibraries/three/addons/loaders/OBJLoader.js +961 -0
- package/Resources/WebLibraries/three/addons/loaders/PLYLoader.js +992 -0
- package/Resources/WebLibraries/three/addons/loaders/RGBELoader.js +18 -0
- package/Resources/WebLibraries/three/addons/loaders/STLLoader.js +423 -0
- package/Resources/WebLibraries/three/addons/loaders/SVGLoader.js +3297 -0
- package/Resources/WebLibraries/three/addons/loaders/TGALoader.js +539 -0
- package/Resources/WebLibraries/three/addons/loaders/UltraHDRLoader.js +757 -0
- package/Resources/WebLibraries/three/addons/math/Capsule.js +159 -0
- package/Resources/WebLibraries/three/addons/math/ColorConverter.js +62 -0
- package/Resources/WebLibraries/three/addons/math/ColorSpaces.js +147 -0
- package/Resources/WebLibraries/three/addons/math/ConvexHull.js +1695 -0
- package/Resources/WebLibraries/three/addons/math/ImprovedNoise.js +88 -0
- package/Resources/WebLibraries/three/addons/math/Lut.js +317 -0
- package/Resources/WebLibraries/three/addons/math/MeshSurfaceSampler.js +315 -0
- package/Resources/WebLibraries/three/addons/math/OBB.js +535 -0
- package/Resources/WebLibraries/three/addons/math/Octree.js +825 -0
- package/Resources/WebLibraries/three/addons/math/SimplexNoise.js +470 -0
- package/Resources/WebLibraries/three/addons/misc/ConvexObjectBreaker.js +539 -0
- package/Resources/WebLibraries/three/addons/misc/GPUComputationRenderer.js +508 -0
- package/Resources/WebLibraries/three/addons/misc/Gyroscope.js +78 -0
- package/Resources/WebLibraries/three/addons/misc/MorphAnimMesh.js +119 -0
- package/Resources/WebLibraries/three/addons/misc/MorphBlendMesh.js +425 -0
- package/Resources/WebLibraries/three/addons/misc/ProgressiveLightMap.js +370 -0
- package/Resources/WebLibraries/three/addons/misc/ProgressiveLightMapGPU.js +322 -0
- package/Resources/WebLibraries/three/addons/misc/RollerCoaster.js +661 -0
- package/Resources/WebLibraries/three/addons/misc/Sculptor.js +1679 -0
- package/Resources/WebLibraries/three/addons/misc/SculptorMesh.js +1504 -0
- package/Resources/WebLibraries/three/addons/misc/SculptorTools.js +1180 -0
- package/Resources/WebLibraries/three/addons/misc/SculptorUtils.js +345 -0
- package/Resources/WebLibraries/three/addons/misc/TileCreasedNormalsPlugin.js +270 -0
- package/Resources/WebLibraries/three/addons/misc/TubePainter.js +611 -0
- package/Resources/WebLibraries/three/addons/misc/Volume.js +520 -0
- package/Resources/WebLibraries/three/addons/misc/VolumeSlice.js +275 -0
- package/Resources/WebLibraries/three/addons/modifiers/CurveModifier.js +374 -0
- package/Resources/WebLibraries/three/addons/modifiers/CurveModifierGPU.js +256 -0
- package/Resources/WebLibraries/three/addons/modifiers/EdgeSplitModifier.js +299 -0
- package/Resources/WebLibraries/three/addons/modifiers/TessellateModifier.js +340 -0
- package/Resources/WebLibraries/three/addons/objects/GroundedSkybox.js +69 -0
- package/Resources/WebLibraries/three/addons/objects/Lensflare.js +489 -0
- package/Resources/WebLibraries/three/addons/objects/LensflareMesh.js +376 -0
- package/Resources/WebLibraries/three/addons/objects/MarchingCubes.js +1261 -0
- package/Resources/WebLibraries/three/addons/objects/Reflector.js +390 -0
- package/Resources/WebLibraries/three/addons/objects/ReflectorForSSRPass.js +393 -0
- package/Resources/WebLibraries/three/addons/objects/Refractor.js +389 -0
- package/Resources/WebLibraries/three/addons/objects/ShadowMesh.js +130 -0
- package/Resources/WebLibraries/three/addons/objects/Sky.js +342 -0
- package/Resources/WebLibraries/three/addons/objects/SkyMesh.js +403 -0
- package/Resources/WebLibraries/three/addons/objects/Water.js +374 -0
- package/Resources/WebLibraries/three/addons/objects/Water2.js +403 -0
- package/Resources/WebLibraries/three/addons/objects/Water2Mesh.js +199 -0
- package/Resources/WebLibraries/three/addons/objects/WaterMesh.js +194 -0
- package/Resources/WebLibraries/three/addons/postprocessing/AfterimagePass.js +187 -0
- package/Resources/WebLibraries/three/addons/postprocessing/BloomPass.js +274 -0
- package/Resources/WebLibraries/three/addons/postprocessing/BokehPass.js +218 -0
- package/Resources/WebLibraries/three/addons/postprocessing/ClearPass.js +97 -0
- package/Resources/WebLibraries/three/addons/postprocessing/CubeTexturePass.js +146 -0
- package/Resources/WebLibraries/three/addons/postprocessing/DotScreenPass.js +114 -0
- package/Resources/WebLibraries/three/addons/postprocessing/EffectComposer.js +365 -0
- package/Resources/WebLibraries/three/addons/postprocessing/FXAAPass.js +40 -0
- package/Resources/WebLibraries/three/addons/postprocessing/FilmPass.js +113 -0
- package/Resources/WebLibraries/three/addons/postprocessing/GTAOPass.js +735 -0
- package/Resources/WebLibraries/three/addons/postprocessing/GlitchPass.js +177 -0
- package/Resources/WebLibraries/three/addons/postprocessing/HalftonePass.js +134 -0
- package/Resources/WebLibraries/three/addons/postprocessing/LUTPass.js +138 -0
- package/Resources/WebLibraries/three/addons/postprocessing/MaskPass.js +195 -0
- package/Resources/WebLibraries/three/addons/postprocessing/OutlinePass.js +776 -0
- package/Resources/WebLibraries/three/addons/postprocessing/OutputPass.js +148 -0
- package/Resources/WebLibraries/three/addons/postprocessing/Pass.js +191 -0
- package/Resources/WebLibraries/three/addons/postprocessing/RenderPass.js +193 -0
- package/Resources/WebLibraries/three/addons/postprocessing/RenderPixelatedPass.js +314 -0
- package/Resources/WebLibraries/three/addons/postprocessing/RenderTransitionPass.js +267 -0
- package/Resources/WebLibraries/three/addons/postprocessing/SAOPass.js +407 -0
- package/Resources/WebLibraries/three/addons/postprocessing/SMAAPass.js +230 -0
- package/Resources/WebLibraries/three/addons/postprocessing/SSAARenderPass.js +313 -0
- package/Resources/WebLibraries/three/addons/postprocessing/SSAOPass.js +527 -0
- package/Resources/WebLibraries/three/addons/postprocessing/SSRPass.js +858 -0
- package/Resources/WebLibraries/three/addons/postprocessing/SavePass.js +132 -0
- package/Resources/WebLibraries/three/addons/postprocessing/ShaderPass.js +135 -0
- package/Resources/WebLibraries/three/addons/postprocessing/TAARenderPass.js +243 -0
- package/Resources/WebLibraries/three/addons/postprocessing/TexturePass.js +131 -0
- package/Resources/WebLibraries/three/addons/postprocessing/UnrealBloomPass.js +541 -0
- package/Resources/WebLibraries/three/addons/shaders/ACESFilmicToneMappingShader.js +96 -0
- package/Resources/WebLibraries/three/addons/shaders/AfterimageShader.js +63 -0
- package/Resources/WebLibraries/three/addons/shaders/BasicShader.js +36 -0
- package/Resources/WebLibraries/three/addons/shaders/BleachBypassShader.js +68 -0
- package/Resources/WebLibraries/three/addons/shaders/BlendShader.js +56 -0
- package/Resources/WebLibraries/three/addons/shaders/BokehShader.js +151 -0
- package/Resources/WebLibraries/three/addons/shaders/BokehShader2.js +404 -0
- package/Resources/WebLibraries/three/addons/shaders/BrightnessContrastShader.js +62 -0
- package/Resources/WebLibraries/three/addons/shaders/ColorCorrectionShader.js +59 -0
- package/Resources/WebLibraries/three/addons/shaders/ColorifyShader.js +57 -0
- package/Resources/WebLibraries/three/addons/shaders/ConvolutionShader.js +74 -0
- package/Resources/WebLibraries/three/addons/shaders/CopyShader.js +52 -0
- package/Resources/WebLibraries/three/addons/shaders/DOFMipMapShader.js +63 -0
- package/Resources/WebLibraries/three/addons/shaders/DepthLimitedBlurShader.js +183 -0
- package/Resources/WebLibraries/three/addons/shaders/DigitalGlitch.js +104 -0
- package/Resources/WebLibraries/three/addons/shaders/DotScreenShader.js +75 -0
- package/Resources/WebLibraries/three/addons/shaders/ExposureShader.js +51 -0
- package/Resources/WebLibraries/three/addons/shaders/FXAAShader.js +298 -0
- package/Resources/WebLibraries/three/addons/shaders/FilmShader.js +73 -0
- package/Resources/WebLibraries/three/addons/shaders/FocusShader.js +94 -0
- package/Resources/WebLibraries/three/addons/shaders/FreiChenShader.js +103 -0
- package/Resources/WebLibraries/three/addons/shaders/GTAOShader.js +437 -0
- package/Resources/WebLibraries/three/addons/shaders/GammaCorrectionShader.js +52 -0
- package/Resources/WebLibraries/three/addons/shaders/HalftoneShader.js +332 -0
- package/Resources/WebLibraries/three/addons/shaders/HorizontalBlurShader.js +68 -0
- package/Resources/WebLibraries/three/addons/shaders/HorizontalTiltShiftShader.js +70 -0
- package/Resources/WebLibraries/three/addons/shaders/HueSaturationShader.js +74 -0
- package/Resources/WebLibraries/three/addons/shaders/KaleidoShader.js +65 -0
- package/Resources/WebLibraries/three/addons/shaders/LuminosityHighPassShader.js +68 -0
- package/Resources/WebLibraries/three/addons/shaders/LuminosityShader.js +54 -0
- package/Resources/WebLibraries/three/addons/shaders/MirrorShader.js +62 -0
- package/Resources/WebLibraries/three/addons/shaders/NormalMapShader.js +60 -0
- package/Resources/WebLibraries/three/addons/shaders/OutputShader.js +103 -0
- package/Resources/WebLibraries/three/addons/shaders/PoissonDenoiseShader.js +230 -0
- package/Resources/WebLibraries/three/addons/shaders/RGBShiftShader.js +61 -0
- package/Resources/WebLibraries/three/addons/shaders/SAOShader.js +201 -0
- package/Resources/WebLibraries/three/addons/shaders/SMAAShader.js +489 -0
- package/Resources/WebLibraries/three/addons/shaders/SSAOShader.js +331 -0
- package/Resources/WebLibraries/three/addons/shaders/SSRShader.js +396 -0
- package/Resources/WebLibraries/three/addons/shaders/SepiaShader.js +57 -0
- package/Resources/WebLibraries/three/addons/shaders/SobelOperatorShader.js +98 -0
- package/Resources/WebLibraries/three/addons/shaders/SubsurfaceScatteringShader.js +95 -0
- package/Resources/WebLibraries/three/addons/shaders/TechnicolorShader.js +51 -0
- package/Resources/WebLibraries/three/addons/shaders/ToonShader.js +349 -0
- package/Resources/WebLibraries/three/addons/shaders/TriangleBlurShader.js +79 -0
- package/Resources/WebLibraries/three/addons/shaders/UnpackDepthRGBAShader.js +60 -0
- package/Resources/WebLibraries/three/addons/shaders/VelocityShader.js +137 -0
- package/Resources/WebLibraries/three/addons/shaders/VerticalBlurShader.js +66 -0
- package/Resources/WebLibraries/three/addons/shaders/VerticalTiltShiftShader.js +70 -0
- package/Resources/WebLibraries/three/addons/shaders/VignetteShader.js +56 -0
- package/Resources/WebLibraries/three/addons/shaders/VolumeShader.js +285 -0
- package/Resources/WebLibraries/three/addons/shaders/WaterRefractionShader.js +106 -0
- package/Resources/WebLibraries/three/addons/textures/FlakesTexture.js +54 -0
- package/Resources/WebLibraries/three/addons/tsl/WebGLNodesHandler.js +607 -0
- package/Resources/WebLibraries/three/addons/tsl/display/AfterImageNode.js +256 -0
- package/Resources/WebLibraries/three/addons/tsl/display/AnaglyphPassNode.js +550 -0
- package/Resources/WebLibraries/three/addons/tsl/display/BilateralBlurNode.js +377 -0
- package/Resources/WebLibraries/three/addons/tsl/display/BleachBypass.js +33 -0
- package/Resources/WebLibraries/three/addons/tsl/display/BloomNode.js +599 -0
- package/Resources/WebLibraries/three/addons/tsl/display/CRT.js +150 -0
- package/Resources/WebLibraries/three/addons/tsl/display/ChromaticAberrationNode.js +163 -0
- package/Resources/WebLibraries/three/addons/tsl/display/DenoiseNode.js +354 -0
- package/Resources/WebLibraries/three/addons/tsl/display/DepthOfFieldNode.js +572 -0
- package/Resources/WebLibraries/three/addons/tsl/display/DotScreenNode.js +104 -0
- package/Resources/WebLibraries/three/addons/tsl/display/FSR1Node.js +481 -0
- package/Resources/WebLibraries/three/addons/tsl/display/FXAANode.js +357 -0
- package/Resources/WebLibraries/three/addons/tsl/display/FilmNode.js +101 -0
- package/Resources/WebLibraries/three/addons/tsl/display/GTAONode.js +727 -0
- package/Resources/WebLibraries/three/addons/tsl/display/GaussianBlurNode.js +412 -0
- package/Resources/WebLibraries/three/addons/tsl/display/GodraysNode.js +604 -0
- package/Resources/WebLibraries/three/addons/tsl/display/ImportanceSampledEnvironment.js +564 -0
- package/Resources/WebLibraries/three/addons/tsl/display/LensflareNode.js +282 -0
- package/Resources/WebLibraries/three/addons/tsl/display/Lut3DNode.js +109 -0
- package/Resources/WebLibraries/three/addons/tsl/display/MotionBlur.js +33 -0
- package/Resources/WebLibraries/three/addons/tsl/display/OITPassNode.js +341 -0
- package/Resources/WebLibraries/three/addons/tsl/display/OutlineNode.js +916 -0
- package/Resources/WebLibraries/three/addons/tsl/display/ParallaxBarrierPassNode.js +90 -0
- package/Resources/WebLibraries/three/addons/tsl/display/PixelationPassNode.js +227 -0
- package/Resources/WebLibraries/three/addons/tsl/display/RGBShiftNode.js +96 -0
- package/Resources/WebLibraries/three/addons/tsl/display/RecurrentDenoiseNode.js +812 -0
- package/Resources/WebLibraries/three/addons/tsl/display/RetroPassNode.js +263 -0
- package/Resources/WebLibraries/three/addons/tsl/display/SMAANode.js +729 -0
- package/Resources/WebLibraries/three/addons/tsl/display/SSAAPassNode.js +344 -0
- package/Resources/WebLibraries/three/addons/tsl/display/SSAONode.js +422 -0
- package/Resources/WebLibraries/three/addons/tsl/display/SSGINode.js +698 -0
- package/Resources/WebLibraries/three/addons/tsl/display/SSRNode.js +1430 -0
- package/Resources/WebLibraries/three/addons/tsl/display/SSSNode.js +479 -0
- package/Resources/WebLibraries/three/addons/tsl/display/Sepia.js +24 -0
- package/Resources/WebLibraries/three/addons/tsl/display/Shape.js +29 -0
- package/Resources/WebLibraries/three/addons/tsl/display/SharpenNode.js +284 -0
- package/Resources/WebLibraries/three/addons/tsl/display/SobelOperatorNode.js +168 -0
- package/Resources/WebLibraries/three/addons/tsl/display/StereoCompositePassNode.js +190 -0
- package/Resources/WebLibraries/three/addons/tsl/display/StereoPassNode.js +117 -0
- package/Resources/WebLibraries/three/addons/tsl/display/TAAUNode.js +700 -0
- package/Resources/WebLibraries/three/addons/tsl/display/TRAANode.js +609 -0
- package/Resources/WebLibraries/three/addons/tsl/display/TemporalReprojectNode.js +1024 -0
- package/Resources/WebLibraries/three/addons/tsl/display/TransitionNode.js +141 -0
- package/Resources/WebLibraries/three/addons/tsl/display/boxBlur.js +65 -0
- package/Resources/WebLibraries/three/addons/tsl/display/depthAwareBlend.js +80 -0
- package/Resources/WebLibraries/three/addons/tsl/display/depthAwareBlur.js +63 -0
- package/Resources/WebLibraries/three/addons/tsl/display/hashBlur.js +55 -0
- package/Resources/WebLibraries/three/addons/tsl/display/lensDirt.js +30 -0
- package/Resources/WebLibraries/three/addons/tsl/display/radialBlur.js +68 -0
- package/Resources/WebLibraries/three/addons/tsl/lighting/ClusteredLightsNode.js +994 -0
- package/Resources/WebLibraries/three/addons/tsl/lighting/DynamicLightsNode.js +201 -0
- package/Resources/WebLibraries/three/addons/tsl/lighting/LightProbeGridNode.js +183 -0
- package/Resources/WebLibraries/three/addons/tsl/lighting/data/AmbientLightDataNode.js +67 -0
- package/Resources/WebLibraries/three/addons/tsl/lighting/data/DirectionalLightDataNode.js +117 -0
- package/Resources/WebLibraries/three/addons/tsl/lighting/data/HemisphereLightDataNode.js +105 -0
- package/Resources/WebLibraries/three/addons/tsl/lighting/data/PointLightDataNode.js +140 -0
- package/Resources/WebLibraries/three/addons/tsl/lighting/data/SpotLightDataNode.js +167 -0
- package/Resources/WebLibraries/three/addons/tsl/math/Bayer.js +84 -0
- package/Resources/WebLibraries/three/addons/tsl/math/curlNoise.js +107 -0
- package/Resources/WebLibraries/three/addons/tsl/math/voronoiNoise.js +112 -0
- package/Resources/WebLibraries/three/addons/tsl/shadows/TileShadowNode.js +542 -0
- package/Resources/WebLibraries/three/addons/tsl/shadows/TileShadowNodeHelper.js +212 -0
- package/Resources/WebLibraries/three/addons/tsl/utils/GroundedSkybox.js +62 -0
- package/Resources/WebLibraries/three/addons/tsl/utils/RNoise.js +51 -0
- package/Resources/WebLibraries/three/addons/tsl/utils/Raymarching.js +70 -0
- package/Resources/WebLibraries/three/addons/tsl/utils/SoftParticles.js +53 -0
- package/Resources/WebLibraries/three/addons/tsl/utils/SpecularHelpers.js +302 -0
- package/Resources/WebLibraries/three/addons/tsl/utils/TAAUtils.js +184 -0
- package/Resources/WebLibraries/three/addons/utils/BufferGeometryUtils.js +1523 -0
- package/Resources/WebLibraries/three/addons/utils/CameraUtils.js +82 -0
- package/Resources/WebLibraries/three/addons/utils/ColorUtils.js +76 -0
- package/Resources/WebLibraries/three/addons/utils/GaussianSplatUtils.js +229 -0
- package/Resources/WebLibraries/three/addons/utils/GeometryCompressionUtils.js +547 -0
- package/Resources/WebLibraries/three/addons/utils/GeometryUtils.js +226 -0
- package/Resources/WebLibraries/three/addons/utils/LDrawUtils.js +211 -0
- package/Resources/WebLibraries/three/addons/utils/SceneOptimizer.js +459 -0
- package/Resources/WebLibraries/three/addons/utils/SceneUtils.js +363 -0
- package/Resources/WebLibraries/three/addons/utils/ShadowMapViewer.js +244 -0
- package/Resources/WebLibraries/three/addons/utils/ShadowMapViewerGPU.js +233 -0
- package/Resources/WebLibraries/three/addons/utils/SkeletonUtils.js +496 -0
- package/Resources/WebLibraries/three/addons/utils/SortUtils.js +175 -0
- package/Resources/WebLibraries/three/addons/utils/UVsDebug.js +173 -0
- package/Resources/WebLibraries/three/addons/utils/WebGLTextureUtils.js +115 -0
- package/Resources/WebLibraries/three/addons/utils/WebGPUTextureUtils.js +81 -0
- package/Resources/WebLibraries/three/addons/utils/WorkerPool.js +167 -0
- package/Resources/WebLibraries/three/addons/utils/unwrapUVs.js +865 -0
- package/Resources/WebLibraries/three/three.core.js +61162 -0
- package/Resources/WebLibraries/three/three.module.js +19537 -0
- package/Resources/WebLibraries/three/three.tsl.js +41903 -0
- package/Resources/WebLibraries/three/three.webgpu.js +53714 -0
- package/Resources/share-rules.json +64 -0
- package/Resources/skills/2d-game/SKILL.md +305 -0
- package/Resources/skills/3d-game/SKILL.md +274 -0
- package/Resources/skills/accounts/SKILL.md +41 -0
- package/Resources/skills/android-design/SKILL.md +159 -0
- package/Resources/skills/app-ai/SKILL.md +154 -0
- package/Resources/skills/app-intents/SKILL.md +31 -0
- package/Resources/skills/app-kinds/SKILL.md +122 -0
- package/Resources/skills/apple-watch/SKILL.md +43 -0
- package/Resources/skills/assets/SKILL.md +183 -0
- package/Resources/skills/building-blocks/SKILL.md +97 -0
- package/Resources/skills/device-control/SKILL.md +56 -0
- package/Resources/skills/device-integrations/SKILL.md +278 -0
- package/Resources/skills/finder-files/SKILL.md +19 -0
- package/Resources/skills/game/SKILL.md +416 -0
- package/Resources/skills/game-3d/SKILL.md +12 -0
- package/Resources/skills/game-art/SKILL.md +11 -0
- package/Resources/skills/game-feel/SKILL.md +13 -0
- package/Resources/skills/game-levels/SKILL.md +12 -0
- package/Resources/skills/game-live/SKILL.md +12 -0
- package/Resources/skills/game-physics/SKILL.md +13 -0
- package/Resources/skills/game-playtest/SKILL.md +26 -0
- package/Resources/skills/game-ui/SKILL.md +278 -0
- package/Resources/skills/github-projects/SKILL.md +62 -0
- package/Resources/skills/icloud-sync/SKILL.md +30 -0
- package/Resources/skills/iphone-hardware/SKILL.md +57 -0
- package/Resources/skills/iphone-widgets/SKILL.md +53 -0
- package/Resources/skills/lg-developer-mode/SKILL.md +152 -0
- package/Resources/skills/mac-widgets/SKILL.md +60 -0
- package/Resources/skills/maps/SKILL.md +8 -0
- package/Resources/skills/menu-bar/SKILL.md +36 -0
- package/Resources/skills/more-apps/SKILL.md +53 -0
- package/Resources/skills/phone-controllers/SKILL.md +79 -0
- package/Resources/skills/phone-pages/SKILL.md +173 -0
- package/Resources/skills/roku-developer-mode/SKILL.md +106 -0
- package/Resources/skills/scene-3d/SKILL.md +27 -0
- package/Resources/skills/scripting/SKILL.md +17 -0
- package/Resources/skills/share-extension/SKILL.md +22 -0
- package/Resources/skills/tv-design/SKILL.md +72 -0
- package/Resources/skills/web-app/SKILL.md +170 -0
- package/Resources/skills/web-game/SKILL.md +95 -0
- package/Resources/skills/web-or-native/SKILL.md +108 -0
- package/Resources/skills/wish-links/SKILL.md +156 -0
- package/THIRD_PARTY_NOTICES.md +170 -0
- package/cli/ai.mjs +237 -0
- package/cli/android.mjs +941 -0
- package/cli/app-ai.mjs +473 -0
- package/cli/browser.mjs +284 -0
- package/cli/calls.mjs +594 -0
- package/cli/dev.mjs +820 -0
- package/cli/devices.mjs +984 -0
- package/cli/lamp.mjs +1326 -0
- package/cli/lampapp.mjs +332 -0
- package/cli/lamps/android-host/LampPageGateway.kt +345 -0
- package/cli/lamps/android-host/app/build.gradle.kts +40 -0
- package/cli/lamps/android-host/build.gradle.kts +4 -0
- package/cli/lamps/android-host/game/AndroidManifest.xml +33 -0
- package/cli/lamps/android-host/game/MainActivity.kt +173 -0
- package/cli/lamps/android-host/gradle/libs.versions.toml +39 -0
- package/cli/lamps/android-host/gradle.properties +8 -0
- package/cli/lamps/android-host/page/AndroidManifest.xml +35 -0
- package/cli/lamps/android-host/page/MainActivity.kt +193 -0
- package/cli/lamps/android-host/settings.gradle.kts +30 -0
- package/cli/lamps/android-host/tools.json +43 -0
- package/cli/lamps/lamp-controllers.js +2 -0
- package/cli/lamps/lamp-for-games.js +6922 -0
- package/cli/lamps/lamp.js +7082 -0
- package/cli/lamps/mac-starter/.lamp/meta.json +1 -0
- package/cli/lamps/mac-starter/APP.md +12 -0
- package/cli/lamps/mac-starter/Package.swift +8 -0
- package/cli/lamps/mac-starter/Sources/App.swift +11 -0
- package/cli/lamps/mac-starter/Sources/ContentView.swift +17 -0
- package/cli/lamps/mac-starter/Sources/LampSupport.swift +18215 -0
- package/cli/lamps/mac-starter/build.sh +336 -0
- package/cli/lamps/mac-starter/gitignore +3 -0
- package/cli/lamps/mac-starter/lamp-starter.json +6 -0
- package/cli/lamps/web-starter/APP.md +8 -0
- package/cli/lamps/web-starter/app.js +1 -0
- package/cli/lamps/web-starter/index.html +17 -0
- package/cli/lamps/web-starter/lamp-starter.json +5 -0
- package/cli/lamps/web-starter/lamp.js +7082 -0
- package/cli/lamps/web-starter/style.css +25 -0
- package/cli/link.mjs +202 -0
- package/cli/local-ai.mjs +193 -0
- package/cli/mac.mjs +621 -0
- package/cli/mdns.mjs +205 -0
- package/cli/msix.mjs +413 -0
- package/cli/network.mjs +209 -0
- package/cli/openrouter.mjs +133 -0
- package/cli/outside.mjs +203 -0
- package/cli/page.js +317 -0
- package/cli/place.mjs +298 -0
- package/cli/png.mjs +184 -0
- package/cli/share.mjs +270 -0
- package/cli/skill/SKILL.md +280 -0
- package/cli/skills.mjs +71 -0
- package/cli/state.mjs +176 -0
- package/cli/update.mjs +162 -0
- package/package.json +20 -4
- package/site/lib/quota.js +59 -0
- package/site/lib/shared-wishes.js +1727 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: game-ui
|
|
3
|
+
description: A game's screens and how they feel - picking the screen flow that fits this game (how it opens, teaches, restarts and returns) before drawing any of them, what the shared display and each phone show in each phase, authored art direction, an overworld where one suits, one signature motion, phone controllers built for the player's job, teaching controls in play, and checking the real opening. Read before designing or changing a game's opening, title, menus, level select, HUD, pause or results, whatever the game is made with; 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
|
+
# A game's screens
|
|
7
|
+
|
|
8
|
+
A game's interface should feel made for its world. The failure to avoid is one screen holding everything: the controls,
|
|
9
|
+
a stage picker, a join code and the settings, around a small game. Apply this to a new game, or when the person asks
|
|
10
|
+
for its screens to change: don't redesign a game they already like on your own.
|
|
11
|
+
|
|
12
|
+
## A short brief
|
|
13
|
+
|
|
14
|
+
Before drawing a screen, settle these for yourself, and make each one for this game rather than the first that comes:
|
|
15
|
+
|
|
16
|
+
- what the players do, and what counts as winning;
|
|
17
|
+
- who is holding what, and from how far they look: a shared TV across the room, a Mac at a desk, a phone in the hand;
|
|
18
|
+
- three qualities of its world (playful, homemade, a bit chaotic);
|
|
19
|
+
- one material or medium the interface is made of (a recipe book, cut paper, a two-ink print, chalk on slate, a tin toy);
|
|
20
|
+
- a palette of a few colors, a shape language, and one signature motion (below).
|
|
21
|
+
|
|
22
|
+
## Pick the flow first
|
|
23
|
+
|
|
24
|
+
For a new game, or when the person asks to change how its screens go, decide the flow before drawing any screen: how
|
|
25
|
+
the game opens, where it teaches, how a restart works and how a player comes back. A title over a backdrop is what comes
|
|
26
|
+
first to mind, and few games need it, so ask what the player should do first and what, if anything, has to come before
|
|
27
|
+
that. These are examples of a flow, each with when it fits and what it costs:
|
|
28
|
+
|
|
29
|
+
- **Instant play** (2048): it opens on the game, ready to play, and the first press is the start press, which brings
|
|
30
|
+
the controls before the clock or the danger begins. A new game is one quiet press. It fits a game a glance explains, with nothing to choose. There's no
|
|
31
|
+
moment for mood or choices, so the name stays small and settings wait in pause.
|
|
32
|
+
- **Arcade loop** (Asteroids): the name, the game playing itself and the best scores turn over until someone starts, the
|
|
33
|
+
controls come as the run begins, and game over comes back round with the score. It fits short runs and a score to beat.
|
|
34
|
+
The loop has to be worth watching, or it's a title with extra steps.
|
|
35
|
+
- **An opening in the fiction** (UNDERRUN): it opens inside the world, on a transmission, a scene or someone talking, and
|
|
36
|
+
play grows out of that, with the name arriving when it's earned and the controls where the fiction hands over to
|
|
37
|
+
play. It fits a game with a story or a strong place. It
|
|
38
|
+
costs writing and slows a second visit, so it's short and can be skipped at any moment, and the registered state keeps
|
|
39
|
+
which beat it's on and how far through, so a change or a return goes on from there and a finished one isn't replayed.
|
|
40
|
+
- **A briefing** (HexGL): the course, the vehicle and what's at stake, then the controls with a countdown. It fits a game where what
|
|
41
|
+
you're about to face changes how you play. It adds a step before every round, so Rematch and Continue go past it.
|
|
42
|
+
- **Calm exploring** (Moonpool): it opens in the place, with nothing to fail, the name passing through and the first
|
|
43
|
+
thing worth finding in sight. The first press brings the controls, what to do comes from what the player notices, and
|
|
44
|
+
a return puts them where they left off.
|
|
45
|
+
It fits a game with no pressure. A goal can go unseen, so the world has to point at it.
|
|
46
|
+
|
|
47
|
+
Another flow is often better: a game played only with phones may open on joining, a board game on its seats. The
|
|
48
|
+
path with a title below is one more choice, not the default.
|
|
49
|
+
|
|
50
|
+
Write the choice in APP.md as a `Flow:` line, so a later change keeps it: a sentence or two on how the game opens, where
|
|
51
|
+
it teaches, how a restart and a return go and why that suits this game, never only a name. Leave it where it is when a
|
|
52
|
+
change doesn't touch how the screens go.
|
|
53
|
+
|
|
54
|
+
### What every flow keeps
|
|
55
|
+
|
|
56
|
+
Leave out the screens the game has no use for:
|
|
57
|
+
|
|
58
|
+
1. **A title**, where the flow has one: the game's name in a scene or strong emblem, one dominant Play or Continue, and a
|
|
59
|
+
few quieter choices (How to play, Settings). It's the first screen and the main menu at once. No level cards or
|
|
60
|
+
join code here: those are later screens.
|
|
61
|
+
2. **Joining or setup**: only when the game needs it, and only the choices needed now. Rule tweaks go behind a labeled
|
|
62
|
+
secondary choice.
|
|
63
|
+
3. **Level or mode choice**: a screen of its own, when the choice means something. A game with one endless mode goes
|
|
64
|
+
straight to play.
|
|
65
|
+
4. **Play**, then **Pause** with Resume first, and **Results** that say what happened before any decoration.
|
|
66
|
+
|
|
67
|
+
Starting is one action and it visibly changes something: no splash that only asks for a press before the real menu, and
|
|
68
|
+
no second confirmation of what the player just chose. A prompt to press something after the opening is built from the
|
|
69
|
+
real bindings (the game skill says how).
|
|
70
|
+
|
|
71
|
+
**The opening never shows controls or key bindings**, whatever the flow, and however many players share the keyboard:
|
|
72
|
+
local multiplayer is no exception. That means no key or button name and no label for what a control does (Space, WASD,
|
|
73
|
+
A, "Whack: F"), on a card, on a tag beside a character or in a start prompt. It invites with a word, Play or Start,
|
|
74
|
+
that a click or any of the game's confirm buttons answers. Players learn the controls afterwards, either on a short
|
|
75
|
+
screen of their own after the start press or as the match begins, before play, and the flow chooses which. Rematch and
|
|
76
|
+
Continue go past them, and they stay in pause. The stick and buttons Lamp draws on a touch screen are the controls
|
|
77
|
+
themselves, not labels.
|
|
78
|
+
|
|
79
|
+
Rematch and quick start keep the session's choices: players, level, mode, and go straight to the round. Settings aren't
|
|
80
|
+
a step on the way to play.
|
|
81
|
+
Back returns to the previous choice with its state intact, and leaving a lobby, restarting a round and quitting read
|
|
82
|
+
as different things. Confirm only what would throw away progress or break up the party.
|
|
83
|
+
|
|
84
|
+
Each screen has one job. "What is this game?" and "which level?" are two questions, so they're two screens.
|
|
85
|
+
|
|
86
|
+
### With phones
|
|
87
|
+
|
|
88
|
+
Before writing a phone's screens, go through each phase of the flow and settle what the shared display shows and what
|
|
89
|
+
each player's phone shows, and keep that as a small table under the `Flow:` line. The shared display is whatever everyone looks at: the
|
|
90
|
+
Mac, a TV, or a phone or iPad running the game. A phone used as a controller, by a phone page or an app of the project's own
|
|
91
|
+
(the phone-controllers skill), is a different thing from a phone running the game, which has only its own screen and
|
|
92
|
+
needs no split.
|
|
93
|
+
|
|
94
|
+
A party quiz might come out like this; another game's will differ:
|
|
95
|
+
|
|
96
|
+
| Phase | Shared display | Each player's phone |
|
|
97
|
+
| --- | --- | --- |
|
|
98
|
+
| Joining | the code, who's in | name, then "You're in" |
|
|
99
|
+
| Waiting | who's still to come | what the game is waiting for |
|
|
100
|
+
| A question | the question, the time left | the answers |
|
|
101
|
+
| Results | what happened, the scores | their own result, Again |
|
|
102
|
+
|
|
103
|
+
- Say who steers a menu everyone can see: the first player, the host, or a vote. All phones moving one marker isn't a
|
|
104
|
+
design.
|
|
105
|
+
- Waiting always says for what, on both, and the game never sits silent.
|
|
106
|
+
- A phone that drops is named on the shared display, and the flow says whether the game holds or carries on. It comes
|
|
107
|
+
back to the current phase as the same player, never to the start.
|
|
108
|
+
|
|
109
|
+
When making or changing a phone controller, design it from the player's job in this game, then its phases:
|
|
110
|
+
|
|
111
|
+
- **Primary interaction:** what this player mostly does on the phone, shaped by the mechanic. A pattern lock takes the
|
|
112
|
+
whole screen and is drawn on with one finger, and each attempt's clues stack up beside it.
|
|
113
|
+
- **Supporting actions:** only what the job needs around it (Undo, Submit, ready, a power-up).
|
|
114
|
+
- **Feedback and information:** what the phone tells this player that the shared display doesn't, right where they're
|
|
115
|
+
acting: a wrong attempt answers on the phone, with no change of phase.
|
|
116
|
+
- **Each phase its own screen:** controls for another phase aren't on it, so a player between rounds isn't left looking
|
|
117
|
+
at a dimmed copy of play.
|
|
118
|
+
- **A plainer way:** a gesture has one to the same move where the mechanic allows it, spelled out in the design: tap the
|
|
119
|
+
nodes in order, with Undo and Submit. Where the mechanic is the timing or the skill of the gesture itself, don't
|
|
120
|
+
promise the same game by another route: give an easier setting, or say there's no plainer way.
|
|
121
|
+
|
|
122
|
+
Then ask: do the phone's actions, feedback and information fit this player's job? This is a question to answer for the
|
|
123
|
+
game, not a rule against any layout. A buzzer, a wheel or a pad can suit many games, and a pad is often right when eyes
|
|
124
|
+
stay on the shared display. Lock art around generic buttons doesn't fit: the player still only presses buttons.
|
|
125
|
+
|
|
126
|
+
## Authored, not defaulted
|
|
127
|
+
|
|
128
|
+
Certain choices mark a game as made in one sitting, because they're what comes first: pill buttons in a centered stack,
|
|
129
|
+
a centered title with its tagline, start prompt and controls underneath, a default rounded font, emoji as art, soft
|
|
130
|
+
drop shadows on cards, a teal gradient, a static backdrop with a panel on it.
|
|
131
|
+
Any of them can be right, but only when chosen for this game. Two games shouldn't share a composition.
|
|
132
|
+
|
|
133
|
+
The name is treated live text: set in a face that fits, then given size, spacing, a slant, an outline, a stamp or a
|
|
134
|
+
place in the scene. Letters can sit on a sign, follow a path, or be cut out of something. System fonts are a fine
|
|
135
|
+
start, and a licensed font may ship in the game's own folder with its credit, but `assets` doesn't fetch fonts. `make_art`
|
|
136
|
+
paints no lettering, so never ask it for a logo, and its pictures have their own soft, rounded style: use one where that
|
|
137
|
+
suits the medium, and draw the rest in code. A small game needs zero or one new picture.
|
|
138
|
+
|
|
139
|
+
## Theme in the composition
|
|
140
|
+
|
|
141
|
+
Theme changes how a screen is built, not only its colors. Choose a small vocabulary and use it on every screen:
|
|
142
|
+
background, surfaces, edges, the focus marker, a display type and a reading type, a few icons, and one way of moving
|
|
143
|
+
between screens.
|
|
144
|
+
|
|
145
|
+
- **A cooking game**: the title is an open cookbook, the levels are its tabbed recipes with a picture of each dish, a
|
|
146
|
+
stamped rating marks a finished one, and a page turn carries you between them.
|
|
147
|
+
- **A camping party game**: the title is a campsite at dusk, the levels are stops on a trail map joined by a dotted
|
|
148
|
+
path, a pennant marks where you are, and the camera moves along the trail.
|
|
149
|
+
|
|
150
|
+
The metaphor stays a presentation, never a puzzle: destinations keep ordinary names, and what can be chosen looks
|
|
151
|
+
choosable.
|
|
152
|
+
|
|
153
|
+
Level choices show a preview, a name and progress, with focused, selected, locked and completed each distinct. A lock
|
|
154
|
+
says what opens it. Never tell these states or the players apart by color alone: add a shape, label or icon.
|
|
155
|
+
|
|
156
|
+
Give the title or scene room, and save the strongest accent for what's focused and what matters now.
|
|
157
|
+
|
|
158
|
+
## A menu that's a place, where it suits
|
|
159
|
+
|
|
160
|
+
Some games choose their levels in the world instead of on a screen of cards: a small map where a character or vehicle
|
|
161
|
+
goes from stop to stop. It suits a game with places to go, and it's one idea among others: a cooking game can use its
|
|
162
|
+
recipes, a heist a planning table, and a game of one arena needs none. Don't add one to a small game that asked for
|
|
163
|
+
something plainer.
|
|
164
|
+
|
|
165
|
+
**Worked example: Pond Hop.** A party game of frogs on three ponds. The title is the first pond, close up, and Play lifts
|
|
166
|
+
the camera to show all three joined by a trail of lily pads. The frog sits on the pad of the chosen pond. Left and right
|
|
167
|
+
hop it to the next pad, the pond's name and best score appear beside it, OK dives in, and Back returns to the title.
|
|
168
|
+
|
|
169
|
+
What makes it work anywhere:
|
|
170
|
+
|
|
171
|
+
- The stops are a list of nodes, not a space to steer through: arrows choose, OK enters, Back returns. No analog stick,
|
|
172
|
+
diagonal, timing or gesture is needed to enter a level, so it works with a TV remote, touch and phones.
|
|
173
|
+
- A returning player never walks the path again: Continue and Rematch start the chosen level directly.
|
|
174
|
+
- Decide who steers it ("With phones", above).
|
|
175
|
+
- In a small window the choices stay the same size; the map recomposes rather than shrinks.
|
|
176
|
+
- What the registered state keeps is yours to name: the screen, the node and the focus, with the camera registered too,
|
|
177
|
+
restored directly with no intro replayed (the game skill, "Changes while it's played"). The map isn't `busy()`.
|
|
178
|
+
|
|
179
|
+
## A finished look
|
|
180
|
+
|
|
181
|
+
A game should look finished, in whatever style suits it:
|
|
182
|
+
|
|
183
|
+
- **The playfield dominates.** The world takes most of the screen; the HUD shows only what's needed in play and sits
|
|
184
|
+
clear of the action. A racer's speed and lap sit at the edges of the driving view; a board game's score
|
|
185
|
+
sits beside its board.
|
|
186
|
+
- **Menus share the world's look.** Title, pause and results are made of the same material, palette and type as play,
|
|
187
|
+
and pause keeps the scene visible behind it.
|
|
188
|
+
- **Every detail chosen.** Type, spacing, icons and each control's states (rest, focus, pressed, disabled) are styled
|
|
189
|
+
for this game: nothing is left as a browser or system default by accident.
|
|
190
|
+
- **Focus and access stay.** Keyboard and controller focus is always visible, and controls stay real buttons that every
|
|
191
|
+
input the game promises can reach.
|
|
192
|
+
|
|
193
|
+
## Teaching and input
|
|
194
|
+
|
|
195
|
+
- Teach by doing: a safe first objective, the action named beside the thing it applies to, then the next action when
|
|
196
|
+
it's needed. A wall of keys before play teaches nothing.
|
|
197
|
+
- How to play and the controls stay reachable wherever the game can stop: from pause, and from its title if it has one.
|
|
198
|
+
They show the player's actual bindings (the game skill says how). On a phone, say touch, not keys. Essential help
|
|
199
|
+
never needs hover.
|
|
200
|
+
- A menu opens with visible focus on the likely choice, and works with every input the game promises.
|
|
201
|
+
- Input belongs to the screen on top: a press in a menu never also moves the player behind it.
|
|
202
|
+
- With phones as controllers, the shared screen shows what's public (who's in, whose turn, the score); each phone shows
|
|
203
|
+
its player's current action, and that a choice was received. A join code belongs to the joining screen (the
|
|
204
|
+
phone-pages skill), which a game played only with phones may open on; it's never on a title.
|
|
205
|
+
- A phone controller is part of the game ("With phones"), held the way its primary interaction suits: two thumbs
|
|
206
|
+
sideways, a lock upright. Same medium and palette as the game, and buttons named with its verbs ("Hop", not "OK").
|
|
207
|
+
What isn't usable now looks it, and a move shows only what the game accepted, so a phone with no game there says so.
|
|
208
|
+
The phone-pages skill has the layouts, and how views, moves and interrupted gestures work.
|
|
209
|
+
- Never carry essential information by sound alone.
|
|
210
|
+
|
|
211
|
+
## Feedback and layout
|
|
212
|
+
|
|
213
|
+
- Every control answers at once: a focus marker that moves, a press that gives. What's routine stays small, so a win
|
|
214
|
+
can feel bigger. Each response says what happened and how much it mattered, and tuning it in the running game beats
|
|
215
|
+
any fixed timing.
|
|
216
|
+
- One signature motion the game repeats (a squash and leap, a page turn, a stamp) gives it more character than many
|
|
217
|
+
effects. Quiet screens are allowed: type and empty space can carry a game, and a results screen needn't explode.
|
|
218
|
+
- Quick transitions that a fast press can interrupt, with no queue of animations. A particle never hides a hazard or
|
|
219
|
+
an instruction.
|
|
220
|
+
- Keep text readable over anything that moves, with a quiet panel behind it if needed. Try the real strings: long names,
|
|
221
|
+
big scores, the longest button glyph.
|
|
222
|
+
- Keep clear of safe areas and thumbs on a phone and of cropped edges on a TV (the tv-design skill and the game's device
|
|
223
|
+
rules have the measurements). A small window recomposes the screen; it doesn't shrink everything.
|
|
224
|
+
- Offer reduced motion and mute where there's motion or sound to reduce, and keep meaning without either.
|
|
225
|
+
|
|
226
|
+
Sound carries the same world as the screens; the game skill says how to make and play it.
|
|
227
|
+
|
|
228
|
+
## Proof
|
|
229
|
+
|
|
230
|
+
Play the journey, don't only look at it:
|
|
231
|
+
|
|
232
|
+
- the whole of the flow, from its opening through a round to how it ends, then a rematch or a return with the choices
|
|
233
|
+
kept;
|
|
234
|
+
- pause, help and Back from each place, returning to where they were;
|
|
235
|
+
- each input the game supports, and a mix of them where players differ;
|
|
236
|
+
- long text, a small window and a wide one;
|
|
237
|
+
- mute and reduced motion;
|
|
238
|
+
- how it looks: the opening, play and results read as one game; the HUD stays readable at the smallest window; focus,
|
|
239
|
+
pressed and disabled look different; nothing shows a browser's default look by accident;
|
|
240
|
+
- joining, a failed join and reconnecting, where the game takes phones, and a gesture interrupted partway (the
|
|
241
|
+
phone-pages skill).
|
|
242
|
+
|
|
243
|
+
Look at each screen, and at motion with `look_at_app`'s `motion`: one picture proves appearance, not navigation or
|
|
244
|
+
sound. Lamp can't play a phone page: a join is proved only where phones are really used. When you finish, name any
|
|
245
|
+
device or path you didn't run.
|
|
246
|
+
|
|
247
|
+
## Check the real opening
|
|
248
|
+
|
|
249
|
+
After your last edit to any screen and before you say a new game is done, or a change to its flow, see what a new
|
|
250
|
+
player sees. A look from before that edit doesn't count, so every later edit to a screen means this check again.
|
|
251
|
+
|
|
252
|
+
`look_at_app` with `reopen` starts the game again from its beginning: a plain look shows where the person is in an
|
|
253
|
+
open game, and `use_app` plays on from there, so after playtesting it can be anywhere. While the person has the game
|
|
254
|
+
open, Lamp asks them to press Reload first, with no picture until they do. Its saves stay (a fresh start keeps them),
|
|
255
|
+
so the picture may be a returning player's. Look before pressing anything; where the opening changes by itself, follow
|
|
256
|
+
the look with `use_app` and `wait` before any other move. Say which you saw, and when you couldn't see the opening, say
|
|
257
|
+
so instead of calling it checked.
|
|
258
|
+
|
|
259
|
+
First, write out every word on the opening, in the scenery and on tags as well as in the text. Any key name, button
|
|
260
|
+
name or control label among them fails, for every flow and however well it teaches: remove it before you say it's done,
|
|
261
|
+
and move it to where the flow teaches the controls.
|
|
262
|
+
|
|
263
|
+
Then hold the rest against the `Flow:` line, not against a picture of a title: does everything on screen serve what the
|
|
264
|
+
player is doing right now? A game played only with phones may open on joining. What fails is anything there because a
|
|
265
|
+
title usually has it: level cards, a join code that isn't this screen's job, a tagline and prompt stacked under the name
|
|
266
|
+
with no reason in your brief.
|
|
267
|
+
|
|
268
|
+
Say in a line, by name, what's on that screen that doesn't serve the flow (a rules strip, two cards of controls), or that
|
|
269
|
+
nothing does. Fix what you named and run this check again. Then press start, and see the controls appear before play,
|
|
270
|
+
with prompts that match the real bindings, and starting that does something the first time.
|
|
271
|
+
|
|
272
|
+
## One critique pass
|
|
273
|
+
|
|
274
|
+
Once the journey plays, look at each screen against your brief once, the phone page by its code (the phone-pages skill,
|
|
275
|
+
"Seeing the page"). Name the one thing on it that reads as a template, and fix that, along with anything you saw break.
|
|
276
|
+
For a phone controller you made or changed, answer the question in "With phones" when you report, from what you read.
|
|
277
|
+
Then stop polishing; navigation that doesn't work is fixed however many passes it takes. This pass doesn't paint new
|
|
278
|
+
pictures, and a wish that asked for something small stays small.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: github-projects
|
|
3
|
+
description: Someone's project on GitHub named in a request - explaining it, making a Lamp app or game from it ("Lampify it"), or using part of it - reading it in a git clone, and lampify, which credits the exact commit, keeps its licenses, makes the manifest and says what a Lamp app made from it still lacks. Read before using a project from GitHub.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Someone's project on GitHub
|
|
7
|
+
|
|
8
|
+
A link to a project on GitHub says where something is, not what to do with it. The request says that. Follow it as
|
|
9
|
+
written: explain it when that's asked, make an app or a game from it when that's asked, use a part of it when that's
|
|
10
|
+
asked. When a link comes with nothing that says which ("https://github.com/owner/game", or "check this out"), ask the
|
|
11
|
+
person with `ask` (explain it, make it into an app or game, something else) before cloning anything.
|
|
12
|
+
|
|
13
|
+
## Reading it
|
|
14
|
+
|
|
15
|
+
Clone it shallowly into the reference folder and read it there:
|
|
16
|
+
|
|
17
|
+
git clone --depth 1 https://github.com/owner/name .lamp/reference/name
|
|
18
|
+
|
|
19
|
+
A branch or tag the address names: add `--branch <name>`. The folder is for reading: never build in it or point the app
|
|
20
|
+
at it, it isn't part of the app. A clone that fails because the project is private: call `lampify` with `read_only: true`,
|
|
21
|
+
which fetches it with the person's GitHub sign-in and credits nothing, and read its copy, whose path its answer gives.
|
|
22
|
+
|
|
23
|
+
Asked to explain it: read it and answer. Nothing is credited and nothing is made.
|
|
24
|
+
|
|
25
|
+
## A Lamp app someone put on GitHub
|
|
26
|
+
|
|
27
|
+
When the project has `lamp-app.json` or a `.lampapp` file at its top, it's made with Lamp already: don't rebuild it. Tell
|
|
28
|
+
the person to open it with File → Open from GitHub… and paste its address. Lamp reviews it there.
|
|
29
|
+
|
|
30
|
+
## Making a Lamp app or game from it
|
|
31
|
+
|
|
32
|
+
This is making someone's project into a Lamp app ("Lampify it"): Lamp's structure, the project's code and assets in it,
|
|
33
|
+
its credit and licenses in place, and the rest of what a Lamp app has.
|
|
34
|
+
|
|
35
|
+
1. Clone it and read enough to know what it is: a page drawn with canvas or WebGL, a three.js or Phaser game, native
|
|
36
|
+
code, an engine Lamp's devices can't run.
|
|
37
|
+
2. Give the app its structure with `make_app_for` (a game or an app, the devices, web or native), and read the skill
|
|
38
|
+
for that kind (`game`, `web-app`, `2d-game`, `3d-game`). The structure is Lamp's: its page or its Swift package,
|
|
39
|
+
`build.sh`, `Package.swift`, Lamp's own files, `icon.json`, `APP.md`. A web page with no build step (index.html with
|
|
40
|
+
its scripts and styles, a canvas or WebGL game among them) is a web app brought in: `kind` "app", `made` "web", and
|
|
41
|
+
the web-app skill's "A web app brought in" is the rule for everything after, whatever the person's devices are.
|
|
42
|
+
3. Before using any of its code or assets, call `lampify` with its address and the commit your clone is at
|
|
43
|
+
(`git -C .lamp/reference/name rev-parse HEAD`). Lamp gets its own untouched copy at that commit, credits it in
|
|
44
|
+
credits.json, keeps every license and notice file under `Licenses/`, and answers with the manifest and what's still
|
|
45
|
+
missing. `adapted` is true for the project the app is made from (the default): its updates come to the person from
|
|
46
|
+
there. Anything else you bring in from GitHub (a library, a sprite pack) is cloned and lampified the same way with
|
|
47
|
+
`adapted: false`. Every later call passes the same commit: lampify never moves on to a newer one by itself.
|
|
48
|
+
4. Bring its code and assets into Lamp's structure: a web page's files into `Web/` as they are, laid out as the project
|
|
49
|
+
has them, in place of the scaffold's; native code into the package's sources. Keep what makes it work and drop only
|
|
50
|
+
what the person asked to drop. Never copy its own build scripts, package manifests, workflows or wrapper page over Lamp's
|
|
51
|
+
files (`Package.swift`, `build.sh`, `Sources/LampSupport.swift`, the `lamp*.js` files), and never run anything it
|
|
52
|
+
holds (its installers, its build, its scripts). Keep its copyright headers, and its author's credit on screen.
|
|
53
|
+
5. Give it what a Lamp app has that a project on GitHub doesn't: its line in `about.json`, its icon's design in
|
|
54
|
+
`icon.json`, and `APP.md` saying what it is and what it's based on (and, for a web app brought in, that it came in
|
|
55
|
+
as it is). Never write `lamp-app.json`, the project's entry
|
|
56
|
+
in `credits.json` or copies of its licenses yourself: lampify does.
|
|
57
|
+
6. Look at it with `look_at_app` until it works.
|
|
58
|
+
7. Call `lampify` again with the same address and commit, and fix whatever it says is still missing, until it says
|
|
59
|
+
nothing is.
|
|
60
|
+
8. Tell the person what it's based on, its license, and when it came with none, that whether to share or publish it
|
|
61
|
+
is their call, and Lamp will remind them when they do. When the address named a tag or a branch, say its updates will come from the project's
|
|
62
|
+
default branch. Putting it on GitHub is theirs to choose, with Also put on GitHub on its link's Release Update; never do it for them.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: icloud-sync
|
|
3
|
+
description: Keeping the person's data the same on every device signed in to their iCloud account with LampSync - declaring it, the API, signing, what the simulator shows, and what may never sync. Read before an app keeps data in iCloud.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# The same data on every device
|
|
7
|
+
|
|
8
|
+
To keep the person's data the same on every device signed in to their iCloud account (the Mac and the iPhone, or an
|
|
9
|
+
iPhone and an iPad), declare `{"icloud": true}` in `capabilities.json` and keep that data with `LampSync` from
|
|
10
|
+
LampSupport.swift instead of LampStore:
|
|
11
|
+
|
|
12
|
+
- `@StateObject private var notes = LampSync.collection("notes", of: Note.self)` in the view that owns the list (one
|
|
13
|
+
object per name, shared by every view that asks), then `notes.items`, `notes.put(note)`, `notes.delete(id)`,
|
|
14
|
+
`notes.get(id)`; the view follows changes made anywhere.
|
|
15
|
+
- Items are Codable and Identifiable, and the same rules as LampStore's apply to changing a saved type.
|
|
16
|
+
- Use it for the data people would expect everywhere; settings for one device stay in LampStore.
|
|
17
|
+
|
|
18
|
+
## Signing and status
|
|
19
|
+
|
|
20
|
+
Lamp signs the app for iCloud with the person's Apple team, which must be in the Apple Developer Program (a free
|
|
21
|
+
account can't use iCloud; the build then fails at signing, and you say so plainly). Sync needs the device signed in
|
|
22
|
+
to iCloud; the simulator usually isn't, so what you see there is the data kept on that device, and
|
|
23
|
+
`LampSync.shared.status` says why. Offer the status in the app's settings.
|
|
24
|
+
|
|
25
|
+
## What never syncs
|
|
26
|
+
|
|
27
|
+
Apple's terms forbid keeping sensitive health information about a person in iCloud: what is medical (diagnoses,
|
|
28
|
+
conditions, symptoms, medications, lab results, clinical records, reproductive or mental-health entries) stays on the
|
|
29
|
+
device, in LampStore, never in LampSync. Everyday activity and fitness numbers (steps, distance, active calories,
|
|
30
|
+
workouts, water) aren't that, and may sync. When it's unclear which a kind is, keep it on the device.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: iphone-hardware
|
|
3
|
+
description: What the phone itself offers an iPhone app - motion, the camera and scanning, location, haptics, Face ID, Bluetooth and nearby phones, Apple Health, NFC, AR and music - with the frameworks to use, and the capabilities.json declarations Lamp signs the app for. Read before using any of them.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# The phone's own hardware, and Health
|
|
7
|
+
|
|
8
|
+
The phone itself is the app's best material: use what it has, without being asked, whenever it fits what the user
|
|
9
|
+
wants.
|
|
10
|
+
|
|
11
|
+
## What to use for each
|
|
12
|
+
|
|
13
|
+
- Motion: `LampMotion` from LampSupport.swift (tilt, gravity, acceleration, rotation, compass heading, today's
|
|
14
|
+
steps, a shake count) for anything that tilts, steers, shakes or counts.
|
|
15
|
+
- Camera: AVFoundation's AVCaptureSession in a UIViewRepresentable for live capture, UIImagePickerController or
|
|
16
|
+
PhotosPicker to take or choose a picture, VisionKit's DataScannerViewController to read text and codes live and
|
|
17
|
+
VNDocumentCameraViewController to scan documents.
|
|
18
|
+
- Location and maps: CoreLocation (ask for when-in-use) and MapKit. Notifications at a place:
|
|
19
|
+
UNUserNotificationCenter with a location trigger.
|
|
20
|
+
- Haptics: `.sensoryFeedback` for taps and successes, CoreHaptics for patterns.
|
|
21
|
+
- Face ID or Touch ID: LocalAuthentication.
|
|
22
|
+
- Bluetooth devices: CoreBluetooth; nearby phones without a network: MultipeerConnectivity.
|
|
23
|
+
- NFC tags: CoreNFC.
|
|
24
|
+
- Siri and Shortcuts: App Intents. AR: ARKit with RealityKit. Music: MusicKit or MediaPlayer.
|
|
25
|
+
|
|
26
|
+
## Health
|
|
27
|
+
|
|
28
|
+
`LampHealth` from LampSupport.swift, after `{"healthkit": true}` in capabilities.json: `authorize(read:write:workouts:)`
|
|
29
|
+
once, then `total(.steps)` (today's; a day's sum, or its average for heart rate and the like),
|
|
30
|
+
`dailyTotals(.activeCalories, days: 7)`, `latest(.weight)`, `samples(.heartRate, days:)`, `sleep()` (hours, last
|
|
31
|
+
night), `workouts(days:)`, and `save(.caloriesEaten, 350)` to log what the person tells it; `Kind` lists steps,
|
|
32
|
+
distance, calories, heart rate, sleep, weight, water, protein and the rest, each with `unitName`.
|
|
33
|
+
|
|
34
|
+
- The simulator has no Health data of its own: save a sample there to have something to read, and only there. Never
|
|
35
|
+
write test data on a person's own phone, where it would join their real record; what the app logs for them is only
|
|
36
|
+
what they told it.
|
|
37
|
+
- A Mac has none at all (`LampHealth.isAvailable` is false): an app for both reads on the iPhone and keeps what the
|
|
38
|
+
Mac shows in LampSync, if it's activity and fitness that may go to iCloud (see the iCloud rule); medical data stays
|
|
39
|
+
on the iPhone.
|
|
40
|
+
|
|
41
|
+
## Permissions and declarations
|
|
42
|
+
|
|
43
|
+
The app already declares why it wants each of these (microphone, speech, camera, photos, location, motion,
|
|
44
|
+
Bluetooth, Face ID, health, NFC, Siri, nearby devices, music), so just request authorization before use and handle
|
|
45
|
+
denial in the interface.
|
|
46
|
+
|
|
47
|
+
Health, NFC, Siri, nearby phones and background work need a declaration first: write `capabilities.json` at the app's
|
|
48
|
+
root, e.g. `{"healthkit": true, "nfc": true, "siri": true, "weather": true, "homekit": true, "timeSensitive": true,
|
|
49
|
+
"backgroundModes": ["audio", "location"], "bonjourServices": ["_myapp._tcp", "_myapp._udp"], "backgroundTasks":
|
|
50
|
+
["com.example.refresh"]}`, and Lamp signs the app for them and declares them.
|
|
51
|
+
With a free Apple account Apple won't sign NFC, Siri, `weather`, `timeSensitive` or iCloud; the request's device line
|
|
52
|
+
says when the person's team is a free one, and then those stay out.
|
|
53
|
+
|
|
54
|
+
- Modes: audio, location, fetch, processing, remote-notification, bluetooth-central, bluetooth-peripheral.
|
|
55
|
+
- `bonjourServices` are the service types MultipeerConnectivity browses for (both _tcp and _udp of the same name, up
|
|
56
|
+
to 15 characters).
|
|
57
|
+
- `backgroundTasks` are the identifiers BGTaskScheduler registers, needed with the fetch and processing modes.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: iphone-widgets
|
|
3
|
+
description: An iPhone app's home screen widgets, Live Activities and Control Center controls (Widget/) - how they're written, the code they share with the app, the data the app hands them, buttons in them, and how to see them in the simulator. Read before writing or changing anything in Widget/.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Home screen widgets, Live Activities and controls
|
|
7
|
+
|
|
8
|
+
## Writing them
|
|
9
|
+
|
|
10
|
+
Write them with WidgetKit, SwiftUI and ActivityKit in a `Widget/` folder at the app's root, beside Sources/, starting
|
|
11
|
+
with Widget/Widget.swift: one `@main` on a `WidgetBundle` holding the widgets (`StaticConfiguration` with a
|
|
12
|
+
`TimelineProvider`, `.containerBackground(.fill.tertiary, for: .widget)`, `.supportedFamilies` for the sizes that fit)
|
|
13
|
+
and any `ActivityConfiguration` (the lock screen's view and the `dynamicIsland` regions). Lamp builds that folder into
|
|
14
|
+
the app as its extension.
|
|
15
|
+
|
|
16
|
+
It shares no code with Sources/ and has nothing from LampSupport.swift, except Widget/Shared/: Swift there is compiled
|
|
17
|
+
into both the app and the extension (Lamp links it into Sources/ as Sources/WidgetShared; edit it in Widget/Shared/),
|
|
18
|
+
the place for an `ActivityAttributes` type and anything else both sides need.
|
|
19
|
+
|
|
20
|
+
## The widget's data
|
|
21
|
+
|
|
22
|
+
- In the app, `LampWidget.share(Summary(…), as: "summary")` with any Codable value, at launch and whenever it changes
|
|
23
|
+
(it redraws the widgets too).
|
|
24
|
+
- In the widget, `LampWidget.read(Summary.self, from: "summary") { summary in … }` in getSnapshot and getTimeline, or
|
|
25
|
+
`await` it, from Widget/LampWidgetSupport.swift, which Lamp writes: never edit it. It gives what the app shared
|
|
26
|
+
last, also while the app is closed, and nil until then: show a short line asking to open the app.
|
|
27
|
+
|
|
28
|
+
## Live Activities
|
|
29
|
+
|
|
30
|
+
A Live Activity starts from the app, `Activity.request(attributes:content:)`, and is changed with `update` and ended
|
|
31
|
+
with `end` from the app while it runs; there's no server to push changes, so give a timer or progress an end date
|
|
32
|
+
(`Text(timerInterval:countsDown:)`, `ProgressView(timerInterval:)`) and it moves by itself.
|
|
33
|
+
|
|
34
|
+
## Buttons and controls
|
|
35
|
+
|
|
36
|
+
A button or toggle in a widget or Live Activity runs an App Intent, `Button(intent: AddCupIntent()) { … }` or
|
|
37
|
+
`Toggle(isOn:intent:)`: write that intent in Widget/Shared/ as a `LiveActivityIntent`, which iOS performs in the app
|
|
38
|
+
(starting it out of sight when it's closed), and keep the work under `#if !LAMP_WIDGET` (defined only in the widget,
|
|
39
|
+
which can't reach the app's code): change the data there and `LampWidget.share` it, and the widget redraws.
|
|
40
|
+
|
|
41
|
+
A Control Center control is a `ControlWidget` in the same `WidgetBundle`, marked `@available(iOS 18, *)`:
|
|
42
|
+
`StaticControlConfiguration(kind: "AddCup") { ControlWidgetButton(action: AddCupIntent()) { Label("Add a Cup",
|
|
43
|
+
systemImage: "cup.and.saucer") } }`.
|
|
44
|
+
|
|
45
|
+
## Seeing them, and what to tell the person
|
|
46
|
+
|
|
47
|
+
- `use_app` with `key` "lock" shows the lock screen, where a Live Activity is, and "home" the home screen; then the
|
|
48
|
+
picture.
|
|
49
|
+
- Not every iPhone has a Dynamic Island (the iPhone 14 Pro and Pro Max, and every iPhone 15 and later but the 16e
|
|
50
|
+
have one; iPads don't): `look_at_app` says which simulator the app is open on, and when it has none, say so and
|
|
51
|
+
that the person can choose one under Try On.
|
|
52
|
+
- Only the person can add a widget to the home screen, and Lamp shows them how: don't explain it, and say in a
|
|
53
|
+
sentence that it's ready to add.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lg-developer-mode
|
|
3
|
+
description: How Lamp walks the person through turning on Developer Mode on their LG TV (webOS) the way LG supports - opening the Developer Mode app's page in the LG Content Store and then the app itself on the TV, while the person installs it, restarts the TV when asked, signs in and turns its switches on with their own remote. Lamp's TV setup follows the steps below when the person clicks Do It for Me.
|
|
4
|
+
setup-for: tv
|
|
5
|
+
setup-system: webOS
|
|
6
|
+
setup-step: developer-mode
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Turning on Developer Mode on an LG TV
|
|
10
|
+
|
|
11
|
+
LG lets a TV take the person's own apps once its Developer Mode app is installed, signed in to a free LG developer
|
|
12
|
+
account and switched on. Lamp can't do that for them and mustn't try: installing an app, restarting the TV, signing in
|
|
13
|
+
and turning the switches on are the person's, on the TV, with its remote. What Lamp does is put the right screen in
|
|
14
|
+
front of them at each step and say in one short line what to do.
|
|
15
|
+
|
|
16
|
+
What happens on the TV, in order:
|
|
17
|
+
|
|
18
|
+
1. The person installs Developer Mode from the LG Content Store.
|
|
19
|
+
2. On some TVs the app shows no Sign In until the TV has been fully restarted (unplugged, not just turned off with
|
|
20
|
+
the remote, which only puts it to sleep). Until then its switches can be turned on but nothing works.
|
|
21
|
+
3. The person signs in with their LG developer account and turns Dev Mode Status on; the TV restarts.
|
|
22
|
+
4. In Developer Mode again, the person turns Key Server on and types the passphrase it shows into Lamp. The key
|
|
23
|
+
server answers only while Developer Mode is open on the screen, so it stays open until Lamp has connected.
|
|
24
|
+
|
|
25
|
+
A TV that was set up before may show Developer Mode already signed in, with Dev Mode Status on: then only Key Server
|
|
26
|
+
and the passphrase are left.
|
|
27
|
+
|
|
28
|
+
Lamp reaches the TV over its second-screen socket, the protocol LG's Connect SDK publishes: `wss://<address>:3001`,
|
|
29
|
+
the TV's own certificate kept with the key the TV hands back once the person lets Lamp in. Later connections offer
|
|
30
|
+
that key, to a TV showing the same certificate only, and the TV doesn't ask again. Requests that open or list apps
|
|
31
|
+
need the key, and fail with 401 without it.
|
|
32
|
+
|
|
33
|
+
## What Lamp never does
|
|
34
|
+
|
|
35
|
+
- Press the remote's buttons for the person, install the app silently, or sign in for them.
|
|
36
|
+
- See the LG account's password or the passphrase in any conversation: the passphrase is typed into the setup window
|
|
37
|
+
and goes only to the TV's key server (port 9991), exactly as typed (it's case-sensitive).
|
|
38
|
+
- Say a step happened that it can't see. Lamp sees that the TV let it in, that the app is installed, and that the TV
|
|
39
|
+
went away and came back; a sign-in or a switch is the person's to do, and Lamp says nothing of it as done.
|
|
40
|
+
- Open anything but the LG Content Store's page for Developer Mode and the Developer Mode app.
|
|
41
|
+
|
|
42
|
+
## Not yet checked on a real TV
|
|
43
|
+
|
|
44
|
+
- That the store query below (the Connect SDK's form) opens Developer Mode's own page rather than the store's front
|
|
45
|
+
page. The TV only says it opened the store, so the line said then always says what to do on the front page.
|
|
46
|
+
|
|
47
|
+
## The steps
|
|
48
|
+
|
|
49
|
+
Lamp's setup reads this block and follows it in order; the frontmatter's `setup-for`, `setup-system` and `setup-step`
|
|
50
|
+
say which setup step it does (the TV row's first, on webOS). `{name}` is the TV's name. A step is one of: `connect`
|
|
51
|
+
(let Lamp in; asks on the TV the first time), `request` (send one request; `failed` is said and the setup goes on when
|
|
52
|
+
`continueOnFailure`), `wait` (ask the TV every `every` seconds until the value at `until.json` in the answer to
|
|
53
|
+
`until.uri` equals `until.equals`), `confirm` (the person clicks `button` once they've done it; a confirm has no
|
|
54
|
+
`done`, since Lamp didn't see it happen), `rejoin` (the device restarts: Lamp carries on by itself once it has seen it
|
|
55
|
+
stop answering and answer again, and only then says `done`; `button` skips a restart that isn't needed and claims
|
|
56
|
+
nothing), and `handoff` (the last: the TV goes back to the setup window's own step, here the passphrase, which is done
|
|
57
|
+
only once the key is fetched, unlocked and SSH answers).
|
|
58
|
+
|
|
59
|
+
```lamp-setup
|
|
60
|
+
{
|
|
61
|
+
"connection": "webos-second-screen",
|
|
62
|
+
"offer": "Lamp opens each screen on the TV; you press the buttons.",
|
|
63
|
+
"steps": [
|
|
64
|
+
{
|
|
65
|
+
"do": "connect",
|
|
66
|
+
"doing": "Asking {name} to let Lamp in…",
|
|
67
|
+
"ask": "On the TV, choose Accept.",
|
|
68
|
+
"done": "{name} let Lamp in",
|
|
69
|
+
"refused": "{name} didn't let Lamp in. Click Try Again, then choose Accept on the TV."
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"do": "request",
|
|
73
|
+
"uri": "ssap://system.launcher/launch",
|
|
74
|
+
"payload": {
|
|
75
|
+
"id": "com.webos.app.discovery",
|
|
76
|
+
"params": {
|
|
77
|
+
"query": "category/GAME_APPS/com.palmdts.devmode"
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"doing": "Opening the LG Content Store on {name}…",
|
|
81
|
+
"done": "Asked {name} to show Developer Mode in the LG Content Store",
|
|
82
|
+
"failed": "{name} couldn't open the LG Content Store. On the TV, open it and search for Developer Mode.",
|
|
83
|
+
"continueOnFailure": true
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"do": "wait",
|
|
87
|
+
"until": {
|
|
88
|
+
"uri": "ssap://com.webos.applicationManager/listApps",
|
|
89
|
+
"json": "apps.id",
|
|
90
|
+
"equals": "com.palmdts.devmode"
|
|
91
|
+
},
|
|
92
|
+
"every": 3,
|
|
93
|
+
"doing": "Waiting for Developer Mode to be installed…",
|
|
94
|
+
"ask": "On the TV, choose Install. If the store shows its front page, search for Developer Mode first.",
|
|
95
|
+
"done": "Developer Mode is installed on {name}"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"do": "request",
|
|
99
|
+
"uri": "ssap://system.launcher/launch",
|
|
100
|
+
"payload": {
|
|
101
|
+
"id": "com.palmdts.devmode"
|
|
102
|
+
},
|
|
103
|
+
"doing": "Opening Developer Mode on {name}…",
|
|
104
|
+
"done": "Asked {name} to open Developer Mode",
|
|
105
|
+
"failed": "{name} couldn't open Developer Mode. On the TV, open it from your apps.",
|
|
106
|
+
"continueOnFailure": true
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"do": "rejoin",
|
|
110
|
+
"ask": "If Developer Mode shows no Sign In, unplug the TV for 30 seconds, then plug it back in and turn it on. Lamp carries on once the TV answers again.",
|
|
111
|
+
"button": "Sign In Is Showing",
|
|
112
|
+
"done": "{name} is back on"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"do": "request",
|
|
116
|
+
"uri": "ssap://system.launcher/launch",
|
|
117
|
+
"payload": {
|
|
118
|
+
"id": "com.palmdts.devmode"
|
|
119
|
+
},
|
|
120
|
+
"doing": "Opening Developer Mode on {name}…",
|
|
121
|
+
"done": "Asked {name} to open Developer Mode",
|
|
122
|
+
"failed": "{name} couldn't open Developer Mode. On the TV, open it from your apps.",
|
|
123
|
+
"continueOnFailure": true
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"do": "rejoin",
|
|
127
|
+
"ask": "In Developer Mode, sign in with your LG developer account, then turn Dev Mode Status on. The TV restarts, and Lamp carries on once it's back on.",
|
|
128
|
+
"button": "Dev Mode Status Is Already On",
|
|
129
|
+
"link": {
|
|
130
|
+
"title": "Get an LG Developer Account",
|
|
131
|
+
"url": "https://webostv.developer.lge.com/"
|
|
132
|
+
},
|
|
133
|
+
"done": "{name} is back on"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"do": "request",
|
|
137
|
+
"uri": "ssap://system.launcher/launch",
|
|
138
|
+
"payload": {
|
|
139
|
+
"id": "com.palmdts.devmode"
|
|
140
|
+
},
|
|
141
|
+
"doing": "Opening Developer Mode on {name} again…",
|
|
142
|
+
"done": "Asked {name} to open Developer Mode again",
|
|
143
|
+
"failed": "{name} couldn't open Developer Mode. On the TV, open it from your apps.",
|
|
144
|
+
"continueOnFailure": true
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"do": "handoff",
|
|
148
|
+
"ask": "In Developer Mode, turn Key Server on and keep Developer Mode open on the TV. Type the passphrase it shows below exactly as shown, then click Connect."
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
```
|