Estoy desarrollando un motor de juego simple (en C #, si es importante), y no puedo pensar en una forma lo suficientemente decente para implementar scripts en términos de arquitectura.
Es una estrategia simple por turnos con animaciones personalizadas e independientes de la lógica para las batallas. Tiene una capa de arquitectura global para el sistema / cosas de bajo nivel y, lo que es más importante, dos módulos principales, lógica y vista de juego, que se comunican mediante un administrador de eventos.
Y la cuestión es que realmente me gustaría que los guiones influyan tanto en las cosas relacionadas con la lógica del juego (cambio de parámetros de la unidad, etc.) como en las cosas relacionadas con la vista del juego, como animaciones / diálogos especiales para batallas que pueden depender de un cierto disparador con guión.
(Para ser honesto, idealmente quiero que el script controle el flujo del juego, dejando solo la mecánica / gráficos centrales a la lógica / vista, pero soy nuevo en esto, así que no estoy seguro de poder hacerlo ahora)
He estado pensando en tres opciones:
Simplemente deje que las secuencias de comandos vivan en la lógica, pero hágale saber sobre el lado gráfico del juego. Pero esto haría que la división lógica / vista sea muy vaga, ¿no es así?
Convierta las secuencias de comandos en un módulo separado que intercambiará eventos con los demás utilizando el mismo administrador de eventos. Pero supongo que esto debe ser muy cuidadoso con la sincronización de eventos, y también agregar una gran cantidad de tipos de eventos al administrador. (Aún así, favorito personal)
Convierta el script en un módulo sobre todo, para que pueda influir directamente / llamar a las funciones de la lógica / vista. Esto permite una funcionalidad inherentemente más amplia a costa de enroscar todo el esquema de intercambio de eventos y temer que el script pueda romper cosas incluso cuando realmente no debería.
Por lo tanto, no puedo decidir sobre uno de estos ni pensar en una mejor manera de insertar el módulo de secuencias de comandos ... ¿Alguna sugerencia o enlaces útiles?
¡Gracias!
Ps gracias por migrar la pregunta, no sabía que había una sección especializada para gamedev
fuente
Respuestas:
Creo que desea la tercera opción, pero encontrará que tiene razón al pensar que tener eventos lógicos que suceden en potencialmente dos lugares es algo malo. Descubrirá que desea que el módulo lógico del motor termine siendo una marca de actualización que hace dos preguntas: "¿Qué hago ahora?" y '¿Cómo hago eso?' a los que luego puede vincular los scripts para responder a esas preguntas.
Combine esto con la exposición de los objetos que contienen los datos y una API para acceder a los componentes lógicos requeridos (quiero decir que podría hacer un script para el hallazgo de la ruta AI, pero dado que es un código genérico que probablemente se usará y reutilizará, ¿por qué no? incrustarlo en el módulo y luego agregarlo a la API expuesta al lenguaje de script?). Esto debería darle la accesibilidad, así como las ubicaciones claramente definidas donde están sucediendo las cosas.
Una vez más, advierto esto con la misma afirmación que siempre hago. Un producto de trabajo terminado siempre es más valioso que una buena teoría en programación :)
¡Espero que esto ayude!
fuente
Muchos tienden a subestimar el poder de los lenguajes dinámicos pensando que tal flexibilidad tiene un costo de velocidad; Esto es cierto, pero a menudo el costo es simplemente insignificante.
Personalmente, tiendo a desarrollar lo más posible utilizando lenguajes dinámicos que exploten la expresividad y luego perfilo el prototipo para comprender dónde y si se necesita optimización.
En su caso, esto significa que debe intentar avanzar hacia la tercera opción, desarrollando la parte "superior" utilizando un lenguaje dinámico adecuado que también pueda usar como lenguaje de secuencias de comandos.
Se pueden usar muchos patrones después de colocar el dinamismo a la profundidad correcta. Sus scripts personalizados se pueden integrar en un sistema basado en eventos como un sistema de devolución de llamada, cuando el núcleo vuelve a llamar puede proporcionar un entorno adecuado para que el script pueda alterar el estado global o solo el estado de un subconjunto de todo el sistema.
Puede encapsular la interfaz que su script puede interactuar utilizando el patrón Fachada. En los métodos de fachada puede poner la lógica que define cómo , cuándo , si el script puede usar una funcionalidad y abstraer la interacción del script desde la implementación central.
La interfaz de su script debe proporcionar los métodos de fábrica relevantes para que el script pueda generar elementos sin instanciarlos directamente; Estas instancias pueden ser envoltorios sobre los objetos reales para que se pueda implementar una mayor lógica de control de acceso.
fuente
El objeto de secuencias de comandos debe tener acceso a los otros objetos para los que proporcionará datos. Tenga cuidado de no pasar esos otros objetos directamente al objeto de secuencias de comandos. Hacerlo crea una interfaz frágil. Es posible que desee tener algo así como una clase mediadora que gestione esas referencias de objeto y proporcione acceso a datos al objeto de secuencias de comandos.
fuente
Lua es una opción popular para un lenguaje de script de propósito general. Puedes crear tu propio lenguaje de scripting usando Lex y Yacc (mira el artículo en Game Programming Gems 3), pero diría que la mayoría de tus necesidades podrían ser atendidas con Lua sin importar cuán grande o pequeño sea.
fuente