关于 scenario-godot-2d
scenario-godot-2d 是面向构建和审查 Godot 4.7.2 2D 游戏的 Agent 技能,强调将移动、相机、像素美术、瓦片和光照转化为可测指标,并通过确定性运行与画面捕获验证。
主要功能
- 01可测的平台与俯视角控制器
- 02像素美术缩放与相机设置
- 03TileSet 生成和地形审计
- 04精灵与导入资源校验
- 05确定性物理与画面检查
适用场景
- 01将跳跃调至目标高度和时长
- 02构建像素完美或平滑滚动场景
- 03检查地形连接和精灵边缘
- 04以固定帧率验证控制器行为
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-godot-2d安装后在 Claude Code 中输入/scenario-godot-2d确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/critique.mdexpert-notes.mdgui-paths.mdprocedures.mdsources.mdscripts/gd_2d.pyscripts/agentkit/2d/audit_2d.gddual_grid.gdfollow_camera_2d.gdparallax_tools.gdpixel_light.gdshaderpixel_viewport.gdplatformer_body.gdplatformer_tuning.gdsprite_frames_builder.gdterrain_tools.gdtileset_builder.gdtopdown_body.gd详细介绍
Godot 2D(开发者与美术师)
目标:Godot 4.7.2 标准构建版本,macOS,通过 scenario-godot-expert 工具包以无头模式或小窗口运行。
2D 专家会测量游戏手感和像素,而非凭感觉估算:跳跃高度以瓦片为单位,土狼时间窗口以帧数为单位,相机延迟以像素为单位,像素风屏幕则设有整数倍率和边缘杂色数量。Agent 会用代码构建瓦片、控制器和相机,通过确定性物理运行和帧数据回读来验证,然后才宣布完成。如果这里提到的某个同级技能不在你可用的技能中,请让用户安装它
(npx skills add scenario-labs/skills --skill <name>);若无人值守,则根据工具架构继续操作,并标明这一缺失项。
必需背景: scenario-godot-expert(通道、审查流程、工具包 gd_env、gd_run、
gd_review、4.x 陷阱)。
立场(专家补充)
- 手感可以用数字检验。 根据跳跃高度和到达顶点的时间,求出重力和起跳速度,并让高度成为图块尺寸的整数倍(The Shaggy Dev,Bsy8pknHc0M [00:04:13])。Godot 随后会损失约 v·dt/2 的高度:60 个物理帧下,设计高度为 56 px 时,实测为 53.5 px。工具包会加上 g·dt/2,落在 56.25 px [新增]。
- 在时间和空间上留出容错。 土狼时间、跳跃缓冲、角落修正和跳跃切断,各自只需几行代码(The Shaggy Dev)。按完整物理帧数计算窗口:浮点计时器在 0.1 s 内只给出 5 次土狼移动,而不是 6 次 [新增,实测]。
- 俯视视角:用
move_toward,不要做长度运算。 累加式加速度需要limit_length;从长度中减去减速度会导致数值变负并产生振荡(60 个物理帧中出现 55 次符号翻转,实测)。转向若没有最小步长,就永远无法到达目标(BT Plays Games,m71-kZgYXlw [00:07:30],[00:14:08])。 - 摄像机需要设计,而不是直接设为父节点。 设置前瞻、忽略跳跃并在落地时重新设定基准、阻尼,以及带关闭开关的震动(Mark Brown,GMTK)。阻尼会造成与速度/阻尼成正比的滞后,并削弱前瞻效果:32 px 的前瞻在 120 px/s 下只产生 16 px 的领先,因此两个数值都要说明。使用
Camera2D.zoom缩放(2 表示放大),绝不要通过调整视口大小来缩放(DevWorm,RlSpjIb7TLo [00:08:14])。 - 抖动是物理帧率问题。 在 144 Hz 显示器和 60 个物理帧下,物理插值在所有摄像机设置下都达到理想的 0.289 px RMS。关闭插值时,背景会以 0、1、2 px 的步幅跳动,Idle 摄像机平滑则会让玩家抖动 3 px。
Camera2D.process_callback默认设为 Idle:关闭插值时,请自行设置为CAMERA2D_PROCESS_PHYSICS(Chris' Tutorials,43c-Sm5GMbc [00:28:37]);开启插值时,Godot 会强制使用 Physics。 - 像素完美是一项拉伸方式的选择。
viewport加整数缩放会将所有内容锁定到美术像素,包括灯光。实测 640x360(文档中的基础分辨率)和 320x180 都能以整数倍缩放适配 720p、1080p、1440p 和 4K,且不会出现黑边;应根据原生美术尺寸选择。发布时使用独占全屏(窗口模式 4):在 4K 下,1 px 的黑边会让 640x360 从 6 倍缩放降为 5 倍,实测如此(文档,“Multiple resolutions”)。canvas_items支持平滑旋转和亚像素移动(Heartbeast 更喜欢这种方式)。如果要锁定美术像素,同时让摄像机平滑移动,可在基础分辨率上为 SubViewport 增加 2 px,再将放大后的图像偏移剩余像素(Barry's Dev Hell)。 - 图块是可审计的数据。 每个图层使用一个 TileMapLayer,使用外部 TileSet,地形模式应与图块数量匹配,并逐格检查邻接位。绘制陆地,不要绘制水域一侧(DevWorm,ZutpG0_CYrQ [00:32:47]);在 GUI 中,先绘制外围,再绘制中心十字(bluuDevGames,CLcFC6ku240 [00:12:28])。如果每个角都必须以相同方式圆角,则选择双网格(16 个图块,显示图层偏移半个图块)(jess::codes,jEWFSv3ivTg [00:02:26])。然后检查采样器截图,因为索引检查无法发现美术素材错误 [新增]。
- 导入前检查生成的美术素材。 找出像素比例和网格相位,若未对齐网格就进行吸附;将每个动画片段的脚部对齐到基准线,并检查线性滤波下的关键色边缘 [新增,使用 scenario-sprite-pipeline]。
- 物理层应命名,且每个对象只用一个碰撞层。 每个对象只使用一个碰撞层,可以使用多个遮罩;在
layer_names/2d_physics/layer_N中,按检查器所需的内容命名图层(例如“bombable”)(Bogner,HFBNd4Z4vXM [00:10:58] 至 [00:14:17])。新建的物理体默认位于图层 1、遮罩 1:添加图层却不清除图层 1,会得到两个位,实测如此。
首先确定
| 问题 | 为什么会影响方案 | 默认值 |
|---|---|---|
| 像素美术还是平滑 2D? | 拉伸模式、滤镜、光照分辨率、摄像机方法 | 像素美术:基础分辨率 640x360(非常小的美术资源用 320x180),viewport + keep + integer、Nearest、Exclusive Fullscreen |
| 锁定网格还是在像素上平滑移动摄像机? | 仅使用 viewport,还是使用 pixel_viewport.gd | 摄像机缓慢移动时,通过 pixel_viewport.gd 实现平滑移动 |
| 平台游戏还是俯视游戏? | GROUNDED 还是 FLOATING,使用哪种套件主体 | 根据需求简介确定 |
| 瓦片大小和地形风格 | 47-blob、16-tile sides,还是 dual grid | 16 px、47-blob 地形 |
| 目标显示器 | 整数倍数和黑边 | 1280x720、1366x768、1920x1080、2560x1440、3840x2160 |
| 刷新和联网 | 开启还是关闭物理插值 | 开启(使用自有平滑处理的联网游戏则关闭,参见文档) |
| 美术资源来源 | Scenario 清单、手工制作、占位资源 | 美术资源就位前使用 gd_2d.make_* 占位资源 |
工作流
- 项目。
P = gd_env.base_project("2d", ...)、gd_2d.install_kit(P)、gd_2d.pixel_art_settings(P, ...)、gd_run.import_project(P)。关卡检查:stretch_matrix.gd显示根节点采用了基础尺寸、模式、整数拉伸、Nearest 和插值;每个目标窗口的整数倍数和黑边都与gd_2d.integer_scales一致。 - 导入美术资源。 对每张生成的图像执行
detect_pixel_scale、pixel_grid_check,如果阶段或比例不符,再执行snap_to_grid。然后导入资源、执行audit_imports,并使用sprite_frames_builder.gd根据清单构建 SpriteFrames,再对每个精灵调用register()。关卡检查:审核无误;每个动画片段中最低的墨迹像素都落在相同的世界 y 坐标;在非整数比例下截取的画面中,key_fringe= 0。 - 图块。 使用
tileset_builder.gd(先设定图块尺寸,再根据 alpha 生成邻接位、碰撞体、遮挡体和单向边缘),并保存为.tres;使用set_cells_terrain_connect绘制。如果美术资源是 16 图块双网格集,则使用dual_grid.gd。关卡检查:terrain_tools.audit_layer报告 0 个侧边和 0 个角落不匹配;采样画面(环形、十字形、单个图块、内角)在联系表中显示正常。 - 角色。 使用
platformer_body.gd+platformer_tuning.gdResource,或topdown_body.gd。将大脑与身体分离,以便测试驱动意图。关卡检查(--fixed-fps 60,每次await body.stepped移动一次):顶点与设计值相差不超过 0.5 px;按移动次数统计土狼时间和输入缓冲;测出最大可跨越的图块间隙;不会卡在图块接缝上;俯视角色恰好在 0 处停下,且斜向速度等于直线速度。 - 摄像机。 使用
follow_camera_2d.gd(物理步进,限制范围取自图层的已用矩形),或使用pixel_viewport.gd,在锁定像素上实现平滑视图。关卡检查:角色原地跳跃时摄像机 y 坐标保持不变;着陆后重新设定基准;长距离下落时角色始终留在屏幕内;关闭震动后偏移为 0。在--fixed-fps 144的窗口化运行中,启用插值时背景步进最多为 1 px。 - 光照、排序、视差。 使用 CanvasModulate + PointLight2D 和径向 GradientTexture2D;根据图块 alpha 创建遮挡体;使用以脚部为原点的 y 排序容器;每个平面使用一个 Parallax2D。关卡检查:检测点的亮度(受光、阴影、遮挡体拥有者受光,并与无遮挡体的对照项比较);测试前后遮挡时的重叠颜色;视差位移等于 scroll_scale 乘以摄像机运动量;最低缩放时没有空隙;自动滚动 90 帧内没有接缝。
- 审核并交接。 执行
audit_2d.gd:scenes、gd_run.check_all、kit_compile.gd,然后生成不超过 1600 px 的截取画面联系表,并打开查看。关卡检查:没有警告项、编译错误为 0,联系表中没有损坏的图块、边缘杂色或空隙。在书面计划中内嵌核心代码(设置键、跳跃计算、控制器步进、摄像机),使其不依赖套件即可运行;套件文件仅作为快捷方式提及。
数值
| 数值 | 测量结果或来源 | 相对于 |
|---|---|---|
| 基础尺寸 320x180,整数倍:在 1280x720 和 1366x768 下为 4x(黑边 43、24),在 1080p 下为 6x,在 1440p 下为 8x,在 4K 下为 12x,在 1170x2532 下为 3x | 实测 | 窗口尺寸 |
| 基础尺寸 640x360,整数倍:在 720p 和 1366x768 下为 2x(黑边 43、24),在 1080p 下为 3x,在 1440p 下为 4x,在 4K 下为 6x;3840x2159 配合 320 和 180 px 黑边时为 5x | 实测 | 窗口尺寸 |
| 跳跃 56 px,最高点 0.35 s,下落 0.28 s:向上重力 914.3,向下重力 1428.6 px/s²,起跳速度 327.6 px/s(含补偿) | 实测,工具包默认值 [已添加] | 16 px 瓦片,60 个刻度 |
| 跳跃截断系数 0.4:按住一刻度上升 12.79 px(不到一块瓦片);最小高度约为 (cut·v)²/2g | 实测,工具包默认值 | 16 px 瓦片 |
| 土狼时间 0.1 s = 离地后可移动 6 次;缓冲时间 0.1 s = 落地前可移动 5 次 | 实测 | 60 个刻度 |
| 角落修正 4 px:头部碰撞边缘 3 px 时,跳跃高度可从 34 px 增至完整的 56 px | 实测 | 10x14 角色 |
| 以 120 px/s 奔跑,跳跃高度 56 px:可越过 4 块瓦片,不能越过 5 块 | 实测 | 16 px 瓦片 |
| 俯视视角下以 120 px/s 移动,加速度 900、减速度 1200:达到最大速度需移动 8 次,停止需移动 6 次 | 实测,工具包默认值 | 60 个刻度 |
| Camera2D 平滑速度:默认值 5,约 3 的手感合适,10 的手感就像没有平滑效果 | DevWorm;实测读取默认值 | px/s 平滑单位 |
| 指数阻尼 8/s:在 30、60 或 144 Hz 下,0.30 s 内消除 90% 的跳跃偏差;滞后 = 速度 / 阻尼 | 实测 | 帧率 |
| 144 Hz 下抖动下限:开启插值时为 0.289 px RMS,关闭时为 0.55 | 实测 | 屏幕 px |
| 4x 缩放时的亚像素摄像机:每次移动 1 px,而非吸附到 4 px | 实测 | 屏幕 px |
| 宽度与视图相同的平面,其视差 repeat_times:缩放 1 需要 1,0.5 需要 3,0.25 需要 5 | 实测 | Camera2D 缩放 |
分级光照:具有 GRADIENT_INTERPOLATE_CONSTANT 的 4 阶 Gradient 在 64 px 范围内产生 4 个亮度级别,LINEAR 则为 64 级 | 实测 | CanvasModulate 上的 PointLight2D |
色边:未使用 fix_alpha_border 或 fix_alpha_edges() 时有 73 个着色 px,使用后为 0 | 实测 | 0.7x 下的 96 px 画面 |
质量门槛
除上述每项 GATE 外,还需打开并检查地形采样器、双网格、色边条和光照截图的联系表(圆角要与形状衔接,不得有悬浮部件或洋红色边缘,阴影应位于右侧)。评分标准:critique.md。
常见错误
| 错误 | 表现形式 | 修复方法 |
|---|---|---|
| 手动编写 project.godot | stretch disabled,像素模糊 | gd_2d.pixel_art_settings,再读取根节点 |
| 在 Match Corners and Sides 中设置 16 格边 | 出现空洞和错误边缘(32 + 10 处不匹配) | 使用 Match Sides,或绘制 47-blob 图块集 |
| 手动输入 Peering 位 | 出现随机边缘图块 | 根据图块 alpha 推导,并进行检查 |
| 只根据公式计算跳跃 | 跳跃顶点低 2.5 px,本应越过的间隙却无法越过 | 补偿 g·dt/2,或测量并调试 |
| Camera2D 作为玩家子节点,且未做其他设置 | 静止、视野短、跳跃抖动 | follow_camera_2d.gd |
| 摄像机空闲平滑,关闭插值 | 144 Hz 下玩家相对背景抖动 | 开启物理插值 |
| Camera2D 位于开启插值的像素 SubViewport 内 | 图像跳动 -5、+3 px | 设置 canvas_transform(pixel_viewport.gd) |
| 期望通过 Snap 着色器让光照像素化 | 衰减仍然平滑 | 使用 viewport 拉伸或 SubViewport 世界;通过 CONSTANT 渐变分段;shadow_filter 设为 None(默认值) |
| 遮挡体所有者变暗 | 墙壁或精灵未受光照 | 翻转剔除模式(由屏幕绕序决定),并与对照对象核对 |
| y 排序容器中的精灵原点居中 | 玩家绘制在其身后的树上方 | 将原点设在脚部,并通过 offset 移动美术图;较高的图块设置 y_sort_origin |
| 通过更改视口或窗口大小来缩放 | UI 和像素比例也随之改变 | Camera2D.zoom |
| 像素艺术使用全屏(模式 3) | 在 1 px 条带上,倍率降低一档 | 独占全屏(模式 4) |
| 将阴影烘焙进角色精灵 | 阴影绘制在后方的树干上 | 使用单独的阴影 Sprite2D,设置 z_index = -1;角色有自己的 z 后,将 z_as_relative 设为 false(DevWorm,lvuLjMAr_BE [00:09:24]) |
| 图块动画覆盖相邻图块 | “图块已存在”,保留 1 帧 | 先擦除相邻图块(DevWorm,ZutpG0_CYrQ [00:24:13]) |
| repeat_times 为 1 时缩小视图使用视差效果 | 出现品红色或黑色间隙 | parallax_tools.repeat_times_for |
| 运行时加载采用线性过滤的键控精灵 | 出现品红色轮廓 | 导入它,或使用 Image.fix_alpha_edges() |
在同一秒内编辑并重新导入 .import | 仍使用旧纹理 | gd_2d.set_import_params(布尔值使用小写,更新时间戳),检查 .ctex 是否已更改 |
交接
- 接收自 scenario-sprite-pipeline、scenario-game-assets、scenario-sprite-animation:PNG
或 WebP 条带、图块集,以及包含
frames、w、h、ground的清单。请询问原生像素尺寸和关键颜色。 - 接收自 scenario-godot-architecture:项目布局、自动加载项、输入动作名称。
- 交付给 scenario-godot-gameplay:带有意图字段和
jumped、landed、stepped信号的实体;用于导航的 TileMapLayer。scenario-godot-animation:注册在脚部的 SpriteFrames。 - 交付给 scenario-godot-vfx、scenario-godot-shaders、scenario-godot-ui(通过
pixel_viewport.world_to_screen显示 HUD)、scenario-godot-performance-export、scenario-godot-audio(在landed上挂接钩子)。 - 升级至 scenario-godot-expert 处理通道故障。
Godot 4.7 注意事项
- TileMap 和 ParallaxBackground/ParallaxLayer 自 4.3 起已弃用:请使用 TileMapLayer(4 参数
set_cell)和 Parallax2D。自 4.5 起,图块物理按physics_quadrant_size分块。单向方向(one_way_collision_direction,默认值为 (0, 1))是 4.7 新增的功能(deltas 文件)。 - Camera2D:
enabled加上make_current()、position_smoothing_enabled、ignore_rotation。启用插值后,缩放变更会在一个 tick 内平滑过渡(实测需要 2 到 3 帧才能达到 2.0)。 - 4.7.2 中读取的默认值:画布纹理过滤为 Linear,关闭 2D 变换吸附,关闭物理插值,CharacterBody2D 安全边距为 0.08,地面吸附为 1 px。纹理导入:Lossless,无 mipmap,开启
fix_alpha_border,detect_3d/compress_to为 1。 - 4.7.2 中,一个图块的一个遮挡层上可以有多个遮挡多边形(2 个,保存后仍保留):4.3 视频(suzF2Y166eA [00:12:22])中的第二个遮挡层并非必需。
- 应避免使用的 Godot 3 名称:
KinematicBody2D、YSort、作为节点的Light2D、set_cellv、world_to_map、Camera2D.current。
参考资料
references/procedures.md:包含代码和实时结果的操作流程;expert-notes.md:按来源整理并附带时间戳的原则;critique.md:自查标准;gui-paths.md:编辑器菜单;sources.md: 视频和文档。scripts/gd_2d.py:设置、导入审计、像素网格检查、跳跃计算、占位图集。scripts/agentkit/2d/:图块集、地形、双网格、实体、摄像机、像素视口、精灵帧、视差、审计、光照着色器。
评论
支持 Markdown