Estoy trabajando en un sistema de entidad para un juego en red y estoy asignando a cada entidad una identificación de entero de 32 bits única que puedo usar para serializar referencias a entidades y las entidades mismas.
Actualmente solo estoy incrementando un contador cada vez que se crea una entidad. Supongo que los identificadores finalmente se agotarán, pero realmente no espero tener 4 mil millones de entidades. Además, esto evita el problema si la entidad # 5 se destruye y obtenemos una identificación de 5. ¿Está destinado a referirse al nuevo # 5 o al antiguo # 5 eliminado?
El problema es que no estoy seguro de cómo manejar / evitar colisiones. Actualmente, si un cliente recibe una actualización para una entidad con una identificación más alta que su "identificación libre" actual, simplemente supera su identificación gratuita más allá de eso. Pero eso no parece muy robusto.
Pensé en asignar rangos a cada cliente para que puedan asignar entidades sin conflictos (digamos que los n bits superiores son el número de jugador), pero me preocupa lo que sucede si los rangos comienzan a superponerse con el tiempo.
¿Hay una mejor manera de manejar esto? ¿Debería preocuparme si los identificadores se desbordan o superan el límite permitido? Podría agregar código para detectar estos casos, pero ¿qué haría si suceden además del bloqueo?
Otra opción es usar algo con una mayor probabilidad de ser único, como un GUID de 128 bits, pero eso parece realmente pesado para un juego que está tratando de minimizar el tráfico de red. Además, de manera realista, nunca necesitaría más entidades a la vez y luego encajaría en un entero de 32 bits o incluso 24 bits.
¡Gracias!
fuente
Respuestas:
Lo que he hecho es hacer que el servidor haga todo . El cliente (s) simplemente puede pedirle al servidor que haga algo, pero no puede hacer nada por sí mismo. En este caso, el servidor siempre será el que asigne los ID y el problema resuelto.
No he tratado con la predicción del lado del cliente mientras esperaba que el servidor aprobara acciones como: "Dispara un cohete" o "Haz una estación solar aquí". Estas acciones querrán crear entidades, y las entidades tienen ID. Hasta ahora, estoy sentado esperando a que llegue el servidor, pero creo que lo que hay que hacer es crear una entidad temporal mientras espera la aprobación del servidor. Cuando reciba la aprobación del servidor, el servidor asignará una ID y podrá actualizar o sobrescribir el objeto temporal.
Tampoco he tratado con un desbordamiento de ID, pero si el servidor tiene el control total y detecta un desbordamiento, podría hacer cualquier manejo que considere necesario (reiniciar en 0, elegir de una pila libre, bloquearse, etc.) y todo los clientes ni siquiera lo sabrán ni les importará. Los clientes solo aceptarán las ID entregadas por el servidor.
fuente
Cuando hice esto para un juego comercial multijugador, hice exactamente lo que propones: usar un entero GUID de 32 bits, donde los ocho bits superiores son el número de jugador, y los veinticuatro bits inferiores contienen un número localmente único.
Si / cuando el número local se desborda (en mi caso, casi nunca sucedería; bajo el uso normal, se necesitarían de cuatro a cinco días de tiempo de reproducción continua en una sola sesión de red para que ocurra), el propietario enviará un Mensaje "Restablecimiento de todos mis objetos" y renumerar todos los objetos aún existentes a partir de cero. El mensaje les dijo a todos los pares que descartaran los objetos que habían recibido y que los volvieran a consultar.
Un enfoque más sofisticado sería un mensaje "Objeto con GUID 'n' es ahora Objeto con GUID 'm'" para cada objeto existente. Pero en mi caso, era poco probable que ocurriera realmente, y no pensé que a la gente realmente le importaría que los objetos remotos desaparecieran del mundo durante medio segundo, después de cinco días sin parar en una sola sesión de red. ;)
fuente
Si tus clientes pueden generar sus propias entidades, supongo que tienes un juego multijugador de igual a igual.
Si ese es el caso, probablemente no tenga demasiados clientes. Ciertamente, no más de 256. Y su identificación de entidad está garantizada para caber en 24 bits (¡16000000+ entidades son suficientes para todos!). Entonces, solo haga que el byte más alto de su identificación sea igual a la identificación del cliente:
o algo.
Y si me equivoco y tiene un servidor autorizado, simplemente nunca cree nuevas entidades en los clientes.
fuente
Estoy usando el método 'más ingenuo' (solo incrementa un número entero para cada nueva ID) en mi juego persistente de varios jugadores y funciona bien porque no dejo que el cliente cree nuevas ID: s.
Si deja que el cliente decida (mediante el uso de una especie de técnica GUID explicada), el cliente también puede introducir varios errores al asignar una ID antigua a un nuevo elemento (eso es exactamente lo que pensé en la cabeza pensando como 5 segundos , puede haber muchas otras lagunas).
Como de costumbre, para evitar trampas , el servidor debe hacer TODA la creación y validación .
fuente