feat: Add scripts for mob dependency management and server setup
- Implemented `findMobDependencies.ts` to identify foreign key constraints referencing the Mob table and log dependent rows. - Created `fullServerSetup.ts` for idempotent server setup, including economy items, item recipes, game areas, mobs, and optional demo mob attacks. - Developed `removeInvalidMobsWithDeps.ts` to delete invalid mobs and their dependencies, backing up affected scheduled mob attacks. - Added unit tests in `testMobUnit.ts` and `mob.test.ts` for mob functionality, including stats computation and instance retrieval. - Introduced reward modification tests in `testRewardMods.ts` and `rewardMods.unit.ts` to validate drop selection and coin multiplier behavior. - Enhanced command handling for mob deletion in `mobDelete.ts` and setup examples in `setup.ts`, ensuring proper permissions and feedback. - Created utility functions in `testHelpers.ts` for deterministic drop selection from mob definitions.
This commit is contained in:
56
README/CLEANUP.md
Normal file
56
README/CLEANUP.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Resumen de la limpieza de mobs inválidos
|
||||
|
||||
Qué hice
|
||||
|
||||
- Detecté mob definitions inválidas en la tabla `Mob` usando `scripts/cleanInvalidMobs.ts`.
|
||||
- Guardé un respaldo completo de las filas inválidas en `invalid_mobs_backup.json` en la raíz del repo.
|
||||
- Busqué dependencias en tablas que referencian `Mob` con `scripts/findMobDependencies.ts`.
|
||||
- Guardé un respaldo de las filas dependientes en `scheduled_mob_attack_backup.json`.
|
||||
- Eliminé las filas dependientes en `ScheduledMobAttack` y luego eliminé las filas inválidas de `Mob` con `scripts/removeInvalidMobsWithDeps.ts`.
|
||||
|
||||
Backups
|
||||
|
||||
- `invalid_mobs_backup.json` — contiene objetos con `id`, `row` (registro original) y `error` (ZodError).
|
||||
- `scheduled_mob_attack_backup.json` — contiene filas de `ScheduledMobAttack` que apuntaban a los mobs inválidos.
|
||||
|
||||
Comandos usados
|
||||
|
||||
- Detectar mobs inválidos (no destructivo):
|
||||
|
||||
npx tsx scripts/testMobData.ts
|
||||
|
||||
- Generar backup + eliminar mobs inválidos (no recomendado sin revisar):
|
||||
|
||||
XATA_DB=... npx tsx scripts/cleanInvalidMobs.ts
|
||||
|
||||
- Buscar dependencias (muestra FK y filas dependientes):
|
||||
|
||||
XATA_DB=... npx tsx scripts/findMobDependencies.ts
|
||||
|
||||
- Backups + borrado de dependencias y mobs (ya ejecutado):
|
||||
|
||||
XATA_DB=... npx tsx scripts/removeInvalidMobsWithDeps.ts
|
||||
|
||||
Restauración
|
||||
|
||||
- Si deseas restaurar datos desde los backups, hay dos estrategias:
|
||||
|
||||
1) Restauración completa (reinsertar mobs, luego scheduled attacks): requiere restaurar `Mob` antes de `ScheduledMobAttack`.
|
||||
|
||||
2) Restauración parcial (solo scheduled attacks): solo posible si los `Mob` existen o se restauran con anterioridad.
|
||||
|
||||
Pistas para restaurar (ejemplo rápido)
|
||||
|
||||
- Para reinserción manual (SQL generada): examina `invalid_mobs_backup.json`, reconstruye los objetos `metadata` y ejecuta INSERTs en la tabla `Mob` respetando columnas.
|
||||
|
||||
- Para reinserción de `ScheduledMobAttack`: usa `scheduled_mob_attack_backup.json` e inserta filas; asegúrate de que `mobId` apunte a un `Mob` existente.
|
||||
|
||||
Siguientes pasos recomendados
|
||||
|
||||
- Revisar backups antes de cualquier restauración.
|
||||
- Añadir validación previa a la UI que crea mobs para evitar shapes inválidos (ya existe zod pero su uso puede ampliarse).
|
||||
- Añadir tests DB-backed en staging para evitar que filas inválidas lleguen a producción.
|
||||
|
||||
Contacto
|
||||
|
||||
- Si quieres, puedo generar un script de restauración `scripts/restoreFromBackup.ts` que hace esto de forma idempotente y segura. Pídelo y lo creo.
|
||||
111
README/CREATE_MOB.md
Normal file
111
README/CREATE_MOB.md
Normal file
@@ -0,0 +1,111 @@
|
||||
Crear un Mob (guía para usuario final)
|
||||
|
||||
Este documento explica cómo crear o editar un mob en el proyecto Amayo.
|
||||
Incluye: campos obligatorios, ejemplos JSON, validación y formas de persistir (UI o DB).
|
||||
|
||||
1) Datos requeridos
|
||||
|
||||
- key (string, único): identificador del mob. Ej: "slime.green".
|
||||
- name (string): nombre legible. Ej: "Slime Verde".
|
||||
- tier (number): nivel/tier del mob (entero no negativo). Ej: 1.
|
||||
- base (objeto): contiene stats base obligatorias:
|
||||
- hp (number): puntos de vida base.
|
||||
- attack (number): valor de ataque base.
|
||||
- defense (number, opcional): defensa base.
|
||||
|
||||
2) Campos opcionales útiles
|
||||
|
||||
- scaling (objeto): parámetros de escalado por nivel de área.
|
||||
- hpPerLevel, attackPerLevel, defensePerLevel (number, opcional)
|
||||
- hpMultiplierPerTier (number, opcional)
|
||||
- tags (string[]): etiquetas libres (ej: ["undead","slime"]).
|
||||
- rewardMods (objeto): ajustes de recompensa (coinMultiplier, extraDropChance).
|
||||
- behavior (objeto): comportamiento en combate (maxRounds, aggressive, critChance, critMultiplier).
|
||||
|
||||
3) Ejemplo JSON mínimo
|
||||
|
||||
{
|
||||
"key": "slime.green",
|
||||
"name": "Slime Verde",
|
||||
"tier": 1,
|
||||
"base": { "hp": 18, "attack": 4 }
|
||||
}
|
||||
|
||||
4) Ejemplo JSON completo
|
||||
|
||||
{
|
||||
"key": "skeleton.basic",
|
||||
"name": "Esqueleto",
|
||||
"tier": 2,
|
||||
"base": { "hp": 30, "attack": 6, "defense": 1 },
|
||||
"scaling": { "hpPerLevel": 4, "attackPerLevel": 0.8, "defensePerLevel": 0.2 },
|
||||
"tags": ["undead"],
|
||||
"rewardMods": { "coinMultiplier": 1.1, "extraDropChance": 0.05 },
|
||||
"behavior": { "aggressive": true, "critChance": 0.05, "critMultiplier": 1.5 }
|
||||
}
|
||||
|
||||
## Formato de "drops" soportado
|
||||
|
||||
Para permitir que los mobs otorguen ítems al morir o por `extraDropChance`, el motor soporta dos formatos para el campo `drops` en la definición del mob:
|
||||
|
||||
- Formato BÁSICO (mapa simple):
|
||||
|
||||
```json
|
||||
{"ore.iron": 1, "ore.gold": 1}
|
||||
```
|
||||
|
||||
Cada key es `itemKey` y el valor es la cantidad (qty). Cuando se necesita elegir un ítem se selecciona una key al azar.
|
||||
|
||||
- Formato PONDERADO (array):
|
||||
|
||||
```json
|
||||
[
|
||||
{ "itemKey": "ore.iron", "qty": 1, "weight": 8 },
|
||||
{ "itemKey": "ore.gold", "qty": 1, "weight": 2 }
|
||||
]
|
||||
```
|
||||
|
||||
Cada entrada puede incluir `weight` (entero/numero) para definir probabilidad relativa. El motor hace una tirada ponderada y entrega el item seleccionado.
|
||||
|
||||
Si no hay `drops` configurados o la selección falla, se aplicará un `fallback` que entrega 1 moneda.
|
||||
|
||||
|
||||
5) Validación
|
||||
|
||||
El proyecto usa Zod para validar la definición. Puedes ejecutar localmente:
|
||||
|
||||
npx tsx scripts/testMobData.ts
|
||||
|
||||
Eso intentará inicializar el repositorio de mobs y mostrará errores Zod si la definición es inválida.
|
||||
|
||||
6) Formas de persistir
|
||||
|
||||
- Interfaz del bot (UI): actualmente algunos comandos admin usan `createOrUpdateMob` y persisten en la tabla `Mob` en la DB. Usa los comandos del bot (si tienes permisos administrador) para crear/editar mobs.
|
||||
|
||||
- Directamente en la DB: insertar un row en la tabla `Mob` con `metadata` JSON conteniendo la definición. Recomendado: usa `createOrUpdateMob` o valida con Zod antes.
|
||||
|
||||
7) Pruebas y comprobaciones
|
||||
|
||||
- Obtener una instancia de prueba:
|
||||
- Usa `src/game/mobs/mobData.getMobInstance(key, areaLevel)` en la consola o en un script para ver stats escaladas.
|
||||
- Lista de keys disponibles:
|
||||
- `src/game/mobs/mobData.listMobKeys()`
|
||||
|
||||
8) Precauciones
|
||||
|
||||
- Evita crear mobs con shapes incompletas (faltas de `key`, `name`, `tier`, `base`) — provocará rechazos de validación y puede romper procesos que esperen campos.
|
||||
- Si actualizas a mano la DB, haz un backup antes y valida con Zod.
|
||||
|
||||
9) Soporte
|
||||
|
||||
- Si quieres que el equipo integre campos adicionales (por ejemplo `lootTable`), coméntalo y añadiré la extensión al esquema y pruebas.
|
||||
|
||||
---
|
||||
|
||||
Creado automáticamente por scripts de mantenimiento. Si quieres que lo formatee o añada más ejemplos, lo actualizo.
|
||||
|
||||
---
|
||||
|
||||
Sección añadida: Formatos de drops
|
||||
|
||||
Para detalle técnico sobre cómo definir `drops` en la definición de un mob (soporte de mapa simple y array ponderado), ver la sección "Formato de \"drops\" soportado" al final de este README o en los comentarios del archivo `src/game/mobs/mobData.ts`.
|
||||
Reference in New Issue
Block a user