{
    "_lisez_moi": "Contrat sonore partage. PHP (tools/game-data-manager/audio_contract.php) et Godot (scripts/core/audio_contract.gd) lisent CE fichier: la liste des evenements n'existe qu'ici, donc les deux cotes ne peuvent pas diverger. Ce n'est pas une donnee d'auteur editable dans le gestionnaire, c'est le contrat du code.",
    "contract_version": 1,
    "buses": ["Master", "Music", "Ambience", "SFX", "UI"],
    "channels": ["music", "ambience"],
    "contexts": ["main_menu", "intro", "restaurant", "dungeon"],
    "cue_defaults": {
        "weight": 1,
        "volume_db": -6.0,
        "pitch_min": 1.0,
        "pitch_max": 1.0,
        "probability": 1.0,
        "cooldown_seconds": 0.0,
        "max_instances": 2,
        "avoid_repeat": true
    },
    "channel_defaults": {
        "weight": 1,
        "volume_db": -14.0,
        "playback": "loop_one",
        "fade_seconds": 1.2,
        "avoid_repeat": true
    },
    "limits": {
        "volume_db": [-60.0, 6.0],
        "pitch": [0.5, 2.0],
        "probability": [0.0, 1.0],
        "cooldown_seconds": [0.0, 60.0],
        "max_instances": [1, 16],
        "fade_seconds": [0.0, 10.0],
        "weight": [0.0, 1000.0]
    },
    "playback_modes": ["loop_one", "weighted_playlist"],
    "cue_modes": ["inherit", "silent", "custom"],
    "clip_kinds": ["sfx", "music", "ambience"],
    "asset_root": "res://assets/audio/",
    "scopes": {
        "player_configs": {
            "label": "Joueur",
            "prefix": "player_",
            "keys": ["footstep", "dash_start", "hurt", "immune_hit", "death", "heal", "consume", "equip", "interact", "interact_refused", "attack_windup", "attack_release", "attack_impact", "attack_interrupt", "projectile_fire", "projectile_hit", "projectile_wall"]
        },
        "weapons": {
            "label": "Arme",
            "prefix": "player_",
            "keys": ["attack_windup", "attack_release", "attack_impact", "attack_interrupt", "projectile_fire", "projectile_hit", "projectile_wall"]
        },
        "enemies": {
            "label": "Monstre",
            "prefix": "enemy_",
            "keys": ["spawn", "alert", "alert_lost", "idle", "footstep", "hurt", "death", "attack_windup", "attack_release", "attack_impact", "attack_interrupt", "attack_end", "projectile_fire", "projectile_hit", "projectile_wall", "phase_enter", "phase_exit", "shield_block", "immune_hit"]
        },
        "enemy_attacks": {
            "label": "Attaque",
            "prefix": "enemy_",
            "keys": ["attack_windup", "attack_release", "attack_impact", "attack_interrupt", "attack_end", "projectile_fire", "projectile_hit", "projectile_wall"]
        },
        "rooms": {
            "label": "Salle",
            "prefix": "dungeon_",
            "keys": ["room_enter", "room_leave", "wave_start", "room_cleared", "warp_open", "warp_blocked", "warp_used", "reward_offer", "reward_chosen", "ingredient_pickup"]
        },
        "biomes": {
            "label": "Biome",
            "prefix": "dungeon_",
            "keys": ["room_enter", "room_leave", "wave_start", "room_cleared", "warp_open", "warp_blocked", "warp_used", "reward_offer", "reward_chosen", "ingredient_pickup"]
        }
    },
    "groups": {
        "ui": "Interface",
        "player": "Joueur",
        "enemy": "Monstres",
        "restaurant": "Restaurant",
        "dungeon": "Donjon",
        "departure": "Départ comique",
        "return": "Retour de plongée"
    },
    "events": {
        "ui_confirm": {"group": "ui", "bus": "UI", "spatial": false, "loop": false, "priority": 90, "label": "Confirmation", "hint": "Bouton principal accepté, choix validé."},
        "ui_back": {"group": "ui", "bus": "UI", "spatial": false, "loop": false, "priority": 90, "label": "Retour", "hint": "Annulation, fermeture par Échap ou bouton retour."},
        "ui_navigate": {"group": "ui", "bus": "UI", "spatial": false, "loop": false, "priority": 70, "label": "Navigation", "hint": "Déplacement du focus au clavier ou à la manette.", "defaults": {"cooldown_seconds": 0.04, "max_instances": 1}},
        "ui_hover": {"group": "ui", "bus": "UI", "spatial": false, "loop": false, "priority": 40, "label": "Survol", "hint": "Souris entrée sur un contrôle. Discret et facultatif.", "defaults": {"volume_db": -18.0, "cooldown_seconds": 0.08, "max_instances": 1}},
        "ui_open": {"group": "ui", "bus": "UI", "spatial": false, "loop": false, "priority": 85, "label": "Ouverture d'écran", "hint": "Un menu ou un panneau apparaît."},
        "ui_close": {"group": "ui", "bus": "UI", "spatial": false, "loop": false, "priority": 85, "label": "Fermeture d'écran", "hint": "Un menu ou un panneau disparaît."},
        "ui_error": {"group": "ui", "bus": "UI", "spatial": false, "loop": false, "priority": 95, "label": "Action refusée", "hint": "Achat impossible, condition non remplie."},
        "ui_toggle": {"group": "ui", "bus": "UI", "spatial": false, "loop": false, "priority": 80, "label": "Bascule", "hint": "Case à cocher ou interrupteur."},
        "ui_slider": {"group": "ui", "bus": "UI", "spatial": false, "loop": false, "priority": 60, "label": "Curseur", "hint": "Glissement d'un réglage. Cadence limitée.", "defaults": {"cooldown_seconds": 0.06, "max_instances": 1}},
        "ui_purchase": {"group": "ui", "bus": "UI", "spatial": false, "loop": false, "priority": 95, "label": "Achat accepté", "hint": "Amélioration ou objet effectivement acheté."},

        "player_footstep": {"group": "player", "bus": "SFX", "spatial": true, "loop": false, "priority": 30, "label": "Pas", "hint": "Émis à la distance parcourue, jamais par image.", "defaults": {"volume_db": -16.0, "max_instances": 2, "pitch_min": 0.94, "pitch_max": 1.06}},
        "player_dash_start": {"group": "player", "bus": "SFX", "spatial": true, "loop": false, "priority": 85, "label": "Ruée", "hint": "Dash accepté, après la dépense de stamina."},
        "player_hurt": {"group": "player", "bus": "SFX", "spatial": true, "loop": false, "priority": 95, "label": "Blessure", "hint": "Dégâts réellement acceptés. Silencieux pendant les i-frames."},
        "player_death": {"group": "player", "bus": "SFX", "spatial": true, "loop": false, "priority": 100, "label": "Mort", "hint": "Coup létal. Remplace la blessure.", "defaults": {"max_instances": 1}},
        "player_immune_hit": {"group": "player", "bus": "SFX", "spatial": true, "loop": false, "priority": 85, "label": "Coup résisté à 100 %", "hint": "Le héros est immunisé à tous les types du coup: aucun dégât, aucune blessure. Distinct de la blessure pour qu'on entende que l'armure a tenu.", "defaults": {"max_instances": 2, "cooldown_seconds": 0.08}},
        "player_heal": {"group": "player", "bus": "SFX", "spatial": true, "loop": false, "priority": 80, "label": "Soin", "hint": "Points de vie effectivement rendus."},
        "player_consume": {"group": "player", "bus": "SFX", "spatial": true, "loop": false, "priority": 80, "label": "Consommable", "hint": "Objet consommé depuis un slot."},
        "player_equip": {"group": "player", "bus": "SFX", "spatial": true, "loop": false, "priority": 80, "label": "Équipement", "hint": "Arme ou équipement changé."},
        "player_interact": {"group": "player", "bus": "SFX", "spatial": true, "loop": false, "priority": 75, "label": "Interaction réussie", "hint": "Branche métier réussie, pas la simple tentative."},
        "player_interact_refused": {"group": "player", "bus": "SFX", "spatial": true, "loop": false, "priority": 75, "label": "Interaction refusée", "hint": "Cible inutilisable, mains pleines, condition manquante."},
        "player_attack_windup": {"group": "player", "bus": "SFX", "spatial": true, "loop": false, "priority": 70, "label": "Préparation d'attaque", "hint": "Une seule fois par attaque acceptée."},
        "player_attack_release": {"group": "player", "bus": "SFX", "spatial": true, "loop": false, "priority": 85, "label": "Déclenchement d'attaque", "hint": "Début d'un bloc de frappe, pas par image."},
        "player_attack_impact": {"group": "player", "bus": "SFX", "spatial": true, "loop": false, "priority": 90, "label": "Impact de l'attaque", "hint": "Dégâts acceptés par une cible. Source: l'arme.", "defaults": {"max_instances": 3, "cooldown_seconds": 0.03}},
        "player_attack_interrupt": {"group": "player", "bus": "SFX", "spatial": true, "loop": false, "priority": 70, "label": "Attaque interrompue", "hint": "Annulation. Jamais avec la fin normale."},
        "player_projectile_fire": {"group": "player", "bus": "SFX", "spatial": true, "loop": false, "priority": 85, "label": "Tir", "hint": "Une fois par volée, pas par projectile."},
        "player_projectile_hit": {"group": "player", "bus": "SFX", "spatial": true, "loop": false, "priority": 85, "label": "Projectile touche", "hint": "Collision avec une cible.", "defaults": {"max_instances": 3}},
        "player_projectile_wall": {"group": "player", "bus": "SFX", "spatial": true, "loop": false, "priority": 60, "label": "Projectile sur un mur", "hint": "Collision décor. La portée maximale n'est pas un impact."},

        "enemy_spawn": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 70, "label": "Apparition", "hint": "Monstre relâché dans la salle."},
        "enemy_alert": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 80, "label": "Alerte", "hint": "Le monstre repère le joueur."},
        "enemy_alert_lost": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 60, "label": "Perte d'aggro", "hint": "Le monstre perd la trace du joueur."},
        "enemy_idle": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 25, "label": "Bruit d'inactivité", "hint": "Grognement espacé hors combat.", "defaults": {"volume_db": -14.0, "probability": 0.35, "cooldown_seconds": 6.0, "max_instances": 1}},
        "enemy_footstep": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 25, "label": "Pas", "hint": "À la distance parcourue.", "defaults": {"volume_db": -20.0, "max_instances": 2}},
        "enemy_hurt": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 85, "label": "Blessure", "hint": "Dégâts acceptés, coup non létal.", "defaults": {"max_instances": 3, "cooldown_seconds": 0.05}},
        "enemy_death": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 95, "label": "Mort", "hint": "Une seule fois. Remplace la blessure.", "defaults": {"max_instances": 1}},
        "enemy_attack_windup": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 70, "label": "Préparation d'attaque", "hint": "Une seule fois par attaque acceptée."},
        "enemy_attack_release": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 85, "label": "Déclenchement d'attaque", "hint": "Un par bloc de frappe. Jamais par image d'une zone continue."},
        "enemy_attack_impact": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 90, "label": "Impact de l'attaque", "hint": "Dégâts acceptés par le joueur.", "defaults": {"max_instances": 2, "cooldown_seconds": 0.05}},
        "enemy_attack_interrupt": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 70, "label": "Attaque interrompue", "hint": "Annulation ou mort en préparation."},
        "enemy_attack_end": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 50, "label": "Fin d'attaque", "hint": "Fin normale seulement."},
        "enemy_projectile_fire": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 85, "label": "Tir", "hint": "Une fois par volée."},
        "enemy_projectile_hit": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 85, "label": "Projectile touche", "hint": "Collision avec le joueur."},
        "enemy_projectile_wall": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 60, "label": "Projectile sur un mur", "hint": "Collision décor."},
        "enemy_phase_enter": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 88, "label": "Entrée de phase", "hint": "Une fois par changement réel. Un maintien final ne la rejoue pas.", "defaults": {"max_instances": 1}},
        "enemy_phase_exit": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 65, "label": "Sortie de phase", "hint": "La phase quittée parle avant que la suivante entre.", "defaults": {"max_instances": 1}},
        "enemy_immune_hit": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 80, "label": "Coup résisté à 100 %", "hint": "La créature est immunisée aux types du coup (résistance 0). Distinct du bouclier: ce n'est pas une protection de phase, c'est la nature de la bête — le joueur doit comprendre qu'il faut changer d'arme.", "defaults": {"max_instances": 2, "cooldown_seconds": 0.08}},
        "enemy_shield_block": {"group": "enemy", "bus": "SFX", "spatial": true, "loop": false, "priority": 80, "label": "Coup bloqué", "hint": "Dégâts refusés: bouclier de phase ou fenêtre d’invulnérabilité d’un geste. Un coup sans effet et sans bruit se lit comme un bug.", "defaults": {"max_instances": 2, "cooldown_seconds": 0.08}},

        "restaurant_pickup": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 70, "label": "Prise d'objet", "hint": "Assiette, ingrédient ou plat pris en main."},
        "restaurant_drop": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 70, "label": "Dépôt d'objet", "hint": "Objet posé sur une station ou une table."},
        "restaurant_cook_start": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 75, "label": "Début de cuisson", "hint": "Cuisson effectivement lancée."},
        "restaurant_cook_cancel": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 70, "label": "Cuisson annulée", "hint": "Annulation explicite par le joueur."},
        "restaurant_cook_loop": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": true, "priority": 40, "label": "Cuisson (boucle)", "hint": "Boucle tenue pendant la cuisson. Une instance par station.", "defaults": {"volume_db": -18.0, "max_instances": 1}},
        "restaurant_dish_ready": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 85, "label": "Plat prêt", "hint": "Fin de cuisson. Muet si simulé hors scène."},
        "restaurant_serve": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 85, "label": "Service", "hint": "Plat remis à un client."},
        "restaurant_wash_loop": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": true, "priority": 40, "label": "Lavage (boucle)", "hint": "Boucle tenue pendant le lavage.", "defaults": {"volume_db": -18.0, "max_instances": 1}},
        "restaurant_wash_done": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 75, "label": "Lavage terminé", "hint": "Assiette propre."},
        "restaurant_clear_table": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 70, "label": "Débarrassage", "hint": "Table débarrassée."},
        "restaurant_trash": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 70, "label": "Déchets", "hint": "Objet jeté."},
        "restaurant_customer_enter": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 60, "label": "Client entre", "hint": "Client effectivement assis ou en file."},
        "restaurant_customer_order": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 65, "label": "Commande", "hint": "Le client passe commande."},
        "restaurant_customer_leave_angry": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 80, "label": "Client mécontent", "hint": "Départ sans être servi."},
        "restaurant_tip": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 80, "label": "Pourboire", "hint": "Pourboire ramassé."},
        "restaurant_takeaway": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 75, "label": "Vente à emporter", "hint": "Vente au comptoir conclue."},
        "restaurant_purchase": {"group": "restaurant", "bus": "SFX", "spatial": false, "loop": false, "priority": 90, "label": "Achat de meuble", "hint": "Meuble acheté."},
        "restaurant_place_element": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 75, "label": "Meuble posé", "hint": "Placement confirmé."},
        "restaurant_move_element": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 70, "label": "Meuble déplacé", "hint": "Déplacement confirmé."},
        "restaurant_rotate_element": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 65, "label": "Meuble pivoté", "hint": "Rotation confirmée."},
        "restaurant_remove_element": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 70, "label": "Meuble retiré", "hint": "Retrait confirmé."},
        "restaurant_hire": {"group": "restaurant", "bus": "SFX", "spatial": false, "loop": false, "priority": 90, "label": "Recrutement", "hint": "Employé embauché."},
        "restaurant_door_open": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 70, "label": "Ouverture", "hint": "Rideau ou porte ouverte."},
        "restaurant_door_close": {"group": "restaurant", "bus": "SFX", "spatial": true, "loop": false, "priority": 70, "label": "Fermeture", "hint": "Rideau ou porte fermée."},

        "dungeon_room_enter": {"group": "dungeon", "bus": "SFX", "spatial": false, "loop": false, "priority": 80, "label": "Entrée de salle", "hint": "Salle réellement entrée."},
        "dungeon_room_leave": {"group": "dungeon", "bus": "SFX", "spatial": false, "loop": false, "priority": 70, "label": "Sortie de salle", "hint": "Salle quittée."},
        "dungeon_wave_start": {"group": "dungeon", "bus": "SFX", "spatial": false, "loop": false, "priority": 85, "label": "Vague", "hint": "Vague relâchée."},
        "dungeon_room_cleared": {"group": "dungeon", "bus": "SFX", "spatial": false, "loop": false, "priority": 90, "label": "Salle terminée", "hint": "Dernier monstre abattu."},
        "dungeon_rhythm_beat": {"group": "dungeon", "bus": "SFX", "spatial": false, "loop": false, "priority": 40, "label": "Temps de la mesure", "hint": "Chaque temps d'une salle en rythme (le défi du temple)."},
        "dungeon_berimbau_echo": {"group": "dungeon", "bus": "SFX", "spatial": true, "loop": false, "priority": 70, "label": "Écho du berimbau", "hint": "Le héros gratte son berimbau dans une salle noire : la salle s'éclaire un instant."},
        "dungeon_warp_open": {"group": "dungeon", "bus": "SFX", "spatial": true, "loop": false, "priority": 80, "label": "Passage ouvert", "hint": "L'accès devient utilisable."},
        "dungeon_warp_blocked": {"group": "dungeon", "bus": "SFX", "spatial": true, "loop": false, "priority": 75, "label": "Passage bloqué", "hint": "Tentative refusée."},
        "dungeon_warp_used": {"group": "dungeon", "bus": "SFX", "spatial": true, "loop": false, "priority": 85, "label": "Passage emprunté", "hint": "Transition acceptée."},
        "dungeon_boards_break": {"group": "dungeon", "bus": "SFX", "spatial": true, "loop": false, "priority": 80, "label": "Planches brisées", "hint": "Les planches qui barricadent une bouche de métro cèdent sous les coups."},
        "dungeon_barrier_open": {"group": "dungeon", "bus": "SFX", "spatial": true, "loop": false, "priority": 85, "label": "Barrière ouverte", "hint": "Un objet de quête ouvre la barrière d'un passage (la passe de métro) : le héros s'y engage."},
        "dungeon_reward_offer": {"group": "dungeon", "bus": "SFX", "spatial": false, "loop": false, "priority": 85, "label": "Récompenses offertes", "hint": "Le choix s'affiche."},
        "dungeon_reward_chosen": {"group": "dungeon", "bus": "SFX", "spatial": false, "loop": false, "priority": 90, "label": "Récompense choisie", "hint": "Choix confirmé."},
        "dungeon_ingredient_pickup": {"group": "dungeon", "bus": "SFX", "spatial": true, "loop": false, "priority": 75, "label": "Ingrédient ramassé", "hint": "Butin effectivement collecté."},
        "dungeon_dive_end": {"group": "dungeon", "bus": "SFX", "spatial": false, "loop": false, "priority": 90, "label": "Fin de plongée", "hint": "Retour au restaurant."},

        "departure_shout": {"group": "departure", "bus": "SFX", "spatial": false, "loop": false, "priority": 85, "label": "Cri de départ", "hint": "Le héros crie avant de charger. Par défaut, le même cri que les monstres qui le repèrent."},
        "departure_windup": {"group": "departure", "bus": "SFX", "spatial": false, "loop": false, "priority": 80, "label": "Chauffe", "hint": "Début de la mise en scène de départ."},
        "departure_sprint": {"group": "departure", "bus": "SFX", "spatial": false, "loop": false, "priority": 80, "label": "Sprint", "hint": "Course lancée."},
        "departure_launch": {"group": "departure", "bus": "SFX", "spatial": false, "loop": false, "priority": 70, "label": "Objets projetés", "hint": "Objets traversés. Pas un son par brique.", "defaults": {"max_instances": 3, "cooldown_seconds": 0.08}},
        "departure_wall_break": {"group": "departure", "bus": "SFX", "spatial": false, "loop": false, "priority": 95, "label": "Mur défoncé", "hint": "Impact final."},
        "return_gasp": {"group": "return", "bus": "SFX", "spatial": false, "loop": false, "priority": 80, "label": "Respiration difficile", "hint": "Trois grandes respirations au retour par épuisement."},
        "return_kick": {"group": "return", "bus": "SFX", "spatial": false, "loop": false, "priority": 85, "label": "Coup de pied", "hint": "L'ambulancier expédie le héros dans le restaurant."},
        "return_land": {"group": "return", "bus": "SFX", "spatial": false, "loop": false, "priority": 95, "label": "Atterrissage", "hint": "Impact du héros au sol après le K.-O."},
        "return_groan": {"group": "return", "bus": "SFX", "spatial": false, "loop": false, "priority": 80, "label": "Effort pour se relever", "hint": "Le héros tente péniblement de se remettre debout."}
    }
}
