Je pense que la solution idéale est un savant mélange des 2.
D'un côté le client doit faire un maximum de choses, et de l'autre le serveur doit synchroniser tout le monde de temps en temps.
On le voit bien dans les jeux en ligne. Lorsqu'il y a un lag, tu ne vois plus personne bouger pendant X secondes puis tu te retrouves téléporté à ton point de départ. Pendant le lag, tu n'étais plus connecté au serveur, mais tu pouvais quand même bouger, tirer, ... Lorsque la connexion revient, tu te retrouves la ou tu étais avant le lag. Tout vérifier en permanence ce n'est pas possible, mais tu peux très bien vérifier de temps en temps et rectifier les erreurs.
Par exemple, imagine qu'un joueur se déplace tout droit. Tu peux raisonnablement penser qu'il gardera la même direction/vitesse pour les prochaines 100ms. Du coup, le joueur ne va pas envoyer sa position tous les 10ms mais tous les 100ms. Pour les autres joueurs, tu prédis sa position en fonction de sa dernière position connue, de sa vitesse et de sa direction. Dès que tu reçois une nouvelle position de la part du joueur, tu utilises celle-ci comme nouvelle position initiale (pareil pour la vitesse/direction).
Bref, en essayant de prédire ce que le joueur va faire et en rectifiant en cas d'erreur, tu peux limiter significativement le nombre de paquets qui transitent (critique pour un jeu réseau).
Mais ça reste compliqué à gérer pour toi, car tu dois pouvoir corriger toutes les erreurs (si le joueur a subitement changer de direction, il est possible qu'il ait "évité" les tirs ennemis, ...). Bref, commence simple avec du TCP + transmission de toutes les données + vérification de tout. Quand ça marchera bien, tu pourras commencer à optimiser tout ça.