claude-code-arcane 2.1.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/README.md +57 -55
- package/agents/audio/audio-director.md +90 -0
- package/agents/audio/audio-programmer.md +97 -0
- package/agents/audio/audio-qa.md +95 -0
- package/agents/audio/composer.md +88 -0
- package/agents/audio/technical-sound-designer.md +90 -0
- package/agents/audio/voice-director.md +96 -0
- package/agents/career/career-strategist.md +88 -0
- package/agents/career/cv-reviewer.md +81 -0
- package/agents/career/hiring-manager.md +68 -0
- package/agents/career/mock-interviewer.md +76 -0
- package/agents/freelance/client-screener.md +84 -0
- package/agents/freelance/discovery-call.md +65 -0
- package/agents/freelance/pipeline-strategist.md +99 -0
- package/agents/freelance/proposal-reviewer.md +82 -0
- package/dist/cli.js +52 -13
- package/docs/RELEASE-SETUP.md +1 -1
- package/docs/SKILLS-CATALOG.md +47 -3
- package/docs/USER-GUIDE.md +77 -72
- package/docs/agent-hierarchy.md +21 -1
- package/docs/presentations/build_arcane_deck.py +2 -2
- package/docs/presentations/build_arcane_deck_12.py +2 -2
- package/package.json +2 -2
- package/profiles/audio.yaml +45 -0
- package/profiles/freelance.yaml +43 -0
- package/profiles/job-hunt.yaml +5 -2
- package/rules/drafter-reviewer.md +16 -3
- package/rules/freelance-guardrails.md +53 -0
- package/rules/gamedev/audio-code.md +45 -0
- package/skills/adaptive-music/SKILL.md +171 -0
- package/skills/adaptive-music/references/anti-patterns.md +53 -0
- package/skills/audio-audit/SKILL.md +164 -0
- package/skills/audio-audit/references/anti-patterns.md +65 -0
- package/skills/audio-audit/scripts/check_assets.py +208 -0
- package/skills/audio-bible/SKILL.md +119 -0
- package/skills/audio-bible/references/anti-patterns.md +39 -0
- package/skills/audio-mix/SKILL.md +151 -0
- package/skills/audio-mix/references/anti-patterns.md +65 -0
- package/skills/audio-spec/SKILL.md +107 -0
- package/skills/audio-spec/references/anti-patterns.md +45 -0
- package/skills/career-registry/SKILL.md +95 -0
- package/skills/career-registry/scripts/career_registry.py +488 -0
- package/skills/client-screen/SKILL.md +83 -0
- package/skills/client-screen/references/red-flags.md +95 -0
- package/skills/cover-letter/SKILL.md +4 -3
- package/skills/cv-tailor/SKILL.md +11 -2
- package/skills/freelance-deliver/SKILL.md +90 -0
- package/skills/freelance-hunt/SKILL.md +126 -0
- package/skills/freelance-hunt/references/templates/Connects.md +39 -0
- package/skills/freelance-hunt/references/templates/Contrato.md +60 -0
- package/skills/freelance-hunt/references/templates/Propuesta.md +66 -0
- package/skills/freelance-kickoff/SKILL.md +94 -0
- package/skills/freelance-pipeline/SKILL.md +109 -0
- package/skills/freelance-pipeline/scripts/import_history.py +425 -0
- package/skills/freelance-profile/SKILL.md +93 -0
- package/skills/freelance-proposal/SKILL.md +112 -0
- package/skills/freelance-scan/SKILL.md +196 -0
- package/skills/freelance-scan/references/dedup.md +35 -0
- package/skills/freelance-scan/references/platforms.md +167 -0
- package/skills/freelance-scan/scripts/freelance_search.py +1077 -0
- package/skills/interview-prep/SKILL.md +11 -3
- package/skills/job-aplicar/SKILL.md +5 -1
- package/skills/job-hunt/SKILL.md +17 -0
- package/skills/job-outcome/SKILL.md +15 -1
- package/skills/job-upskill/SKILL.md +10 -2
- package/skills/middleware-integration/SKILL.md +186 -0
- package/skills/middleware-integration/references/anti-patterns.md +69 -0
- package/skills/midi-compose/SKILL.md +136 -0
- package/skills/midi-compose/references/smf-format.md +129 -0
- package/skills/midi-compose/scripts/compose_midi.py +326 -0
- package/skills/midi-compose/templates/example-composition.json +69 -0
- package/skills/music-composition/SKILL.md +106 -0
- package/skills/music-composition/references/form.md +57 -0
- package/skills/music-composition/references/game-music.md +82 -0
- package/skills/music-composition/references/harmony.md +82 -0
- package/skills/music-composition/references/melody.md +48 -0
- package/skills/music-composition/references/orchestration.md +69 -0
- package/skills/music-composition/references/rhythm-groove.md +49 -0
- package/skills/procedural-audio/SKILL.md +157 -0
- package/skills/procedural-audio/references/anti-patterns.md +45 -0
- package/skills/sfx-design/SKILL.md +130 -0
- package/skills/sfx-design/references/anti-patterns.md +53 -0
- package/skills/spatial-audio/SKILL.md +139 -0
- package/skills/spatial-audio/references/anti-patterns.md +53 -0
- package/skills/ui-sound-design/SKILL.md +133 -0
- package/skills/ui-sound-design/references/anti-patterns.md +57 -0
- package/skills/voice-pipeline/SKILL.md +150 -0
- package/skills/voice-pipeline/references/anti-patterns.md +69 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Freelance Guardrails (marketplaces y clientes directos)
|
|
2
|
+
|
|
3
|
+
Buscar empleo es gratis: aplicás a 40 puestos y solo perdés tiempo. Freelancear no. Cada propuesta cuesta algo, cada contrato malo toca tu reputación, y cada "¿me agregás esto rapidito?" sin cobrar sale de tu bolsillo.
|
|
4
|
+
|
|
5
|
+
Estas cuatro reglas existen porque los tres recursos que se gastan (plata, reputación, tiempo no facturado) no se recuperan.
|
|
6
|
+
|
|
7
|
+
**El costo de postularse tiene nombre distinto en cada plataforma** y las reglas valen igual: Connects en Upwork, bids en Freelancer.com, y en outreach directo son las horas que ponés en escribir la propuesta. Donde abajo diga Connects, leé "lo que te cuesta postularte".
|
|
8
|
+
|
|
9
|
+
Las rutas son relativas al career workspace (`./career-workspace/` o env `CAREER_WORKSPACE`).
|
|
10
|
+
|
|
11
|
+
## 1. Postularse cuesta plata: no se gasta sin screen
|
|
12
|
+
|
|
13
|
+
Nunca redactar una propuesta para una oferta cuyo cliente no pasó `/client-screen`, ni para una que quedó bajo el umbral de score.
|
|
14
|
+
|
|
15
|
+
Si el usuario quiere postularse igual a una que falló el screen, se puede - **pero se le dice qué falló y se registra en la nota**. Un pago sin verificar que nadie nombró es una postulación tirada, y peor: es la propuesta que sí te contestan y termina en disputa.
|
|
16
|
+
|
|
17
|
+
## 2. La reputación se protege rechazando
|
|
18
|
+
|
|
19
|
+
Ganar un contrato no siempre es bueno. Casi toda plataforma calcula un puntaje sobre contratos cerrados (en Upwork es el Job Success Score) donde un cliente insatisfecho pesa más que dos contentos, y con clientes directos el equivalente son las referencias que no vas a poder pedir. Un contrato con alcance difuso, presupuesto irrealista o cliente sin historial es **riesgo de reputación**, no una oportunidad.
|
|
20
|
+
|
|
21
|
+
Cuando el screen marca riesgo alto, la recomendación por defecto es no postularse. Decir "no" es una acción del pipeline, no una ausencia de acción.
|
|
22
|
+
|
|
23
|
+
## 3. Nada se cotiza abajo del piso
|
|
24
|
+
|
|
25
|
+
Todo bid pasa por el piso declarado en `01-Perfiles/` (tarifa mínima aceptable). El piso es **neto**, después de la comisión de la plataforma: si se queda un 10%, un piso de 40 USD/h exige bidear 45. Con cliente directo la comisión es cero, pero el piso sigue siendo neto de impuestos y de las horas no facturables.
|
|
26
|
+
|
|
27
|
+
Si el usuario todavía no fijó un piso, `/freelance-scan market` da la mediana de lo que cobran otros con su perfil. Es un punto de partida, no el piso: el piso lo define su costo de vida, no el mercado.
|
|
28
|
+
|
|
29
|
+
Alcance nuevo, precio nuevo. Ninguna propuesta ni contrato se amplía sin cotizarlo: si el trabajo extra no entra en un change order con número, no entra.
|
|
30
|
+
|
|
31
|
+
## 4. El envío siempre lo hace el usuario
|
|
32
|
+
|
|
33
|
+
Ninguna skill de este perfil envía una propuesta, acepta un contrato ni gasta el presupuesto de postulaciones. Se redacta, se revisa, se muestra, y el usuario copia y manda.
|
|
34
|
+
|
|
35
|
+
Esto no es prudencia nuestra: **la API de Upwork no tiene mutation para postularse ni para gastar Connects**, justamente para frenar bots de auto-bidding, y las demás plataformas prohíben el envío automatizado en sus términos. Ninguna skill debe pretender lo contrario, y una que lo intentara estaría violando los ToS además de esta regla.
|
|
36
|
+
|
|
37
|
+
El corolario para las **fuentes**: ninguna skill del perfil puede depender de credenciales que cada usuario tenga que conseguir por su cuenta. Este perfil lo instala cualquiera, y una fuente con API key aprobada a mano funciona para uno y está rota para el resto. Las fuentes automáticas son públicas y sin key (ver `skills/freelance-scan/references/platforms.md`); lo demás se pega a mano.
|
|
38
|
+
|
|
39
|
+
## La estructura no la sostiene este archivo
|
|
40
|
+
|
|
41
|
+
Una regla sin columna derecha es una intención.
|
|
42
|
+
|
|
43
|
+
| Regla | Qué la hace cumplir |
|
|
44
|
+
|---|---|
|
|
45
|
+
| Screen antes de gastar en postularse | `/freelance-proposal` exige la nota de screen; sin ella, pregunta y no redacta |
|
|
46
|
+
| Rechazar por riesgo de reputación | `/client-screen` emite veredicto explícito; el agente `client-screener` es adversarial por diseño |
|
|
47
|
+
| Piso de tarifa | `/freelance-proposal` lee el piso del perfil y falla ruidoso si el bid queda abajo; `/freelance-scan market` da la referencia de mercado |
|
|
48
|
+
| Alcance nuevo, precio nuevo | `/freelance-pipeline` detecta drift de alcance en contratos activos y pide change order |
|
|
49
|
+
| Envío manual | Ningún script del perfil escribe a una plataforma: `freelance_search.py` solo lee, y no hay otro |
|
|
50
|
+
|
|
51
|
+
## Registro
|
|
52
|
+
|
|
53
|
+
Toda decisión de no postularse se registra igual que una postulación: nota en `03-Aplicaciones/` con `estado: descartado` y el motivo en `## Notas`. Los descartes son la mitad de los datos que `/freelance-pipeline` necesita para decirte si tu criterio de selección funciona.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "src/audio/**"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Audio Code Rules
|
|
7
|
+
|
|
8
|
+
- NEVER hardcode asset paths or clip references in gameplay code — post middleware events by name/ID
|
|
9
|
+
- Gameplay code MUST NOT call `Play()`/`PlayOneShot()` directly — raise an audio event, let the audio layer resolve it
|
|
10
|
+
- Concurrency limits (max instances, priority, cooldown) MUST be declared in data, never enforced with ad-hoc counters in gameplay
|
|
11
|
+
- Use delta time for ALL fades, ducking ramps and RTPC interpolation (frame-rate independence)
|
|
12
|
+
- NO static singletons for audio state — inject the audio service
|
|
13
|
+
- Every RTPC/parameter driven from gameplay must be normalized and clamped at the boundary before it reaches the middleware
|
|
14
|
+
- Voice budget is a hard limit: define max simultaneous voices per category and drop by priority, never let it grow unbounded
|
|
15
|
+
- Audio must degrade silently — a missing bank or failed event NEVER throws into the gameplay frame
|
|
16
|
+
- Keep the audio update off the render-critical path; audio work budget is 5-10% of frame time
|
|
17
|
+
- Reference the audio bible section each event implements in code comments
|
|
18
|
+
|
|
19
|
+
## Examples
|
|
20
|
+
|
|
21
|
+
**Correct** (event-driven, data-declared):
|
|
22
|
+
|
|
23
|
+
```csharp
|
|
24
|
+
// Gameplay raises intent; the audio layer owns resolution and limits.
|
|
25
|
+
audioService.Post(AudioEvent.PlayerFootstep, transform.position);
|
|
26
|
+
|
|
27
|
+
float wetness = Mathf.Clamp01(surface.Wetness); // clamped at the boundary
|
|
28
|
+
audioService.SetParameter(AudioParam.SurfaceWetness, wetness);
|
|
29
|
+
|
|
30
|
+
// Fade driven by delta time, not frame count.
|
|
31
|
+
currentVolume = Mathf.MoveTowards(currentVolume, targetVolume, fadeRate * Time.deltaTime);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Incorrect** (hardcoded, direct, frame-dependent):
|
|
35
|
+
|
|
36
|
+
```csharp
|
|
37
|
+
AudioSource.PlayClipAtPoint(
|
|
38
|
+
Resources.Load<AudioClip>("SFX/footstep_concrete_01"), // VIOLATION: hardcoded path
|
|
39
|
+
transform.position); // VIOLATION: direct playback from gameplay
|
|
40
|
+
|
|
41
|
+
AudioManager.Instance.Play("footstep"); // VIOLATION: static singleton
|
|
42
|
+
|
|
43
|
+
currentVolume -= 0.02f; // VIOLATION: no delta time
|
|
44
|
+
audioService.SetParameter(AudioParam.SurfaceWetness, rawSensorValue); // VIOLATION: unclamped
|
|
45
|
+
```
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: adaptive-music
|
|
3
|
+
description: "Musica interactiva para juegos: layering vertical, re-secuenciacion horizontal, stingers, reglas de transicion con sync points, y mapeo de estados de gameplay a musica. Usar para: musica adaptativa, sistema de musica dinamica, transiciones musicales, combat music."
|
|
4
|
+
category: "audio"
|
|
5
|
+
argument-hint: "[design|layers|transitions|stingers|map]"
|
|
6
|
+
user-invocable: true
|
|
7
|
+
allowed-tools: Read, Glob, Grep, Write, Edit
|
|
8
|
+
---
|
|
9
|
+
# adaptive-music — Sistemas de Música Interactiva
|
|
10
|
+
|
|
11
|
+
Diseña el sistema que decide **qué música suena cuándo** y **cómo pasa de un estado a otro sin que se escuche la costura**.
|
|
12
|
+
|
|
13
|
+
Esta skill diseña el sistema. El material musical lo escribe `/music-composition`; la implementación en middleware la baja `/middleware-integration`.
|
|
14
|
+
|
|
15
|
+
## Cuándo usar
|
|
16
|
+
|
|
17
|
+
- Cuando la música tiene que responder a gameplay y no alcanza con reproducir un track
|
|
18
|
+
- Cuando las transiciones entre estados (exploración → combate → victoria) suenan a corte
|
|
19
|
+
- Cuando el loop fatiga y necesitás variación estructural, no otro track
|
|
20
|
+
- Antes de que el compositor escriba una nota: el sistema condiciona cómo se compone
|
|
21
|
+
|
|
22
|
+
## Modos
|
|
23
|
+
|
|
24
|
+
| Modo | Qué hace |
|
|
25
|
+
|---|---|
|
|
26
|
+
| `design` | El sistema completo: eje dominante, capas/segmentos, matriz, stingers, parámetros |
|
|
27
|
+
| `layers` | Solo la arquitectura vertical: qué capas, qué rol, qué restricción compositiva |
|
|
28
|
+
| `transitions` | Solo la matriz de transiciones con sync points y segmentos de transición |
|
|
29
|
+
| `stingers` | Solo los stingers: armonía, sincronización, cooldown |
|
|
30
|
+
| `map` | Solo la tabla estado de gameplay → música, con triggers e histéresis |
|
|
31
|
+
|
|
32
|
+
## Input
|
|
33
|
+
|
|
34
|
+
1. Leer audio bible, sección 2 (emotional targets por game state) y 6 (music direction). Si no existe, avisar y ofrecer `/audio-bible`
|
|
35
|
+
2. Listar los estados de gameplay reales — del código o del GDD, no inventados
|
|
36
|
+
3. Preguntar al usuario: middleware target (Wwise / FMOD / engine nativo / sin definir), budget de memoria para música, y si hay material compuesto o se parte de cero
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Los dos ejes
|
|
41
|
+
|
|
42
|
+
Todo sistema de música adaptativa es una combinación de estos dos. Elegir cuál domina es la primera decisión.
|
|
43
|
+
|
|
44
|
+
### Vertical — layering
|
|
45
|
+
|
|
46
|
+
Un mismo bloque temporal, capas que entran y salen. Todas suenan sincronizadas porque comparten grid y armonía.
|
|
47
|
+
|
|
48
|
+
- **Fuerte en:** respuesta inmediata a parámetros continuos (proximidad de enemigo, salud, intensidad de combate)
|
|
49
|
+
- **Débil en:** cambiar de material. Todo suena a la misma pieza
|
|
50
|
+
- **Costo:** memoria (N stems simultáneos) y una restricción compositiva real — cada capa debe funcionar sola y en toda combinación
|
|
51
|
+
|
|
52
|
+
### Horizontal — re-secuenciación
|
|
53
|
+
|
|
54
|
+
Segmentos distintos que se concatenan según reglas, con transiciones en puntos musicalmente válidos.
|
|
55
|
+
|
|
56
|
+
- **Fuerte en:** cambiar de material y de forma; estructura no repetitiva
|
|
57
|
+
- **Débil en:** respuesta inmediata. La transición espera el sync point
|
|
58
|
+
- **Costo:** latencia de respuesta (hasta un compás o más) y complejidad de reglas
|
|
59
|
+
|
|
60
|
+
**Recomendación:** vertical para intensidad continua, horizontal para cambios de estado discretos. La mayoría de los juegos necesitan los dos: capas dentro de cada segmento, re-secuenciación entre segmentos.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Sync points — dónde se puede cortar
|
|
65
|
+
|
|
66
|
+
Una transición suena bien o mal según **dónde** ocurre, no según el crossfade. De más responsivo a más musical:
|
|
67
|
+
|
|
68
|
+
| Sync point | Latencia | Cuándo usarlo |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| **Inmediato** | 0 | Emergencias (muerte del jugador). Suena a corte, y a veces eso está bien |
|
|
71
|
+
| **Siguiente beat** | hasta 1 beat | Reacción rápida que igual respeta el pulso |
|
|
72
|
+
| **Siguiente compás (bar)** | hasta 1 compás | El default sano para la mayoría de los casos |
|
|
73
|
+
| **Siguiente grid** | variable | Cuando definís una grilla más gruesa (2 o 4 compases) |
|
|
74
|
+
| **Exit cue** | hasta el fin del segmento | Máxima musicalidad, máxima latencia |
|
|
75
|
+
| **Entry cue del destino** | — | Define desde dónde arranca el segmento destino |
|
|
76
|
+
|
|
77
|
+
**Segmento de transición** — un fragmento corto que se inserta entre origen y destino. Resuelve los saltos que ningún sync point salva: cambio de tonalidad, de tempo o de métrica. Es la herramienta que más mejora un sistema y la que menos se usa.
|
|
78
|
+
|
|
79
|
+
En Wwise esto es la Transition Matrix del Music Switch Container: origen × destino, con Exit Cue del origen, Entry Cue del destino, fade in/out, y segmento de transición opcional. En FMOD el equivalente son transition regions y transition timelines. El concepto es el mismo; la nomenclatura cambia.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Stingers
|
|
84
|
+
|
|
85
|
+
Frases cortas que se superponen sin interrumpir la música de fondo, sincronizadas al grid para que no suenen encima del tiempo equivocado.
|
|
86
|
+
|
|
87
|
+
- Uso: eventos puntuales que merecen puntuación musical — descubrimiento, kill, item raro, fallo
|
|
88
|
+
- **Deben compartir armonía con el material de fondo**, o sonar deliberadamente disonantes. Un stinger en la tonalidad equivocada es el error más audible del sistema
|
|
89
|
+
- Sincronizar a beat o compás, nunca inmediato
|
|
90
|
+
- Definir cooldown: dos stingers superpuestos suenan a error
|
|
91
|
+
- Si el fondo modula, el stinger necesita versiones por tonalidad o tiene que ser tonalmente neutro (percusión, cluster, ruido)
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Diseño del mapeo
|
|
96
|
+
|
|
97
|
+
El entregable central: la tabla estado → música.
|
|
98
|
+
|
|
99
|
+
| Estado de gameplay | Trigger | Segmento / capas | Sync point | Notas |
|
|
100
|
+
|---|---|---|---|---|
|
|
101
|
+
| Explore calm | default | bed + pulse | bar | loop indefinido |
|
|
102
|
+
| Explore alert | enemigo a <30 m | + harmony | beat | vuelve a calm con 5 s de histéresis |
|
|
103
|
+
| Combat | combate iniciado | segmento combat, todas las capas | bar | |
|
|
104
|
+
| Combat low health | HP < 25% | + intensity, filtro | beat | |
|
|
105
|
+
| Victory | combate resuelto | stinger + segmento victory | exit cue | one-shot, vuelve a explore |
|
|
106
|
+
| Death | HP = 0 | inmediato, corte | inmediato | |
|
|
107
|
+
|
|
108
|
+
**Parámetros continuos** aparte: qué RTPC/parámetro maneja qué, con rango normalizado y curva.
|
|
109
|
+
|
|
110
|
+
| Parámetro | Rango | Controla | Curva |
|
|
111
|
+
|---|---|---|---|
|
|
112
|
+
| `combat_intensity` | 0-1 | volumen de capa intensity | log |
|
|
113
|
+
| `player_health` | 0-1 | filtro low-pass sobre el bus música | lineal |
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Histéresis — el detalle que rompe los sistemas
|
|
118
|
+
|
|
119
|
+
Un estado que se calcula por umbral (`enemigo a <30 m`) va a oscilar cuando el jugador camine en el borde. El resultado es música entrando y saliendo cada segundo.
|
|
120
|
+
|
|
121
|
+
Toda transición basada en umbral necesita:
|
|
122
|
+
- **Umbrales distintos por dirección** — entra a 30 m, sale a 40 m
|
|
123
|
+
- **Tiempo mínimo en estado** — no se puede salir antes de N segundos
|
|
124
|
+
- **Debounce del trigger** — la condición tiene que sostenerse antes de contar
|
|
125
|
+
|
|
126
|
+
Sin esto, el sistema funciona en el editor y falla con un jugador real.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Enfoques generativos
|
|
131
|
+
|
|
132
|
+
Cuando la variación por capas y segmentos no alcanza:
|
|
133
|
+
|
|
134
|
+
- **Selección estocástica de capas/segmentos** — la variación sale de qué combinación suena. El más barato y controlable; empezar acá siempre
|
|
135
|
+
- **Cadenas de Markov** — melodía estocástica entrenada sobre material propio. Preserva idioma, no genera estructura
|
|
136
|
+
- **L-systems / gramáticas recursivas** — generan estructura jerárquica por reescritura de reglas. Complemento de Markov, que no tiene forma
|
|
137
|
+
- **Restricciones armónicas** — capa de validación sobre lo generado: el generador propone, las reglas de función y voice leading filtran
|
|
138
|
+
|
|
139
|
+
La generación de notas en tiempo real tiene un techo de calidad y un riesgo de que suene mal en producción que la selección de material pregrabado no tiene. Justificar antes de ir por ahí.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Proceso
|
|
144
|
+
|
|
145
|
+
1. **Listar estados reales** del gameplay, con sus triggers exactos
|
|
146
|
+
2. **Elegir el eje dominante** (vertical / horizontal / mixto) y justificarlo contra el budget
|
|
147
|
+
3. **Definir capas o segmentos** y la restricción compositiva que impone al compositor
|
|
148
|
+
4. **Llenar la matriz de transiciones** con sync points, y marcar dónde hace falta segmento de transición
|
|
149
|
+
5. **Definir stingers** con su armonía y cooldown
|
|
150
|
+
6. **Definir parámetros continuos** con rango y curva
|
|
151
|
+
7. **Agregar histéresis** a toda transición por umbral
|
|
152
|
+
8. **Presentar** al usuario y preguntar "¿Escribo el diseño a `<path>`?" antes de usar Write
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Verdict
|
|
157
|
+
|
|
158
|
+
- **READY** — la matriz está completa, todo umbral tiene histéresis, los stingers tienen armonía definida, y el compositor sabe qué restricción respetar
|
|
159
|
+
- **CONCERNS** — el diseño existe pero hay transiciones sin sync point, umbrales sin histéresis, o el budget de memoria no se verificó contra el número de stems
|
|
160
|
+
- **BLOCKED** — los estados de gameplay no están definidos, o no hay dirección musical de la cual derivar los emotional targets
|
|
161
|
+
|
|
162
|
+
## Anti-patterns
|
|
163
|
+
|
|
164
|
+
> → Read references/anti-patterns.md
|
|
165
|
+
|
|
166
|
+
## Next steps
|
|
167
|
+
|
|
168
|
+
- `/music-composition` para escribir el material respetando las restricciones de capas
|
|
169
|
+
- `/middleware-integration` para implementar la matriz en Wwise/FMOD
|
|
170
|
+
- `/audio-mix` para el ducking entre música y diálogo
|
|
171
|
+
- `/audio-audit` para verificar memoria y voice count del sistema en runtime
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Música Adaptativa — Anti-patterns
|
|
2
|
+
|
|
3
|
+
## Crossfade como única transición
|
|
4
|
+
|
|
5
|
+
Fundir dos piezas en tonalidades o tempos distintos suena a error, no a transición. El crossfade solo funciona si el material comparte armonía y grid. Si no, hace falta sync point + segmento de transición.
|
|
6
|
+
|
|
7
|
+
## Transiciones inmediatas por default
|
|
8
|
+
|
|
9
|
+
Cortar al instante es responsivo y musicalmente destructivo. Reservarlo para muerte del jugador y cortes deliberados. El default sano es siguiente compás.
|
|
10
|
+
|
|
11
|
+
## Umbrales sin histéresis
|
|
12
|
+
|
|
13
|
+
El caso clásico: el jugador camina en el borde de un radio de detección y la música de combate entra y sale seis veces en diez segundos. Umbrales asimétricos + tiempo mínimo en estado + debounce. Siempre.
|
|
14
|
+
|
|
15
|
+
## Capas que dependen entre sí
|
|
16
|
+
|
|
17
|
+
Si la capa de melodía se escribió asumiendo que la de armonía suena, al quitar la armonía la melodía queda flotando sin contexto. Cada capa tiene que funcionar sola y con cualquier subconjunto de las de abajo.
|
|
18
|
+
|
|
19
|
+
## Stingers en la tonalidad equivocada
|
|
20
|
+
|
|
21
|
+
El error más audible del sistema. Si el fondo modula y el stinger es tonal y fijo, va a chocar. Versiones por tonalidad, o stingers tonalmente neutros.
|
|
22
|
+
|
|
23
|
+
## Stingers sin cooldown
|
|
24
|
+
|
|
25
|
+
Cinco kills en dos segundos disparan cinco stingers superpuestos. Suena a bug.
|
|
26
|
+
|
|
27
|
+
## Contar los stems y no la memoria
|
|
28
|
+
|
|
29
|
+
Ocho stems estéreo a 48 kHz sonando simultáneos es mucho más que "ocho archivos". Si van descomprimidos en memoria, el número crece rápido. Verificar el budget antes de comprometer la arquitectura vertical.
|
|
30
|
+
|
|
31
|
+
## Diseñar el sistema después de componer
|
|
32
|
+
|
|
33
|
+
Si el compositor entregó una pieza lineal de tres minutos con clímax, convertirla en capas es imposible sin rehacerla. El sistema se diseña primero y define la restricción compositiva.
|
|
34
|
+
|
|
35
|
+
## Un estado por situación
|
|
36
|
+
|
|
37
|
+
Veinte estados de música para veinte situaciones de gameplay produce una matriz de transiciones de 400 celdas que nadie va a autorear bien. Agrupar situaciones por emotional target: la mayoría de los juegos vive bien con 4-6 estados.
|
|
38
|
+
|
|
39
|
+
## Loop que cierra con cadencia auténtica
|
|
40
|
+
|
|
41
|
+
Cada vuelta suena a arranque forzado. Cerrar abierto: semicadencia, pedal, cadencia plagal.
|
|
42
|
+
|
|
43
|
+
## Música ocupando el rango del diálogo
|
|
44
|
+
|
|
45
|
+
Si el arreglo vive en 500 Hz-2 kHz y hay VO, uno de los dos pierde, y el ducking agresivo se escucha. Se resuelve en el arreglo, no en el mix.
|
|
46
|
+
|
|
47
|
+
## Ignorar el estado inicial y el retorno
|
|
48
|
+
|
|
49
|
+
Se diseña explore → combat con cuidado y se olvida combat → explore. El retorno es la transición que el jugador escucha más veces.
|
|
50
|
+
|
|
51
|
+
## Probar solo en el editor
|
|
52
|
+
|
|
53
|
+
El editor de middleware permite disparar estados a mano, en el orden correcto, sin ruido. El jugador real dispara transiciones en secuencias imposibles. Probar con gameplay, no con botones.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: audio-audit
|
|
3
|
+
description: "Auditoria de audio: voice count, CPU, memoria, streaming, compliance de loudness (ASWG-R001), conformidad de assets contra spec y checklist por plataforma. Usar para: QA de audio, performance de audio, verificar loudness, revisar assets, pre-certificacion."
|
|
4
|
+
category: "audio"
|
|
5
|
+
argument-hint: "[full | perf | loudness | assets | platform]"
|
|
6
|
+
user-invocable: true
|
|
7
|
+
allowed-tools: Read, Glob, Grep, Write, Edit, Bash
|
|
8
|
+
---
|
|
9
|
+
# audio-audit — QA y Compliance de Audio
|
|
10
|
+
|
|
11
|
+
Verifica que el audio del proyecto cumple: performance dentro del presupuesto, assets conformes al spec, y loudness dentro del target de plataforma.
|
|
12
|
+
|
|
13
|
+
## Cuándo usar
|
|
14
|
+
|
|
15
|
+
- Antes de una milestone o de certificación
|
|
16
|
+
- El audio se corta, se satura o come demasiado CPU
|
|
17
|
+
- Verificar assets entregados por un contractor
|
|
18
|
+
- Auditar loudness para cumplir requisitos de plataforma
|
|
19
|
+
- Después de integrar un sistema nuevo, para medir su costo real
|
|
20
|
+
|
|
21
|
+
## Input
|
|
22
|
+
|
|
23
|
+
1. Leer audio bible (sección 8, standards) y los specs de `/audio-spec`
|
|
24
|
+
2. Determinar plataformas target, y cuál es la más baja
|
|
25
|
+
3. Preguntar al usuario: alcance (`full` / solo perf / solo loudness / solo assets) y si hay captura de profiler disponible
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 1. Performance
|
|
30
|
+
|
|
31
|
+
**Presupuesto:** el audio dispone del **5-10% del frame time**. A 60 fps el frame son 16.6 ms, así que el audio tiene ~0.8-1.7 ms. A 90 fps (VR) el frame son ~11 ms y el margen es menor.
|
|
32
|
+
|
|
33
|
+
| Métrica | Cómo se mide | Verdict |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| **CPU de audio** | Profiler del middleware, en gameplay real | FAIL si supera el 10% del frame sostenido |
|
|
36
|
+
| **Voces activas** | Pico vs límite configurado | CONCERNS si el pico toca el límite; FAIL si hay descartes de sonidos de prioridad alta |
|
|
37
|
+
| **Memoria de audio** | Por bank y total, vs budget del proyecto | FAIL si supera el budget en la plataforma más baja |
|
|
38
|
+
| **Accesos de streaming** | Contador de streaming del profiler | CONCERNS si hay starvation |
|
|
39
|
+
| **Game objects registrados** | Contador, medido a lo largo de una sesión larga | FAIL si crece monótonamente (leak) |
|
|
40
|
+
|
|
41
|
+
**Medir en gameplay real, no en el editor.** El editor dispara eventos en orden, uno por vez, sin ruido. El jugador produce combinaciones que nadie planificó. Y medir en la **plataforma más baja** del target: el presupuesto que cierra en PC no dice nada de un handheld.
|
|
42
|
+
|
|
43
|
+
**El leak de game objects es el hallazgo más frecuente.** Si el contador de objetos registrados crece durante una sesión de dos horas y nunca baja, hay des-registros faltantes. Se ve solo en sesiones largas.
|
|
44
|
+
|
|
45
|
+
### Costos de referencia
|
|
46
|
+
|
|
47
|
+
Para saber si un número medido es razonable:
|
|
48
|
+
|
|
49
|
+
| Operación | Costo esperado por fuente |
|
|
50
|
+
|---|---|
|
|
51
|
+
| Convolución HRTF (512 taps) | ~2 ms |
|
|
52
|
+
| Encode ambisónico | ~0.1 ms |
|
|
53
|
+
| Decode ambisónico a binaural | ~1 ms total |
|
|
54
|
+
| Footstep procedural | ~1-2 ms |
|
|
55
|
+
| Síntesis de viento | ~0.5 ms/frame |
|
|
56
|
+
| Panning + atenuación | despreciable |
|
|
57
|
+
|
|
58
|
+
Si lo medido se desvía mucho del esperado, la causa suele ser configuración (más taps, más fuentes espacializadas de las previstas) antes que el motor.
|
|
59
|
+
|
|
60
|
+
## 2. Loudness
|
|
61
|
+
|
|
62
|
+
Referencia de industria en juegos: **ASWG-R001** (Sony), la única especificación publicada por una plataforma mayor.
|
|
63
|
+
|
|
64
|
+
| Contexto | Loudness promedio | True peak máximo |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| Consola / home | **−23 LUFS** (±2) | **−1 dBTP** |
|
|
67
|
+
| Portable / handheld | **−18 LUFS** | −1 dBTP |
|
|
68
|
+
|
|
69
|
+
**Cómo medir bien:**
|
|
70
|
+
|
|
71
|
+
- Se mide el **programa completo en gameplay representativo**, no un asset aislado. Medir un `.wav` no dice nada sobre cumplimiento
|
|
72
|
+
- Sesión de duración suficiente para promediar: al menos varios minutos cubriendo exploración, combate y diálogo
|
|
73
|
+
- Medir el **true peak**, no el peak de sample: la codificación lossy puede generar picos por encima del valor medido en PCM
|
|
74
|
+
- **Confirmar el target vigente** de cada plataforma antes de certificación. Las recomendaciones se revisan — el promedio de ASWG también se citó como −24 LKFS, así que no confiar en un número memorizado
|
|
75
|
+
|
|
76
|
+
**Verdict:** COMPLIANT dentro del target con su tolerancia; NON-COMPLIANT fuera, o con true peak por encima de −1 dBTP.
|
|
77
|
+
|
|
78
|
+
## 3. Conformidad de assets
|
|
79
|
+
|
|
80
|
+
Verificación mecánica contra los standards del bible. Esto se automatiza:
|
|
81
|
+
|
|
82
|
+
| Chequeo | Falla típica |
|
|
83
|
+
|---|---|
|
|
84
|
+
| Sample rate | Mezcla de 44.1 y 48 kHz en el mismo proyecto |
|
|
85
|
+
| Bit depth | 24-bit donde el pipeline espera 16 |
|
|
86
|
+
| Canales | Estéreo en un asset que se usa como fuente 3D mono |
|
|
87
|
+
| Naming | No sigue el patrón; rompe batch y automatización de banks |
|
|
88
|
+
| DC offset | Produce clicks al concatenar |
|
|
89
|
+
| Silencio al inicio | Retrasa el ataque; se percibe como lag |
|
|
90
|
+
| Clipping | Picos a 0 dBFS en el asset crudo |
|
|
91
|
+
| Duración vs spec | Fuera del rango especificado |
|
|
92
|
+
| Loudness por categoría | Assets de la misma categoría con niveles dispares |
|
|
93
|
+
|
|
94
|
+
**Fuente 3D en estéreo es el hallazgo más común y el más silencioso:** el middleware la trata distinto o la colapsa, y la localización espacial se degrada sin que nadie vea un error.
|
|
95
|
+
|
|
96
|
+
La skill trae el verificador: `scripts/check_assets.py`, stdlib-only (módulo `wave`), recursivo sobre una carpeta.
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
python skills/audio-audit/scripts/check_assets.py assets/audio \
|
|
100
|
+
--rate 48000 --bits 16 --mono-3d --naming '^(sfx|vo|mus)_'
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Chequea sample rate, bit depth, canales, naming, clipping, DC offset, silencio inicial, archivos vacíos o silenciosos, y avisa cuando el sample rate obliga a un resampleo costoso. Emite `[FAIL]` / `[WARN]` / `[SKIP]` por hallazgo y cierra con COMPLIANT / CONCERNS / NON-COMPLIANT; exit code 1 solo si hay FAIL, para usarlo en CI.
|
|
104
|
+
|
|
105
|
+
Lo que necesita una herramienta externa (loudness integrado, análisis espectral) se reporta como `[SKIP]` en vez de abortar la corrida.
|
|
106
|
+
|
|
107
|
+
## 4. Checklist por plataforma
|
|
108
|
+
|
|
109
|
+
| Ítem | Aplica a |
|
|
110
|
+
|---|---|
|
|
111
|
+
| Loudness dentro del target del contexto | Todas |
|
|
112
|
+
| True peak ≤ −1 dBTP | Todas |
|
|
113
|
+
| Manejo de interrupciones (llamada, alarma) | Móvil |
|
|
114
|
+
| Manejo de cambio de ruta (auriculares) | Móvil, consola |
|
|
115
|
+
| Respeto del switch de silencio | iOS |
|
|
116
|
+
| Comportamiento en background | Móvil |
|
|
117
|
+
| Mezcla con audio de terceros | Móvil |
|
|
118
|
+
| Audio no rompe al perder foco | Todas |
|
|
119
|
+
| Memoria dentro del budget de la plataforma | Todas |
|
|
120
|
+
| Se puede mutear todo desde opciones | Todas |
|
|
121
|
+
| Controles separados: música / SFX / voz / UI | Todas |
|
|
122
|
+
| Información crítica no exclusivamente por audio | Todas (accesibilidad) |
|
|
123
|
+
| Subtítulos para todo el diálogo | Todas (accesibilidad) |
|
|
124
|
+
|
|
125
|
+
El comportamiento en background y el switch de silencio en iOS son causas concretas de rechazo de store, no recomendaciones.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Proceso
|
|
130
|
+
|
|
131
|
+
1. **Determinar el alcance** y la plataforma más baja del target
|
|
132
|
+
2. **Capturar** con el profiler del middleware en gameplay representativo, no en el editor
|
|
133
|
+
3. **Medir performance** contra el presupuesto y comparar con los costos de referencia
|
|
134
|
+
4. **Medir loudness** del programa completo, con true peak
|
|
135
|
+
5. **Verificar assets** contra los standards, automatizado si el volumen lo justifica
|
|
136
|
+
6. **Recorrer el checklist** de plataforma
|
|
137
|
+
7. **Reportar** con severidad por hallazgo y, si el usuario lo pide, preguntar "¿Escribo el reporte a `<path>`?" antes de usar Write
|
|
138
|
+
|
|
139
|
+
### Formato del reporte
|
|
140
|
+
|
|
141
|
+
Por hallazgo: qué se midió, valor medido, valor esperado, severidad, y dónde está el problema. Un hallazgo sin número medido no es un hallazgo, es una impresión.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Verdict
|
|
146
|
+
|
|
147
|
+
Global, y por sección:
|
|
148
|
+
|
|
149
|
+
- **COMPLIANT** — performance dentro del presupuesto en la plataforma más baja, loudness dentro del target, assets conformes, checklist completo
|
|
150
|
+
- **CONCERNS** — hay desvíos que no bloquean: pico de voces tocando el límite, assets con naming inconsistente, loudness en el borde de la tolerancia
|
|
151
|
+
- **NON-COMPLIANT** — CPU o memoria fuera de presupuesto, loudness fuera del target, leak de game objects, o un ítem de checklist que es causa de rechazo de plataforma
|
|
152
|
+
|
|
153
|
+
Un NON-COMPLIANT en cualquier sección bloquea certificación.
|
|
154
|
+
|
|
155
|
+
## Anti-patterns
|
|
156
|
+
|
|
157
|
+
> → Read references/anti-patterns.md
|
|
158
|
+
|
|
159
|
+
## Next steps
|
|
160
|
+
|
|
161
|
+
- `/spatial-audio` si el costo de espacialización está fuera de presupuesto
|
|
162
|
+
- `/audio-mix` si el problema es loudness o balance entre categorías
|
|
163
|
+
- `/middleware-integration` si hay leaks, banks mal organizados o descartes de voces
|
|
164
|
+
- `/procedural-audio` si la memoria no cierra por cantidad de samples
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Audio Audit — Anti-patterns
|
|
2
|
+
|
|
3
|
+
## Medir en el editor
|
|
4
|
+
|
|
5
|
+
El editor dispara eventos en orden, uno por vez, sin ruido de fondo. El jugador produce combinaciones que nadie planificó. Las mediciones del editor no predicen nada.
|
|
6
|
+
|
|
7
|
+
## Medir en la plataforma más alta
|
|
8
|
+
|
|
9
|
+
El presupuesto cierra cómodo en PC y revienta en el handheld. La auditoría se hace contra el piso del target.
|
|
10
|
+
|
|
11
|
+
## Medir loudness de un asset
|
|
12
|
+
|
|
13
|
+
Los targets de LUFS son del programa completo en gameplay representativo. Medir un `.wav` no dice nada sobre cumplimiento.
|
|
14
|
+
|
|
15
|
+
## Sesión de medición demasiado corta
|
|
16
|
+
|
|
17
|
+
Treinta segundos de exploración tranquila da un LUFS que no representa el juego. La medición tiene que cubrir exploración, combate y diálogo.
|
|
18
|
+
|
|
19
|
+
## Confiar en un target memorizado
|
|
20
|
+
|
|
21
|
+
Las recomendaciones de plataforma se revisan. Confirmar el vigente antes de certificación.
|
|
22
|
+
|
|
23
|
+
## Medir peak de sample en vez de true peak
|
|
24
|
+
|
|
25
|
+
Un mix que llega a 0 dBFS en PCM puede generar picos por encima al codificarse en lossy. El −1 dBTP existe justamente por eso.
|
|
26
|
+
|
|
27
|
+
## No buscar leaks
|
|
28
|
+
|
|
29
|
+
El contador de game objects registrados que crece durante dos horas y nunca baja es el hallazgo más frecuente, y solo se ve en sesiones largas. Una prueba de cinco minutos no lo encuentra.
|
|
30
|
+
|
|
31
|
+
## Aceptar el pico de voces al límite
|
|
32
|
+
|
|
33
|
+
Si el pico toca el límite configurado, cualquier situación un poco peor empieza a descartar sonidos. Y si lo que se descarta es feedback de la acción del jugador, el juego se siente roto sin ningún error visible.
|
|
34
|
+
|
|
35
|
+
## Ignorar qué se descarta
|
|
36
|
+
|
|
37
|
+
El número de descartes por sí solo no dice nada. Lo que importa es la prioridad de lo descartado: perder un ambiente lejano está bien, perder el disparo del jugador no.
|
|
38
|
+
|
|
39
|
+
## Fuente 3D en estéreo
|
|
40
|
+
|
|
41
|
+
El hallazgo más silencioso: el middleware la colapsa o la trata distinto, y la localización espacial se degrada sin que aparezca ningún error. Verificar canales por categoría de uso.
|
|
42
|
+
|
|
43
|
+
## Mezcla de sample rates
|
|
44
|
+
|
|
45
|
+
44.1 y 48 kHz en el mismo proyecto obliga a resampleo en runtime, que cuesta CPU y puede introducir artefactos. Un solo sample rate por proyecto.
|
|
46
|
+
|
|
47
|
+
## Silencio al inicio del asset
|
|
48
|
+
|
|
49
|
+
Retrasa el ataque y se percibe como lag de input, aunque el código responda instantáneo. Se detecta automáticamente y casi nunca se busca.
|
|
50
|
+
|
|
51
|
+
## Hallazgo sin número
|
|
52
|
+
|
|
53
|
+
"El audio suena saturado" no es un hallazgo. Qué se midió, valor medido, valor esperado, dónde. Sin eso, nadie puede arreglarlo ni verificar que se arregló.
|
|
54
|
+
|
|
55
|
+
## Auditar a mano miles de assets
|
|
56
|
+
|
|
57
|
+
La conformidad de sample rate, canales, naming y duración es mecánica: se automatiza. La inspección manual de 4.000 archivos garantiza que algo se pase por alto.
|
|
58
|
+
|
|
59
|
+
## Fallar cuando falta una herramienta externa
|
|
60
|
+
|
|
61
|
+
Si el chequeo profundo necesita una herramienta que no está instalada, reportar `[SKIP]` y seguir. Abortar la auditoría entera por una dependencia opcional deja al usuario sin los chequeos que sí se podían correr.
|
|
62
|
+
|
|
63
|
+
## Dejar el checklist de plataforma para el final
|
|
64
|
+
|
|
65
|
+
El comportamiento en background y el switch de silencio en iOS son causas concretas de rechazo. Descubrirlos en certificación cuesta una release.
|