level-design
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseLevel design
关卡设计
A level is a sequence of intentional experiences delivered through space.
Good level design is a process: define the metrics movement is built on, block
out geometry with primitives, play it, then dress it — never the reverse. This
skill is the engine-neutral practice; use / to
lay out 2D grids and gridmaps for 3D.
godot-tilemapunity-tilemap-2d关卡是通过空间传递的一系列有目的性的体验。优秀的关卡设计是一个流程:先定义移动所基于的指标,用基础几何体搭建blockout(白盒),进行测试,再添加细节——绝不能颠倒顺序。本技能是独立于引擎的实践方法;若要为2D网格和3D网格地图布局,可使用/。
godot-tilemapunity-tilemap-2dWhen to use
适用场景
- Use to plan a level's structure: critical path, pacing, gating, encounters, and where the player learns vs is tested.
- Use the blockout → test → iterate → dress workflow to build a level that plays well before any art exists.
- Use to derive level metrics from the character's movement so geometry is reachable and fair.
When not to use: to generate levels algorithmically, use
(authored and procedural design are complementary). For the engine's tile/grid
painting tools, use / . For the movement
abilities the metrics come from, that's the engine movement skill + .
procedural-gengodot-tilemapunity-tilemap-2dinput-systems- 用于规划关卡结构:关键路径、节奏、关卡限制、遭遇战,以及玩家学习机制与接受测试的区域。
- 采用白盒搭建 → 测试 → 迭代 → 添加细节的工作流,在任何美术资源制作完成前,先打造出玩法流畅的关卡。
- 根据角色的移动能力推导关卡指标,确保几何体的可达性与公平性。
不适用场景:若要通过算法生成关卡,请使用(人工设计与程序化设计互为补充)。若要使用引擎的瓦片/网格绘制工具,请使用 / 。若要获取指标所基于的移动能力,请使用引擎移动技能 + 。
procedural-gengodot-tilemapunity-tilemap-2dinput-systemsCore workflow
核心工作流
- Derive metrics first. Measure the character: max jump height and distance, run speed, reach, camera range. Every gap, ledge, and corridor is sized in these units. Lock them before building geometry.
- Blockout (whitebox/greybox). Build the whole level from untextured primitives at correct scale. Validate flow, sightlines, and reachability while changes are cheap. No art yet.
- Define the critical path (start → goal) and the golden path you expect most players to take. Layer optional/secret paths off it.
- Pace the experience. Alternate tension and rest in a deliberate curve; don't run combat-combat-combat. Give the player room to breathe and to anticipate.
- Teach, then test. Introduce each mechanic in a safe space, let the player practice, then test it under pressure. Difficulty rises in a sawtooth, not a straight line.
- Gate with intent. Use locks/keys, abilities, and one-way drops to control order and pacing; guide with light, lines, and landmarks rather than walls.
- Playtest and iterate. Watch real players: where do they get lost, stuck, bored, or killed unfairly? Fix the blockout; only dress when it plays well.
- 先推导指标:测量角色的各项参数:最大跳跃高度与距离、奔跑速度、可触及范围、相机视野。每个缺口、平台边缘和走廊都以这些单位为尺寸标准。在搭建几何体前锁定这些参数。
- 白盒搭建(blockout/whitebox/greybox):使用无纹理的基础几何体按正确比例搭建整个关卡。在修改成本较低时,验证流程、视线和可达性。此时不添加任何美术资源。
- 定义关键路径(起点→终点)和你预期大多数玩家会选择的黄金路径。在主路径之外设置可选/隐藏路径。
- 把控体验节奏:刻意交替紧张与放松的节奏曲线;不要连续安排战斗-战斗-战斗。给玩家留出喘息和预判的空间。
- 先教学,再测试:在安全区域引入每个机制,让玩家练习,再在压力环境下测试。难度呈锯齿状上升,而非直线上升。
- 有目的地设置关卡限制:使用锁/钥匙、能力和单向掉落来控制顺序与节奏;用光线、线条和地标引导玩家,而非墙壁。
- 测试并迭代:观察真实玩家的表现:他们在哪里迷路、卡关、感到无聊或被不公平地击杀?先修改白盒;只有当玩法流畅时,再添加细节。
Patterns
设计模式
1. Player metrics drive every dimension
1. 玩家指标驱动所有维度
gdscript
undefinedgdscript
undefinedMeasure the character ONCE, then size geometry in these units. If the jump
Measure the character ONCE, then size geometry in these units. If the jump
changes, gaps must be re-derived — never eyeball reachability.
changes, gaps must be re-derived — never eyeball reachability.
const RUN_SPEED := 240.0 # px/s (or m/s in 3D)
const MAX_JUMP_H := 96.0 # peak height of a full jump
const MAX_JUMP_DIST := 200.0 # horizontal distance of a running jump
const SAFE_GAP := MAX_JUMP_DIST * 0.7 # comfortable, not pixel-perfect
const HARD_GAP := MAX_JUMP_DIST * 0.95 # a deliberate skill check
const RUN_SPEED := 240.0 # px/s (or m/s in 3D)
const MAX_JUMP_H := 96.0 # peak height of a full jump
const MAX_JUMP_DIST := 200.0 # horizontal distance of a running jump
const SAFE_GAP := MAX_JUMP_DIST * 0.7 # comfortable, not pixel-perfect
const HARD_GAP := MAX_JUMP_DIST * 0.95 # a deliberate skill check
Build platforms so required jumps use SAFE_GAP; reserve HARD_GAP for optional reward.
Build platforms so required jumps use SAFE_GAP; reserve HARD_GAP for optional reward.
A reachable level falls out of honest metrics. A platform placed `MAX_JUMP_DIST +
1` away is impossible; one at `SAFE_GAP` is fair. Keep these constants beside the
level data so designers and code agree.
基于真实指标设计的关卡自然具备可达性。一个设置在`MAX_JUMP_DIST +1`距离外的平台是不可触及的;而设置在`SAFE_GAP`距离的平台则是公平的。将这些常量与关卡数据放在一起,确保设计师和代码逻辑保持一致。2. Encounter / pacing as data (a tension timeline)
2. 遭遇战/节奏数据化(紧张度时间线)
gdscript
undefinedgdscript
undefinedAuthor the level as a sequence of beats with an intended intensity (0..1).
Author the level as a sequence of beats with an intended intensity (0..1).
This makes the pacing curve explicit and reviewable before you build rooms.
This makes the pacing curve explicit and reviewable before you build rooms.
const BEATS := [
{ "room": "entry", "type": "teach", "intensity": 0.1 },
{ "room": "hall_1", "type": "combat", "intensity": 0.5 },
{ "room": "vista", "type": "rest", "intensity": 0.1 }, # breather + reward
{ "room": "gauntlet", "type": "combat", "intensity": 0.8 },
{ "room": "save_room", "type": "rest", "intensity": 0.2 }, # before the boss
{ "room": "boss", "type": "climax", "intensity": 1.0 },
]
const BEATS := [
{ "room": "entry", "type": "teach", "intensity": 0.1 },
{ "room": "hall_1", "type": "combat", "intensity": 0.5 },
{ "room": "vista", "type": "rest", "intensity": 0.1 }, # breather + reward
{ "room": "gauntlet", "type": "combat", "intensity": 0.8 },
{ "room": "save_room", "type": "rest", "intensity": 0.2 }, # before the boss
{ "room": "boss", "type": "climax", "intensity": 1.0 },
]
Read the intensity column top-to-bottom: it should rise overall but dip for rests
Read the intensity column top-to-bottom: it should rise overall but dip for rests
(a sawtooth), never flatline high. Drive spawns/music intensity from this.
(a sawtooth), never flatline high. Drive spawns/music intensity from this.
undefinedundefined3. Gating and the critical path (a small graph)
3. 关卡限制与关键路径(小型图结构)
gdscript
undefinedgdscript
undefinedModel the level as rooms + gated connections. Validate that the goal is
Model the level as rooms + gated connections. Validate that the goal is
reachable with the keys/abilities the player can actually obtain in order.
reachable with the keys/abilities the player can actually obtain in order.
const ROOMS := {
"entry": { "exits": [ { "to": "hall_1" } ] },
"hall_1": { "exits": [ { "to": "vista", "needs": "double_jump" },
{ "to": "side_room" } ] }, # optional branch
"side_room": { "exits": [ { "to": "hall_1" } ], "grants": "double_jump" },
"vista": { "exits": [ { "to": "boss", "needs": "red_key" } ] },
}
const ROOMS := {
"entry": { "exits": [ { "to": "hall_1" } ] },
"hall_1": { "exits": [ { "to": "vista", "needs": "double_jump" },
{ "to": "side_room" } ] }, # optional branch
"side_room": { "exits": [ { "to": "hall_1" } ], "grants": "double_jump" },
"vista": { "exits": [ { "to": "boss", "needs": "red_key" } ] },
}
Validation (do this!): from "entry", can the player reach "boss" given that
Validation (do this!): from "entry", can the player reach "boss" given that
"double_jump" is granted in "side_room" before "vista" requires it? A flood
"double_jump" is granted in "side_room" before "vista" requires it? A flood
fill that only traverses an exit when its needs
is already satisfiable
needsfill that only traverses an exit when its needs
is already satisfiable
needsproves the critical path isn't soft-locked.
proves the critical path isn't soft-locked.
undefinedundefinedPitfalls
常见误区
- Dressing before it plays. Detailing a blockout you haven't validated wastes the most expensive work on a layout you'll change. Greybox and test first.
- Geometry that ignores metrics: gaps the jump can't clear, ledges below reach, corridors narrower than the camera needs. Size everything in player units.
- Flat pacing. Wall-to-wall combat (or wall-to-wall calm) numbs the player. Alternate tension and rest; place a breather and a save before the climax.
- Testing a mechanic before teaching it. Players meet a hazard for the first time in a lethal spot. Introduce safely, let them practice, then test.
- Soft-locks and dead ends. A gate needs an ability/key obtainable only past the gate. Validate the critical path's key/ability order, not just connectivity.
- No readability / guidance. Players get lost when nothing draws the eye. Use light, leading lines, color, and landmarks to point toward the path.
- One-way drops with no signposting strand or surprise players. Telegraph irreversible moves.
- Confusing procedural with authored. Generation gives variety, not
authored pacing. Use for variety; hand-author for intent.
procedural-gen
- 先添加细节再验证玩法:在未验证的白盒上添加细节,会把最耗时的工作浪费在后续需要修改的布局上。先进行灰盒搭建和测试。
- 几何体设计忽略指标:角色跳跃无法越过的缺口、低于可触及范围的平台边缘、比相机视野更窄的走廊。所有尺寸都应基于玩家单位。
- 节奏平淡:从头到尾的战斗(或从头到尾的平静)会让玩家麻木。交替紧张与放松的节奏;在高潮前设置喘息点和存档点。
- 未教学就测试机制:玩家首次遇到危险就处于致命场景。先在安全区域引入机制,让玩家练习,再进行测试。
- 软锁和死胡同:某个关卡限制需要的能力/钥匙只能在通过该限制后获得。验证关键路径中能力/钥匙的获取顺序,而不仅仅是连通性。
- 缺乏可读性/引导:当没有任何元素吸引玩家注意力时,他们会迷路。使用光线、引导线、色彩和地标指向路径。
- 无提示的单向掉落:困住或惊吓玩家。提前告知不可逆的操作。
- 混淆程序化与人工设计:程序化生成带来多样性,但无法实现人工设计的节奏。使用增加多样性;通过人工设计实现目的性。
procedural-gen
References
参考资料
- — the difficulty/tension curve in depth, teaching-loop design (introduce→develop→twist→test), readability and guidance techniques, 2D vs 3D layout considerations, and a blockout review checklist.
references/pacing-and-flow.md
- — 深入讲解难度/紧张度曲线、教学循环设计(引入→拓展→变体→测试)、可读性与引导技巧、2D与3D布局注意事项,以及白盒搭建检查清单。
references/pacing-and-flow.md
Related skills
相关技能
- ,
godot-tilemap— paint 2D level grids; gridmaps for 3D.unity-tilemap-2d - — generate variety to complement authored structure.
procedural-gen - — encounter enemies that navigate the space you build.
game-ai - ,
platformer,puzzle— genres that compose this skill.roguelike
- ,
godot-tilemap— 绘制2D关卡网格;3D网格地图。unity-tilemap-2d - — 生成多样性内容,补充人工设计的结构。
procedural-gen - — 可在你搭建的空间中导航的遭遇战敌人。
game-ai - ,
platformer,puzzle— 整合本技能的游戏类型。roguelike