Cómo SEED crea un mundo que los jugadores nunca dejan de construir
Adam Axler - Unity
Senior Content Marketing Manager

Para tu comodidad, tradujimos esta página mediante traducción automática. No podemos garantizar la precisión ni la confiabilidad del contenido traducido. Si tienes alguna duda sobre la precisión del contenido traducido, consulta la versión oficial en inglés de la página web.
No se puede predecir qué construirán los jugadores. En SEED , ese es precisamente el objetivo, y el principal desafío de renderizado.
SEED es el sandbox MMO persistente de Klang Games, construido con Unity. Está ambientado en un planeta distante donde los jugadores gestionan personajes autónomos llamados plántulas, construyen casas y negocios, comercian en una economía impulsada por los jugadores y organizan sociedades con sus propios roles y leyes. El mundo sigue funcionando después de que los jugadores cierran sesión, y está en constante crecimiento. Cada nueva casa, tienda, árbol y plántula ejerce mayor presión sobre el rendimiento de renderizado de Unity , en todo tipo de hardware, desde ordenadores de gama alta hasta teléfonos móviles.
La simulación se ejecuta en los servidores de Klang Games. La función del cliente de Unity es renderizar el estado que transmite el servidor, por lo que su carga de trabajo depende de lo que hayan creado los jugadores, no de lo que haya planeado el equipo.
“Dado que SEED es un juego que depende completamente del servidor, el cliente se encarga principalmente de leer y renderizar el estado y reenviar las interacciones del jugador, como hacer clic o mover la cámara”, explica Artem Dyadichkin , ingeniero gráfico de Klang Games.
Hablamos con Dyadichkin y Nikita Fetisov , ingeniero sénior de juegos, sobre cómo renderizar sociedades construidas por los jugadores con el Universal Render Pipeline (URP) , cómo mantener miles de objetos pequeños a bajo coste y cómo utilizar datos reales de los jugadores para encontrar cuellos de botella en PC y dispositivos móviles.

Un mundo construido a partir de pequeñas piezas
El estilo artístico de SEED realiza gran parte del trabajo de escalado antes de que se ejecute cualquier código. El juego tiene un estilo visual estilizado y un bajo número de polígonos, y en lugar de depender de texturas, almacena la mayor parte de sus datos de superficie en la geometría.
“La mayor parte de nuestros datos de color se almacenan dentro de los datos de los vértices”, afirma Dyadichkin. “Los datos del vértice saben de qué color es, qué definición de material tiene: ¿es metal, es liso? Todas esas características están integradas en las propias mallas.
Esto permite ahorrar en sombreado y ancho de banda de memoria, lo cual es fundamental en dispositivos móviles.
Los edificios adoptan el mismo enfoque, pero llevado al extremo. En lugar de tratar cada estructura como una única malla grande, SEED construye edificios a partir de muchos módulos pequeños, parecidos a ladrillos: paredes, suelos, bordes de tejados y esquinas sobre una cuadrícula de un metro. Los jugadores colocan bloques de construcción toscos (voxels), y el juego expande cada uno de ellos en unos 15 módulos, que forman aproximadamente la mitad del exterior del edificio y la otra mitad su interior, que se genera solo cuando un jugador mira dentro. La sociedad más grande en una de las islas más concurridas de SEED tiene 172 edificios, compuestos por aproximadamente 12.500 vóxeles, o 190.000 módulos.
“Utilizamos BatchRendererGroup para renderizarlos y agruparlos, y realizamos esos agrupamientos mediante trabajos”, explica Dyadichkin. “Aunque hay muchísimos módulos que debemos renderizar, los edificios en sí mismos nunca han supuesto un verdadero cuello de botella en lo que respecta al rendimiento de la renderización.”
Esos trabajos se ejecutan en el sistema de trabajos de C# y el equipo los compila con el compilador Burst . Dyadichkin afirma que casi siempre van de la mano en el código del cliente de SEED .

SEMILLA | Juegos de Klang
Mantenerse en la ruta predeterminada en URP
SEED utiliza URP para escalar tanto en PC como en dispositivos móviles, y Klang Games se ciñe deliberadamente a la configuración predeterminada de Unity.
“Intentamos ceñirnos a las soluciones predeterminadas de Unity, para así asegurarnos de que, cuando llegue la próxima actualización, se solucione el problema”, afirma Dyadichkin.
Eso es importante porque el equipo actualiza Unity aproximadamente una o dos veces al año (actualmente SEED funciona con Unity 6.3) e incorpora nuevas funciones de renderizado a medida que el proyecto crece. Cuando el juego requiere alguna personalización, el equipo amplía URP en lugar de reemplazarlo, utilizando funciones de renderizado personalizadas para efectos e interacciones específicas del juego.
Su uso de Shader Graph sigue el mismo principio. Los elementos de la naturaleza utilizan el sombreador Lit predeterminado, mientras que los personajes y objetos utilizan sombreadores Unlit con un pase de iluminación personalizado. En cualquier caso, el equipo no tiene que preocuparse por perjudicar las funcionalidades de rendimiento de URP.
“Puedes estar seguro de que si creas un gráfico de sombreado, no interrumpirá el procesamiento por lotes de SRP [Scriptable Render Pipeline] ni el de GPU Resident Drawer”, afirma Dyadichkin. “Tener la certeza de que todas las funciones principales de URP siguen siendo compatibles, al tiempo que se dispone de espacio para personalizar lo que se desee en un sombreador, es una gran ventaja.”
Esa red de seguridad es importante en un mundo donde los jugadores, no los diseñadores, deciden cuánto tiene que dibujar el cliente.
Interactuar con miles de objetos
Cuanto más densa sea la comunidad de jugadores, más difícil será representarla y permitirles hacer clic en cualquier parte de ella.
Cuando se hace zoom en los jugadores, SEED utiliza una selección de píxeles perfecta. Una función de renderizado personalizada dibuja los objetos en un destino de renderizado separado, una textura fuera de pantalla en la que la GPU realiza el renderizado en lugar de en la pantalla. Cada objeto está codificado con un identificador único que tanto la CPU como la GPU pueden leer. El cliente lee el píxel que se encuentra debajo del cursor para determinar con exactitud sobre qué objeto se sitúa el jugador.
En los dispositivos móviles, la yema del dedo es mucho menos precisa que un cursor, por lo que el cliente también comprueba los píxeles que rodean cada toque. Si detecta más de un objeto cerca, muestra al jugador una lista para elegir, lo que facilita la selección de objetos más pequeños en zonas densamente construidas.
Cuando los jugadores alejan la vista, el cliente vuelve a usar el trazado de rayos físico, ya que la selección por GPU es más difícil de escalar a lo largo de una vista amplia.
Detrás de esos rayos se esconde una enorme cantidad de colisionadores. SEED utiliza Unity Physics no para simular, sino para inicializar rápidamente los modelos y consultarlos.
“Cada árbol tiene un colisionador, cada objeto y potencialmente cada ladrillo de construcción puede tener uno, y los personajes y las plántulas también”, dice Dyadichkin. “Podemos inicializar esta enorme cantidad de colisionadores muy rápidamente y luego realizar consultas sobre ellos para comprobar su ubicación y otras interacciones.”
Una vez que el jugador abre un edificio, aparece su interior y el cliente tiene más elementos que observar a medida que se desplaza entre los pisos e inspecciona las habitaciones individuales. Un proceso que se ejecuta de forma continua determina si cada objeto se encuentra dentro o fuera de un edificio, así como la habitación y el piso que ocupa.
“Eso nos permite hacer todo tipo de cosas: deshabilitar o habilitar GameObjects, o configurar las capas de renderizado correctas para controlar la iluminación”, explica Dyadichkin.

SEMILLA | Juegos de Klang
Perfilando el mundo que los jugadores realmente construyeron
La parte más difícil de optimizar los mundos creados por los jugadores es obtener datos realistas. Klang Games lo obtiene del juego en vivo.
El equipo guarda instantáneas del servidor para la recuperación ante desastres, y una vez que los jugadores han construido sociedades lo suficientemente grandes, esas instantáneas se convierten en casos de prueba.
“Podemos restaurar lo que los jugadores han construido y usarlo para realizar pruebas de rendimiento y probar funcionalidades a gran escala”, dice Fetisov. “Podemos trabajar con estas sociedades ya desarrolladas en lugar de empezar desde cero o intentar simular los datos nosotros mismos.”
La carga de una instantánea de una gran ciudad localmente reveló un inesperado cuello de botella en el procesamiento de la CPU en PC.
“Nuestro juego no sufre cuellos de botella en la GPU la mayor parte del tiempo, sino más bien en la CPU”, afirma Dyadichkin. “Es un juego muy estilizado, con pocos polígonos y casi sin texturas.”
Utilizando Unity Profiler , Dyadichkin descubrió que el hilo de renderizado dedicaba más tiempo del esperado a enviar llamadas de dibujo. El equipo utiliza GPU Resident Drawer , por lo que Dyadichkin esperaba que instanciara esos objetos. El depurador de fotogramas demostró lo contrario.

SEMILLA | Juegos de Klang
“Seguíamos recurriendo por defecto al procesamiento por SRP en lugar del procesamiento por lotes híbrido”, dice Dyadichkin. “Resultó que GPU Resident Drawer no estaba capturando todos estos objetos porque casi todos nuestros prefabs tienen grupos LOD .”
La diferencia importa a la escala de SEED . El procesador por lotes SRP reduce el coste de CPU de configurar cada llamada de dibujo, pero sigue enviando una por objeto. GPU Resident Drawer va más allá, agrupando objetos que comparten una malla y un material en dibujos instanciados, que el Depurador de fotogramas etiqueta como lotes híbridos. Con miles de objetos pequeños, esa es la diferencia entre muchas llamadas de dibujo ligeras y unas pocas grandes.
El culpable de que faltaran objetos fue el fundido cruzado de LOD animado. El efecto se veía mejor, pero impedía que los objetos entraran en la ruta del cajón residente de la GPU.
“Hemos desactivado la parte de animación.” “Seguimos teniendo fundido cruzado, pero ahora con transiciones configuradas manualmente”, dice. “Ahora las llamadas de dibujo se instancian de nuevo, lo que reduce la carga sobre nuestro hilo de renderizado de la CPU.”

SEMILLA | Juegos de Klang
Representar una sociedad madura dentro de la memoria móvil
En dispositivos móviles, la representación de SEED se topó con una limitación diferente. “En el ámbito móvil, el problema no reside en la CPU, sino en la memoria”, afirma Fetisov. “Ese es el principal obstáculo de nuestro proyecto.”
Una sociedad madura puede contener una enorme cantidad de edificios, objetos al aire libre, personajes y mallas. Cada malla y material que el cliente renderiza debe caber primero en la memoria. Klang Games depende en gran medida del Memory Profiler y de las comparaciones de instantáneas de memoria para determinar adónde va esa memoria. El equipo descubrió texturas almacenadas tres veces debido a una referencia rota, dependencias de Addressables que duplicaban el mismo material y colecciones de C# mucho más grandes de lo necesario.
“Surgieron muchos problemas: en la versión de escritorio no había inconveniente y la gente ni se daba cuenta, pero en la versión móvil era un gran problema”, dice Fetisov. “Utilizamos bastante el Unity Memory Profiler , especialmente las comparaciones de instantáneas [de memoria].”
Incluso sin texturas, la geometría se acumula.
“Algunas de las mallas eran bastante gruesas, especialmente las de los árboles”, dice Fetisov. “Si se cargan todos los niveles de detalle (LOD), un solo árbol puede ocupar megabytes de memoria, y tenemos muchas variaciones de árboles.”
Dado que el equipo crea Addressables para cada plataforma , puede enviar árboles simplificados a dispositivos móviles sin modificar el código del juego. “El mismo código que carga la silla en la versión de escritorio la carga en la versión móvil”, explica Fetisov. “Pero los propios Addressables pueden ser activos optimizados para dispositivos móviles.”
El cambio más significativo fue la sustitución completa de los grupos LOD en los dispositivos móviles. Los niveles de detalle clásicos implicaban almacenar múltiples mallas por tipo de objeto en la memoria, el mismo coste que Fetisov describe con los árboles. Mesh LOD , introducido en Unity 6.2, almacena cada nivel de detalle dentro de una sola malla, y las variantes móviles de SEED ahora lo utilizan exclusivamente. También redujo la carga de trabajo del pequeño equipo artístico de Klang Games.
“El cambio de LOD a Mesh LOD fue un paso crucial para poder renderizar el mundo del juego en dispositivos móviles”, afirma Fetisov.

SEMILLA | Juegos de Klang
Diseñando para lo que los jugadores construirán a continuación.
El principal desafío de renderizado de SEED no va a desaparecer: Los jugadores deciden qué tiene que dibujar el cliente, y nunca dejan de construir. “Se trata de un equilibrio constante entre la fidelidad visual que buscamos para estos mundos creados por los jugadores y una velocidad de fotogramas estable en dispositivos de gama baja”, afirma Dyadichkin.
Klang Games no puede predecir qué construirán los jugadores a continuación, pero sí puede compararlo con lo que ya han construido.
“Diseña, construye y prueba desde el primer día para la escala que deseas alcanzar”, dice Fetisov. “Realiza pruebas de rendimiento con cargas realistas desde el principio y continúa haciéndolo.”
SEMILLA Está disponible en acceso anticipado. Consulta más historias de desarrolladores de Unity en el Unity y el centro de recursos de Unity.