AgentSkillsCN

godot-genre-party

派对游戏的专家级蓝图,包括小游戏资源系统(通过 .tres 文件定义)、本地多人输入(4 人控制器管理)、非对称玩法(1v3 平衡)、场景管理(干净地加载/卸载小游戏)、持久计分(跨轮次统计胜局),以及分屏渲染(每位玩家一个 SubViewport)。适用于马里奥派对风格的游戏,或 WarioWare 系列游戏。触发关键词:party_game、minigame_collection、local_multiplayer、asymmetric_gameplay、split_screen、dynamic_input_mapping。

SKILL.md
--- frontmatter
name: godot-genre-party
description: "Expert blueprint for party games including minigame resource system (define via .tres files), local multiplayer input (4-player controller management), asymmetric gameplay (1v3 balance), scene management (clean minigame loading/unloading), persistent scoring (track wins across rounds), and split-screen rendering (SubViewport per player). Use for Mario Party-style games or WarioWare collections. Trigger keywords: party_game, minigame_collection, local_multiplayer, asymmetric_gameplay, split_screen, dynamic_input_mapping."

Genre: Party / Minigame Collection

Expert blueprint for party games balancing accessibility, variety, and social fun.

NEVER Do

  • NEVER long tutorials — Players want instant fun. 3-second looping GIF + 1-sentence instruction is ideal.
  • NEVER excessive downtime — Loading between 10s minigames kills momentum. Keep assets light, use threaded loading, or persistent board scene.
  • NEVER inconsistent controls — Minigame A uses A to jump, B uses B. Standardize: A=Accept/Action, B=Back/Cancel across all minigames.
  • NEVER forget dynamic input mapping — Remap InputMap at runtime (InputMap.action_add_event) for "p1_jump", "p2_jump" per controller.
  • NEVER ignore accessibility — Color-blind modes, audio cues for visual events, adjustable difficulty. Party games need inclusive design.

Available Scripts

MANDATORY: Read the appropriate script before implementing the corresponding pattern.

party_input_router.gd

4-player device isolation for local multiplayer. Maps device_id to player_id, handles join requests, routes inputs to player-specific signals.


Core Loop

  1. Lobby: Players join and select characters/colors.
  2. Meta: Players move on a board or vote for the next game.
  3. Play: Short, intense minigame (30s - 2m).
  4. Score: Winners get points/coins.
  5. Repeat: Cycle continues until a turn limit or score limit.

Skill Chain

PhaseSkillsPurpose
1. Inputinput-mappingHandling 2-4 local controllers dynamically
2. Scenegodot-scene-managementLoading/Unloading minigames cleanly
3. Datagodot-resource-data-patternsDefining minigames via Resource files
4. UIgodot-ui-containersScoreboards, instructions screens
5. Logicgodot-turn-systemManaging the "Board Game" phase

Architecture Overview

1. Minigame Definition

Using Resources to define what a minigame is.

gdscript
# minigame_data.gd
class_name MinigameData extends Resource

@export var title: String
@export var scene_path: String
@export var instructions: String
@export var is_1v3: bool = false
@export var thumbnail: Texture2D

2. The Party Manager

Singleton that persists between minigames.

gdscript
# party_manager.gd
extends Node

var players: Array[PlayerData] = [] # Tracks score, input_device_id, color
var current_round: int = 1
var max_rounds: int = 10

func start_minigame(minigame: MinigameData) -> void:
    # 1. Show instructions scene
    await show_instructions(minigame)
    # 2. Transition to actual game
    get_tree().change_scene_to_file(minigame.scene_path)
    # 3. Pass player data to the new scene
    # (The minigame scene must look up PartyManager in _ready)

3. Minigame Base Class

Every minigame inherits from this to ensure compatibility.

gdscript
# minigame_base.gd
class_name Minigame extends Node

signal game_ended(results: Dictionary)

func _ready() -> void:
    setup_players(PartyManager.players)
    start_countdown()

func end_game() -> void:
    # Calculate winner
    game_ended.emit(results)
    PartyManager.handle_minigame_end(results)

Key Mechanics Implementation

Local Multiplayer Input

Handling dynamic device assignment.

gdscript
# player_controller.gd
@export var player_id: int = 0 # 0, 1, 2, 3

func _physics_process(delta: float) -> void:
    var device = PartyManager.players[player_id].device_id
    # Use the specific device ID for input
    var direction = Input.get_vector("p%s_left" % player_id, ...) 
    # Better approach: Remap InputMap actions at runtime explicitly

Asymmetric Gameplay (1v3)

Balancing the "One" vs the "Many".

  • The One: Powerful, high HP, unique abilities (e.g., Bowser suit).
  • The Many: Weak individually, must cooperate to survive/win.

Godot-Specific Tips

  • SubViewport: Powerful for 4-player split-screen. Each player gets a camera, all rendering the same world (or different worlds!).
  • InputEventJoypadButton: Use Input.get_connected_joypads() to auto-detect controllers on the Lobby screen.
  • Remapping: Godot's InputMap system can be modified at runtime using InputMap.action_add_event(). Creating "p1_jump", "p2_jump" dynamically is a common pattern.

Common Pitfalls

  1. Long Tutorials: Players just want to play. Fix: 3-second looping GIF + 1 sentence instruction overlay before the game starts.
  2. Downtime: Loading times between 10-second minigames. Fix: Keep minigame assets light. Use a "Board" scene that stays loaded in the background if possible, or use creating Thread loading.
  3. Confusing Controls: Minigame A uses "A" to jump, Minigame B uses "B". Fix: Standardize. "A" is always Accept/Action. "B" is always Back/Cancel.

Reference