~/es/blog/le-hice-un-nintendogs-a-mi-perro

Le hice un Nintendogs a mi perro, y la cara no salió

Dante, mi pastor alemán, ahora vive en el navegador: sin modelos 3D, con esferas fundidas y pelo por capas. De perfil es él; de frente, la cara no salió.

· 6 min de lectura · Read in English

De perfil, es Dante. De frente, es otro perro.

Un pastor alemán 3D de pelo largo echado de perfil sobre las baldosas de un patio, con manto negro, patas color fuego y la casita con su nombre al fondo.Ver la imagen en tamaño completo

Dante en el juego, de perfil. Aquí sí es él.

Ese es el resumen honesto de Dante, un juego estilo Nintendogs que hice en un día con Claude. Lo acaricias, le das de comer, le tiras la pelota, le enseñas trucos y en la noche se va a dormir a su casita. Corre en el navegador, también en el celular, y no tiene un solo modelo 3D descargado: el perro entero sale de código.

Nintendogs lo jugaba de pequeño. Donde vivía antes no había espacio para tener perros, así que ese era el único que podía tener. Ahora que tengo los míos, me dio nostalgia.

Quién es Dante#

Dante es uno de mis dos pastores alemanes. Es de pelo largo y tiene dos títulos de campeón de exposición en El Salvador (ACANSAL, la asociación canina del país en la FCI). Si ya pasaste por la portada de este sitio, lo conoces: es el que se asoma en la terminal.

La otra es Kiara, la veterana gruñona de la casa, y también está en el juego, con su propia máquina de estados. Si Dante se le acerca mucho, le gruñe, y él se aleja con las orejas para atrás: "perdón Kiara 😳". Y si acaricias a Kiara, Dante se sienta a mirarla y suelta un "ella no es campeona...".

El juego completo: Dante sentado en un camino de baldosas entre dos jardines, con barras de hambre, sed, energía, felicidad y limpieza arriba a la izquierda y una barra de herramientas abajo con acariciar, comida, agua, pelota, cepillo, trucos, visita y noche.Ver la imagen en tamaño completo

El patio de la casa, con las barras de Dante arriba a la izquierda.

De juguete a Dante#

Cuatro capturas del mismo ángulo en el patio. Arriba a la izquierda, un perro de juguete hecho de esferas y cilindros, con patas como palitos. Arriba a la derecha, un cuerpo liso de una sola pieza, color caramelo, que parece un frijol con orejas. Abajo a la izquierda, ya con manto negro, pecho dorado y pelo. Abajo a la derecha, la versión de hoy, más peluda y con baldosas y plantas realistas.Ver la imagen en tamaño completo

De izquierda a derecha y de arriba abajo: el primer commit, la primera malla de una sola piel, el pelaje pintado como en las fotos y la versión de hoy.

La primera versión no se parecía a Dante. Era un perro de piezas sueltas, esferas y cilindros agrupados, como un juguete de madera. Ya comía, jugaba y dormía, pero las patas eran palitos y la cabeza una pelota con hocico. Casi todo lo que vino después fue cambiar cómo está hecho el perro.

La segunda ya es una sola piel, aunque parece más un frijol con orejas que un pastor alemán. En la tercera entran el manto negro, el fuego y el pelo por capas. La última es la de hoy, con el patio de la casa y un cielo de verdad.

Un perro hecho de bolitas#

Dante no es un modelo que alguien esculpió. Es una lista de formas simples, elipsoides y cápsulas, cada una colgada de un hueso. Son 101 formas sobre 23 huesos; tres de ellas no suman sino que restan, para tallar la boca y las cuencas. La cabeza, por ejemplo, se arma así:

src/dog.js
P('sph',this.head,[0,0.06,0.09],[0.15,0.115,0.17],C.S,0.02,'head');     // frente (negra), en cuña
P('sph',this.head,[0,0.09,0.19],[0.075,0.055,0.1],C.S,0.014,'head');   // caballete sobre el stop
P('sph',this.head,[0,0.02,0.16],[0.165,0.085,0.12],C.K,0.012,'head');   // máscara alrededor de los ojos
P('sph',this.head,[0,-0.02,0.29],[0.11,0.09,0.31],C.K,0.012,'head');    // hocico más largo y angosto
P('sph',this.head,[0,-0.045,0.33],[0.115,0.06,0.24],C.K,0.01,'head');   // belfos (labio superior que cuelga)

Cada línea es una esfera estirada: en qué hueso va, dónde, de qué tamaño, de qué color, qué tan largo es el pelo ahí y qué zona cuenta cuando lo acaricias. El hocico de Dante es una línea de código.

Juntar esferas da un muñeco de nieve, no un perro. Lo que las vuelve una sola piel es una función de distancia: para cualquier punto del espacio dice qué tan lejos está de la superficie, y donde dos formas se tocan las funde con una unión suave, como dos gotas de cera que se juntan. La boca y las cuencas de los ojos son las tres formas que restan: se tallan en vez de pegarse.

Para sacar una malla de esa función, el juego recorre una grilla de 74 × 115 × 149 puntos con marching cubes. Salen 33,023 vértices y 65,944 triángulos, y en mi Mac tarda 332 ms cada vez que carga la página. En el modo ligero son 12,117 vértices en 109 ms.

Lo bonito es lo que viene gratis. Como cada vértice sabe de qué formas salió, también sabe a qué huesos pertenece, y eso es el skinning hecho. Sentarse, echarse, ponerse panza arriba o pararse en pose de exposición son solo rotaciones de huesos. Los colores salen igual: el manto negro, el fuego y la máscara se pintan por función en el espacio de cada hueso, ajustados contra fotos de Dante, y se mezclan en los bordes sin costuras.

Pelo por capas#

El pelo no son hebras. Son 10 copias de la misma malla, cada una un poquito más afuera que la anterior. En cada capa, un mapa de ruido decide qué puntos sobreviven: en la de adentro casi todos, en la de afuera muy pocos. De lejos, eso se lee como pelo. Las capas caen con gravedad, se mecen, se arrastran cuando corre y reaccionan donde pasas la mano.

Las capas tienen un problema: en el contorno se nota que son láminas. Para eso hay 6,737 mechones de silueta que solo aparecen cuando la piel queda de canto respecto a la cámara. Por eso el borde de Dante se ve peludo y no liso. En el modo ligero quedan 4 capas.

El patio y el cielo#

El patio es el de la casa. Las baldosas y los ladrillos son recortes de fotos del patio real, y el detalle del pelo sale de un recorte de la pechera de Dante.

El cielo es una foto HDRI de Poly Haven que gira con la hora de El Salvador, para que el sol del cielo coincida con la luz que proyecta las sombras. Si entras en la noche, es de noche en el patio y Dante está en su casita. Y si lo dejas encerrado cuando ya amaneció, se pone a llorar: "¡DAVID! ¡la puerta!".

Dónde está el techo#

Dante 3D visto de frente: cabeza redondeada con hocico negro, ojos cafés y la boca entreabierta sobre una pechera dorada muy peluda. Se parece más a un peluche que a un pastor alemán.Ver la imagen en tamaño completo

Dante de frente. Lo quiero igual.

De frente, la cara se lee estilizada. Una cabeza hecha de esferas fundidas no tiene los cientos de planos chiquitos que tiene una cara de verdad. Cráneo en cuña, ojos almendrados, párpados que parpadean, cejas, pómulos, belfos: todo eso está, y aun así parece un peluche de Dante, no Dante. Cada ronda de ajustes desde ahí movió poco la aguja.

El siguiente salto es una malla esculpida o generada desde sus fotos, con esqueleto. Lo bueno es que todo lo demás se queda: el pelo, el patrón, el comportamiento, el patio y el juego. Solo cambia la base. Ese salto no tiene fecha.

Cómo lo hice#

Lo hice en un día, yo usando Claude. Ese día fueron 14 commits, todos con Claude de coautor (13 con Fable 5.1, uno con Opus 5.5). La única dependencia en producción es Three.js; Vite hace el build y Playwright corre los tests.

Hasta tiene tests. Corren en cada push, y uno de ellos le tira la pelota a Dante y espera a que la traiga. Si te interesa cómo trabajo con Claude cuando no es para jugar, aquí cuento cómo armé revisores con subagentes.

Juégalo#

Está en dante.davidquinta.tech, y el código, en GitHub. Arrastra sobre él para acariciarlo: la cabeza, la panza y la cola reaccionan distinto. Si llega una visita al portón, va a ladrar hasta que lo calmes. Y si un truco no le sale, ya sabes: "con mango sí lo hago".

Si le hiciste algo así a tu perro, o a tu gato, cuéntame. Y si quieres el próximo post, está el feed RSS.