DOTS es una de las tecnologías (o grupo de tecnologías), más recientes de Unity. Permite el procesamiento de una cantidad grande de entidades en simultáneo con el mínimo impacto en el juego. También plantea nuevos paradigmas de programación.

ANTES DE EMPEZAR…

Antes de empezar a codear cualquier cosa vamos a explicar un poco qué es DOTS (si ya lo sabes, podes saltearte toda la teoría). Voy a hacerlo lo más resumido posible, ya que lo más importante es entender, en mi opinión, conceptualmente los términos generales y agarrar código de una. DOTS está compuesto básicamente de 4 partes fundamentales (no, no voy a describir sus siglas):

 

ECS (Entity Component System)

Básicamente es un sistema que nos permite diseñar entidades, componerlas y controlarlas todas juntas dentro de un mismo sistema. Vendría a ser algo así como un manager que “gestiona” todos los componentes. Hago énfasis en la palabra porque lo que controla son LOS COMPONENTES y no las ENTIDADES. En sí el sistema no necesita saber “quién” es la entidad, sino sus partes. Por lo que controlaría cada uno de sus componentes individualmente de si estos están en una entidad o en otra completamente diferente. Esto ya nos predispone a programar COMPONENTES que luego van a conformar ENTIDADES. Hasta acá suena a algo similar a lo que ya hacemos con los MonoBehaviours. Pero sólo esa parte es similar.

 

 

En este ejemplo…

  • Las entidades serían el celular y la computadora.
  • Los componentes son la pantalla, el teclado y el mouse.
  • Los sistemas son Controlador de Pantalla, Controlador de Teclado y Controlador de Mouse.

Noten cómo, en este caso, el Controlador de Pantalla maneja los componentes Pantalla sin necesidad de conocer en dónde está o a quién pertenece.

 

JOB SYSTEM

Es el sistema que se encarga básicamente de paralelizar diferentes tipos de tareas. Básicamente podemos usar herramientas como Parallel.ForEach que básicamente es el clásico ForEach pero ejecutado en multithreading. Este sistema nos permite trabajar con multithreading sin necesidad de crear otros threads de manera manual ni configurarlos, ni nada. Sólo lo ejecutamos y el mismo sistema se encarga de gestionar todo lo necesario para su correcta ejecución. Algunos ejemplos sacados de esta página muestra la performance, aunque claro, depende de qué es lo que se esté ejecutando, y la relación podría ser más grande.

 

 

 

BURST COMPILER

Si ven la definición sin entender algunos conceptos como IL, LLVM o bytecode quizás todo sea chino básico, pero a GRANDES rasgos este sistema lo que hace es compilar de manera más rápida y eficiente para obtener un código nativo más optimizado. Lo que básicamente tenemos que saber es que es algo que nos va a ayudar a que nuestros códigos sean y funcionen de manera más eficiente.

 

 

 

NATIVE CONTAINERS

Son contenedores que nos permiten acceder directamente a los datos que están en la memoria, en lugar de tener una copia de ellos con los que trabajar. Es un poco larga la explicación de cuál es la problemática que viene a resolver, pero básicamente nos permite acceder a un conjunto de datos para realizar operaciones en multithreading sin tener el problema de la pregunta “qué pasa si dos threads resuelven al mismo tiempo una operación que necesito que pase una como consecuencia de la otra?“. El multithreading nos viene a solucionar un montón de problemas, pero también produce este tipo de preguntas. Si realizamos un conjunto de tareas en simultáneo pero sí o sí necesitamos que una se resuelva antes que la otra es una problemática que esto puede resolver, al igual que dividir el conjunto de objetos que dependen de otros como para que las tareas sean más sencillas, son unos de los objetivos que estos contenedores vienen a resolver. Cuenta con un conjuto de tipos de datos como arrays, listas, diccionarios, etc, con los que este sistema va a gestionar sus jobs en multithreading de manera eficiente para no toparnos con los problemas mencionados.