scenario-godot-2d

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Godot 2D (developer and artist)

Godot 2D(开发者与美术)

Target: Godot 4.7.2 standard build, macOS, run headless or in small windows through the scenario-godot-expert toolkit.
Expert level in 2D means feel and pixels are measured, not eyeballed: a jump has a height in tiles and a coyote window in ticks, a camera has a lag in pixels, a pixel-art screen has an integer factor and a fringe count. The agent builds tiles, controllers and cameras in code, proves them with deterministic physics runs and frame read-backs, and only then calls them done. If a sibling skill named here is missing from your available skills, ask the user to install it (
npx skills add scenario-labs/skills --skill <name>
); unattended, proceed from tool schemas and flag the gap.
REQUIRED BACKGROUND: scenario-godot-expert (channels, review loop, toolkit
gd_env
,
gd_run
,
gd_review
, 4.x traps).
目标:Godot 4.7.2 标准版,macOS;通过 scenario-godot-expert toolkit 以 headless 模式或在小窗口中运行。
2D 专家水平意味着手感与像素都要经过测量,而不是凭肉眼判断:跳跃高度以 tile 为单位,coyote window 以 tick 为单位;camera 延迟以 pixel 为单位;pixel-art 画面具有整数缩放系数和 fringe 数量。Agent 使用代码构建 tiles、controllers 和 cameras,通过确定性的 physics runs 与 frame read-backs 加以验证,然后才会宣布完成。如果这里提到的某个 sibling skill 不在可用 skills 中,请让用户安装它(
npx skills add scenario-labs/skills --skill <name>
);在无人值守的情况下,依据 tool schemas 继续执行并标记该缺口。
必需背景: scenario-godot-expert(channels、review loop、toolkit
gd_env
、
gd_run
、
gd_review
、4.x traps)。

Stance (the expert delta)

立场(专家级增量)

  1. Feel is numbers you can test. Solve gravity and take-off speed from jump height and time to apex, and make the height a multiple of the tile size (The Shaggy Dev, Bsy8pknHc0M [00:04:13]). Godot then loses about v·dt/2 of it: 53.5 px for a 56 px design at 60 ticks, measured. The kit adds g·dt/2 and lands 56.25 px [added].
  2. Forgive in time and space. Coyote time, jump buffer, corner correction and a jump cut are each a few lines (The Shaggy Dev). Count windows in whole ticks: float timers gave 5 coyote moves for 0.1 s instead of 6 [added, measured].
  3. Top-down:
    move_toward
    , not length arithmetic.
    Additive acceleration needs
    limit_length
    ; subtracting decel from the length goes negative and vibrates (55 sign flips in 60 ticks, measured). Steering never arrives without a minimum step (BT Plays Games, m71-kZgYXlw [00:07:30], [00:14:08]).
  4. A camera is designed, not parented. Lookahead, ignore jumps and re-baseline on landing, damping, shake with an off switch (Mark Brown, GMTK). Damping lags by speed/damping and eats lookahead: 32 px of lookahead gave a 16 px lead at 120 px/s, so state both numbers. Zoom with
    Camera2D.zoom
    (2 zooms in), never by resizing the viewport (DevWorm, RlSpjIb7TLo [00:08:14]).
  5. Jitter is a tick-rate problem. At 144 Hz with 60 physics ticks, physics interpolation gave the ideal 0.289 px RMS for every camera setup. Without it the background stepped 0, 1, 2 px, and Idle camera smoothing made the player wobble 3 px.
    Camera2D.process_callback
    defaults to Idle: with interpolation off, set
    CAMERA2D_PROCESS_PHYSICS
    yourself (Chris' Tutorials, 43c-Sm5GMbc [00:28:37]); with it on, Godot forces Physics.
  6. Pixel-perfect is a stretch decision.
    viewport
    + integer locks everything to art pixels, lights included. 640x360 (the docs' base) and 320x180 both integer-scale to 720p, 1080p, 1440p and 4K with no bars, measured; pick by native art size. Ship Exclusive Fullscreen (window mode 4): a 1 px strip drops 640x360 on 4K from 6x to 5x, measured (docs, Multiple resolutions).
    canvas_items
    gives smooth rotation and sub-pixel motion (Heartbeast prefers it). For locked art with a gliding camera, render a SubViewport at base + 2 px and shift the upscaled image by the remainder (Barry's Dev Hell).
  7. Tiles are data you can audit. One TileMapLayer per layer, an external TileSet, terrain mode matched to the tile count, and peering bits checked cell by cell. Paint the land, never the water side (DevWorm, ZutpG0_CYrQ [00:32:47]); in the GUI, paint bits outer ring first, then the center cross (bluuDevGames, CLcFC6ku240 [00:12:28]). Pick a dual grid (16 tiles, display layer offset half a tile) when every corner must round the same (jess::codes, jEWFSv3ivTg [00:02:26]). Then look at a sampler capture, because index checks pass on wrong art [added].
  8. Generated art is checked before import. Find the pixel scale and grid phase, snap if off-grid, register every clip on its feet line, and check the key-color fringe under linear filtering [added, with scenario-sprite-pipeline].
  9. Physics layers are named and single. One collision layer per object, many masks; name layers by what the checker needs ("bombable"), in
    layer_names/2d_physics/layer_N
    (Bogner, HFBNd4Z4vXM [00:10:58] to [00:14:17]). A new body starts on layer 1 and mask 1: adding a layer without clearing 1 gives 2 bits, measured.
  1. 手感是可供测试的数字。 根据 jump height 和 time to apex 求解 gravity 与 take-off speed,并让高度成为 tile size 的整数倍(The Shaggy Dev, Bsy8pknHc0M [00:04:13])。随后 Godot 会损失约 v·dt/2:在 60 ticks 下,56 px 的设计高度实测变为 53.5 px。kit 会补上 g·dt/2,最终高度为 56.25 px [added]。
  2. 在时间和空间上给予容错。 coyote time、jump buffer、corner correction 和 jump cut 每个都只需几行代码(The Shaggy Dev)。以完整 tick 计数这些窗口:浮点计时器在 0.1 s 内产生了 5 次 coyote move,而不是 6 次 [added, measured]。
  3. Top-down:使用
    move_toward
    ,不要做长度运算。
    加速度叠加需要
    limit_length
    ;从长度中减去减速度会变成负数并引发抖动(实测 60 ticks 内发生 55 次符号翻转)。如果不设置最小步长,steering 永远无法到达目标(BT Plays Games, m71-kZgYXlw [00:07:30], [00:14:08])。
  4. Camera 是设计出来的,而不是简单挂到父节点上。 需要设计 lookahead、ignore jumps、landing re-baseline、damping,以及带关闭开关的 shake(Mark Brown, GMTK)。damping 产生的延迟为 speed/damping,并会吃掉 lookahead:120 px/s 时,32 px 的 lookahead 只形成 16 px 的提前量,因此两个数都要说明。使用
    Camera2D.zoom
    实现缩放(数值 2 表示放大),绝不通过调整 viewport 大小来实现(DevWorm, RlSpjIb7TLo [00:08:14])。
  5. 抖动是 tick-rate 问题。 在 144 Hz、60 physics ticks 下,无论采用哪种 camera setup,physics interpolation 都给出了理想的 0.289 px RMS。关闭 interpolation 时,背景会以 0、1、2 px 为步长跳动,Idle camera smoothing 还会让玩家产生 3 px 的晃动。
    Camera2D.process_callback
    默认为 Idle:关闭 interpolation 时,应自行设置
    CAMERA2D_PROCESS_PHYSICS
    (Chris' Tutorials, 43c-Sm5GMbc [00:28:37]);开启 interpolation 时,Godot 会强制使用 Physics。
  6. Pixel-perfect 取决于 stretch 决策。
    viewport
    配合整数缩放会把所有内容(包括灯光)锁定到美术像素上。640x360(文档基准)和 320x180 都能以整数倍缩放到 720p、1080p、1440p 和 4K,且不会出现黑边,均为实测结果;应根据原生美术尺寸进行选择。发布时采用 Exclusive Fullscreen(window mode 4):实测在 4K 下只要多出 1 px 黑边,640x360 的缩放就会从 6x 降为 5x(文档,Multiple resolutions)。
    canvas_items
    可实现平滑旋转和 sub-pixel motion(Heartbeast 更偏好此方式)。对于采用 gliding camera 的锁定美术,通过 SubViewport 按 base + 2 px 渲染,再按余数偏移放大后的图像(Barry's Dev Hell)。
  7. Tiles 是可审计的数据。 每个 layer 使用一个 TileMapLayer,采用 external TileSet,terrain mode 与 tile 数量匹配,并逐 cell 检查 peering bits。绘制陆地,绝不绘制水侧(DevWorm, ZutpG0_CYrQ [00:32:47]);在 GUI 中,先绘制 bits 外环,再绘制中心十字(bluuDevGames, CLcFC6ku240 [00:12:28])。当每个 corner 都必须以相同方式转折时,选择 dual grid(16 tiles,display layer 偏移半个 tile)(jess::codes, jEWFSv3ivTg [00:02:26])。之后还要查看 sampler capture,因为错误的美术资源也可能通过 index 检查 [added]。
  8. 生成的美术资源在导入前就要检查。 找出 pixel scale 和 grid phase;如果偏离 grid,则执行 snap。在 feet line 上注册每个 clip,并检查 linear filtering 下的 key-color fringe [added, with scenario-sprite-pipeline]。
  9. Physics layers 要有明确名称且保持单一职责。 每个 object 使用一个 collision layer,并可对应多个 masks;根据检查器的需求为 layer 命名,例如“bombable”,并放在
    layer_names/2d_physics/layer_N
    中(Bogner, HFBNd4Z4vXM [00:10:58] 到 [00:14:17])。新 body 默认位于 layer 1 且 mask 为 1:添加 layer 时若未清除 1,就会得到 2 个 bits,均为实测结果。

Establish first

前期确认

QuestionWhy it changes the planDefault
Pixel art or smooth 2D?stretch mode, filter, light resolution, camera methodpixel art: base 640x360 (320x180 for very small art),
viewport
+
keep
+ integer, Nearest, Exclusive Fullscreen
Locked grid or smooth camera over pixels?
viewport
alone, or
pixel_viewport.gd
smooth camera via
pixel_viewport.gd
when the camera moves slowly
Platformer or top-down?GROUNDED or FLOATING, which kit bodyfrom the brief
Tile size and terrain style47-blob, 16-tile sides, or dual grid16 px, 47-blob terrain
Target displaysinteger factors and bars1280x720, 1366x768, 1920x1080, 2560x1440, 3840x2160
Refresh and networkingphysics interpolation on or offon (off for networked games with their own smoothing, docs)
Art sourceScenario manifest, hand-made, placeholder
gd_2d.make_*
placeholders until art lands
问题为何会改变方案默认值
Pixel art 还是平滑 2D?stretch mode、filter、light resolution、camera methodpixel art:base 640x360(极小美术使用 320x180)、
viewport
+
keep
+ integer、Nearest、Exclusive Fullscreen
锁定 grid,还是在 pixels 上使用平滑 camera?单独使用
viewport
,或使用
pixel_viewport.gd
camera 移动缓慢时,通过
pixel_viewport.gd
实现平滑 camera
Platformer 还是 top-down?GROUNDED 或 FLOATING,以及使用哪个 kit body依据 brief
Tile size 和 terrain style47-blob、16-tile sides 或 dual grid16 px、47-blob terrain
目标显示器integer factors 和黑边1280x720、1366x768、1920x1080、2560x1440、3840x2160
刷新率与联网是否开启 physics interpolation开启;对于自带平滑机制的网络游戏则关闭,依据文档
美术来源Scenario manifest、手工制作或 placeholder在正式美术到位前使用
gd_2d.make_*
placeholders

Workflow

工作流

  1. Project.
    P = gd_env.base_project("2d", ...)
    ,
    gd_2d.install_kit(P)
    ,
    gd_2d.pixel_art_settings(P, ...)
    ,
    gd_run.import_project(P)
    . GATE:
    stretch_matrix.gd
    shows the root picked up base size, mode, integer stretch, Nearest and interpolation; the integer factor and bars for each target window match
    gd_2d.integer_scales
    .
  2. Art in. For each generated image:
    detect_pixel_scale
    ,
    pixel_grid_check
    , and
    snap_to_grid
    if the phase or scale is off. Then import,
    audit_imports
    , and build SpriteFrames from the manifest with
    sprite_frames_builder.gd
    plus
    register()
    on each sprite. GATE: audit clean; every clip's lowest ink pixel lands on the same world y;
    key_fringe
    = 0 on a capture at a non-integer scale.
  3. Tiles.
    tileset_builder.gd
    (tile size first, alpha-derived peering bits, collision, occluders, one-way lips), saved as
    .tres
    ; paint with
    set_cells_terrain_connect
    . Use
    dual_grid.gd
    when the art is a 16-tile dual set. GATE:
    terrain_tools.audit_layer
    gives 0 side and 0 corner mismatches; a sampler capture (ring, cross, single cells, inner corners) looks right on a contact sheet.
  4. Character.
    platformer_body.gd
    +
    platformer_tuning.gd
    Resource, or
    topdown_body.gd
    . Brain and body are split so tests drive intents. GATE (
    --fixed-fps 60
    , one move per
    await body.stepped
    ): apex within 0.5 px of design; coyote and buffer counted in moves; largest gap in tiles; no snag on tile seams; top-down stops at exactly 0 and diagonal speed equals straight speed.
  5. Camera.
    follow_camera_2d.gd
    (physics step, limits from the layer's used rect), or
    pixel_viewport.gd
    for a smooth view over locked pixels. GATE: camera y still during a jump in place; re-baseline after landing; a long fall keeps the player on screen; shake off gives offset 0. In a windowed run at
    --fixed-fps 144
    , background steps are at most 1 px with interpolation on.
  6. Lights, sort, parallax. CanvasModulate + PointLight2D with a radial GradientTexture2D; occluders from tile alpha; y-sorted container with feet origins; Parallax2D per plane. GATE: luma at probe points (lit, shadowed, owner lit vs a no-occluder control); overlap color test behind and in front; parallax shift equals scroll_scale times camera motion; no gap at the lowest zoom; no seam over 90 autoscroll frames.
  7. Audit and hand over.
    audit_2d.gd:scenes
    ,
    gd_run.check_all
    ,
    kit_compile.gd
    , then a contact sheet of the captures (at most 1600 px), opened and looked at. GATE: no warn findings, 0 compile errors, and the sheet shows no broken tiles, fringes or gaps. In a written plan, inline the core code (settings keys, jump maths, controller step, camera) so it runs without the kit; name kit files only as shortcuts.
  1. 项目。
    P = gd_env.base_project("2d", ...)
    、
    gd_2d.install_kit(P)
    、
    gd_2d.pixel_art_settings(P, ...)
    、
    gd_run.import_project(P)
    。GATE:
    stretch_matrix.gd
    显示 root 已采用 base size、mode、integer stretch、Nearest 和 interpolation;每个目标窗口的 integer factor 与黑边都应与
    gd_2d.integer_scales
    匹配。
  2. 美术接入。 对每张生成的图像执行
    detect_pixel_scale
    、
    pixel_grid_check
    ,如果 phase 或 scale 偏离,则执行
    snap_to_grid
    。随后进行导入、
    audit_imports
    ,并使用
    sprite_frames_builder.gd
    根据 manifest 构建 SpriteFrames,同时为每个 sprite 调用
    register()
    。GATE:audit 无问题;每个 clip 的最低墨迹像素都落在相同的 world y 上;在非整数缩放的 capture 上,
    key_fringe
    = 0。
  3. Tiles。 使用
    tileset_builder.gd
    构建 tileset,依次设置 tile size、从 alpha 推导的 peering bits、collision、occluders 和 one-way lips,并保存为
    .tres
    ;使用
    set_cells_terrain_connect
    绘制。美术为 16-tile dual set 时,使用
    dual_grid.gd
    。GATE:
    terrain_tools.audit_layer
    的 side 和 corner mismatches 均为 0;sampler capture(ring、cross、single cells、inner corners)在 contact sheet 上显示正确。
  4. 角色。 使用
    platformer_body.gd
    +
    platformer_tuning.gd
    Resource,或
    topdown_body.gd
    。逻辑与实体相分离,让测试可以驱动 intents。GATE(
    --fixed-fps 60
    ,每次
    await body.steped
    执行一步):apex 与设计值相差不超过 0.5 px;coyote 和 buffer 以 move 计数;最大 gap 以 tile 计;tile 接缝处不会卡住;top-down 精确停在 0,且对角速度等于直线速度。
  5. Camera。 使用
    follow_camera_2d.gd
    (采用 physics step,并从 layer 的 used rect 设置 limits),或使用
    pixel_viewport.gd
    实现锁定 pixels 上的平滑视图。GATE:原地跳跃时 camera 的 y 保持不变;落地后重新建立 baseline;长距离坠落时玩家始终在画面内;关闭 shake 后 offset 为 0。在
    --fixed-fps 144
    的窗口运行中,开启 interpolation 后背景步长最多为 1 px。
  6. 灯光、排序与视差。 使用 CanvasModulate + PointLight2D,并配合 radial GradientTexture2D;occluders 来自 tile alpha;使用以脚底为 origin 的 y-sorted container;每个 plane 使用 Parallax2D。GATE:探测点处的 luma 符合预期(受光、阴影中、owner 受光,以及无 occluder 的对照);前后 overlap 颜色测试正确;parallax 位移等于 scroll_scale 乘以 camera 位移;最低 zoom 下没有 gap;经过 90 个 autoscroll frames 后没有 seam。
  7. 审计与交付。 执行
    audit_2d.gd:scenes
    、
    gd_run.check_all
    、
    kit_compile.gd
    ,然后生成 captures 的 contact sheet(最大 1600 px),打开并实际查看。GATE:没有 warn findings、0 个编译错误,且 contact sheet 中没有损坏的 tiles、fringes 或 gaps。在书面方案中,将核心代码(settings keys、jump maths、controller step、camera)直接内联,使其无需 kit 也能运行;kit 文件仅作为快捷方式引用。

Numbers

数值

ValueMeasured or sourceRelative to
Base 320x180, integer: 4x at 1280x720 and 1366x768 (bars 43, 24), 6x at 1080p, 8x at 1440p, 12x at 4K, 3x at 1170x2532livewindow size
Base 640x360, integer: 2x at 720p and 1366x768 (bars 43, 24), 3x at 1080p, 4x at 1440p, 6x at 4K; 3840x2159 gives 5x with 320 and 180 px barslivewindow size
Jump 56 px, apex 0.35 s, fall 0.28 s: g up 914.3, g down 1428.6 px/s², take-off 327.6 px/s with compensationlive, kit defaults [added]16 px tiles, 60 ticks
Jump cut 0.4: a one-tick tap rises 12.79 px (under a tile); minimum height is about (cut·v)²/2glive, kit defaults16 px tiles
Coyote 0.1 s = 6 airborne moves; buffer 0.1 s = 5 moves before landinglive60 ticks
Corner correction 4 px: a 3 px head clip goes from 34 px to the full 56 pxlive10x14 body
120 px/s run, 56 px jump: clears 4 tiles, not 5live16 px tiles
Top-down 120 px/s, accel 900, decel 1200: 8 moves to max, 6 to stoplive, kit defaults60 ticks
Camera2D smoothing speed: default 5, about 3 felt right, 10 felt like noneDevWorm; default read livepx/s smoothing units
Exponential damping 8/s: 90% of a jump closed in 0.30 s at 30, 60 or 144 Hz; lag = speed / dampingliveframe rate
Jitter floor 0.289 px RMS (interpolation on) vs 0.55 (off) at 144 Hzlivescreen px
Sub-pixel camera at 4x: 1 px steps vs 4 px snappedlivescreen px
Parallax repeat_times for a plane as wide as the view: zoom 1 needs 1, 0.5 needs 3, 0.25 needs 5liveCamera2D zoom
Banded light: a 4-stop Gradient with
GRADIENT_INTERPOLATE_CONSTANT
gave 4 luma levels across 64 px, LINEAR 64
livePointLight2D over CanvasModulate
Fringe: 73 tinted px without
fix_alpha_border
or
fix_alpha_edges()
, 0 with
live96 px frame at 0.7x
数值实测或来源相对于
Base 320x180,整数缩放:1280x720 和 1366x768 下为 4x(黑边 43、24),1080p 下为 6x,1440p 下为 8x,4K 下为 12x,1170x2532 下为 3xlive窗口尺寸
Base 640x360,整数缩放:720p 和 1366x768 下为 2x(黑边 43、24),1080p 下为 3x,1440p 下为 4x,4K 下为 6x;3840x2159 下为 5x,并出现 320 px 和 180 px 黑边live窗口尺寸
跳跃 56 px,apex 0.35 s,fall 0.28 s:上升 g 914.3、下降 g 1428.6 px/s²,带补偿的 take-off 为 327.6 px/slive、kit defaults [added]16 px tiles、60 ticks
Jump cut 0.4:单击一 tick 上升 12.79 px(不足一个 tile);最小高度约为 (cut·v)²/2glive、kit defaults16 px tiles
Coyote 0.1 s = 6 个 airborne moves;buffer 0.1 s = 落地前 5 个 moveslive60 ticks
Corner correction 4 px:3 px 的头部 clip 会从 34 px 恢复到完整的 56 pxlive10x14 body
120 px/s 跑动、56 px 跳跃:可越过 4 个 tiles,不能越过 5 个live16 px tiles
Top-down 120 px/s,accel 900、decel 1200:8 个 moves 达到最高速度,6 个 moves 完全停止live、kit defaults60 ticks
Camera2D smoothing speed:默认值为 5,约为 3 时手感合适,10 时几乎感觉不到平滑DevWorm;实时读取默认值px/s 平滑单位
Exponential damping 8/s:在 30、60 或 144 Hz 下,90% 的跳跃差距都在 0.30 s 内闭合;lag = speed / dampinglive帧率
Jitter floor:开启 interpolation 时为 0.289 px RMS,关闭时为 0.55 px RMS,测试环境为 144 Hzlive屏幕 px
4x 下的 sub-pixel camera:产生 1 px 步长,而不是吸附为 4 pxlive屏幕 px
与视图同宽的 plane 所用 Parallax repeat_times:zoom 1 需要 1,zoom 0.5 需要 3,zoom 0.25 需要 5liveCamera2D zoom
Banded light:采用
GRADIENT_INTERPOLATE_CONSTANT
的 4-stop Gradient 在 64 px 内产生 4 个 luma 等级,LINEAR 则产生 64 个
liveCanvasModulate 之上的 PointLight2D
Fringe:未使用
fix_alpha_border
或
fix_alpha_edges()
时有 73 个着色 px,使用后为 0
live0.7x 下的 96 px 帧

Quality gates

质量门槛

Every GATE above, plus a contact sheet of the terrain sampler, dual grid, fringe strip and light captures, opened and judged (rounded corners join the shape, no floating pieces, no magenta edge, shadows from the right side). Rubric: critique.md.
上述每一项 GATE,外加一张包含 terrain sampler、dual grid、fringe strip 和 light captures 的 contact sheet;必须打开并实际查看(圆角正确接合形状、没有悬浮块、没有 magenta edge、阴影来自右侧)。评估量表:critique.md。

Common mistakes

常见错误

MistakeWhat it looks likeFix
Hand-written project.godotstretch
disabled
, blurry pixels
gd_2d.pixel_art_settings
, read the root back
16-tile sides set in Match Corners and Sidesholes and wrong edges (32 + 10 mismatches)Match Sides, or draw the 47-blob set
Peering bits typed by handrandom edge piecesderive from tile alpha, audit
Jump from the formula onlyapex 2.5 px short, a gap that should clear does notcompensate g·dt/2 or measure and tune
Camera2D as child of the player and nothing elsestatic, short-sighted, jumpy
follow_camera_2d.gd
Idle camera smoothing, interpolation offplayer shakes against the background at 144 Hzphysics interpolation on
Camera2D inside a pixel SubViewport with interpolation onimage jumps -5, +3 pxset
canvas_transform
(
pixel_viewport.gd
)
Snap shader expected to pixelate lightfalloff still smooth
viewport
stretch or a SubViewport world; bands from a CONSTANT gradient;
shadow_filter
None (the default)
Occluder owner goes darkwall or sprite unlitflip cull mode (screen winding decides), check against a control
Centered sprite origin in a y-sorted containerplayer drawn over a tree it stands behindorigin at the feet, art moved with
offset
; tall tiles get
y_sort_origin
Zoom by changing the viewport or window sizeUI and pixel scale change with it
Camera2D.zoom
Fullscreen (mode 3) for integer pixel artfactor drops one step on a 1 px stripExclusive Fullscreen (mode 4)
Shadow baked into the character spriteshadow drawn over the tree trunk behindseparate shadow Sprite2D,
z_index = -1
;
z_as_relative = false
once the character has its own z (DevWorm, lvuLjMAr_BE [00:09:24])
Tile animation over a neighboring tile"tiles are already present", 1 frame kepterase the neighbors first (DevWorm, ZutpG0_CYrQ [00:24:13])
Parallax with repeat_times 1 and zoom outmagenta or black gaps
parallax_tools.repeat_times_for
Keyed sprite loaded at runtime with linear filteringmagenta outlineimport it, or
Image.fix_alpha_edges()
.import
edited and reimported in the same second
old texture still used
gd_2d.set_import_params
(lowercase bools, mtime bump), check the
.ctex
changed
错误表现修复方法
手写 project.godotstretch 为
disabled
,像素模糊
使用
gd_2d.pixel_art_settings
,并回读 root
在 Match Corners and Sides 中设置 16-tile sides出现空洞和错误边缘(32 + 10 mismatches)使用 Match Sides,或绘制 47-blob set
手动输入 peering bits出现随机边缘块从 tile alpha 推导并执行 audit
仅根据公式执行跳跃apex 短 2.5 px,本应越过的 gap 无法越过补偿 g·dt/2,或通过测量进行调优
Camera2D 仅作为 player 的子节点静止、视野短、容易跳动使用
follow_camera_2d.gd
使用 Idle camera smoothing,并关闭 interpolation在 144 Hz 下,玩家相对背景发生抖动开启 physics interpolation
Camera2D 位于 pixel SubViewport 内且开启 interpolation图像跳动 -5、+3 px设置
canvas_transform
(
pixel_viewport.gd
)
期待 Snap shader 对灯光进行像素化falloff 仍然平滑使用
viewport
stretch 或 SubViewport world;使用 CONSTANT gradient 产生色阶;
shadow_filter
设为 None(默认值)
Occluder owner 变暗墙体或 sprite 未受光翻转 cull mode(由 screen winding 决定),并与 control 对照检查
在 y-sorted container 中使用居中的 sprite origin玩家被绘制在其身后树干的上面将 origin 放在脚底,通过
offset
移动美术;高 tiles 使用
y_sort_origin
通过改变 viewport 或 window 大小实现 zoomUI 和 pixel scale 随之改变使用
Camera2D.zoom
整数 pixel art 使用 Fullscreen(mode 3)1 px 黑边就会让缩放系数降低一级使用 Exclusive Fullscreen(mode 4)
将阴影烘焙进角色 sprite阴影被绘制到身后树干上使用独立的阴影 Sprite2D,设置
z_index = -1
;角色拥有独立 z 后设置
z_as_relative = false
(DevWorm, lvuLjMAr_BE [00:09:24])
Tile animation 播放到相邻 tile 上出现“tiles are already present”,仅保留 1 帧先清除相邻 tiles(DevWorm, ZutpG0_CYrQ [00:24:13])
Parallax 使用 repeat_times 1 并缩小 zoom出现 magenta 或 black gaps使用
parallax_tools.repeat_times_for
在运行时加载带 keyed sprite,并使用 linear filtering出现 magenta outline对其进行导入,或使用
Image.fix_alpha_edges()
编辑
.import
后在同一秒内重新导入
继续使用旧 texture使用
gd_2d.set_import_params
(小写 bools、mtime bump),并检查
.ctex
已发生变化

Handoffs

交接

  • Receives from scenario-sprite-pipeline, scenario-game-assets, scenario-sprite-animation: PNG or WebP strips, tilesets and a manifest with
    frames
    ,
    w
    ,
    h
    ,
    ground
    . Ask for the native pixel size and key color.
  • Receives from scenario-godot-architecture: project layout, autoloads, input action names.
  • Delivers to scenario-godot-gameplay: bodies with intent fields and signals
    jumped
    ,
    landed
    ,
    stepped
    ; TileMapLayers for navigation. scenario-godot-animation: SpriteFrames registered on feet.
  • Delivers to scenario-godot-vfx, scenario-godot-shaders, scenario-godot-ui (HUD via
    pixel_viewport.world_to_screen
    ), scenario-godot-performance-export, scenario-godot-audio (hooks on
    landed
    ).
  • Escalate to scenario-godot-expert for channel failures.
  • 接收自 scenario-sprite-pipeline、scenario-game-assets、scenario-sprite-animation:PNG 或 WebP strips、tilesets,以及包含
    frames
    、
    w
    、
    h
    、
    ground
    的 manifest。询问原生 pixel size 和 key color。
  • 接收自 scenario-godot-architecture:project layout、autoloads、input action names。
  • 交付给 scenario-godot-gameplay:带 intent fields 和
    jumped
    、
    landed
    、
    stepped
    signals 的 bodies;用于 navigation 的 TileMapLayers。交付给 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
    )。
  • 发生 channel failure 时,升级到 scenario-godot-expert。

Godot 4.7 notes

Godot 4.7 注意事项

  • TileMap and ParallaxBackground/ParallaxLayer are deprecated since 4.3: use TileMapLayer (4-arg
    set_cell
    ) and Parallax2D. Tile physics is chunked by
    physics_quadrant_size
    since 4.5. One-way direction (
    one_way_collision_direction
    , default (0, 1)) is new in 4.7 (deltas file).
  • Camera2D:
    enabled
    plus
    make_current()
    ,
    position_smoothing_enabled
    ,
    ignore_rotation
    . With interpolation on, a zoom change eases over one tick (2 to 3 frames to reach 2.0, measured).
  • Defaults read in 4.7.2: canvas texture filter Linear, 2D transform snap off, physics interpolation off, CharacterBody2D safe margin 0.08 and floor snap 1 px. Texture import: Lossless, no mipmaps,
    fix_alpha_border
    on,
    detect_3d/compress_to
    1.
  • Several occluder polygons on one occlusion layer of one tile work in 4.7.2 (2, kept after save): the second occlusion layer of the 4.3 video (suzF2Y166eA [00:12:22]) is not needed.
  • Godot 3 names to avoid:
    KinematicBody2D
    ,
    YSort
    ,
    Light2D
    as a node,
    set_cellv
    ,
    world_to_map
    ,
    Camera2D.current
    .
  • TileMap 和 ParallaxBackground/ParallaxLayer 自 4.3 起弃用:改用 TileMapLayer(4 参数
    set_cell
    )和 Parallax2D。Tile physics 自 4.5 起按
    physics_quadrant_size
    分块。单向方向(
    one_way_collision_direction
    ,默认值为 (0, 1))是 4.7 的新增功能(deltas file)。
  • Camera2D:
    enabled
    加
    make_current()
    、
    position_smoothing_enabled
    、
    ignore_rotation
    。开启 interpolation 后,zoom 变化会在一个 tick 内平滑过渡(实测需要 2 到 3 帧才能达到 2.0)。
  • 在 4.7.2 中读取的默认值:canvas texture filter 为 Linear,2D transform snap 关闭,physics interpolation 关闭,CharacterBody2D safe margin 为 0.08,floor snap 为 1 px。Texture import:Lossless、无 mipmaps、
    fix_alpha_border
    开启、
    detect_3d/compress_to
    为 1。
  • 在 4.7.2 中,一个 tile 的一个 occlusion layer 上可以使用多个 occluder polygons(保留 2 个,保存后仍然存在):4.3 视频中的第二个 occlusion layer(suzF2Y166eA [00:12:22])不再需要。
  • 应避免使用的 Godot 3 名称:
    KinematicBody2D
    、
    YSort
    、作为节点的
    Light2D
    、
    set_cellv
    、
    world_to_map
    、
    Camera2D.current
    。

References

参考资料

  • references/procedures.md
    : procedures with code and live results;
    expert-notes.md
    : principles by source with timestamps;
    critique.md
    : self-check rubric;
    gui-paths.md
    : editor menus;
    sources.md
    : videos and docs.
  • scripts/gd_2d.py
    : settings, import audit, pixel-grid checks, jump maths, placeholder atlases.
    scripts/agentkit/2d/
    : tileset, terrain, dual grid, bodies, cameras, pixel viewport, sprite frames, parallax, audit, light shader.
  • references/procedures.md
    :包含代码和实时结果的流程;
    expert-notes.md
    :按来源整理并带时间戳的原则;
    critique.md
    :自检量表;
    gui-paths.md
    :编辑器菜单路径;
    sources.md
    :视频和文档。
  • scripts/gd_2d.py
    :settings、import audit、pixel-grid checks、jump maths、placeholder atlases。
    scripts/agentkit/2d/
    :tileset、terrain、dual grid、bodies、cameras、pixel viewport、sprite frames、parallax、audit、light shader。