[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71A4YZNRSJSB02C15G2QJZD":3,"skill-same:01M71A4YZNRSJSB02C15G2QJZD":58},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":33,"linkOnly":34,"markdownContent":35,"markdownBody":36,"frontMatter":37,"refName":38,"commitSha":39,"skillDirectory":40,"forksCount":14,"repositoryHtmlUrl":41,"repositoryHomepageUrl":6,"ownerHtmlUrl":42,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":43,"install":44,"resources":57},"01M71A4YZNRSJSB02C15G2QJZD","threejs-geometry",null,"Three.js geometry creation - built-in shapes, BufferGeometry, custom geometry, instancing. Use when creating 3D shapes, working with vertices, building custom meshes, or optimizing with instanced rendering.","sapsapshen\u002Fai-memory-router","sapsapshen","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F20347959?v=4","01M6XDQEF1DP50DKF37H81J3J5","shenmian","01M6XDQEJPE41Y3DT2763X8ZJN",0,"MIT","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fglobal\u002Fthreejs-geometry\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32],"threejs","geometry","threejs geometry","3D","js","use","community","three","creation","rendering","with","unknown","custom","when","2026-11-10 10:12:30",false,"---\nname: threejs-geometry\ndescription: Three.js geometry creation - built-in shapes, BufferGeometry, custom geometry, instancing. Use when creating 3D shapes, working with vertices, building custom meshes, or optimizing with instanced rendering.\nrisk: unknown\nsource: community\n---\n\n# Three.js Geometry\n\n## Quick Start\n\n```javascript\nimport * as THREE from \"three\";\n\n\u002F\u002F Built-in geometry\nconst box = new THREE.BoxGeometry(1, 1, 1);\nconst sphere = new THREE.SphereGeometry(0.5, 32, 32);\nconst plane = new THREE.PlaneGeometry(10, 10);\n\n\u002F\u002F Create mesh\nconst material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });\nconst mesh = new THREE.Mesh(box, material);\nscene.add(mesh);\n```\n\n## Built-in Geometries\n\n### Basic Shapes\n\n```javascript\n\u002F\u002F Box - width, height, depth, widthSegments, heightSegments, depthSegments\nnew THREE.BoxGeometry(1, 1, 1, 1, 1, 1);\n\n\u002F\u002F Sphere - radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength\nnew THREE.SphereGeometry(1, 32, 32);\nnew THREE.SphereGeometry(1, 32, 32, 0, Math.PI * 2, 0, Math.PI); \u002F\u002F Full sphere\nnew THREE.SphereGeometry(1, 32, 32, 0, Math.PI); \u002F\u002F Hemisphere\n\n\u002F\u002F Plane - width, height, widthSegments, heightSegments\nnew THREE.PlaneGeometry(10, 10, 1, 1);\n\n\u002F\u002F Circle - radius, segments, thetaStart, thetaLength\nnew THREE.CircleGeometry(1, 32);\nnew THREE.CircleGeometry(1, 32, 0, Math.PI); \u002F\u002F Semicircle\n\n\u002F\u002F Cylinder - radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded\nnew THREE.CylinderGeometry(1, 1, 2, 32, 1, false);\nnew THREE.CylinderGeometry(0, 1, 2, 32); \u002F\u002F Cone\nnew THREE.CylinderGeometry(1, 1, 2, 6); \u002F\u002F Hexagonal prism\n\n\u002F\u002F Cone - radius, height, radialSegments, heightSegments, openEnded\nnew THREE.ConeGeometry(1, 2, 32, 1, false);\n\n\u002F\u002F Torus - radius, tube, radialSegments, tubularSegments, arc\nnew THREE.TorusGeometry(1, 0.4, 16, 100);\n\n\u002F\u002F TorusKnot - radius, tube, tubularSegments, radialSegments, p, q\nnew THREE.TorusKnotGeometry(1, 0.4, 100, 16, 2, 3);\n\n\u002F\u002F Ring - innerRadius, outerRadius, thetaSegments, phiSegments\nnew THREE.RingGeometry(0.5, 1, 32, 1);\n```\n\n### Advanced Shapes\n\n```javascript\n\u002F\u002F Capsule - radius, length, capSegments, radialSegments\nnew THREE.CapsuleGeometry(0.5, 1, 4, 8);\n\n\u002F\u002F Dodecahedron - radius, detail\nnew THREE.DodecahedronGeometry(1, 0);\n\n\u002F\u002F Icosahedron - radius, detail (0 = 20 faces, higher = smoother)\nnew THREE.IcosahedronGeometry(1, 0);\n\n\u002F\u002F Octahedron - radius, detail\nnew THREE.OctahedronGeometry(1, 0);\n\n\u002F\u002F Tetrahedron - radius, detail\nnew THREE.TetrahedronGeometry(1, 0);\n\n\u002F\u002F Polyhedron - vertices, indices, radius, detail\nconst vertices = [1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1];\nconst indices = [2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1];\nnew THREE.PolyhedronGeometry(vertices, indices, 1, 0);\n```\n\n### Path-Based Shapes\n\n```javascript\n\u002F\u002F Lathe - points[], segments, phiStart, phiLength\nconst points = [\n  new THREE.Vector2(0, 0),\n  new THREE.Vector2(0.5, 0),\n  new THREE.Vector2(0.5, 1),\n  new THREE.Vector2(0, 1),\n];\nnew THREE.LatheGeometry(points, 32);\n\n\u002F\u002F Extrude - shape, options\nconst shape = new THREE.Shape();\nshape.moveTo(0, 0);\nshape.lineTo(1, 0);\nshape.lineTo(1, 1);\nshape.lineTo(0, 1);\nshape.lineTo(0, 0);\n\nconst extrudeSettings = {\n  steps: 2,\n  depth: 1,\n  bevelEnabled: true,\n  bevelThickness: 0.1,\n  bevelSize: 0.1,\n  bevelSegments: 3,\n};\nnew THREE.ExtrudeGeometry(shape, extrudeSettings);\n\n\u002F\u002F Tube - path, tubularSegments, radius, radialSegments, closed\nconst curve = new THREE.CatmullRomCurve3([\n  new THREE.Vector3(-1, 0, 0),\n  new THREE.Vector3(0, 1, 0),\n  new THREE.Vector3(1, 0, 0),\n]);\nnew THREE.TubeGeometry(curve, 64, 0.2, 8, false);\n```\n\n### Text Geometry\n\n```javascript\nimport { FontLoader } from \"three\u002Fexamples\u002Fjsm\u002Floaders\u002FFontLoader.js\";\nimport { TextGeometry } from \"three\u002Fexamples\u002Fjsm\u002Fgeometries\u002FTextGeometry.js\";\n\nconst loader = new FontLoader();\nloader.load(\"fonts\u002Fhelvetiker_regular.typeface.json\", (font) => {\n  const geometry = new TextGeometry(\"Hello\", {\n    font: font,\n    size: 1,\n    depth: 0.2, \u002F\u002F Was 'height' in older versions\n    curveSegments: 12,\n    bevelEnabled: true,\n    bevelThickness: 0.03,\n    bevelSize: 0.02,\n    bevelSegments: 5,\n  });\n\n  \u002F\u002F Center text\n  geometry.computeBoundingBox();\n  geometry.center();\n\n  const mesh = new THREE.Mesh(geometry, material);\n  scene.add(mesh);\n});\n```\n\n## BufferGeometry\n\nThe base class for all geometries. Stores data as typed arrays for GPU efficiency.\n\n### Custom BufferGeometry\n\n```javascript\nconst geometry = new THREE.BufferGeometry();\n\n\u002F\u002F Vertices (3 floats per vertex: x, y, z)\nconst vertices = new Float32Array([\n  -1,\n  -1,\n  0, \u002F\u002F vertex 0\n  1,\n  -1,\n  0, \u002F\u002F vertex 1\n  1,\n  1,\n  0, \u002F\u002F vertex 2\n  -1,\n  1,\n  0, \u002F\u002F vertex 3\n]);\ngeometry.setAttribute(\"position\", new THREE.BufferAttribute(vertices, 3));\n\n\u002F\u002F Indices (for indexed geometry - reuse vertices)\nconst indices = new Uint16Array([\n  0,\n  1,\n  2, \u002F\u002F triangle 1\n  0,\n  2,\n  3, \u002F\u002F triangle 2\n]);\ngeometry.setIndex(new THREE.BufferAttribute(indices, 1));\n\n\u002F\u002F Normals (required for lighting)\nconst normals = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]);\ngeometry.setAttribute(\"normal\", new THREE.BufferAttribute(normals, 3));\n\n\u002F\u002F UVs (for texturing)\nconst uvs = new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]);\ngeometry.setAttribute(\"uv\", new THREE.BufferAttribute(uvs, 2));\n\n\u002F\u002F Colors (per-vertex colors)\nconst colors = new Float32Array([\n  1,\n  0,\n  0, \u002F\u002F red\n  0,\n  1,\n  0, \u002F\u002F green\n  0,\n  0,\n  1, \u002F\u002F blue\n  1,\n  1,\n  0, \u002F\u002F yellow\n]);\ngeometry.setAttribute(\"color\", new THREE.BufferAttribute(colors, 3));\n\u002F\u002F Use with: material.vertexColors = true\n```\n\n### BufferAttribute Types\n\n```javascript\n\u002F\u002F Common attribute types\nnew THREE.BufferAttribute(array, itemSize);\n\n\u002F\u002F Typed array options\nnew Float32Array(count * itemSize); \u002F\u002F Positions, normals, UVs\nnew Uint16Array(count); \u002F\u002F Indices (up to 65535 vertices)\nnew Uint32Array(count); \u002F\u002F Indices (larger meshes)\nnew Uint8Array(count * itemSize); \u002F\u002F Colors (0-255 range)\n\n\u002F\u002F Item sizes\n\u002F\u002F Position: 3 (x, y, z)\n\u002F\u002F Normal: 3 (x, y, z)\n\u002F\u002F UV: 2 (u, v)\n\u002F\u002F Color: 3 (r, g, b) or 4 (r, g, b, a)\n\u002F\u002F Index: 1\n```\n\n### Modifying BufferGeometry\n\n```javascript\nconst positions = geometry.attributes.position;\n\n\u002F\u002F Modify vertex\npositions.setXYZ(index, x, y, z);\n\n\u002F\u002F Access vertex\nconst x = positions.getX(index);\nconst y = positions.getY(index);\nconst z = positions.getZ(index);\n\n\u002F\u002F Flag for GPU update\npositions.needsUpdate = true;\n\n\u002F\u002F Recompute normals after position changes\ngeometry.computeVertexNormals();\n\n\u002F\u002F Recompute bounding box\u002Fsphere after changes\ngeometry.computeBoundingBox();\ngeometry.computeBoundingSphere();\n```\n\n### Interleaved Buffers (Advanced)\n\n```javascript\n\u002F\u002F More efficient memory layout for large meshes\nconst interleavedBuffer = new THREE.InterleavedBuffer(\n  new Float32Array([\n    \u002F\u002F pos.x, pos.y, pos.z, uv.u, uv.v (repeated per vertex)\n    -1, -1, 0, 0, 0, 1, -1, 0, 1, 0, 1, 1, 0, 1, 1, -1, 1, 0, 0, 1,\n  ]),\n  5, \u002F\u002F stride (floats per vertex)\n);\n\ngeometry.setAttribute(\n  \"position\",\n  new THREE.InterleavedBufferAttribute(interleavedBuffer, 3, 0),\n); \u002F\u002F size 3, offset 0\ngeometry.setAttribute(\n  \"uv\",\n  new THREE.InterleavedBufferAttribute(interleavedBuffer, 2, 3),\n); \u002F\u002F size 2, offset 3\n```\n\n## EdgesGeometry & WireframeGeometry\n\n```javascript\n\u002F\u002F Edge lines (only hard edges)\nconst edges = new THREE.EdgesGeometry(boxGeometry, 15); \u002F\u002F 15 = threshold angle\nconst edgeMesh = new THREE.LineSegments(\n  edges,\n  new THREE.LineBasicMaterial({ color: 0xffffff }),\n);\n\n\u002F\u002F Wireframe (all triangles)\nconst wireframe = new THREE.WireframeGeometry(boxGeometry);\nconst wireMesh = new THREE.LineSegments(\n  wireframe,\n  new THREE.LineBasicMaterial({ color: 0xffffff }),\n);\n```\n\n## Points\n\n```javascript\n\u002F\u002F Create point cloud\nconst geometry = new THREE.BufferGeometry();\nconst positions = new Float32Array(1000 * 3);\n\nfor (let i = 0; i \u003C 1000; i++) {\n  positions[i * 3] = (Math.random() - 0.5) * 10;\n  positions[i * 3 + 1] = (Math.random() - 0.5) * 10;\n  positions[i * 3 + 2] = (Math.random() - 0.5) * 10;\n}\n\ngeometry.setAttribute(\"position\", new THREE.BufferAttribute(positions, 3));\n\nconst material = new THREE.PointsMaterial({\n  size: 0.1,\n  sizeAttenuation: true, \u002F\u002F Size decreases with distance\n  color: 0xffffff,\n});\n\nconst points = new THREE.Points(geometry, material);\nscene.add(points);\n```\n\n## Lines\n\n```javascript\n\u002F\u002F Line (connected points)\nconst points = [\n  new THREE.Vector3(-1, 0, 0),\n  new THREE.Vector3(0, 1, 0),\n  new THREE.Vector3(1, 0, 0),\n];\nconst geometry = new THREE.BufferGeometry().setFromPoints(points);\nconst line = new THREE.Line(\n  geometry,\n  new THREE.LineBasicMaterial({ color: 0xff0000 }),\n);\n\n\u002F\u002F LineLoop (closed loop)\nconst loop = new THREE.LineLoop(geometry, material);\n\n\u002F\u002F LineSegments (pairs of points)\nconst segmentsGeometry = new THREE.BufferGeometry();\nsegmentsGeometry.setAttribute(\n  \"position\",\n  new THREE.BufferAttribute(\n    new Float32Array([\n      -1,\n      0,\n      0,\n      0,\n      1,\n      0, \u002F\u002F segment 1\n      0,\n      1,\n      0,\n      1,\n      0,\n      0, \u002F\u002F segment 2\n    ]),\n    3,\n  ),\n);\nconst segments = new THREE.LineSegments(segmentsGeometry, material);\n```\n\n## InstancedMesh\n\nEfficiently render many copies of the same geometry.\n\n```javascript\nconst geometry = new THREE.BoxGeometry(1, 1, 1);\nconst material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });\nconst count = 1000;\n\nconst instancedMesh = new THREE.InstancedMesh(geometry, material, count);\n\n\u002F\u002F Set transforms for each instance\nconst dummy = new THREE.Object3D();\nconst matrix = new THREE.Matrix4();\n\nfor (let i = 0; i \u003C count; i++) {\n  dummy.position.set(\n    (Math.random() - 0.5) * 20,\n    (Math.random() - 0.5) * 20,\n    (Math.random() - 0.5) * 20,\n  );\n  dummy.rotation.set(Math.random() * Math.PI, Math.random() * Math.PI, 0);\n  dummy.scale.setScalar(0.5 + Math.random());\n  dummy.updateMatrix();\n\n  instancedMesh.setMatrixAt(i, dummy.matrix);\n}\n\n\u002F\u002F Flag for GPU update\ninstancedMesh.instanceMatrix.needsUpdate = true;\n\n\u002F\u002F Optional: per-instance colors\ninstancedMesh.instanceColor = new THREE.InstancedBufferAttribute(\n  new Float32Array(count * 3),\n  3,\n);\nfor (let i = 0; i \u003C count; i++) {\n  instancedMesh.setColorAt(\n    i,\n    new THREE.Color(Math.random(), Math.random(), Math.random()),\n  );\n}\ninstancedMesh.instanceColor.needsUpdate = true;\n\nscene.add(instancedMesh);\n```\n\n### Update Instance at Runtime\n\n```javascript\n\u002F\u002F Update single instance\nconst matrix = new THREE.Matrix4();\ninstancedMesh.getMatrixAt(index, matrix);\n\u002F\u002F Modify matrix...\ninstancedMesh.setMatrixAt(index, matrix);\ninstancedMesh.instanceMatrix.needsUpdate = true;\n\n\u002F\u002F Raycasting with instanced mesh\nconst intersects = raycaster.intersectObject(instancedMesh);\nif (intersects.length > 0) {\n  const instanceId = intersects[0].instanceId;\n}\n```\n\n## InstancedBufferGeometry (Advanced)\n\nFor custom per-instance attributes beyond transform\u002Fcolor.\n\n```javascript\nconst geometry = new THREE.InstancedBufferGeometry();\ngeometry.copy(new THREE.BoxGeometry(1, 1, 1));\n\n\u002F\u002F Add per-instance attribute\nconst offsets = new Float32Array(count * 3);\nfor (let i = 0; i \u003C count; i++) {\n  offsets[i * 3] = Math.random() * 10;\n  offsets[i * 3 + 1] = Math.random() * 10;\n  offsets[i * 3 + 2] = Math.random() * 10;\n}\ngeometry.setAttribute(\"offset\", new THREE.InstancedBufferAttribute(offsets, 3));\n\n\u002F\u002F Use in shader\n\u002F\u002F attribute vec3 offset;\n\u002F\u002F vec3 transformed = position + offset;\n```\n\n## Geometry Utilities\n\n```javascript\nimport * as BufferGeometryUtils from \"three\u002Fexamples\u002Fjsm\u002Futils\u002FBufferGeometryUtils.js\";\n\n\u002F\u002F Merge geometries (must have same attributes)\nconst merged = BufferGeometryUtils.mergeGeometries([geo1, geo2, geo3]);\n\n\u002F\u002F Merge with groups (for multi-material)\nconst merged = BufferGeometryUtils.mergeGeometries([geo1, geo2], true);\n\n\u002F\u002F Compute tangents (required for normal maps)\nBufferGeometryUtils.computeTangents(geometry);\n\n\u002F\u002F Interleave attributes for better performance\nconst interleaved = BufferGeometryUtils.interleaveAttributes([\n  geometry.attributes.position,\n  geometry.attributes.normal,\n  geometry.attributes.uv,\n]);\n```\n\n## Common Patterns\n\n### Center Geometry\n\n```javascript\ngeometry.computeBoundingBox();\ngeometry.center(); \u002F\u002F Move vertices so center is at origin\n```\n\n### Scale to Fit\n\n```javascript\ngeometry.computeBoundingBox();\nconst size = new THREE.Vector3();\ngeometry.boundingBox.getSize(size);\nconst maxDim = Math.max(size.x, size.y, size.z);\ngeometry.scale(1 \u002F maxDim, 1 \u002F maxDim, 1 \u002F maxDim);\n```\n\n### Clone and Transform\n\n```javascript\nconst clone = geometry.clone();\nclone.rotateX(Math.PI \u002F 2);\nclone.translate(0, 1, 0);\nclone.scale(2, 2, 2);\n```\n\n### Morph Targets\n\n```javascript\n\u002F\u002F Base geometry\nconst geometry = new THREE.BoxGeometry(1, 1, 1, 4, 4, 4);\n\n\u002F\u002F Create morph target\nconst morphPositions = geometry.attributes.position.array.slice();\nfor (let i = 0; i \u003C morphPositions.length; i += 3) {\n  morphPositions[i] *= 2; \u002F\u002F Scale X\n  morphPositions[i + 1] *= 0.5; \u002F\u002F Squash Y\n}\n\ngeometry.morphAttributes.position = [\n  new THREE.BufferAttribute(new Float32Array(morphPositions), 3),\n];\n\nconst mesh = new THREE.Mesh(geometry, material);\nmesh.morphTargetInfluences[0] = 0.5; \u002F\u002F 50% blend\n```\n\n## Performance Tips\n\n1. **Use indexed geometry**: Reuse vertices with indices\n2. **Merge static meshes**: Reduce draw calls with `mergeGeometries`\n3. **Use InstancedMesh**: For many identical objects\n4. **Choose appropriate segment counts**: More segments = smoother but slower\n5. **Dispose unused geometry**: `geometry.dispose()`\n\n```javascript\n\u002F\u002F Good segment counts for common uses\nnew THREE.SphereGeometry(1, 32, 32); \u002F\u002F Good quality\nnew THREE.SphereGeometry(1, 64, 64); \u002F\u002F High quality\nnew THREE.SphereGeometry(1, 16, 16); \u002F\u002F Performance mode\n\n\u002F\u002F Dispose when done\ngeometry.dispose();\n```\n\n## See Also\n\n- `threejs-fundamentals` - Scene setup and Object3D\n- `threejs-materials` - Material types for meshes\n- `threejs-shaders` - Custom vertex manipulation\n","# Three.js Geometry\n\n## Quick Start\n\n```javascript\nimport * as THREE from \"three\";\n\n\u002F\u002F Built-in geometry\nconst box = new THREE.BoxGeometry(1, 1, 1);\nconst sphere = new THREE.SphereGeometry(0.5, 32, 32);\nconst plane = new THREE.PlaneGeometry(10, 10);\n\n\u002F\u002F Create mesh\nconst material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });\nconst mesh = new THREE.Mesh(box, material);\nscene.add(mesh);\n```\n\n## Built-in Geometries\n\n### Basic Shapes\n\n```javascript\n\u002F\u002F Box - width, height, depth, widthSegments, heightSegments, depthSegments\nnew THREE.BoxGeometry(1, 1, 1, 1, 1, 1);\n\n\u002F\u002F Sphere - radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength\nnew THREE.SphereGeometry(1, 32, 32);\nnew THREE.SphereGeometry(1, 32, 32, 0, Math.PI * 2, 0, Math.PI); \u002F\u002F Full sphere\nnew THREE.SphereGeometry(1, 32, 32, 0, Math.PI); \u002F\u002F Hemisphere\n\n\u002F\u002F Plane - width, height, widthSegments, heightSegments\nnew THREE.PlaneGeometry(10, 10, 1, 1);\n\n\u002F\u002F Circle - radius, segments, thetaStart, thetaLength\nnew THREE.CircleGeometry(1, 32);\nnew THREE.CircleGeometry(1, 32, 0, Math.PI); \u002F\u002F Semicircle\n\n\u002F\u002F Cylinder - radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded\nnew THREE.CylinderGeometry(1, 1, 2, 32, 1, false);\nnew THREE.CylinderGeometry(0, 1, 2, 32); \u002F\u002F Cone\nnew THREE.CylinderGeometry(1, 1, 2, 6); \u002F\u002F Hexagonal prism\n\n\u002F\u002F Cone - radius, height, radialSegments, heightSegments, openEnded\nnew THREE.ConeGeometry(1, 2, 32, 1, false);\n\n\u002F\u002F Torus - radius, tube, radialSegments, tubularSegments, arc\nnew THREE.TorusGeometry(1, 0.4, 16, 100);\n\n\u002F\u002F TorusKnot - radius, tube, tubularSegments, radialSegments, p, q\nnew THREE.TorusKnotGeometry(1, 0.4, 100, 16, 2, 3);\n\n\u002F\u002F Ring - innerRadius, outerRadius, thetaSegments, phiSegments\nnew THREE.RingGeometry(0.5, 1, 32, 1);\n```\n\n### Advanced Shapes\n\n```javascript\n\u002F\u002F Capsule - radius, length, capSegments, radialSegments\nnew THREE.CapsuleGeometry(0.5, 1, 4, 8);\n\n\u002F\u002F Dodecahedron - radius, detail\nnew THREE.DodecahedronGeometry(1, 0);\n\n\u002F\u002F Icosahedron - radius, detail (0 = 20 faces, higher = smoother)\nnew THREE.IcosahedronGeometry(1, 0);\n\n\u002F\u002F Octahedron - radius, detail\nnew THREE.OctahedronGeometry(1, 0);\n\n\u002F\u002F Tetrahedron - radius, detail\nnew THREE.TetrahedronGeometry(1, 0);\n\n\u002F\u002F Polyhedron - vertices, indices, radius, detail\nconst vertices = [1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1];\nconst indices = [2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1];\nnew THREE.PolyhedronGeometry(vertices, indices, 1, 0);\n```\n\n### Path-Based Shapes\n\n```javascript\n\u002F\u002F Lathe - points[], segments, phiStart, phiLength\nconst points = [\n  new THREE.Vector2(0, 0),\n  new THREE.Vector2(0.5, 0),\n  new THREE.Vector2(0.5, 1),\n  new THREE.Vector2(0, 1),\n];\nnew THREE.LatheGeometry(points, 32);\n\n\u002F\u002F Extrude - shape, options\nconst shape = new THREE.Shape();\nshape.moveTo(0, 0);\nshape.lineTo(1, 0);\nshape.lineTo(1, 1);\nshape.lineTo(0, 1);\nshape.lineTo(0, 0);\n\nconst extrudeSettings = {\n  steps: 2,\n  depth: 1,\n  bevelEnabled: true,\n  bevelThickness: 0.1,\n  bevelSize: 0.1,\n  bevelSegments: 3,\n};\nnew THREE.ExtrudeGeometry(shape, extrudeSettings);\n\n\u002F\u002F Tube - path, tubularSegments, radius, radialSegments, closed\nconst curve = new THREE.CatmullRomCurve3([\n  new THREE.Vector3(-1, 0, 0),\n  new THREE.Vector3(0, 1, 0),\n  new THREE.Vector3(1, 0, 0),\n]);\nnew THREE.TubeGeometry(curve, 64, 0.2, 8, false);\n```\n\n### Text Geometry\n\n```javascript\nimport { FontLoader } from \"three\u002Fexamples\u002Fjsm\u002Floaders\u002FFontLoader.js\";\nimport { TextGeometry } from \"three\u002Fexamples\u002Fjsm\u002Fgeometries\u002FTextGeometry.js\";\n\nconst loader = new FontLoader();\nloader.load(\"fonts\u002Fhelvetiker_regular.typeface.json\", (font) => {\n  const geometry = new TextGeometry(\"Hello\", {\n    font: font,\n    size: 1,\n    depth: 0.2, \u002F\u002F Was 'height' in older versions\n    curveSegments: 12,\n    bevelEnabled: true,\n    bevelThickness: 0.03,\n    bevelSize: 0.02,\n    bevelSegments: 5,\n  });\n\n  \u002F\u002F Center text\n  geometry.computeBoundingBox();\n  geometry.center();\n\n  const mesh = new THREE.Mesh(geometry, material);\n  scene.add(mesh);\n});\n```\n\n## BufferGeometry\n\nThe base class for all geometries. Stores data as typed arrays for GPU efficiency.\n\n### Custom BufferGeometry\n\n```javascript\nconst geometry = new THREE.BufferGeometry();\n\n\u002F\u002F Vertices (3 floats per vertex: x, y, z)\nconst vertices = new Float32Array([\n  -1,\n  -1,\n  0, \u002F\u002F vertex 0\n  1,\n  -1,\n  0, \u002F\u002F vertex 1\n  1,\n  1,\n  0, \u002F\u002F vertex 2\n  -1,\n  1,\n  0, \u002F\u002F vertex 3\n]);\ngeometry.setAttribute(\"position\", new THREE.BufferAttribute(vertices, 3));\n\n\u002F\u002F Indices (for indexed geometry - reuse vertices)\nconst indices = new Uint16Array([\n  0,\n  1,\n  2, \u002F\u002F triangle 1\n  0,\n  2,\n  3, \u002F\u002F triangle 2\n]);\ngeometry.setIndex(new THREE.BufferAttribute(indices, 1));\n\n\u002F\u002F Normals (required for lighting)\nconst normals = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]);\ngeometry.setAttribute(\"normal\", new THREE.BufferAttribute(normals, 3));\n\n\u002F\u002F UVs (for texturing)\nconst uvs = new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]);\ngeometry.setAttribute(\"uv\", new THREE.BufferAttribute(uvs, 2));\n\n\u002F\u002F Colors (per-vertex colors)\nconst colors = new Float32Array([\n  1,\n  0,\n  0, \u002F\u002F red\n  0,\n  1,\n  0, \u002F\u002F green\n  0,\n  0,\n  1, \u002F\u002F blue\n  1,\n  1,\n  0, \u002F\u002F yellow\n]);\ngeometry.setAttribute(\"color\", new THREE.BufferAttribute(colors, 3));\n\u002F\u002F Use with: material.vertexColors = true\n```\n\n### BufferAttribute Types\n\n```javascript\n\u002F\u002F Common attribute types\nnew THREE.BufferAttribute(array, itemSize);\n\n\u002F\u002F Typed array options\nnew Float32Array(count * itemSize); \u002F\u002F Positions, normals, UVs\nnew Uint16Array(count); \u002F\u002F Indices (up to 65535 vertices)\nnew Uint32Array(count); \u002F\u002F Indices (larger meshes)\nnew Uint8Array(count * itemSize); \u002F\u002F Colors (0-255 range)\n\n\u002F\u002F Item sizes\n\u002F\u002F Position: 3 (x, y, z)\n\u002F\u002F Normal: 3 (x, y, z)\n\u002F\u002F UV: 2 (u, v)\n\u002F\u002F Color: 3 (r, g, b) or 4 (r, g, b, a)\n\u002F\u002F Index: 1\n```\n\n### Modifying BufferGeometry\n\n```javascript\nconst positions = geometry.attributes.position;\n\n\u002F\u002F Modify vertex\npositions.setXYZ(index, x, y, z);\n\n\u002F\u002F Access vertex\nconst x = positions.getX(index);\nconst y = positions.getY(index);\nconst z = positions.getZ(index);\n\n\u002F\u002F Flag for GPU update\npositions.needsUpdate = true;\n\n\u002F\u002F Recompute normals after position changes\ngeometry.computeVertexNormals();\n\n\u002F\u002F Recompute bounding box\u002Fsphere after changes\ngeometry.computeBoundingBox();\ngeometry.computeBoundingSphere();\n```\n\n### Interleaved Buffers (Advanced)\n\n```javascript\n\u002F\u002F More efficient memory layout for large meshes\nconst interleavedBuffer = new THREE.InterleavedBuffer(\n  new Float32Array([\n    \u002F\u002F pos.x, pos.y, pos.z, uv.u, uv.v (repeated per vertex)\n    -1, -1, 0, 0, 0, 1, -1, 0, 1, 0, 1, 1, 0, 1, 1, -1, 1, 0, 0, 1,\n  ]),\n  5, \u002F\u002F stride (floats per vertex)\n);\n\ngeometry.setAttribute(\n  \"position\",\n  new THREE.InterleavedBufferAttribute(interleavedBuffer, 3, 0),\n); \u002F\u002F size 3, offset 0\ngeometry.setAttribute(\n  \"uv\",\n  new THREE.InterleavedBufferAttribute(interleavedBuffer, 2, 3),\n); \u002F\u002F size 2, offset 3\n```\n\n## EdgesGeometry & WireframeGeometry\n\n```javascript\n\u002F\u002F Edge lines (only hard edges)\nconst edges = new THREE.EdgesGeometry(boxGeometry, 15); \u002F\u002F 15 = threshold angle\nconst edgeMesh = new THREE.LineSegments(\n  edges,\n  new THREE.LineBasicMaterial({ color: 0xffffff }),\n);\n\n\u002F\u002F Wireframe (all triangles)\nconst wireframe = new THREE.WireframeGeometry(boxGeometry);\nconst wireMesh = new THREE.LineSegments(\n  wireframe,\n  new THREE.LineBasicMaterial({ color: 0xffffff }),\n);\n```\n\n## Points\n\n```javascript\n\u002F\u002F Create point cloud\nconst geometry = new THREE.BufferGeometry();\nconst positions = new Float32Array(1000 * 3);\n\nfor (let i = 0; i \u003C 1000; i++) {\n  positions[i * 3] = (Math.random() - 0.5) * 10;\n  positions[i * 3 + 1] = (Math.random() - 0.5) * 10;\n  positions[i * 3 + 2] = (Math.random() - 0.5) * 10;\n}\n\ngeometry.setAttribute(\"position\", new THREE.BufferAttribute(positions, 3));\n\nconst material = new THREE.PointsMaterial({\n  size: 0.1,\n  sizeAttenuation: true, \u002F\u002F Size decreases with distance\n  color: 0xffffff,\n});\n\nconst points = new THREE.Points(geometry, material);\nscene.add(points);\n```\n\n## Lines\n\n```javascript\n\u002F\u002F Line (connected points)\nconst points = [\n  new THREE.Vector3(-1, 0, 0),\n  new THREE.Vector3(0, 1, 0),\n  new THREE.Vector3(1, 0, 0),\n];\nconst geometry = new THREE.BufferGeometry().setFromPoints(points);\nconst line = new THREE.Line(\n  geometry,\n  new THREE.LineBasicMaterial({ color: 0xff0000 }),\n);\n\n\u002F\u002F LineLoop (closed loop)\nconst loop = new THREE.LineLoop(geometry, material);\n\n\u002F\u002F LineSegments (pairs of points)\nconst segmentsGeometry = new THREE.BufferGeometry();\nsegmentsGeometry.setAttribute(\n  \"position\",\n  new THREE.BufferAttribute(\n    new Float32Array([\n      -1,\n      0,\n      0,\n      0,\n      1,\n      0, \u002F\u002F segment 1\n      0,\n      1,\n      0,\n      1,\n      0,\n      0, \u002F\u002F segment 2\n    ]),\n    3,\n  ),\n);\nconst segments = new THREE.LineSegments(segmentsGeometry, material);\n```\n\n## InstancedMesh\n\nEfficiently render many copies of the same geometry.\n\n```javascript\nconst geometry = new THREE.BoxGeometry(1, 1, 1);\nconst material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });\nconst count = 1000;\n\nconst instancedMesh = new THREE.InstancedMesh(geometry, material, count);\n\n\u002F\u002F Set transforms for each instance\nconst dummy = new THREE.Object3D();\nconst matrix = new THREE.Matrix4();\n\nfor (let i = 0; i \u003C count; i++) {\n  dummy.position.set(\n    (Math.random() - 0.5) * 20,\n    (Math.random() - 0.5) * 20,\n    (Math.random() - 0.5) * 20,\n  );\n  dummy.rotation.set(Math.random() * Math.PI, Math.random() * Math.PI, 0);\n  dummy.scale.setScalar(0.5 + Math.random());\n  dummy.updateMatrix();\n\n  instancedMesh.setMatrixAt(i, dummy.matrix);\n}\n\n\u002F\u002F Flag for GPU update\ninstancedMesh.instanceMatrix.needsUpdate = true;\n\n\u002F\u002F Optional: per-instance colors\ninstancedMesh.instanceColor = new THREE.InstancedBufferAttribute(\n  new Float32Array(count * 3),\n  3,\n);\nfor (let i = 0; i \u003C count; i++) {\n  instancedMesh.setColorAt(\n    i,\n    new THREE.Color(Math.random(), Math.random(), Math.random()),\n  );\n}\ninstancedMesh.instanceColor.needsUpdate = true;\n\nscene.add(instancedMesh);\n```\n\n### Update Instance at Runtime\n\n```javascript\n\u002F\u002F Update single instance\nconst matrix = new THREE.Matrix4();\ninstancedMesh.getMatrixAt(index, matrix);\n\u002F\u002F Modify matrix...\ninstancedMesh.setMatrixAt(index, matrix);\ninstancedMesh.instanceMatrix.needsUpdate = true;\n\n\u002F\u002F Raycasting with instanced mesh\nconst intersects = raycaster.intersectObject(instancedMesh);\nif (intersects.length > 0) {\n  const instanceId = intersects[0].instanceId;\n}\n```\n\n## InstancedBufferGeometry (Advanced)\n\nFor custom per-instance attributes beyond transform\u002Fcolor.\n\n```javascript\nconst geometry = new THREE.InstancedBufferGeometry();\ngeometry.copy(new THREE.BoxGeometry(1, 1, 1));\n\n\u002F\u002F Add per-instance attribute\nconst offsets = new Float32Array(count * 3);\nfor (let i = 0; i \u003C count; i++) {\n  offsets[i * 3] = Math.random() * 10;\n  offsets[i * 3 + 1] = Math.random() * 10;\n  offsets[i * 3 + 2] = Math.random() * 10;\n}\ngeometry.setAttribute(\"offset\", new THREE.InstancedBufferAttribute(offsets, 3));\n\n\u002F\u002F Use in shader\n\u002F\u002F attribute vec3 offset;\n\u002F\u002F vec3 transformed = position + offset;\n```\n\n## Geometry Utilities\n\n```javascript\nimport * as BufferGeometryUtils from \"three\u002Fexamples\u002Fjsm\u002Futils\u002FBufferGeometryUtils.js\";\n\n\u002F\u002F Merge geometries (must have same attributes)\nconst merged = BufferGeometryUtils.mergeGeometries([geo1, geo2, geo3]);\n\n\u002F\u002F Merge with groups (for multi-material)\nconst merged = BufferGeometryUtils.mergeGeometries([geo1, geo2], true);\n\n\u002F\u002F Compute tangents (required for normal maps)\nBufferGeometryUtils.computeTangents(geometry);\n\n\u002F\u002F Interleave attributes for better performance\nconst interleaved = BufferGeometryUtils.interleaveAttributes([\n  geometry.attributes.position,\n  geometry.attributes.normal,\n  geometry.attributes.uv,\n]);\n```\n\n## Common Patterns\n\n### Center Geometry\n\n```javascript\ngeometry.computeBoundingBox();\ngeometry.center(); \u002F\u002F Move vertices so center is at origin\n```\n\n### Scale to Fit\n\n```javascript\ngeometry.computeBoundingBox();\nconst size = new THREE.Vector3();\ngeometry.boundingBox.getSize(size);\nconst maxDim = Math.max(size.x, size.y, size.z);\ngeometry.scale(1 \u002F maxDim, 1 \u002F maxDim, 1 \u002F maxDim);\n```\n\n### Clone and Transform\n\n```javascript\nconst clone = geometry.clone();\nclone.rotateX(Math.PI \u002F 2);\nclone.translate(0, 1, 0);\nclone.scale(2, 2, 2);\n```\n\n### Morph Targets\n\n```javascript\n\u002F\u002F Base geometry\nconst geometry = new THREE.BoxGeometry(1, 1, 1, 4, 4, 4);\n\n\u002F\u002F Create morph target\nconst morphPositions = geometry.attributes.position.array.slice();\nfor (let i = 0; i \u003C morphPositions.length; i += 3) {\n  morphPositions[i] *= 2; \u002F\u002F Scale X\n  morphPositions[i + 1] *= 0.5; \u002F\u002F Squash Y\n}\n\ngeometry.morphAttributes.position = [\n  new THREE.BufferAttribute(new Float32Array(morphPositions), 3),\n];\n\nconst mesh = new THREE.Mesh(geometry, material);\nmesh.morphTargetInfluences[0] = 0.5; \u002F\u002F 50% blend\n```\n\n## Performance Tips\n\n1. **Use indexed geometry**: Reuse vertices with indices\n2. **Merge static meshes**: Reduce draw calls with `mergeGeometries`\n3. **Use InstancedMesh**: For many identical objects\n4. **Choose appropriate segment counts**: More segments = smoother but slower\n5. **Dispose unused geometry**: `geometry.dispose()`\n\n```javascript\n\u002F\u002F Good segment counts for common uses\nnew THREE.SphereGeometry(1, 32, 32); \u002F\u002F Good quality\nnew THREE.SphereGeometry(1, 64, 64); \u002F\u002F High quality\nnew THREE.SphereGeometry(1, 16, 16); \u002F\u002F Performance mode\n\n\u002F\u002F Dispose when done\ngeometry.dispose();\n```\n\n## See Also\n\n- `threejs-fundamentals` - Scene setup and Object3D\n- `threejs-materials` - Material types for meshes\n- `threejs-shaders` - Custom vertex manipulation\n",{"name":5,"risk":30,"source":25,"description":7},"main","7a38d8e7073e61c16eda85681cb32fb68a8657a5","skills-store\u002Fglobal\u002Fthreejs-geometry","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router","https:\u002F\u002Fgithub.com\u002Fsapsapshen","2026-04-14 21:12:12",{"source":8,"skillName":5,"commands":45,"prompt":55,"zipAvailable":56},[46,49,52],{"tool":47,"command":48},"npx","npx skills add sapsapshen\u002Fai-memory-router --skill threejs-geometry",{"tool":50,"command":51},"bunx","bunx skills add sapsapshen\u002Fai-memory-router --skill threejs-geometry",{"tool":53,"command":54},"pnpm","pnpm dlx skills add sapsapshen\u002Fai-memory-router --skill threejs-geometry","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fglobal\u002Fthreejs-geometry\u002FSKILL.md",true,[],[59,82,107,117,130,149],{"skillNo":60,"name":61,"nameZh":6,"description":62,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":63,"categories":64,"keywords":70,"publishedAt":33},"01M71ATQRKG48SH06FQ697T5G9","wechat-search","Search WeChat Official Account articles using OpenClaw's web search and fetch capabilities with compliance-focused design.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fwechat-search-release\u002FSKILL.md",[65],{"categoryNo":66,"categoryName":67,"taxonomyType":68,"taxonomyTypeDesc":69},"01JBSEEDCAT000000000000037","律师与法务","PROFESSION","适用职业",[71,72,73,74,75,76,77,78,79,80,81,29],"wechat search","wechat","search","capabilities","openclaw","design","web search","compliance","web","official","fetch",{"skillNo":83,"name":84,"nameZh":6,"description":85,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":86,"categories":87,"keywords":88,"publishedAt":33},"01M71ATNAVGZB35PFYM2GC5N00","trend-tap","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend tap', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-tap\u002FSKILL.md",[],[89,90,91,92,93,94,73,95,96,97,98,32,99,100,101,102,103,104,105,106],"trend","trend tap","tap","api keys","Bash","time","trending","hacker","aggregator","do","brew","live","data","google","install","read","across","api",{"skillNo":108,"name":109,"nameZh":6,"description":110,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":111,"categories":112,"keywords":113,"publishedAt":33},"01M71ATJ9AM5KM15AA8PS302EB","trend-radar","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend pulse', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-radar\u002FSKILL.md",[],[114,115,89,99,100,101,102,93,73,104,116,105,106,32,97,96,95,103,94,92],"trend radar","radar","pulse",{"skillNo":118,"name":119,"nameZh":6,"description":120,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":121,"categories":122,"keywords":123,"publishedAt":33},"01M71ATGF095N3EJM9G8SD0BB5","tech-news-daily","每日科技新闻汇——从全球多个 RSS 源抓取最新科技新闻，翻译（英→中）、去重、排版成每日简报。当用户询问科技新闻、科技新鲜事、每日科技、技术动态、Daily Tech News 或类似表达时触发此技能。","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftech-news-daily\u002FSKILL.md",[],[124,125,126,127,128,129],"news","tech","tech news daily","daily","rss","翻译",{"skillNo":131,"name":132,"nameZh":6,"description":133,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":134,"categories":135,"keywords":141,"publishedAt":33},"01M71ATFAEAMQ17M70NQNY7SR8","summarize","Summarize URLs or files with the summarize CLI (web, PDFs, images, audio, YouTube).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsummarize\u002FSKILL.md",[136],{"categoryNo":137,"categoryName":138,"taxonomyType":139,"taxonomyTypeDesc":140},"01JBSEEDCAT000000000000021","资料检索与研究","SCENARIO","使用场景",[132,79,142,143,144,29,99,145,146,147,91,148,103],"Audio","cli","youtube","images","https","files","pdfs",{"skillNo":150,"name":151,"nameZh":6,"description":152,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":153,"categories":154,"keywords":155,"publishedAt":33},"01M71ATDNS3R0M4H936PACQAWZ","sonoscli","Control Sonos speakers (discover\u002Fstatus\u002Fplay\u002Fvolume\u002Fgroup).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsonoscli\u002FSKILL.md",[],[151,156,157,158,103,159,146,160,161,162,163,164],"status","play","go","latest","github","discover","control","cmd","volume"]