- Creado nuevo proyecto Nuxt 4 con estructura app/ - Servidor Colyseus separado para evitar problemas con decoradores - Migrado GameRoom y toda la lógica del juego - Implementado cliente con composables useGameClient - Panel de administración funcional - Componentes Vue migrados (HomeScreen, GameScreen, PlayerCard, etc) - Configuración para ejecutar ambos servidores (npm run dev:all)
334 lines
8.7 KiB
Markdown
334 lines
8.7 KiB
Markdown
# Plan de Migración a Nuxt - SnatchGame
|
|
|
|
## Resumen Ejecutivo
|
|
Migración de arquitectura multi-aplicación (Colyseus server + Vue client + Vue admin) a una aplicación unificada Nuxt 3 que maneje servidor, cliente y administración en un solo proyecto.
|
|
|
|
## Análisis de la Arquitectura Actual
|
|
|
|
### Componentes Existentes
|
|
1. **Servidor Colyseus** (Puerto 2567)
|
|
- Framework: Colyseus.io v0.16
|
|
- GameRoom con lógica de juego
|
|
- API REST para admin
|
|
- WebSocket para sincronización en tiempo real
|
|
|
|
2. **Cliente Vue** (Puerto 3000)
|
|
- Vue 3 con Composition API
|
|
- Colyseus.js SDK para conexión
|
|
- Componentes: Home, Game, Settings, PlayerCard, TradeOfferCard
|
|
- Sin build tools (vanilla)
|
|
|
|
3. **Admin Vue** (Puerto 3001)
|
|
- Vue 3 con dashboard de estadísticas
|
|
- SSE (Server-Sent Events) para actualizaciones
|
|
- Control total del juego
|
|
- Sin build tools (vanilla)
|
|
|
|
## Arquitectura Propuesta Nuxt 3
|
|
|
|
### Estructura del Proyecto
|
|
```
|
|
nuxt-snatchgame/
|
|
├── server/
|
|
│ ├── api/ # API REST endpoints
|
|
│ │ ├── admin/ # Admin endpoints
|
|
│ │ └── config.ts # Configuración
|
|
│ ├── plugins/
|
|
│ │ └── colyseus.ts # Integración Colyseus
|
|
│ └── rooms/
|
|
│ └── GameRoom.ts # Lógica del juego
|
|
├── pages/
|
|
│ ├── index.vue # Cliente del juego (/)
|
|
│ └── admin.vue # Dashboard admin (/admin)
|
|
├── components/
|
|
│ ├── game/ # Componentes del juego
|
|
│ │ ├── PlayerCard.vue
|
|
│ │ ├── TradeOfferCard.vue
|
|
│ │ ├── MakeOfferForm.vue
|
|
│ │ └── OfferModal.vue
|
|
│ └── admin/ # Componentes admin
|
|
│ ├── StatsCard.vue
|
|
│ ├── PlayerList.vue
|
|
│ └── ControlPanel.vue
|
|
├── composables/
|
|
│ ├── useGameClient.ts # Cliente Colyseus
|
|
│ └── useAdminService.ts # Servicio admin
|
|
├── types/
|
|
│ └── game.ts # TypeScript types
|
|
├── public/
|
|
│ └── assets/ # Imágenes y recursos
|
|
├── nuxt.config.ts
|
|
└── package.json
|
|
```
|
|
|
|
## Fases de Migración
|
|
|
|
### Fase 1: Setup Inicial (2 horas)
|
|
1. **Crear proyecto Nuxt 3**
|
|
```bash
|
|
npx nuxi@latest init nuxt-snatchgame
|
|
cd nuxt-snatchgame
|
|
```
|
|
|
|
2. **Instalar dependencias necesarias**
|
|
```json
|
|
{
|
|
"dependencies": {
|
|
"nuxt": "^3.x",
|
|
"@colyseus/core": "^0.16.19",
|
|
"@colyseus/schema": "^3.0.42",
|
|
"colyseus": "^0.16.0",
|
|
"colyseus.js": "^0.16.19"
|
|
}
|
|
}
|
|
```
|
|
|
|
3. **Configuración base en nuxt.config.ts**
|
|
- Nitro server configuration
|
|
- WebSocket support
|
|
- Vue 3 setup
|
|
|
|
### Fase 2: Migración del Servidor Colyseus (3 horas)
|
|
|
|
1. **Integrar Colyseus en Nitro**
|
|
```typescript
|
|
// server/plugins/colyseus.ts
|
|
import { Server } from 'colyseus'
|
|
import { WebSocketTransport } from '@colyseus/ws-transport'
|
|
import { GameRoom } from '../rooms/GameRoom'
|
|
|
|
export default defineNitroPlugin((nitroApp) => {
|
|
const gameServer = new Server({
|
|
transport: new WebSocketTransport({
|
|
server: nitroApp.node.server
|
|
})
|
|
})
|
|
|
|
gameServer.define('game', GameRoom)
|
|
.filterBy(['gameMode'])
|
|
.sortBy({ clients: 1 })
|
|
})
|
|
```
|
|
|
|
2. **Migrar GameRoom y tipos**
|
|
- Copiar GameRoom.ts sin cambios
|
|
- Mantener Schema classes
|
|
- Adaptar métodos admin
|
|
|
|
3. **API Endpoints**
|
|
```typescript
|
|
// server/api/admin/stats.get.ts
|
|
export default defineEventHandler(async (event) => {
|
|
// Migrar lógica de stats
|
|
})
|
|
```
|
|
|
|
### Fase 3: Migración del Cliente (3 horas)
|
|
|
|
1. **Página principal del juego**
|
|
```vue
|
|
<!-- pages/index.vue -->
|
|
<template>
|
|
<div>
|
|
<HomeScreen v-if="!inGame" @join="joinGame" />
|
|
<GameScreen v-else :client="gameClient" />
|
|
</div>
|
|
</template>
|
|
```
|
|
|
|
2. **Composable para cliente Colyseus**
|
|
```typescript
|
|
// composables/useGameClient.ts
|
|
export const useGameClient = () => {
|
|
const client = ref<Client | null>(null)
|
|
const room = ref<Room | null>(null)
|
|
|
|
const connect = async (playerName: string) => {
|
|
client.value = new Client('ws://localhost:3000')
|
|
room.value = await client.value.joinOrCreate('game', {
|
|
playerName
|
|
})
|
|
}
|
|
|
|
return { client, room, connect }
|
|
}
|
|
```
|
|
|
|
3. **Migrar componentes Vue**
|
|
- Convertir a script setup
|
|
- Usar auto-imports de Nuxt
|
|
- Mantener lógica existente
|
|
|
|
### Fase 4: Migración del Admin (2 horas)
|
|
|
|
1. **Página admin**
|
|
```vue
|
|
<!-- pages/admin.vue -->
|
|
<template>
|
|
<AdminDashboard />
|
|
</template>
|
|
```
|
|
|
|
2. **Servicio SSE con Nitro**
|
|
```typescript
|
|
// server/api/admin/stream.get.ts
|
|
export default defineEventHandler(async (event) => {
|
|
const stream = createEventStream(event)
|
|
|
|
// Enviar stats cada 250ms
|
|
const interval = setInterval(async () => {
|
|
const stats = await getGameStats()
|
|
await stream.push(stats)
|
|
}, 250)
|
|
|
|
stream.onClosed(() => {
|
|
clearInterval(interval)
|
|
})
|
|
|
|
return stream.send()
|
|
})
|
|
```
|
|
|
|
3. **Composable admin**
|
|
```typescript
|
|
// composables/useAdminService.ts
|
|
export const useAdminService = () => {
|
|
const stats = ref({})
|
|
|
|
const connect = () => {
|
|
const eventSource = new EventSource('/api/admin/stream')
|
|
eventSource.onmessage = (e) => {
|
|
stats.value = JSON.parse(e.data)
|
|
}
|
|
}
|
|
|
|
return { stats, connect }
|
|
}
|
|
```
|
|
|
|
### Fase 5: Integración y Testing (2 horas)
|
|
|
|
1. **Configuración de desarrollo**
|
|
```json
|
|
{
|
|
"scripts": {
|
|
"dev": "nuxt dev",
|
|
"build": "nuxt build",
|
|
"preview": "nuxt preview"
|
|
}
|
|
}
|
|
```
|
|
|
|
2. **Variables de entorno**
|
|
```env
|
|
NUXT_PUBLIC_GAME_NAME=SnatchGame
|
|
NUXT_SERVER_PORT=3000
|
|
```
|
|
|
|
3. **Testing funcional**
|
|
- Verificar conexión WebSocket
|
|
- Probar sincronización de estado
|
|
- Validar panel admin
|
|
- Test de múltiples jugadores
|
|
|
|
## Consideraciones Técnicas
|
|
|
|
### WebSocket en Nuxt/Nitro
|
|
- Nitro soporta WebSocket nativamente
|
|
- Colyseus se integra mediante plugin
|
|
- Un solo puerto para todo (3000)
|
|
|
|
### Estado Compartido
|
|
- Usar Pinia para estado local
|
|
- Colyseus para estado sincronizado
|
|
- SSE para actualizaciones admin
|
|
|
|
### TypeScript
|
|
- Schema-codegen sigue funcionando
|
|
- Types compartidos en /types
|
|
- Auto-imports de Nuxt
|
|
|
|
### Rutas
|
|
- `/` - Cliente del juego
|
|
- `/admin` - Panel de administración
|
|
- `/api/*` - API endpoints
|
|
- WebSocket en el mismo puerto
|
|
|
|
## Simplificaciones MVP
|
|
|
|
1. **Sin autenticación** - Solo nombres de usuario
|
|
2. **Sin base de datos** - Todo en memoria
|
|
3. **Sin Docker** - Deploy directo con Node
|
|
4. **Sin HTTPS** - Solo HTTP/WS local
|
|
5. **Sin optimizaciones** - Código simple y directo
|
|
|
|
## Ventajas de la Migración
|
|
|
|
1. **Un solo proyecto** - Más fácil de mantener
|
|
2. **Un solo puerto** - Simplifica deployment
|
|
3. **Hot reload completo** - Mejor DX
|
|
4. **Auto-imports** - Menos boilerplate
|
|
5. **TypeScript integrado** - Mejor tooling
|
|
6. **SSR opcional** - Mejor SEO si necesario
|
|
|
|
## Riesgos y Mitigaciones
|
|
|
|
| Riesgo | Mitigación |
|
|
|--------|------------|
|
|
| WebSocket en Nitro no probado | Usar h3-ws o plugin dedicado |
|
|
| Colyseus incompatible | Mantener servidor separado si falla |
|
|
| Performance SSE | Usar WebSocket para admin también |
|
|
| Complejidad aumenta | Mantener arquitectura simple |
|
|
|
|
## Cronograma Estimado
|
|
|
|
- **Día 1**: Setup + Servidor (5 horas)
|
|
- **Día 2**: Cliente + Admin (5 horas)
|
|
- **Día 3**: Testing + Ajustes (2 horas)
|
|
|
|
**Total: ~12 horas de desarrollo**
|
|
|
|
## Comando para Iniciar
|
|
|
|
```bash
|
|
# Desarrollo
|
|
npm run dev
|
|
|
|
# Producción
|
|
npm run build
|
|
npm run preview
|
|
```
|
|
|
|
## Estructura de Datos del Juego
|
|
|
|
### Juegos (5 rondas totales)
|
|
1. **Sin reglas** - Ofrecer/Aceptar/Rechazar/Robar sin castigo
|
|
2. **Reglas contraproducentes** - Jugador 2 puede forzar oferta
|
|
3. **Fichas de vergüenza** - Visible para siguiente contrincante
|
|
4. **Derechos mínimos** - Sistema castiga robos denunciados
|
|
5. **Comunicación abierta** - Jugadores pueden hablar
|
|
|
|
### Mecánicas Core
|
|
- 3 rondas por juego (solo la 3ra cuenta)
|
|
- Roles: Jugador 1 / Jugador 2
|
|
- Contrincantes aleatorios
|
|
- Sin comunicación (excepto juego 5)
|
|
- Auto-increment para nombres duplicados
|
|
|
|
## Decisiones de Diseño
|
|
|
|
1. **Nuxt sobre Next.js** - Mejor integración Vue
|
|
2. **Nitro server** - WebSocket nativo
|
|
3. **Sin build tools en components** - Usar SFC de Nuxt
|
|
4. **Colyseus integrado** - No servidor separado
|
|
5. **SSE para admin** - Mantener patrón actual
|
|
|
|
## Próximos Pasos
|
|
|
|
1. ✅ Aprobar plan de migración
|
|
2. ⏳ Crear proyecto Nuxt base
|
|
3. ⏳ Migrar servidor Colyseus
|
|
4. ⏳ Migrar cliente Vue
|
|
5. ⏳ Migrar admin Vue
|
|
6. ⏳ Testing integral
|
|
7. ⏳ Deploy local |