godot-genre-metroidvania

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Genre: Metroidvania

游戏类型:Metroidvania

Expert blueprint for Metroidvanias balancing exploration, progression, and backtracking rewards.
类银河恶魔城游戏的专业设计蓝图,平衡探索、进度推进与回溯奖励。

NEVER Do

绝对禁忌

  • NEVER allow soft-locks — Players must always have ability to backtrack. Design "valves" (one-way drops) carefully with escape routes.
  • NEVER make empty dead ends — Every path should have a reward (upgrade, lore, currency). Empty rooms waste player time.
  • NEVER make backtracking tedious — New abilities should speed traversal (dash, teleport). Or unlock shortcuts connecting distant areas.
  • NEVER forget persistent state — Save collectible pickup status globally. If player collects item in Room A, it must stay collected after leaving.
  • NEVER hide critical path without breadcrumbs — Use landmarks, environmental storytelling, or subtle visual cues. Players should build mental maps.

  • 绝对禁止出现软锁(soft-locks)——玩家必须始终拥有回溯的能力。设计单向掉落通道时需谨慎搭配逃生路线。
  • 绝对禁止设置无奖励的死胡同——每条路径都应有奖励(升级、背景故事、货币)。空房间只会浪费玩家时间。
  • 绝对禁止让回溯过程乏味——新能力应加快移动速度(冲刺、传送),或解锁连接偏远区域的捷径。
  • 绝对不能忘记持久状态——全局保存收集品的拾取状态。如果玩家在A房间收集了物品,离开后该物品必须保持已收集状态。
  • 绝对不能在没有线索的情况下隐藏关键路径——使用地标、环境叙事或细微的视觉提示。玩家应能构建心理地图。

Available Scripts

可用脚本

MANDATORY: Read the appropriate script before implementing the corresponding pattern.
强制要求:在实现对应模式前,请先阅读相应脚本。

minimap_fog.gd

minimap_fog.gd

Grid-based fog-of-war for minimap. Tracks revealed tiles via player position, draws only visited rooms. Scalable via TileMap for large maps.
用于小地图的基于网格的战争迷雾系统。通过玩家位置追踪已解锁的 tiles,仅绘制已访问的房间。可通过TileMap扩展至大型地图。

progression_gate_manager.gd

progression_gate_manager.gd

Ability unlock + world persistence system. Tracks unlocked abilities and room states (doors, bosses), enables global collision gate updates.

能力解锁+世界持久化系统。追踪已解锁的能力和房间状态(门、Boss),支持全局碰撞门更新。

Core Loop

核心循环

  1. Exploration: Player explores available rooms until blocked by a "lock" (obstacle).
  2. Discovery: Player finds a "key" (ability/item) or boss.
  3. Acquisition: Player gains new traversal or combat ability.
  4. Backtracking: Player returns to previous locks with new ability.
  5. Progression: New areas open up, cycle repeats.
  1. 探索:玩家探索可用房间,直到被“锁”(障碍物)阻挡。
  2. 发现:玩家找到“钥匙”(能力/物品)或Boss。
  3. 获取:玩家获得新的移动或战斗能力。
  4. 回溯:玩家使用新能力返回之前的锁点。
  5. 推进:新区域解锁,循环重复。

Skill Chain

技能链

PhaseSkillsPurpose
1. Character
godot-characterbody-2d
,
state-machines
Tight, responsive movement (Coyote time, buffers)
2. World
godot-tilemap-mastery
,
level-design
Interconnected map, biomes, landmarks
3. Systems
godot-save-load-systems
,
godot-scene-management
Persistent world state, room transitions
4. UI
ui-system
,
godot-inventory-system
Map system, inventory, HUD
5. Polish
juiciness
Effects, atmosphere, environmental storytelling
阶段技能用途
1. 角色
godot-characterbody-2d
,
state-machines
流畅、响应灵敏的移动(延迟跳跃、输入缓冲)
2. 世界
godot-tilemap-mastery
,
level-design
互联式地图、生物群系、地标
3. 系统
godot-save-load-systems
,
godot-scene-management
持久化世界状态、房间过渡
4. UI
ui-system
,
godot-inventory-system
地图系统、物品栏、HUD
5. 打磨
juiciness
特效、氛围、环境叙事

Architecture Overview

架构概述

1. Game State & Persistence

1. 游戏状态与持久化

Metroidvanias require tracking the state of every collectible and boss across the entire world.
gdscript
undefined
类银河恶魔城游戏需要追踪整个世界中每个收集品和Boss的状态。
gdscript
undefined

game_state.gd (AutoLoad)

game_state.gd (AutoLoad)

extends Node
var collected_items: Dictionary = {} # "room_id_item_id": true var unlocked_abilities: Array[String] = [] var map_visited_rooms: Array[String] = []
func register_collectible(id: String) -> void: collected_items[id] = true save_game()
func has_ability(ability_name: String) -> bool: return ability_name in unlocked_abilities
undefined
extends Node
var collected_items: Dictionary = {} # "room_id_item_id": true var unlocked_abilities: Array[String] = [] var map_visited_rooms: Array[String] = []
func register_collectible(id: String) -> void: collected_items[id] = true save_game()
func has_ability(ability_name: String) -> bool: return ability_name in unlocked_abilities
undefined

2. Room Transitions

2. 房间过渡

Seamless transitions are key. Use a
SceneManager
to handle instancing new rooms and positioning the player.
gdscript
undefined
无缝过渡是关键。使用
SceneManager
处理新房间的实例化和玩家定位。
gdscript
undefined

door.gd

door.gd

extends Area2D
@export_file("*.tscn") var target_scene_path: String @export var target_door_id: String
func _on_body_entered(body: Node2D) -> void: if body.is_in_group("player"): SceneManager.change_room(target_scene_path, target_door_id)
undefined
extends Area2D
@export_file("*.tscn") var target_scene_path: String @export var target_door_id: String
func _on_body_entered(body: Node2D) -> void: if body.is_in_group("player"): SceneManager.change_room(target_scene_path, target_door_id)
undefined

3. Ability System (State Machine Integration)

3. 能力系统(状态机集成)

Abilities should be integrated into the player's State Machine.
gdscript
undefined
能力应集成到玩家的状态机中。
gdscript
undefined

player_state_machine.gd

player_state_machine.gd

func _physics_process(delta): if Input.is_action_just_pressed("jump") and is_on_floor(): transition_to("Jump") elif Input.is_action_just_pressed("jump") and not is_on_floor() and GameState.has_ability("double_jump"): transition_to("DoubleJump") elif Input.is_action_just_pressed("dash") and GameState.has_ability("dash"): transition_to("Dash")
undefined
func _physics_process(delta): if Input.is_action_just_pressed("jump") and is_on_floor(): transition_to("Jump") elif Input.is_action_just_pressed("jump") and not is_on_floor() and GameState.has_ability("double_jump"): transition_to("DoubleJump") elif Input.is_action_just_pressed("dash") and GameState.has_ability("dash"): transition_to("Dash")
undefined

Key Mechanics Implementation

核心机制实现

Map System

地图系统

A grid-based or node-based map is essential for navigation.
  • Grid Map: Auto-fill cells based on player position.
  • Room State: Track "visited" status to reveal map chunks.
gdscript
undefined
基于网格或节点的地图是导航的关键。
  • 网格地图:根据玩家位置自动填充单元格。
  • 房间状态:追踪“已访问”状态以解锁地图区块。
gdscript
undefined

map_system.gd

map_system.gd

func update_map(player_pos: Vector2) -> void: var grid_pos = local_to_map(player_pos) if not grid_map_data.has(grid_pos): grid_map_data[grid_pos] = VISITED ui_map.reveal_cell(grid_pos)
undefined
func update_map(player_pos: Vector2) -> void: var grid_pos = local_to_map(player_pos) if not grid_map_data.has(grid_pos): grid_map_data[grid_pos] = VISITED ui_map.reveal_cell(grid_pos)
undefined

Ability Gating (The "Lock")

能力限制机制(“锁”)

Obstacles that check for specific abilities.
gdscript
undefined
检查特定能力的障碍物。
gdscript
undefined

breakable_wall.gd

breakable_wall.gd

extends StaticBody2D
@export var required_ability: String = "super_missile"
func take_damage(amount: int, ability_type: String) -> void: if ability_type == required_ability: destroy() else: play_deflect_sound()
undefined
extends StaticBody2D
@export var required_ability: String = "super_missile"
func take_damage(amount: int, ability_type: String) -> void: if ability_type == required_ability: destroy() else: play_deflect_sound()
undefined

Common Pitfalls

常见陷阱

  1. Softlocks: Ensure the player cannot get stuck in an area without the ability to leave. Design "valves" (one-way drops) carefully.
  2. Backtracking Tedium: Make backtracking interesting by changing enemies, opening shortcuts, or making traversal faster with new abilities.
  3. Empty Rewards: Every dead end should have a reward (health upgrade, lore, currency).
  4. Lost Players: Use visual landmarks and environmental storytelling to guide players without explicit markers (e.g., "The Statue Room").
  1. 软锁(Softlocks):确保玩家不会被困在无法离开的区域。设计单向掉落通道时需谨慎。
  2. 回溯乏味:通过更改敌人、开启捷径或利用新能力加快移动速度,让回溯过程更有趣。
  3. 无奖励路径:每个死胡同都应有奖励(生命值升级、背景故事、货币)。
  4. 玩家迷路:使用视觉地标和环境叙事引导玩家,避免使用明确标记(例如“雕像房间”)。

Godot-Specific Tips

Godot专属技巧

  • Camera2D: Use
    limit_left
    ,
    limit_top
    , etc., to confine the camera to the current room bounds. Update these limits on room transition.
  • Resource Preloading: Preload adjacent rooms for seamless open-world feel if not using hard transitions.
  • RemoteTransform2D: Use this to have the camera follow the player but stay detached from the player's rotation/scale.
  • TileMap Layers: Use separate layers for background (parallax), gameplay (collisions), and foreground (visual depth).
  • Camera2D:使用
    limit_left
    limit_top
    等属性将相机限制在当前房间范围内。在房间过渡时更新这些限制。
  • 资源预加载:如果不使用硬过渡,预加载相邻房间以获得无缝开放世界体验。
  • RemoteTransform2D:使用此节点让相机跟随玩家,但不受玩家旋转/缩放的影响。
  • TileMap图层:使用单独的图层处理背景(视差滚动)、游戏玩法(碰撞)和前景(视觉深度)。

Design Principles (from Dreamnoid)

设计原则(来自Dreamnoid)

  • Ability Versatility: Abilities should serve both traversal and combat (e.g., a dash that dodges attacks and crosses gaps).
  • Practice Rooms: Introduce a mechanic in a safe environment before testing the player in a dangerous one.
  • Landmarks: Distinct visual features help players build a mental map.
  • Item Descriptions: Use them for "micro-stories" to build lore without interrupting gameplay.
  • 能力多功能性:能力应同时服务于移动和战斗(例如,既能躲避攻击又能跨越缺口的冲刺)。
  • 练习房间:在安全环境中引入机制,再让玩家在危险场景中测试。
  • 地标:独特的视觉特征帮助玩家构建心理地图。
  • 物品描述:用物品描述讲述“微型故事”,在不打断游戏流程的情况下构建背景设定。

Reference

参考

  • Master Skill: godot-master
  • 核心技能:godot-master