ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

TheBigPromptLibrary 中的 Decentraland SDK7 Coder GPT:一份可复用的 DOD 场景开发 API 手册

TheBigPromptLibrary 中的 Decentraland SDK7 Coder GPT:一份可复用的 DOD 场景开发 API 手册
  • 提示工程
  • AI 安全治理

【免费下载链接】TheBigPromptLibrary

A collection of prompts, system prompts and LLM instructions

项目地址:https://gitcode.com/gh_mirrors/th/TheBigPromptLibrary
点击查看免费下载

本篇基于 2aD2Y5SiB_Decentraland_SDK7_Coder.md 这份自定义 GPT 指令文件展开:它把 Decentraland SDK7 从 OOP(对象导向)迁移到 DOD(数据导向设计,Data-Oriented Design,ECS 实体-组件-系统架构)后的整套核心 API 压缩进了一个 GPT 的系统指令中。读完后你将掌握:SDK7 场景代码的标准骨架(固定 imports +main()入口)、实体与组件的增删改查、GLTF 模型与 Animator 动画状态、形状/碰撞/材质/文本、System 优先级调度、几何向量与四元数运算、音频、指针交互、玩家与表情触发等全套编码模式,以及这份“指令即文档”的提示词工程写法。

1. 这个 GPT 是什么:把 SDK 速查表写进系统指令

该文件位于仓库 CustomInstructions/ChatGPT 目录(在 CustomInstructions/README.md 的 GPT 清单中以 id2aD2Y5SiB登记)。文件开头的元信息如下:

  • GPT Title:Decentraland SDK7 Coder
  • GPT Description:Generates code for decentraland scenes in SDK7 (DOD) - By Parutkin

其核心定位由指令的第一句话给出:

The new Decentraland SDK7 shifted from Object-Oriented Programming (OOP) approach to a Data-Oriented Design (DOD)

也就是说,这个 GPT 的职责是“SDK7 DOD 代码生成器”:它不依赖模型自身记忆,而是把官方文档中最容易出错的 API 签名(imports、组件方法、动画状态、输入动作枚举等)全部固化为指令内容,并要求模型“严格按此生成”。文件末尾还声明了知识库附件Decentraland SDK7 Docs.md(GPT Kb Files List),用于在对话中检索更完整的官方文档细节;从仓库结构看,该知识库文件并未随仓库归档,本文所有 API 事实均来自该 GPT 指令文件本身。

从源码结构看,这类“指令即文档”的写法是整个 TheBigPromptLibrary 仓库收录的典型 GPT 形态:把领域速查表直接作为 system prompt,让模型输出与特定框架 API 严格一致的代码,减少幻觉出不存在的旧版 OOP 类名(如 SDK5/6 时代的Object3D风格用法)。

2. 场景代码骨架:固定 imports 与main()入口

指令对 imports 有一条强约束:“always use the exact import as shown here, even if the code does not need them”(始终按原样使用以下 import,即使代码用不到)。这是保证生成代码可直接编译的策略——SDK7 的 ECS API 分散在@dcl/sdk/ecs与@dcl/sdk/math两个包中,漏导入是新手最高频的报错。完整导入块如下:

// Imports start import { Quaternion, Vector3 } from '@dcl/sdk/math' import { Animator, AudioSource, AvatarAttach, GltfContainer, Material, Transform, VideoPlayer, VisibilityComponent, engine, pointerEventsSystem, Name, triggerEmote, triggerSceneEmote, } from '@dcl/sdk/ecs' import { onEnterScene, onLeaveScene } from '@dcl/sdk/src/players' // imports end

注意导入块的结构信息:

  • @dcl/sdk/math提供数学类型(Vector3、Quaternion等);
  • @dcl/sdk/ecs提供 ECS 核心(engine、组件、pointerEventsSystem、表情触发函数等);
  • @dcl/sdk/src/players提供玩家进出场景回调onEnterScene/onLeaveScene。

场景逻辑统一运行在主函数中:

export function main() { // scenes code }

因此任何让该 GPT 生成场景的请求,产出代码都应能套入“imports +main()”这个骨架:初始化放在main()内(建实体、加组件、注册交互),逐帧逻辑放在 System 里(见第 8 节)。

3. 实体(Entities):创建、层级与挂载

SDK7 中一切可视/可交互对象都是“实体(entity)”,层级关系由Transform组件的parent字段表达。指令给出的实体操作全集:

// 创建实体 const entity = engine.addEntity(); // 删除单个实体 engine.removeEntity(entity); // 删除实体及其所有子实体 removeEntityWithChildren(engine, parentEntity); // 指定父实体(建立父子关系) Transform.create(childEntity, { parent: parentEntity }); // 把子实体从父实体上分离(挂回场景根) Transform.getMutable(childEntity).parent = engine.RootEntity; // 把实体挂载到玩家头像上 Transform.create(attachedEntity, { scale: Vector3.create(1, 1, 1), position: Vector3.create(0, 2, 0), parent: engine.PlayerEntity, // 或 engine.CameraEntity 做相机挂载 });

要点:

  • 两个特殊父节点:engine.PlayerEntity(挂在玩家头像坐标下)和engine.CameraEntity(挂在相机下,适合做“跟随视角”的 UI 或特效);
  • 分离子实体不需要专门 API,直接改parent为engine.RootEntity即可;
  • 批量清理用removeEntityWithChildren,避免留下孤儿节点。

4. 组件(Components):Schema、自定义组件与 CRUD

4.1 Schema 内置类型

自定义组件通过engine.defineComponent(name, schema)定义,schema 字段支持的基础类型:

Schemas.Boolean / Schemas.Byte / Schemas.Double / Schemas.Float / Schemas.Int / Schemas.Int64 / Schemas.Number / Schemas.Short / Schemas.String / Schemas.Entity

以及带嵌套数值属性的复合类型:

Schemas.Vector3 / Schemas.Quaternion / Schemas.Color3 / Schemas.Color4

4.2 组件定义示例:从标记位到复杂结构

指令给出了由浅入深的三个定义示例:

// 标记(Flag)组件:无字段,只表示“有/没有” export const IsEnemyFlag = engine.defineComponent("isEnemyFlag", {}); // 带 Schema 的组件 export const WheelSpinComponent = engine.defineComponent("wheelSpinComponent", { spinning: Schemas.Boolean, speed: Schemas.Float }); // 含数组、嵌套结构(Map)与枚举(OneOf)的复杂 Schema const MySchema = { numberList: Schemas.Array(Schemas.Int), myComplexField: Schemas.Map({ nestedField1: Schemas.Boolean, nestedField2: Schemas.Boolean }), myField: Schemas.OneOf({ type1: Schemas.Vector3, type2: Schemas.Quaternion }) };

Schemas.Array、Schemas.Map、Schemas.OneOf展示了 ECS 数据可以在组件内组合成数组、嵌套对象和“多态”字段,这是 DOD 相对 OOP 的核心优势:状态数据与行为分离,且可被序列化/同步。

4.3 组件的查询与变更 API

操作API
给实体命名Name.create(entity, { value: 'entityNameString' })
按名查找实体engine.getEntityOrNullByName('entityNameString')
新增或替换组件(避免重复组件报错)Transform.createOrReplace(entity, { position: Vector3.create(x, y, z) })
判断实体是否有某组件Transform.has(entity)
从实体移除某组件Transform.deleteFrom(entity)
只读访问组件Transform.get(entity)
可变访问组件(用于修改)Transform.getMutable(entity)
遍历拥有某组件的全部实体engine.getEntitiesWith(Transform)
让实体始终朝向玩家Billboard.create(entity, { billboardMode: BillboardMode.BM_Y })

对应代码:

// Add name to an entity Name.create(entity, { value: 'entityNameString' }) // Fetching an entity by name const namedEntity = engine.getEntityOrNullByName('entityNameString') // Adding or replacing a component to prevent errors due to duplicate components Transform.createOrReplace(entity, { position: Vector3.create(x, y, z) }) // Checking if an entity has a specific component const hasTransform = Transform.has(entity) // Removing a specific component from an entity Transform.deleteFrom(entity) // Accessing a read-only version of a component const transform = Transform.get(entity) // Accessing a mutable version of a component for modifications const mutableTransform = Transform.getMutable(entity) mutableTransform.scale.x = 5 // Loop through components for (const [entity] of engine.getEntitiesWith(Transform)) { const transform = Transform.getMutable(entity) // Do calculations } // Entity face the player Billboard.create(entity, { billboardMode: BillboardMode.BM_Y })

这里值得强调的两个工程细节(指令原文即以此为注记):

  • createOrReplace防重复:对已带Transform的实体再create会因“重复组件”抛错,替换语义更安全;
  • get只读、getMutable可写:想改数据必须走 mutable 通道;
  • getEntitiesWith(Component)是 ECS 的“查询”原语——不需要维护对象引用列表,按组件类型即可遍历,这是 DOD 与 OOP 在组织方式上的本质区别。

5. GLTF 模型与 Animator 动画

加载模型与驱动动画是 DOD 场景最常用的组合:

GltfContainer.create(entity, { src: 'models/myModel.glb' }) // 3D 模型带动画 GltfContainer.create(entity, { src: 'models/shark.glb' }) Animator.create(entity, { states: [ { clip: 'swim', playing: true, loop: true, speed: 1, weight: 1, shouldReset: false }, { clip: 'bite', playing: false, loop: false } ], })

Animator的状态数组里每个 clip 可配置:playing(是否播放)、loop(是否循环)、speed(播放速率)、weight(混合权重)、shouldReset(是否重置姿态)。运行时对动画的操控:

// 取回某个 clip 状态 const swimAnim = Animator.getClip(shark, 'swim') // 播放单一动画并停止其余动画 Animator.playSingleAnimation(entity, 'swim', true) // 停止全部动画 Animator.stopAllAnimations(entity)

getClip返回的 clip 状态同样可以通过 mutable 方式修改weight/speed,从而实现“游动 + 咬合”两个状态间的淡入淡出(blend)。

6. 形状、碰撞体、材质与文本

不用外部模型时,SDK7 提供内置几何体、文本与碰撞体组件。指令收录的 API:

// 内置形状 MeshRenderer.setBox(entity) MeshRenderer.setPlane(entity) MeshRenderer.setSphere(entity) MeshRenderer.setCylinder(entity, 1, 1) MeshRenderer.setCylinder(entity, 0, 1) // 半径为 0 的圆柱即圆锥(cone) // 文本 TextShape.create(entity, { text: 'Hello \nWorld', textColor: Color4.create(1, 0, 0, 1), fontSize: 5, lineCount: 2, lineSpacing: "30px", }) // 碰撞体 MeshCollider.setBox(entity) MeshCollider.setPlane(entity) // …

材质部分给出 PBR 材质完整示例:

// Attach material Material.setPbrMaterial(entity, { albedoColor: Color4.Red(), metallic: 0.8, roughness: 0.1, texture: Material.Texture.Common({ src: 'materials/wood.png' }), bumpTexture: Material.Texture.Common({ src: 'materials/woodBump.png' }) })

参数含义:albedoColor基础色、metallic金属度(0~1)、roughness粗糙度(0~1,越小越光滑),texture/bumpTexture分别挂贴图与凹凸贴图。从指令示例看,这套写法让 GPT 生成的场景“开箱即有质感”,而不用手写MeshRenderer+Material的低层组合。

7. System:逐帧逻辑与优先级调度

所有“每帧执行”的逻辑都封装为 System。指令明确要求:持久变量必须声明在 System 函数之外(否则每帧被重置):

// Basic system declaration and addition to engine // Persistent variables have to be declared outside of system function mySystem(dt: number) { console.log("Performed on every tick. My system is running") } // Add system (the number is the priority, low = first, high = last) engine.addSystem(mySystem, 1, 'systemNameString') // Remove system engine.removeSystem('systemNameString')

要点:

  • System 签名为(dt: number) => void,dt是帧间隔(毫秒),做移动/旋转等时间相关计算时应以它为基准,保证不同帧率下行为一致;
  • engine.addSystem(fn, priority, name)中第二参数是优先级:数值小的先执行,数值大的后执行,因此“先做输入/状态更新、后做物理/动画结算”的多 System 场景可通过优先级排序;
  • 以名字为句柄移除 System(engine.removeSystem('systemNameString')),便于做场景内“开关式”的逻辑模块。

8. 几何工具:向量与四元数

// 方向向量快捷方法 Vector3.Up(); Vector3.Down(); Vector3.Left(); Vector3.Right(); Vector3.Forward(); Vector3.Backward() // 创建四元数 let myQuaternion = Quaternion.create(0, 0, 0, 1) // 欧拉角(度)转四元数 let fromEuler = Quaternion.fromEulerDegrees(90, 0, 0) // 四元数转欧拉角 let toEuler = Quaternion.toEulerAngles(myQuaternion) // 标量工具函数 let random = Scalar.randomRange(1, 100) let midPointScalar = Scalar.lerp(1, 10, 0.5) let clampedValue = Scalar.clamp(150, 0, 100)

工程上常用的模式是:从欧拉角构造旋转(Quaternion.fromEulerDegrees)→ 写入Transform的rotation;反向调试时用toEulerAngles还原可读的角度值。Scalar.randomRange / lerp / clamp则覆盖了随机分布、插值与取值截断这三类高频小工具。

9. 音频:AudioSource

AudioSource.create(entity, { audioClipUrl: 'sounds/sound-effect.mp3', loop: true, playing: true, volume: 1 // range from 0 to 1 })

指令中唯一显式标注的取值范围是volume(0~1)。音频与实体绑定,因此同样可以挂在PlayerEntity/CameraEntity下实现“随玩家移动”的空间音效,或在onLeaveScene回调中停掉/切换(见第 12 节)。

10. 交互:指针事件与 InputAction

InputAction三个关键枚举在电脑端的映射(指令原文给出的对应关系):

枚举电脑端
InputAction.IA_POINTER鼠标左键
InputAction.IA_PRIMARYE 键
InputAction.IA_SECONDARYF 键

可点击实体的标准写法(pointerEventsSystem.onPointerDown的第一参数是描述对象,第二参数是回调;下方代码按原文整理并补齐了原文缺失的右括号):

pointerEventsSystem.onPointerDown({ entity: clickableEntity, opts: { button: InputAction.IA_POINTER, hoverText: 'Click' } }, function () { console.log("clicked entity") const t = Transform.getMutable(clickableEntity) t.scale.y += 0.2 })

opts.button指定触发按键,hoverText是悬停时的提示文案。回调里通过getMutable改缩放是一个典型的“交互反馈”范式。

11. 玩家:移动、自定义动画与表情

// 传送玩家(GPT 内部封装的辅助函数) movePlayerTo({ newRelativePosition: Vector3.create(1, 0, 1), cameraTarget: Vector3.create(8, 1, 8), }) // 触发自定义 'Snowball_Throw' 动画(GPT 内部封装的辅助函数) const entityForCustomAnimation = engine.addEntity() triggerCustomAnimation(entityForCustomAnimation, Vector3.create(8, 0, 8), 'animations/Snowball_Throw.glb', 'Make snowball') // 触发预定义表情 triggerEmote({ predefinedEmote: emoteName })

注意movePlayerTo与triggerCustomAnimation是该 GPT 指令自定的封装函数(参数分别为“新相对位置 + 相机注视点”和“实体 + 位置 + 动画 GLB + 提示文本”),并非 SDK 官方导出名——从指令结构看,它们用于约束 GPT 生成一致的玩家操控代码;在真实项目中应对照官方 API(如@dcl/sdk/ecs的movePlayerTo导出)确认签名后再使用。

预定义表情(predefinedEmote的取值)共 15 个:

wave, fistpump, robot, raiseHand, clap, money, kiss, tik, hammer, tektonik, dontsee, handsair, shrug, disco, dab, headexplode

此外,imports 中的triggerSceneEmote可触发“场景表情”(作用于场景中实体而非玩家),与triggerEmote互补。

读取玩家/相机变换与遍历全场玩家:

// 读取玩家和相机的位置、朝向 function getPlayerAndCameraData() { if (Transform.has(engine.PlayerEntity) && Transform.has(engine.CameraEntity)) { const playerPos = Transform.get(engine.PlayerEntity).position const playerRot = Transform.get(engine.PlayerEntity).rotation const cameraPos = Transform.get(engine.CameraEntity).position const cameraRot = Transform.get(engine.CameraEntity).rotation // Log player and camera data } } // 遍历所有玩家 for (const [entity, data, transform] of engine.getEntitiesWith(PlayerIdentityData, Transform)) { // Process each player's data } let currentPlayer = getPlayer() if (currentPlayer) { // Access currentPlayer data such as name, userId, isGuest, position, avatar details }

这里体现了 ECS 查询的泛化能力:getEntitiesWith(PlayerIdentityData, Transform)同时按两个组件做查询,解构即得[entity, 身份数据, 变换数据]三元组;getPlayer()返回当前玩家的快捷句柄(含name、userId、isGuest、位置与头像信息)。

12. 玩家进出场景回调

onEnterScene((player) => { if (!player) return console.log('ENTERED SCENE', player) }) onLeaveScene((userId) => { if (!userId) return console.log('LEFT SCENE', userId) })

注意两个回调的载荷不同:进入场景时拿到的对象是player,离开场景时拿到的只是userId字符串。这是编写“欢迎牌自动跟随玩家”“人走即回收资源”等逻辑时的关键差异,也是这个 GPT 指令特意把两者一起固化的原因。回调内先做if (!player) return的空值守卫,是官方文档推荐的防御写法。

13. 这份指令的提示词工程价值

跳出 Decentraland 本身,这份文件对“如何给编码型 GPT 写 system prompt”给出了几个可复用的手法:

  1. 角色 + 范式声明开头:先说明 SDK7 是 DOD 而非 OOP,防止模型套用旧版 API;
  2. 全量导入块 + 强约束:把 imports 原文固化并声明“必须逐字使用”,用确定性换正确率;
  3. 按主题切块(ENTITIES / COMPONENTS / GLTF / MATERIALS / SYSTEMS / GEOMETRY / SOUNDS / INTERACTION / PLAYER),每块只给“用途注释 + 最小可运行代码”,等价于一张可检索的速查表;
  4. 知识库兜底:指令覆盖高频 API,长尾细节交给 GPT 知识库文件(Decentraland SDK7 Docs.md)在对话中按需检索;
  5. 把易错点写进注释:如“持久变量要放在 system 外”“优先级小的先执行”“用createOrReplace防重复组件”,这些都是社区实践中踩坑最多的地方。

14. 小结

2aD2Y5SiB_Decentraland_SDK7_Coder.md 把 Decentraland SDK7 的 DOD 开发范式压缩为一份可直接驱动模型产码的 API 手册:从固定的 imports 与main()骨架,到实体层级、组件 Schema 与 CRUD、GLTF/Animator、形状与 PBR 材质、System 优先级调度、向量四元数、音频、指针交互、玩家与表情,全部以“注释 + 最小示例”形式组织。对于想理解“领域速查表如何变成高质量编码提示词”的开发者,以及需要在 TheBigPromptLibrary 中找 SDK7 相关提示词样本的团队,这份文件是一个信息密度很高的参照。

适用前提与限制:文中所有 API 签名与参数均以该 GPT 指令文件为准;movePlayerTo、triggerCustomAnimation等封装函数名是 GPT 指令自定义的,落到真实 SDK7 项目前应以官方文档核对;文中pointerEventsSystem.onPointerDown示例补全了原文缺省的括号,属排版整理而非语义改动。

  • 提示工程
  • AI 安全治理

【免费下载链接】TheBigPromptLibrary

A collection of prompts, system prompts and LLM instructions

项目地址:https://gitcode.com/gh_mirrors/th/TheBigPromptLibrary
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进