下载 App
10/16案例分享
【案例分享】「本地改了但线上没变」:资源构建引用与预下载的排查路径
一句话结论
运行时遇到 Could not find resource xxx,九成不是文件不存在,而是它没进构建产物。
判断依据只有一条:构建产物的 manifest 里没有的本地资源,运行时一定访问不到。下面这套排查顺序,能把「资源在哪一步被裁掉」定位到具体一行配置。
先分清两件事:构建引用 vs 预下载
这两个概念经常被混在一起,但它们管的是不同阶段:
构建引用 —— 管哪些资源进包,配置项是 groups,出问题的表现是「资源根本不在包里,永远找不到」
预下载 —— 管进包的资源什么时候下,配置项是 preload_groups,出问题的表现是「资源在包里但没下完,时有时无」
排查要先看第一个。如果资源压根没进包,调预下载是白费功夫。
构建引用的两种模式
resources.json 的 groups 决定用哪种:
全量引用 —— groups 里存在独立的双星号条目时触发,行为是所有本地资源入包
增强引用 —— groups 里没有独立双星号(如只有 scripts 加双星号)时触发,行为是从根资源出发递归追踪引用链,仅可达资源入包,未引用资源裁剪
构建器自动检测,不用手动配。
增强引用是省包体利器,也是资源丢失的头号来源 —— 因为它会裁剪。一个资源只要「没被任何可达路径引用到」,就会被静默裁掉,构建时不一定有明显报错。
四种典型配置
// 1. 全量引用 + 全预下载(早期版默认)
{
"preload_groups": ["default"],
"groups": { "default": ["**"] }
}
// 2. 增强引用 + 预下载
{
"preload_groups": ["default"],
"groups": { "default": ["scripts/**"] }
}
// 3. 全量引用 + DWP(新版本默认)
{
"preload_groups": [],
"groups": { "default": ["**"] }
}
// 4. 增强引用 + DWP(资源量大时推荐)
{
"preload_groups": [],
"groups": { "default": ["scripts/**"] }
}
DWP = 边玩边下(Download While Playing)。不配 preload_groups 时,blocking 类型资源仍在启动时补齐,其余资源由引擎按需下载。
groups 的 glob 匹配的是什么
匹配的是资源相对于 asset_dirs 的路径,不是项目根路径:
// settings.json
{
"build": {
"asset_dirs": ["../assets", "../scripts"]
}
}
双星号 —— 所有 asset_dir 下的所有文件
scripts 加双星号 —— ../scripts 目录下的所有文件
双星号加 .lua —— 所有 asset_dir 下的 .lua 文件
搞错基准目录,是「配了但没生效」最常见的原因。
增强引用怎么追踪引用链
1. groups 模式匹配到的文件作为根资源
2. 从根资源出发,递归分析文本中引用的资源路径
3. 沿引用链展开,可达的入包,其余裁剪
例子:
main.lua ← groups 匹配,根资源
→ "config/game.json" ← Lua 中的字符串字面量,命中资源路径
→ "Textures/player.png" ← JSON 中的字符串值,命中资源路径
→ "Sounds/bgm.ogg" ← 同上
按文本类型提取字符串:
.lua —— 提取单双引号字符串,跳过 require
.json —— 提取双引号字符串
引擎 xml —— 解析属性
★ 头号陷阱:路径拼接
兜底机制:对于路径拼接场景,精确匹配失败后,会用 endswith 做模糊匹配。
例如代码里写了:
local path = imageRoot .. imageId .. "_normal.png"
提取到的片段 "_normal.png" 会去模糊匹配项目里所有以它结尾的资源。
但兜底不保证覆盖所有拼接情况。
-- 危险:构建器无法静态提取完整路径
local path = "Textures/" .. id .. ".png"
-- 安全:完整路径字面量,构建器能直接匹配
local path = "Textures/player_idle.png"
结论:始终使用完整路径字面量,不要依赖路径拼接。
Lua 模块同理:
-- 危险
local mod = require("game." .. name)
-- 安全:可静态解析
local mod = require("game.level")
排查顺序(照着走)
出现 Could not find resource xxx 时:
第 1 步,资源未被引用计算覆盖。增强引用模式下,路径是复杂拼接生成的,构建器提不出完整路径。修法是改成完整路径字面量,或把该资源(或其父目录)加进 groups 模式。
第 2 步,资源未下载。没直接命中 preload_groups,也不属于 blocking 类型。修法是把资源所在 group 加进 preload_groups,或运行时用 cache:DownloadResource 手动下载。
第 3 步,资源不存在或未包含。查文件是否在 asset_dirs 下、有没有对应 .meta、是否被引用或匹配。
第 4 步,引号匹配干扰。同一行里双引号字符串内含单引号(如 "it's")会干扰相邻路径提取。修法是别在资源路径所在行混用引号,或把路径单独写一行。
第 4 条特别隐蔽 —— 它跟你写的那行代码「看起来」毫无关系,但确实会让旁边那行的资源路径提取失败。
切换引用模式前必须确认的事
从全量引用切到增强引用(把独立双星号改成具体模式),要先做这两项检查:
1. 依赖引用链进构建的资源,尽量用完整路径字面量,别只靠运行时拼接
2. Lua 模块用可静态解析的 require("foo.bar") 或 require "foo.bar",别用动态模块名
做完检查、并经明确确认后,再改。
顺序反了会怎样:改了模式 → 一堆资源被裁 → 运行时才发现 → 又得逐个补字面量。先改代码再改配置,切换过程就没有「资源丢失」窗口。
前后端资源区分
资源可通过 .meta 里的 c_or_s 显式标记使用端:
c —— 客户端资源
s —— 服务端资源
cs —— 两端共享
当前后端入口不同(project.json 或 resources.json 里配 entry@client 和 entry@server),且项目用增强引用时,构建会自动把「仅服务端可达、客户端不可达」的本地资源标为 s。
显式配的 c_or_s 优先于自动计算。
全量引用项目不做自动端别识别,但显式配置仍然有效。
远端依赖资源的端别由远端项目决定。
构建日志会告诉你当前策略
不用猜,构建日志里有:
[INFO] 构建策略: 增强引用 — 检测到 groups 无全量通配,仅包含可达资源,未引用资源将被裁剪
[INFO] 预下载: 未启用 — 检测到 preload_groups 为空,blocking 资源启动补齐,其余资源由引擎 DWP 按需下载
先读这两行,再决定往哪个方向查。
什么时候该切增强引用,什么时候别切
这套机制不是「越省越好」。用错场景,代价比省下的包体大。
适合切增强引用 + DWP 的情况:
资源量明显偏大,包体已经影响到下载转化
脚本用到的资源是项目里的少数,大部分是备用素材
团队能保证所有资源路径都写成完整字面量
不适合切的情况:
项目小、资源少 —— 省下的包体有限,却要承担「资源被裁」的风险,不划算
有大量运行时拼接路径 —— 兜底匹配不保证覆盖,切换后必然丢资源
用动态模块名 require —— 构建器提取不到,模块不会进包
赶上线、没时间逐个回归 —— 资源丢失是运行时才暴露的,压线切换风险太高
判断依据:先问「我能不能列出所有资源路径的完整字面量」。能,就可以切;不能,先改代码。
一个反直觉的点:全量引用虽然包体大,但它是默认安全的 —— 不会因为某处路径写得不规范就丢资源。从安全切到省,需要一次系统性排查;从省切回安全,改一行配置就行。所以不确定的时候,留在全量引用这边。
可迁移的经验
1. 「找不到资源」先问「它进包了吗」,而不是先怀疑文件路径写错。构建产物的 manifest 是唯一事实来源。
2. 静态可分析性是构建器的硬约束。任何「运行时才算出来」的路径,都可能被裁剪 —— 这是所有静态构建系统的通病,不只这一个引擎。
3. 配置改动前先让代码满足新约束,别反过来。
4. 同一行混用引号会干扰解析器 —— 这类「看起来无关」的坑,在写资源路径时值得多留一个心眼。
5. 先读日志里的策略声明,比翻配置文件快。
00:11
【个人案例分享】动态注册事件与创建触发器截图
【个人案例分享】动态注册事件与创建触发器
废话阶段: 一般我们刚接触星火的时候,使用触发编辑器里的触发器都是直接通过新建触发器来创建,然后往里面添加预先设置好的事件。 虽然能做出游戏,但这样子的触发器是全局的,后面想添加新的玩法或者内容可能会因为之前的全局触发器导致影响后面的新玩法或者内容。可能会有人想到用打开/关闭触发器或者移除触发器来控制,但这样子仍然不是很方便,所以有没有什么方法可以让某个触发器在必要的时候出现,不必要的时候不在。所
16 赞
3 回复
星火编辑器-新手教程-关于多游戏模式的配置和触发的获取截图
星火编辑器-新手教程-关于多游戏模式的配置和触发的获取
HELLO 大家好,我是阿木木牧。最近第一版的内部小范围(几人)第一个图的测试已经结束了。 整体游戏以装备数值的崩坏而告终~ (虽然大家都很欢快。。。) 现在准备开始开发下个阶段的内容啦,就是将游戏模式拆分出来。分成单人模式,多人组队模式(合作PVE),多人匹配模式(对抗模式)。那么,怎么配置呢?说来也很简单哈~ 1,在游戏编辑器中,数据编辑器,找到地图设置。 2,编辑地图设置。比如我希望最大数量
14 赞
3 回复
00:19
如何实现单位的随意拖拽摆放?【星火编辑器教程】截图
如何实现单位的随意拖拽摆放?【星火编辑器教程】
很多小伙伴想做自走棋类的游戏,那么就会涉及到单位的一个最基础的操作,就是选中单位并拖拽和摆放,那如何实现单位的拖拽摆放呢,今天就来教大家如何实现这样的功能。实现效果如下视频所示。 教程开始 第一步: 打开编辑器的触发编辑器,新建一个文件夹(我就叫“拖拽功能”,方便对拖拽功能的逻辑进行归类,如果你不建文件夹也没关系,习惯而已) 第二步: 点击文件夹右边的+号,添加一个变量,我这里叫“变量_目前选中的
19 赞
12 回复
不支持当前设备截图
不支持当前设备
荣耀400pro
2 赞
3 回复
00:18
修复一下这个挂起过。有概率用不了的bug吧截图
修复一下这个挂起过。有概率用不了的bug吧
太绝望了[表情_豹哭][表情_豹哭][表情_豹哭][表情_豹哭]
1 赞
1 回复
05:19
1截图
1
1.完成后,获得信用点的增益依旧有效,可以卡无限信用点。理论上 2.部分天赋和在一起可以实现永续,那些天赋,我下一个发,因为只能传一个视频。 3.卡,人多点就卡,知道卡死,但是手机不会卡就游戏卡
2 赞
无须申请,星火编辑器现已公测开放下载截图
无须申请,星火编辑器现已公测开放下载
—————————————————— 各位关注星火编辑器的小伙伴: 感谢大家一直以来对编辑器支持! 破晓已去,曙光降临! 星火编辑器现已开启公测! · 关于下载和资格申请 现已无需申请,请去下面的官方首页直接下载! 缘起测试是星火编辑器自诞生以来第一次对外测试! 从2022年八月开始到十一月,历时三个月。 缘起之后缘聚测试,历时又七个月! 缘聚之后,破晓降临,历时又十二个月! 曾经微弱的星火现已渐
官方
331 赞
375 回复
00:11
人物有小概率会卡着不往前走截图
人物有小概率会卡着不往前走
3 赞
1 回复