DigitalPulseSoftware / Erewhon-Game

Video game about programming your spaceships to destroy other programmed spaceships o/
MIT License
36 stars 7 forks source link

[FR] [Discussion] Comment contrôler les déplacements ? #6

Closed SirLynix closed 6 years ago

SirLynix commented 6 years ago

Cette issue est un topic de discussion, elle ne vise pas à régler un problème existant mais à discuter d'une direction à prendre pour l'évolution du jeu.

Actuellement, les déplacements sont contrôlés exclusivement par le script Lua via un callback de cette forme:

function Spaceship:OnUpdateInput(elapsedTime)
    return moveX, moveY, moveZ, torqueX, torqueY, torqueZ
end

Cette fonction est appelée trente fois par seconde, et renvoie le déplacement à appliquer au vaisseau (chaque valeur retournée représente un pourcentage entre -1 et 1 inclus). Le mouvement est relatif à l'orientation du vaisseau, la rotation est absolue.

Cette approche pose plusieurs problèmes:

Une solution pourrait être de passer sur des fonctions plus simples, type "self.Core:MoveToDestination(point, orient)" qui donnerait l'information à un composant C++ chargé du calcul des inputs.

Cependant on y perd en souplesse.

Des avis ?

Faymoon commented 6 years ago

Salut Je suis 100% pour la solution que tu propose , vu les désavantages de la fonction et puis on a pas tous envie de faire du PID(surtout les débutants) ;)

GuillaumeDesforges commented 6 years ago

Cette solution permet effectivement d'avoir un plus haut niveau pour l'IA. Mais aura-t-on quand même un contrôle plus fin sur le path finder ? La possibilité de "planifier" un stack de destinations ? (trajectoires courbes par ex)

SirLynix commented 6 years ago

Autant je suis d'accord pour l'introduction d'une solution plus simple pour permettre de naviguer, autant j'ai peur de trop restreindre le contrôle.

Par exemple, supposons qu'on fasse une API du style:

local nodes = {
     Vec3(....),
     Vec3(....),
     Vec3(....),
     ...
}

self.Navigation:FollowPath(nodes)

qui fasse donc suivre une trajectoire à notre vaisseau.

Déjà on peut se poser la question de la complexité du calcul d'une telle trajectoire et donc de sa réelle utilité.
Ensuite, imaginons que notre vaisseau se fasse tirer dessus sur son chemin (un scénario assez probable), mettons qu'il détecte le projectile et essaie de l'esquiver (ou réduire en tout cas son impact).
Comment ferait-il ça ?

GuillaumeDesforges commented 6 years ago

Je dirai pile, quand on arrive à destination on passe à la suivante.

Si on détecte un projectile :

self.Navigation.Path:Clear()
// Recalculer une autre trajectoire
self.Navigation.Path:AddNodes(newNodes)

ou même

// mettons que je veuille supprimer les quatres derniers points car j'ai calculé que le projectile allait me frapper entre les 4 et 5ème points
self.Navigation.Path:Pop(4)
// Recalculer une autre trajectoire
// ...
// Rajouter les nouveaux points
self.Navigation.Path:AddNodes(newNodes)

et quand on ne veut garder que les 6 premiers : self.Navigation.Path:pop(self.Navigation.Path:size()-6)

SirLynix commented 6 years ago

Le problème c'est qu'éviter un projectile ça demande un peu plus que simplement calculer une nouvelle trajectoire, il faudrait donner vraiment un coup de propulsion dans une certaine direction pour pouvoir l'éviter.

Je me demande si un système de noeuds à rejoindre doit effectivement faire partie du jeu de base ou être une extension de la part du joueur.

GuillaumeDesforges commented 6 years ago

Ah! Si le game design veut que les vaisseaux soient pilotés en micro et non autorités ce n'est pas pareil...

Dans ce cas là un module "autopilote" ?

SirLynix commented 6 years ago

En fait l'idée c'est de brider le moins possible le joueur dans ses possibilités, et effectivement on est sur un modèle de micro-gestion.

Que ferait le module autopilote ? Il éviterait lui-même les projectiles ? Je pense que ça devrait être la tâche du joueur.

GuillaumeDesforges commented 6 years ago

Si le joueur doit micro gérer les déplacements, ça peut être très vite fastidieux pour mettre en place un système basique qui permet d'avoir une pile de point et d'aller de point en points. Surtout si il y a de la cinématique et des déviations (collision avec un autre vaisseau ?).

Du coup laisser possible la micro, mais aussi un autopilote pour les trajets plus longs. Juste qui va vers la destination, rien d'intelligent. Comme pour les avions :p

SirLynix commented 6 years ago

C'est tout l'intérêt de cette issue, chercher le meilleur compromis entre la micro-gestion (ce qui est actuellement implémenté) et l'arcade (quelque chose de marrant à faire et d'accessible).

Je pense qu'une bonne piste de réflexion c'est de partir sur effectivement un module d'autopilote, ou de navigation (terme plus approprié au vu du lore du jeu, une IA faisant appel à une autre IA semble étrange).
On peut donc imaginer une API comme celle-ci:

-- Fonctions
Spaceship.Navigation:FollowEntity(entity, triggerDistance) -- Comment fonctionne ce module avec le radar ?
Spaceship.Navigation:MoveToPosition(pos, rot, triggerDistance)

-- Évenements (appelés selon la distance avec le triggerDistance)
Spaceship.Navigation:OnDestinationReached() -- Appelé lorsque la destination est à moins de triggerDistance unités (permettant facilement d'implémenter un système de noeuds)

Rajouter la possibilité de suivre un chemin par-dessus cette API est facile, et pour avoir de la micro-gestion par-dessus on peut imaginer cette API complémentaire:

Spaceship.Engines:Impulse(Vec3 impulse, number duration)

qui, sans arrêter la navigation pour autant, permet d'ajuster la position (et on peut imaginer la rotation d'un vaisseau) à l'aide de petites impulsions ayant une certaine durée dans le temps.

GuillaumeDesforges commented 6 years ago

ça paraît solide ! (RARG le c cédille majuscule inaccessible sorry)

Dans ce cas là il faut aussi un Spaceship.Navigation:Pause() et Spaceship.Navigation:Resume()

SirLynix commented 6 years ago

Je ne suis pas sûr que la possibilité de pause soit pertinente, je vois plutôt un arrêt pur et dur (un Spaceship.Navigation:Stop() en fin de compte), où le resume ici serait un autre appel à Spaceship.Navigation:FollowEntity ou Spaceship.Navigation:MoveToPosition.

SirLynix commented 6 years ago

Cette issue est maintenant implémentée.