He diseñado un sistema de entidad para un FPS. Básicamente funciona así:
Tenemos un objeto "mundial", llamado GameWorld. Esto contiene una matriz de GameObject, así como una matriz de ComponentManager.
GameObject contiene una matriz de componentes. También proporciona un mecanismo de eventos que es realmente simple. Los componentes mismos pueden enviar un evento a la entidad, que se transmite a todos los componentes.
El componente es básicamente algo que le da a GameObject ciertas propiedades, y dado que GameObject es en realidad solo un contenedor de ellos, todo lo que tiene que ver con un objeto de juego ocurre en los Componentes. Los ejemplos incluyen ViewComponent, PhysicsComponent y LogicComponent. Si se necesita la comunicación entre ellos, eso se puede hacer mediante el uso de eventos.
ComponentManager solo una interfaz como Component, y para cada clase de Componente, generalmente debería haber una clase de ComponentManager. Estos administradores de componentes son responsables de crear los componentes e inicializarlos con propiedades leídas de algo así como un archivo XML.
ComponentManager también se encarga de las actualizaciones masivas de componentes, como el PhysicsComponent, donde utilizaré una biblioteca externa (que hace todo en el mundo a la vez).
Para la configurabilidad, utilizaré una fábrica para las entidades que leerán un archivo XML o un script, crearán los componentes especificados en el archivo (que también agrega una referencia en el administrador de componentes adecuado para actualizaciones masivas) y luego inyectarlos en un objeto GameObject.
Ahora viene mi problema: voy a tratar de usar esto para juegos multijugador. No tengo idea de cómo abordar esto.
Primero: ¿Qué entidades deberían tener los clientes desde el principio? Debo comenzar explicando cómo un motor para un solo jugador determinaría qué entidades crear.
En el editor de niveles puede crear "pinceles" y "entidades". Los pinceles son para paredes, pisos y techos, básicamente formas simples. Las entidades son el GameObject del que te hablé. Al crear entidades en el editor de niveles, puede especificar propiedades para cada uno de sus componentes. Estas propiedades se pasan directamente a algo como un constructor en el script de la entidad.
Cuando guarda el nivel para que se cargue el motor, se descompone en una lista de entidades y sus propiedades asociadas. Los pinceles se convierten en una entidad "engendro del mundo".
Cuando carga ese nivel, solo instancia todas las entidades. Suena simple, ¿eh?
Ahora, para las redes de las entidades me encuentro con numerosos problemas. Primero, ¿qué entidades deberían existir en el cliente desde el principio? Suponiendo que tanto el servidor como el cliente tienen el archivo de nivel, el cliente también podría instanciar todas las entidades en el nivel, incluso si están allí solo a los fines de las reglas del juego en el servidor.
Otra posibilidad es que el cliente instancia una entidad tan pronto como el servidor envía información al respecto, y eso significa que el cliente solo tendrá entidades que necesita.
Otro problema es cómo enviar la información. Creo que el servidor podría usar la compresión delta, lo que significa que solo envía nueva información cuando algo cambia, en lugar de enviar una instantánea al cliente en cada cuadro. Aunque eso significa que el servidor debe realizar un seguimiento de lo que cada cliente sabe en este momento.
Y finalmente, ¿cómo deberían inyectarse las redes en el motor? Estoy pensando en un componente, NetworkComponent, que se inyecta en cada entidad que se supone que está conectada en red. Pero, ¿cómo debe saber el componente de red qué variables red y cómo? conectar acceder a ellas, y finalmente cómo el componente de red correspondiente en el cliente debe saber cómo cambiar las variables en red?
Estoy teniendo grandes problemas para abordar esto. Realmente agradecería que me ayudaras en el camino. También estoy abierto a consejos sobre cómo mejorar el diseño del sistema de componentes, así que no tenga miedo de sugerir eso.