Dominó dominicano · iPhone, web, iMessage
Capi
Juega 1 contra 1 o por parejas con tus panas, en tiempo real en iPhone y la web o por turnos en iMessage. Sin crear cuenta.
- Rol
- Período
- Stack
- Enlaces
En números
1
motor de reglas para el servidor, la web, la app de iPhone y iMessage
~1,240
líneas en el motor, con 0 dependencias de producción
960
finales con semilla, verificados para que siempre haya una jugada legal y la partida termine
8
anchos de pantalla, de 320 a 1280 px, sin fichas montadas después de ninguna jugada
- Cliente
- API
- Postgres
- Realtime
- Cliente a API POST /api
/games La jugada y el último state_version leído por el cliente./[id] /move - API a Postgres Lee la mesa
- API a Cliente 409 si state_version cambió El cliente solicita el estado más reciente.
- API apply
Move Usa el mismo motor de reglas que la web y la app de iPhone: unas 1,240 líneas y 0 dependencias en tiempo de ejecución. - API a Postgres Escribe si state_version no cambió Solo la API puede escribir. Las políticas de acceso no permiten inserciones ni actualizaciones anónimas.
- Postgres a Realtime postgres_changes La fila actualizada.
- Realtime a Cliente Envía el nuevo estado a cada jugador
- Cliente Resincronización Si no llegan actualizaciones, el cliente solicita el estado a los 10 segundos y repite cada 10 segundos durante un máximo de 30 minutos.
La idea
Capi lleva el dominó dominicano a internet. Elige un nombre, comparte un código o enlace y juega 1 contra 1 o 2 contra 2 con tus panas. Sin crear una cuenta.
Desde la versión 1.1 también puedes empezar una partida en iMessage, con invitaciones y turnos que llegan como burbujas en el chat.
Lo que construí
Escribí las reglas en un solo paquete de TypeScript: unas 1,240 líneas sin dependencias de producción. La web, la API del servidor y la app de iPhone lo importan, para que la capicúa, el tranque, la puntuación y la posición de las fichas funcionen igual. En producción, el reparto usa crypto.getRandomValues. Las pruebas pueden repetir cualquier partida a partir de una semilla.
La web usa Next.js y Supabase. Postgres guarda el estado de la partida y solo la API puede escribirlo, después de que una migración eliminara todas las políticas anónimas de inserción y actualización. Supabase Realtime entrega las jugadas; las mesas sin actividad también actualizan su estado cada 10 segundos. La app de iPhone usa Expo y React Native con la misma API. Una extensión de iMessage en Swift crea las burbujas y muestra la partida web dentro de Mensajes.
Retos técnicos
-
Validar cada jugada
La API valida cada jugada con el motor y la guarda solo si state_version coincide con lo que leyó el cliente. Una jugada basada en un estado anterior recibe HTTP 409, para que dos jugadas simultáneas no dañen la mesa.
-
Recuperar una mesa trabada
En septiembre, un jugador reportó una partida trabada por una actualización en tiempo real que no llegó. Agregué una consulta del estado tras 10 segundos sin actividad, que se repite cada 10 segundos por hasta 30 minutos. El cliente comparte el estado recibido por el canal de chat de la mesa, para que los jugadores de la versión 1.0 también se pongan al día. Un nuevo conjunto de pruebas juega 960 partidas con semilla y verifica que cada mesa tenga una acción legal y termine.
-
La misma mesa en cualquier pantalla
La fila de fichas dobla en los bordes de la mesa y tiene que caber en pantallas de 320 a 1280 px. Una prueba de propiedades juega 200 partidas con el reducer real. Después de cada jugada, revisa que no haya fichas montadas en 8 anchos y 2 niveles de diseño.
-
La misma mesa dentro de Mensajes
La extensión nativa en Swift se encarga de las burbujas, la identidad del jugador y los asientos. Muestra playcapi.com en una vista web y usa el mismo motor y la misma API que la app y la web, sin duplicar las reglas. Un manejador de mensajes comunica las jugadas y los finales de ronda y de partida a la extensión, que los convierte en burbujas. Cada partida usa una sola sesión de Mensajes, para que cada burbuja nueva reemplace la anterior.
Antes y después
| Antes | Después | Fuente | |
|---|---|---|---|
| Recuperación cuando se pierde una actualización en tiempo real | Una actualización perdida podía dejar una mesa donde nadie podía jugar. | Resincronización cada 10 segundos, retransmisión por el chat de la mesa y 960 finales con semilla en las pruebas. | Commit f5cadf0 y los commits del arreglo del 30 de septiembre de 2026 |
Lo próximo
Próxima versión: mostrar tu diseño de fichas a los demás jugadores y verlo completo antes de comprar. En iMessage, elegir mesa y partidas de 100 o 200 puntos, además de dos correcciones al unirse a una partida.
Pruébalo
Enfoques compartidos
Separar las reglas de la interfaz
The Cap Room, SWARMGEDDON, Anota, Conuco, The Veil · El Velo
Probar con entornos y datos reales
Mantener el español y el inglés al día