脚本与编辑器问答 2023/09/22
本次问答活动在Bedrock附加组件Discord举行。十位微软/ Mojang员工参与解答了关于脚本与编辑器API的问题,所有问题均来自社区征集。
WARNING
并非所有聊天记录都被完整转载,部分内容经过编辑整理。如需查看完整记录,请加入上述Discord服务器并获取"events archive"权限。
脚本功能
更强大的摄像机控制
- 问:未来能否通过脚本API实现摄像机路径点旋转功能?
- 答:摄像机路径可视化(以及各类路径可视化)是个很棒的建议,我们正在考虑这个方向
支持更多编程语言?
- 问:上次问答中你们表示无法承诺支持JS以外的语言,现在情况有变化吗?我们还要继续用JS一年吗?
- 答:目前没有变化。虽然我们的脚本系统已经与Javascript实现了一定程度的解耦,但支持多语言运行时仍需要巨大的开发成本
通过脚本生成世界
- 问:在研究《我的世界:传奇》时,我发现村庄和生物群系是通过B#脚本系统放置的。ScriptAPI有计划支持类似功能吗?
- 答:对于游戏功能,我们始终在寻找最佳的API设计方案来实现可定制性。脚本虽然强大,但世界生成也可能更适合采用JSON数据驱动的方式。我们收到大量关于世界生成的反馈,未来会综合考虑各种API方案
- 问:能否获取生物群系的气候值、ID、噪声类型等数据?或者通过getTags获取生物群系的所有标签?
- 答:已收到反馈——"生物群系发现"API将是未来值得投入的方向
QuickJS引擎
- 问:有计划添加JIT编译提升脚本运行效率吗?
- 答:技术难点在于即使支持JIT的引擎(如V8)也无法在我们所有目标设备上运行
- 答:再次说明,当前JS引擎不支持JIT编译。如果未来更换引擎,我们会考虑在部分平台启用JIT(但很多平台确实无法支持)
- 问:近期会弃用QuickJS吗?
- 答:目前没有更换QuickJS的计划
- 答:我们致力于让脚本覆盖更多场景,性能优化是重要环节。这包括两方面:确保API设计对常见用例高效,以及改进QJS集成和基岩引擎本身
与Java模组框架(如Fabric)不同,我们是在引擎之上提供版本化接口,而非直接修改引擎。但我们会努力保持易用性和强大功能!
JSON文件读写
- 问:会开放通过JS读写JSON文件的功能吗?
- 答:如果将JSON文件放在scripts文件夹内,可以通过import读取。但写入JSON功能基本不会开放
- 答:自定义数据文件可以使用.json格式存放在scripts目录,但这是只读的 不能在任何位置保存任意文件(包括.json) 不能直接从behavior_pack其他位置加载/解析.json文件
- 答:这个问题我需要再确认下实现细节,稍后回复😅 但完全理解这个需求场景
脚本替代JSON事件
- 问:脚本会全面替代JSON事件吗?能否通过脚本创建行为,而不仅是替换JSON事件?比如制作高级实体组件、物品方块组件,并控制它们在其他脚本事件触发时的行为
- 答:脚本确实不限于JSON事件,但仍以事件驱动为主。大体思路是JSON负责定义,脚本负责逻辑。脚本会持续增强并与更多系统集成
- 答:重点是明确JSON与脚本的职责边界,让创作者清楚何时该用哪种方式🙂
动态属性注册变更
- 问:为什么动态属性不再需要通过worldInitialize事件注册了?
- 答:我们意识到任何限制都能被绕过(比如把数据存在方块或告示牌上),长期存档可能突然达到限制,而且API限制过多导致创作者仍在使用记分板存数据——这恰恰是我们想避免的
自定义脚本模块
- 问:能否创建类似@minecraft/server-editor的自定义脚本模块?
- 答:打包功能将解决这个问题!
OreUI限制
- 问:OreUI能使用第三方React库吗?
- 答:由于内置网页渲染器(OreUI基础)为性能优化,与标准浏览器不完全兼容,第三方React库通常无法正常渲染
社区支持
- 问:社区如何帮助推广脚本API?
- 答:关于编辑器相关脚本...😉 我们非常希望看到你们使用编辑器的视频!实时展示创作过程和痛点对团队极有帮助!
- 答:帮我们识别社区需要的工具和文档!我们知道学习曲线很陡峭
- 答:保持友善。使用脚本的人不要显得高人一等,多帮助鼓励新人
- 答:视频教程会帮助很多人。稳定API应该适合做教程,因为我们需要保持向后兼容
实体AI控制
- 问:能否实现类似模拟玩家(minecraft/server-gametest)那样深度的实体行为控制?
- 答:当前没有开发计划,但希望未来能提供AI API。标准免责声明——短期内不会推出
- 问:应该能强制启停AI目标或调整优先级
- 答:已记录——希望未来推出AI API(非短期)。可能通过直接/间接操作AI目标组件实现
初步设想是提供一组AI基础功能(+++增强版模拟玩家API?),然后社区可以在此基础上构建高级功能。也想听听大家对这个方案的意见
数据存储方案
- 问:有计划为每个独立物品存储数据吗?
- 答:这是个好建议,我们正在考虑。当前重点是世界和实体动态属性,接下来会研究物品堆动态属性
- 答:我们希望能让创作者不再用lore文本存数据😄 最近取消了实体动态属性的注册要求,物品动态属性可能采用相同方式
- 答:正在调研!我们绝不希望lore成为物品堆的存储方案,特别是lore会同步到客户端
- 问:能否从ItemStack类获取物品ID?
- 答:不同于实体,物品堆会被复制/合并/拆分,难以分配可靠ID。替代方案可能是在运行时添加物品标签,或等待物品动态属性功能
欢迎分享具体需要物品ID的使用场景
- 问:退出世界时保存数据的新数据结构?
- 答:如前所述,实体和世界动态属性是当前解决方案。我们已取消大小限制,正努力让API稳定发布
文件API正在讨论中。主要目标是让玩家不再依赖记分板存储,欢迎提出需求
- 答:我们不太愿意添加worldUnloadingSaveAllYourStuff事件,因为无法控制所有平台的所有卸载情况(更不用说崩溃等)。建议使用动态属性持续保存状态。当然这也有缺点(代码需要更健壮)。总之关于大量游戏状态保存,我们还在探索最佳方案
工作线程
- 问:会实现工作线程或多线程脚本语言支持吗?
- 答:考虑过工作线程,暂无近期计划,但今天听到的使用场景很有价值
增强脚本引擎
- 问:有计划提供更底层的世界数据访问吗?比如直接获取修改整个区块,而非逐个setBlock/fill
- 答:我们很希望提供更高性能的方块API。setBlock在多方块操作时开销较大,fill在设置不同方块类型时又太局限。也讨论过用工作线程执行大计算量任务
- 问:能否调整命令队列容量?128条限制有时不够用
- 答:这个限制可以研究。查询命令队列大小的API对你有帮助吗?想了解更多受影响的具体场景
- 问:能否在世界加载RP/BP前运行JS?这样就能动态生成纹理和物品,大幅加快"匠魂"等模组的加载速度
- 答:尚未研究但会考虑
末影箱组件
- 问:脚本API会添加末影箱组件吗?
- 答:目前待办列表没有这个,但感谢建议!
斜杠命令
- 问:自定义斜杠命令注册功能何时推出?
- 答:短期内不会,但讨论过
- 答:先用/scriptevent吧😛
新事件类型
- 问:会增加更多前置事件吗?比如entityHurt、entityDie等的前置事件
- 答:正在内部讨论中🙂
- 问:有计划添加物品转移事件吗?比如物品移动、丢弃、拾取、给予、移除、修改、合并等
- 答:感谢提醒,这确实是我们想添加的功能
- 问:考虑添加BeforeCommandExecute事件吗?
- 答:尚未考虑。你有哪些具体使用场景?
客户端脚本
- 问:会有制作客户端模组的方法吗?或者让领域/世界中的脚本能在客户端运行?
- 答:客户端脚本经常被提及,我们认可其价值。创建客户端JS实例不难,但设计/实现/维护整套新API是巨大工程。需要考虑UI控制和输入方案跨设备兼容性,还会增加脚本编写的复杂度(需要显式同步两个脚本上下文)
- 问:显然多个客户端脚本模块正在开发中,但具体路线图是什么?功能范围和设计意图?请告诉我们一切!
- 答:目前主要专注服务端脚本API。在可能的情况下,我们倾向于在服务端添加API(如/server-ui)
某些场景确实需要客户端脚本——客户端验证、UI、输入管理等——未来可能会正式支持,但短期/中期内不会。这里有很多棘手问题。再次强调,我们倾向于尽可能把功能放在服务端API以保持简单
- 答:另一个重点是避免混淆。如果考虑客户端脚本,它必须提供独特价值而非简单复制服务端功能,因为二者本质不同。我们希望大多数场景能由服务端处理(编辑器也在服务端管理输入!),但也注意到客户端脚本的需求
脚本与数据驱动交互
- 问:能否增强脚本与资源/行为包数据驱动文件间的信息传递? 希望能从脚本为实体/附着物添加molang查询。例如通过脚本设置实体骨骼角度:
entity.setMolangFunction("wiki", "getMyAngle", () => {
return 32;
});然后在动画中写rotation: [0, "script.wiki:getMyAngle()", 0] 这样可以实现逆向运动学等效果,无需占用q.skin_id或q.variant,也不用修改player.json
- 答:实体属性就是解决方案!如果有实体属性无法满足的场景请告知 客户端到服务器的回调想法很有趣,但我们要避免增加更多客户端权威行为
向量类增强
- 问:能为向量类添加更多方法吗?
- 答:好建议!虽然要避免在紧密循环中频繁JS与引擎交互(性能开销大),但我们也在考虑提供更多基础辅助方法
Beta版API转正
- 问:有计划将beta版API转为正式功能吗?
- 答:正在积极行动!每个版本的更新日志都会标注转正的API 1.20.30和1.20.40会有大量beta转正的API!
方块数据存储
- 问:未来能否像Entity.prototype.setProperty和ItemStack.prototype.setLore那样缓存/保存方块的动态数据?
- 答:建议使用动态属性或实体属性(有时称'actor属性')保存状态
方块和物品堆的动态属性需要更多底层支持,所以实现周期会更长(方块也可以通过世界坐标存储属性)。另外方块状态(block states)可能适合存储简单数据
商城支持
- 问:商城会支持脚本吗?
- 答:Spellrune是2022年夏季首个支持脚本的商城地图。今年初起所有商城地图都已支持脚本。目前已有多个商城地图使用脚本 如果没玩过Spellrune,这款免费地图非常棒:https://www.minecraft.net/en-us/marketplace/pdp?id=f5cc05fc-616a-4963-a02b-5db3fcc9e311
WebSocket支持
- 问:有计划为ScriptAPI添加WebSocket吗?
- 答:我个人喜欢WebSocket的某些场景,但短期内不太可能官方支持。这是个不受控的接口😦
如果要添加,需要确保脚本能等效处理所有数据(如事件等)。在专用服务器上可以通过server-net传输数据
实体生命值API
- 问:有计划通过脚本API增强实体生命值定制吗?比如修改最大生命值、取消伤害事件等
- 答:我们正在考虑和讨论这个方向
动态属性增强
- 问:未来会改进动态属性支持更复杂类型吗?比如: 物品:目前无法正确序列化物品到字符串,因为我们无法访问全部相关数据 类型化数组:希望能直接保存字节数组到动态属性,因为字符串容量有限 什么是类型化数组?参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray
- 答:好想法!
NBT数据访问
- 问:能否添加特殊函数获取实体/物品/方块的原始数据?不是说写NBT(虽然能写会很酷) 或者创建NBT API实现读取和修改(非创建/插入)NBT标签
- 答:即使只读访问原始数据也可能导致版本间兼容问题(如属性功能变更)。NBT中有很多混乱内容
我们更倾向于通过方法和API封装NBT功能。例如itemstack的部分成员就是对NBT的较薄封装
API设计理念
- 问:在设计API结构时,为什么有时用方法而非属性获取信息?这些决策是如何做出的?
- 答:关于方法vs属性我们有内部决策流程。虽然目前不是100%一致(这是个演进过程),但我们正努力提升一致性
- 问:构建新脚本功能或重构现有功能的设计流程是什么?
- 答:首先考虑使用场景:创作者想用这个API实现什么玩法?系统的哪些部分需要暴露?哪些部分需要允许修改?这有助于构思API形态。如果是beta版API,我们会重新审视这些问题
同时考虑代码库实现。有时会遇到限制迫使我们调整设计,有时会发现系统更有趣的特性可以加入API
然后我们编写规范文档,团队评审并迭代。实现过程中发现的问题可能进一步调整设计
方法vs属性的基本原则是:"如果是简单操作(非复杂计算/设置)?用属性,否则用方法"
- 问:设计API时追求哪些特质?
- 答:主要几点:
- 能否保证API向后兼容?是否有确定性的行为和时序?
- 是否充分覆盖目标场景并与现有API良好交互?
- 是否易用、类型明确(便于智能提示)、清晰?我们通过大量测试和内部demo确保易用性
- 脚本API如何与命令、JSON或molang现有功能交互/比较?
脚本的重点是提供超级稳定的体验构建平台,同时作为游戏可扩展性的一部分。因此可用性+可靠性+兼容性至关重要
- 问:实现新API时最不喜欢哪部分?集成到现有代码库困难/复杂吗?
- 答:(非开发者视角)我喜欢整个API设计过程。从决定哪些API对社区最重要,到设计讨论,再到发布获取反馈。最具挑战的是实现时发现代码库限制导致设计调整,但这种挑战也很有趣!🤪
- 问:如何为附加组件已有系统设计接口?
- 答:我们尽量保持JSON组件与脚本在命名上的一致性(为了创作者熟悉度)。但有时API会受益于命名/接口的差异,所以这不是硬性规定
关于getter与只读属性,我们遵循一系列规则保持一致性。例如:复杂计算用getter,返回常量/预计算值用属性。不过这是门艺术,早期开发时不够一致所以有些例外
本地化支持
- 问:目前只能通过typeId表示方块、物品、实体等,这对用户不友好 建议添加获取texts文件夹中定义的lang键的属性/方法,这样就能用RawMessage显示符合用户语言的正确名称
例如:
Block.rawName; // tile.dirt.name
ItemStack.rawName; // item.bow.name
Entity.rawName; // entity.cow.name
Enchantment.rawName; // enchantment.durability- 答:好建议!我们确实希望在更多地方支持本地化文本。如果不暴露物品/方块等的本地化键,就很难使用它们😛
JSON在附加组件中的未来
- 问:有计划减少附加组件中对JSON的依赖吗?
- 答:不是要"减少JSON使用",但对于游戏逻辑,JSON的表达能力确实存在上限。脚本更适合开放式的逻辑实现。某些事件最终会以脚本为主要逻辑方式,但可能保留简单场景的"快捷方式"(比如触发事件时直接播放粒子效果等)
"minecraft:equippable"组件
- 问:最近更新增加了在副手槽放置奇怪物品(如方块和主手物品)时的错误提示。但这限制了我的"任意物品进副手"模组。错误提示很有用,但能否添加"forceEquip"选项绕过限制?另外建议增强副手功能
- 答:已记录反馈。关键是在无限定制与避免意外游戏副作用/图形错误间找到平衡 对于你的场景,可以尝试给所有物品添加副手组件,虽然这有点麻烦
@minecraft/vanilla-data模块
- 问:有计划内置这个模块吗?手动包含既不方便又让新手困惑
- 答:不会将vanilla-data模块移入server。一个重要原因是解耦API契约与数据契约:脚本API模块是强版本化的API契约,不包含游戏当前版本的具体内容
例如@minecraft/server 1.5.0可以在1.19.40或1.20.40基岩版上使用,但这两个版本的"vanilla-data"(可用方块/物品类型)不同。API契约只保证功能,不保证内容
但分离后确实存在工具链问题——现在需要将JS文件包含在

