[conception] La taxation

Voir le sujet précédent Voir le sujet suivant Aller en bas

[conception] La taxation

Message  Apeiron le Jeu 26 Déc - 15:35

Motivation

Les crédits permettent à Nova d'utiliser des unités de population pour travailler dans les bâtiments. A part pour la doctrine étatisme [1] ils sont donc indispensables dans une économie. Si on oublie le commerce entre joueurs (il faut bien que l'argent vienne de quelque part ^^), il n'y a que deux sources de crédits : la vente de ressources perçue par les entreprises (donc concernant essentiellement les humains), et la taxation de la population perçue par le gouvernement. La taxation est donc le moyen usuel pour vous permettre d'utiliser votre population et obtenir tout le reste dans le jeu. Vous l'aurez compris : le sujet est grave. Smile

Justification économique

En schématisant il existe trois formes d'imposition : l'impôt sur le revenu (exemples en France : CSG, IRPP), l'impôt sur le capital (ISF, taxe foncière) et l'impôt sur la consommation (TVA, TIPP). Dans Nova le gouvernement choisit tout simplement un taux de taxation, ce qui bien sûr influe directement sur ses gains en taxation mais aussi influe sur l'évolution de la richesse de la planète. La formule est (pour une planète donnée à un instant t) :
imposition(t) = tauxTaxation*richesse(t)*population(t).

La richesse de la planète représente le niveau de vie moyen des habitants. Si le taux de taxation est fort la planète se stabilisera dans la pauvreté (1 crédit par jour par habitant pour une taxation de 100%), alors que s'il est faible la planète se stabilisera dans l'opulence (21 crédits par jour par habitant pour une taxation de 0%). L'imposition influe donc sur le capital. Il est à noter que les gains de l'imposition étant proportionnels à la fois au taux d'imposition mais aussi à la richesse de la planète, il est plus rentable pour le gouvernement en terme de rentrées d'argent d'avoir un taux d'imposition moyen.

La richesse de la population détermine les salaires qui seront versés à la population : plus la population sera aisée (et donc cultivée et compétente, et libérée des pressions économiques) plus elle voudra être payée cher. Certains facteurs peuvent modifier les salaires versés (comme le trait Financier) mais pour simplifier nous considérons que le salaire moyen est égal à la richesse de la planète. D'un autre côté plus la richesse sera grande plus grands seront les revenus de l'imposition. Supposons pour simplifier que les gens sont payés uniformément (il n'y a pas de classes sociales distinctes demandant des salaires différents) et étudions le bilan financier du gouvernement.
Pour un instant donné et donc à population et richesse fixés, le gouvernement dépense la richesse de la planète pour chaque unité de population qu'il emploie, soit pertes = richesse*nombrePopEmployée = richesse*%popEmployée*population. Mais d'un autre côté il gagne grâce à l'imposition gains = tauxTaxation*richesse*population. Donc son bilan est : bilan = gains - pertes = tauxTaxation*richesse*population - richesse*%popEmployée*population = (tauxTaxation - %popEmployée)*richesse*population.
Ainsi, pour être à l'équilibre pour une planète donnée le gouvernement peut tout simplement employer un pourcentage de population égal au taux de taxation qu'il a choisi. Par exemple pour un taux de 40%, le gouvernement peut employer 40% de la population et être à l'équilibre, ou en employer moins et être en positif, ou en employer plus et perdre des crédits sur cette planète. On a ainsi un lien entre imposition et revenu.

Le gouvernement ne gagne pas d'argent en vendant ses ressources à la population : nous considérons pour simplifier que quand le gouvernement distribue quelque chose à la population il le fait sous forme d'un service public gratuit (financé par la taxation bien sûr). Donc le gouvernement a intérêt à ce que les entreprises viennent distribuer d'elles-mêmes les ressources à sa population. De leur côté elles ont intérêt à le faire car leur seul source de revenu est la vente de ces ressources. Le taux de taxation fixé par le gouvernement s'applique également à ces revenus, ce qui permet donc à l'imposition d'influencer également la consommation. Si le taux est trop fort les entreprises ne gagneront pas assez et iront vendre ailleurs. S'il est trop faible le gouvernement ne gagnerait pas beaucoup. Dans certains cas il peut même être intéressant (mais je vous passe les calculs) pour les entreprises qu'elles versent des pots de vin au gouvernement pour qu'il accepte en échange de baisser son taux de taxation.

Ainsi, nous disposons d'une formule simple qui simule grossièrement des comportements économiques réels. Je travaille actuellement sur des possibilités de raffiner le système économique de Nova, notamment par rapport aux classes sociales/raciales ou à l'échange de ressources, mais je préfère rester simple pour aller directement à l'essentiel dans ce pavé déjà assez long et technique.

L'écoulement du temps

Nova n'est pas un jeu en tour par tour. Outre que nous trouvions cela moins bon pour l'immersion nous ne souhaitions pas obliger les joueurs à se connecter trop souvent. Une solution à cela est de faire des tours lents (une semaine dans le cas de Babylone 5), mais nous avons estimé que ce serait impraticable (plusieurs mois juste pour coloniser son domaine...) et frustrants pour les joueurs qui souhaiteraient passer souvent. De plus nous avons pu constater sur Weymery les mérites d'un rythme continu (c'est à dire en fait du tour par tour avec un rythme d'une seconde), alternant des périodes de croissance molles et des connexions frénétiques en temps de guerre.

Mais à ce stade vous devez comprendre que le serveur ne peut décemment pas simuler ce qu'il se passe dans toute la Galaxie à chaque seconde : la quantité de ressources demandées seraient invraisemblable. Toutefois cela n'invalide pas pour autant le temps continu. Nous n'avons pas besoin que chaque seconde soit simulée, mais uniquement que le jeu puisse calculer les changements entre deux connexions (ou rafraichissements de page) des joueurs. A ces mises à jours exigées par les joueurs nous avons aussi ajouté des mises à jour techniques. Par exemple contrairement à Weymery dans Nova la consommation des ressources pour construire un vaisseau ne se fait pas d'un coup mais au fur et à mesure. Si les stocks baissent le serveur est capable [2] d'estimer la date où il n'y aura plus de minerai en réserve et donc où la consommation de minerai pour la construction devra se faire non plus au rythme des chantiers, mais au rythme de production des mines. Ainsi, une mise à jour est programmée à cette date, et quand elle a lieu la consommation de minerai (et donc la date estimée de fin de construction) sont changées.

Ainsi, au lieu de calculer l'imposition à chaque seconde il suffit de calculer l'imposition entre une date t0 et une date t1. De plus, si un joueur perd de l'argent il faut pouvoir prévoir à quelle date son compte bancaire sera vide. En effet à partir de cette date le joueur ne pourra plus embaucher autant d'unités de population qu'il le souhaitera, mais uniquement autant que ses revenus le lui permettront. Il y aura donc de la population renvoyée [3] à partir de cette date, même si le joueur ne se connecte pas entretemps.

(Suite plus tard)

--------------------------------------------------------------

[1] Étatisme bloque les entreprises, supprime la taxation et les salaires, et impose un taux de richesse sur l'ensemble de votre domaine.

[2] Grâce au travail de Nimeroni, gloire à lui !

[3] Nous avons fixé un ordre de priorité sur quel type de population serait renvoyé en premier mais pour le moment le détail m'échappe. Il me semble que ce sont les plus hauts salaires qui sautent en premier.
avatar
Apeiron
Grand Inquisiteur de la Cohérence
Grand Inquisiteur de la Cohérence

Masculin Nombre de messages : 5471
Age : 29
Date d'inscription : 09/11/2008

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: [conception] La taxation

Message  Nimeroni le Sam 28 Déc - 23:02

Apeiron a écrit:Mais à ce stade vous devez comprendre que le serveur ne peut décemment pas simuler ce qu'il se passe dans toute la Galaxie à chaque seconde : la quantité de ressources demandées seraient invraisemblable.

C'est encore plus important dans le cas d'une coupure du serveur.

Dans le cas du temps réel, le serveur devrais faire d'un coup le calcul de chaque tour pendant qu'il était hors ligne. Par exemple, un serveur hors ligne pendant 35 secondes devra faire d'un coup 35 tours. Cela entrainera donc un gros "freeze" du serveur pour l'utilisateur et des grincements de dents pour l'hebergeur.

A l'inverse, dans le cas du pseudo temps réel, le serveur ne dois faire que le calcul de chaque "point clef" de manière récursive (un point clef en génère presque systèmatiquement un autre). Si pendant les 35 secondes, seule une planète deviens épuisée, alors le serveur n'a qu'une mise a jour a faire et rien d'autre. De plus, comme chaque point clef possède la date de sa propre mise a jour, le moment réel de la mise a jour n'a AUCUNE importance tant que l'information est disponible quand elle est necessaire.

Cette dernière propriétée sera la base d'une optimisation (...beaucoup) plus tard. Au lieu de faire des mises a jour dès que possible, rien n'interdit de faire des mises a jour qu'au moment ou l'information est demandée par l'utilisateur (ou par un autre evenement). Cette optimisation retire le besoin d'une boucle évenementielle, donc le serveur ne fera plus aucun travail tant qu'il ne sera pas demandé. Malheureusement, elle présente le risque d'avoir un temps de mise a jour important quand l'utilisateur demande une information qui n'a pas été mise a jour depuis longtemps, ce qui se traduira par une impression de freeze.
De plus, certains evenements doivent avoir lieu si un joueur regarde simplement la case après le chargement des infos en mémoire (comme dans le cas de la création ou le déplacement des flottes). Il est possible de contourner le problème en utilisant le navigateur comme rappel. Cela offre une petite information a un hacker ("quelquechose aura lieu a ce moment"), mais je ne crois pas que ce soit bien grave.

A titre d'information, le système de rappel est utilisé dans Weymery. J'ai encore un peu de conception a faire la dessus
(par exemple, je vais avoir besoin de réflechir sur les dépendances dans les mises a jour), mais l'optimisation semble tenir la route.

Dernière chose au sujet du temps !
Pour renforcer l'impression d'un jeu en temps réel, le navigateur de l'utilisateur fait lui-même du temps réel (il possède une boucle, toussa). A chaque seconde, il calcul la situation actuelle vis a vis des informations qu'il a récuperé du serveur. Par exemple, si une planète est affichée et qu'elle possède des mines, le joueur va voir le minerai augmenté a chaque seconde. Il ne s'agit que d'une illusion de l'interface (le minerai sur le serveur n'augmente pas), mais comme le serveur se met a jour quand l'utilisateur donne un ordre, le jeu se comportera comme si l'utilisateur avait les bonnes valeurs a tout moment.  Wink
avatar
Nimeroni
Drogué de connaissance
Drogué de connaissance

Masculin Nombre de messages : 1654
Age : 29
Localisation : Devant mon PC pardis !
Date d'inscription : 09/11/2008

Voir le profil de l'utilisateur http://nimeroni.blogspot.fr/

Revenir en haut Aller en bas

Re: [conception] La taxation

Message  Apeiron le Jeu 13 Fév - 17:49

Les dangers de l'approximation

Au début j'avais construit le système économique sous forme d'un jeu tour par tour, ce qui m'a posé problème lorsque nous sommes passés à un modèle en temps continu : comment calculer les valeurs intermédiaires ? J'avais réussi par des calculs savants à base d'interpolation polynomiale à générer des valeurs approximatives, mais cela pose un problème de conception.

En effet, s'il existe des irrégularités dans les valeurs (des pics absurdes par exemple) cela rend le système chaotique et empêche les joueurs de bien gérer leur domaine. Pire, même si nous voulions cacher ces défauts certains joueurs pourraient finir par les comprendre et les utiliser [0], ce qui risquerait de déséquilibrer le jeu.

Non, pour nous un bon jeu nécessite des règles aisées à comprendre, et dans la mesure du possible sans bug à exploiter. De plus, nous préférons dévoiler un maximum d'information sur le jeu afin que la communauté puisse travailler avec le plus de données possibles et nous aider à améliorer le jeu si elle le veut [1].

Le but est donc de trouver des solutions exactes pour les valeurs intermédiaires, avec des fonctions appropriées.

Les fonctions candidates

Lorsqu'un domaine est actualisé à la date t1 le serveur ne connaît que la date de la dernière mise à jour t0 et l'état du domaine à t0. L'intervalle de temps est dt = t1 - t0. Il nous faudrait donc une fonction reliant facilement f(t0), f(dt) et f(t1) = f(t0+dt). A ce stade je pensais surtout aux fonctions :
- linéaires de la forme f(t) = a*t car f(t0+dt) = f(t0) + f(dt)
- exponentielles de la forme f(t) = a^t car f(t0+dt) = f(t0) * f(dt)
- voire logarithmiques de la forme f(t) = log_a(t) car f(t1/t0) = f(t1) - f(t0)

Mon but était de faire le meilleur choix pas en terme de complexité mais en terme de gameplay. Mon choix s'est à l'époque porté sur les courbes logarithmiques :



En effet, avec des courbes logarithmiques la croissance est forte au début mais faible à la fin (oui, il y a une fin : n'oublions pas que la population est bornée par le seuil démographique). Cela permet à un joueur venant de s'installer (ou de se faire raser) de pouvoir rapidement commencer à faire des choses, même s'il reste intéressant de rester au même endroit pour atteindre le seuil démographique.

Pour les courbes exponentielles c'est le contraire : la croissance est faible au début mais forte à la fin, ce qui fait qu'il faut attendre un moment avant que le domaine ne soit utilisable, et quand le joueur commence à pouvoir l'utiliser les valeurs de seuil sont atteintes très rapidement ensuite. Les courbes linéaires sont un compromis : la croissance est la même en tout point de la courbe. Bref, les courbes logarithmiques semblaient mieux d'un point de vue gameplay.

Notez que d'un point de vue RP les trois courbes peuvent se justifier :
- Les courbes exponentielles correspondent à l'évolution d'une population sans intervention de l'extérieur : plus il y a de gens plus ces gens peuvent faire de nombreux enfants. C'est donc un modèle sans immigration (transporter beaucoup de monde est trop couteux probablement, à cause des coûts d'hyperpropulsion ou de supports vitaux) et où les conditions sociales ou climatiques ne sont pas un frein à la croissance démographique (contrairement à nos sociétés actuelles, mais bon c'est le futur, hé !).
- Les courbes logarithmiques correspondent à un modèle où le peuplement (en quelques mois quand on regarde les échelles de temps considérées) de la planète se fait essentiellement par l'immigration. Au début beaucoup de gens peuvent arriver avec leur tente sous le bras en prenant les endroits les plus charmants, et rapidement il faut de plus en plus de moyens pour pouvoir aménager les zones les plus hostiles, ce qui ralentit la colonisation. De plus, les premiers arrivants ont pu mettre en place des lois pour préserver leur confort et avantages à eux, ce qui a désincité les arrivants suivants.
- Pour les courbes linéaires on peut imaginer un panachage des raisons précédentes, ou tout simplement une migration constante, par exemple imposée par la Guilde des Transports.

Calcul de la population avec des logarithmes

Je décidais d'appliquer le même modèle à l'évolution de la richesse et de la population, et après avoir codé et testé [2] les programmes j'obtenais de jolies courbes pour la croissance et la décroissance (sans le cas d'une épidémie par exemple) :





Ce qui était bien à ce stade c'est que mes résultats vérifiaient bien qu'on obtenait les mêmes valeurs après une longue période ou en mettant à jour très souvent.

Je m'assurais aussi que les changements d'état se passaient bien, par exemple suite à un manque de médicaments ou durant une épidémie à la découverte d'un vaccin :





Calcul de la taxation ?

Je décidais d'utiliser le même modèle pour la richesse. Ainsi les deux avaient des courbes appréciables en terme de gameplay, et les biens de consommations devenaient à la richesse ce que les médicaments étaient pour la population.

Rappelons la formule du premier pavé : imposition(t) = tauxTaxation*richesse(t)*population(t).
La valeur de la taxation entre deux mises à jour t0 et t1 est la somme des imposition(t) pour chaque instant t, c'est à dire l'intégrale de imposition(t) entre t = t0 et t1. Donc, à des constantes près, cela revient à intégrer un produit de deux fonctions logarithmes.

Je connais la primitive d'un logarithme au carré. Mais en fait les courbes de richesses et de population n'ont aucune raison d'être synchronisées. En poussant un peu via un logiciel d'intégration je découvre qu'il faut utiliser une nouvelle fonction : le bilogarithme. Problème : le serveur ne la connaît pas. Je fais bien quelques essais d'approximation, mais je vous renvoie à la première section pour vous rappeler pourquoi c'est une mauvaise idée. ^^

Comment sortir de l'impasse ?

Ne pas utiliser ces logarithmes récalcitrants, et utiliser par exemple les fonctions linéaires.

Je sais que c'est un peu dommage de ne pas avoir de jolies courbes, mais au moins comme cela les résultats seront simples donc facilement implémentables et vérifiables. De plus, le serveur s'en sortira mieux à calculer des polynômes que des logarithmes, ce qui facilitera les mises à jour. Bref, techniquement c'est bien mieux, et au niveau gameplay cela n'est pas aussi dégénéré que les exponentielles.

Il ne faut pas être triste (oh oui, je la sens, votre tristesse Very Happy) car les fonctions linéaires ont un autre avantage : leur croissance est la même durant toute la période considérée. Ainsi il sera simple pour nous d'afficher le taux de croissance, en plus de la date à laquelle la population ou la richesse atteindront leurs seuils respectifs.

L'économie de Nova est basée sur les ressources. C'est un jeu de flux. Donc avoir des flux constants est simple, ce qui facilite notre travail et votre compréhension. Et à ce propos, je mettrai les formules finales dans les règles quand nous aurons fixé les valeurs pour les ressources.

Je vous tiendrai au courant. Smile


------------------------------------------------------------------------------------------------------------

[0] Comme ce qui nous avions fait avec le seigneuriage à Weymery, c'est dire si nous connaissons bien la situation. Very Happy

[1] Pour ceux qui se poseraient la question, notre politique sur l'exploitation de bug est simple : vous avez le droit de l'utiliser à condition de nous prévenir de son existence. Ainsi vous pourrez utiliser votre trouvaille le temps que nous corrigions le bug et contribuerez à améliorer le jeu. Par contre si vous l'utilisez sans nous l'avons signalé le jour où nous nous en apercevons vous perdez tout. Mais vraiment tout. Faut pas déconner. ^^

[2] Notez que je vous épargne toute la partie technique de la présentation, qui m'a pris à l'époque plusieurs semaines pour tout boucler et présenter quelque chose d'utilisable à notre codeur préféré. ^^'
avatar
Apeiron
Grand Inquisiteur de la Cohérence
Grand Inquisiteur de la Cohérence

Masculin Nombre de messages : 5471
Age : 29
Date d'inscription : 09/11/2008

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: [conception] La taxation

Message  Apeiron le Jeu 6 Mar - 15:32

Précédemment l'évolution se calculait selon l'état actuel et le seuil à atteindre. Mais maintenant que la courbe est linéaire l'évolution ne dépend plus que du seuil.

Plus précisément, pour une courbe y = ax (+b) on a a = (y1-y0)/(x1-x0). En prenant les valeurs extrêmes pop(0) = 0 et pop(T) = S où S est le seuil et T est le temps voulu pour  l'atteindre, on a : a = S/T.

En fait il ne s'agit que de la valeur absolue de l'évolution car si pop < seuil il faut une croissance, si pop = seuil il faut une stagnation et si pop > seuil il faut une décroissance.

Ainsi, pour la population :

Code:
if pop = seuil then
   lastUpd = newUpd
   exit
croiss = seuil/time
// où time = 2592000 secondes si on souhaite toujours 30 jours
if pop > seuil then
   croiss = - croiss
pop = pop + croiss*(newUpd - lastUpd)
lastUpd = newUpd
updPop = lastUpd + (seuil - pop)/croiss
// où updPop est la date où la pop atteindra la valeur de seuil
// donc est un candidat potentiel pour newUpd

Remarque que si on arrive à doubler le seuil alors on double le taux de croissance, ce qui peut être assez intuitif.

Si on fait travailler un peu le navigateur du joueur ça pourrait faciliter la lecture et l'immersion du joueur que la population apparaisse en milliards d'habitants pour le nombre de bonhommes utilisables, mais aussi apparaissent en habitants en précisant le flux. Par exemple si la population est croissante pour un seuil de 10 milliards alors à côté de la population par habitant serait affiché "+3858" qui représente l'augmentation de la population en habitants par seconde (10 milliards / 2592000).

C'est la même chose pour la richesse à ceci près qu'on souhaite un minimum à 1 (la fonction n'est plus linéaire mais affine). On a donc rich(0) = 1 et rich(T) = R. D'où croiss = (R-1)/T, et donc :

Code:
if rich = seuil then
   lastUpd = newUpd
   exit
croiss = (seuil-1)/time
if rich > seuil then
   croiss = - croiss
rich = rich + croiss*(newUpd - lastUpd)
lastUpd = newUpd
updRich = lastUpd + (seuil - rich)/croiss

(bien sûr ici c'est le seuil et la croissance pour la richesse et pas la population, je te laisse gérer tes noms de variables)

Passons maintenant à la taxation :

taxation(t) = tauxImp*pop(t)*rich(t)
où pop(t) = croissPop*t + pop(init)
et pop(t) = croissRich*t + rich(init)
avec croiss pouvant être positif, négatif ou nul selon le cas
donc :
Impôt[entre t = t0 et t1]
= Integ[de t = t0 à t1](tauxImp*(croissPop*t + pop(t0))*(croissRich*t + rich(t0)))
= tauxImp*croissPop*croissRich*Integ[de t = t0 à t1](t^2)
+ tauxImp*croissPop*rich(t0)*Integ[de t = t0 à t1](t)
+ tauxImp*pop(t0)*croissRich*Integ[de t = t0 à t1](t)
+ tauxImp*pop(t0)*rich(t0)*Integ[de t = t0 à t1](1)

où :
Integ[de t = t0 à t1](t^2) = (t^3 /3)[entre t = t0 et t1] = (t1^3 - t0^3)/3
Integ[de t = t0 à t1](t) = (t^2 /2)[entre t = t0 et t1] = (t1^2 - t0^2)/2
Integ[de t = t0 à t1](1) = (t)[entre t = t0 et t1] = t1 - t0

d'où :
Impôt[entre t = t0 et t1]
= tauxImp*croissPop*croissRich*(t1^3 - t0^3)/3
+ tauxImp*croissPop*rich(t0)*(t1^2 - t0^2)/2
+ tauxImp*pop(t0)*croissRich*(t1^2 - t0^2)/2
+ tauxImp*pop(t0)*rich(t0)*(t1 - t0)

Ce qui nous donne le code suivant :

Code:
if lastPop < seuilPop
   croissPop = seuilPop/time
if lastPop = seuilPop
   croissPop = 0
if lastPop > seuilPop
   croissPop = -seuilPop/time
if lastRich < seuilRich
   croissRich = (seuilRich-1)/time
if lastRich = seuilRich
   croissRich = 0
if lastRich > seuilRich
   croissRich = (1-seuilRich)/time
integ0 = newUpd - lastUpd
integ1 = (newUpd^2 - lastUpd^2)/2
integ2 = (newUpd^3 - lastUpd^3)/3
impot = lastPop*lastRich*integ0
impot = lastPop*croissRich*integ1 + impot
impot = croissPop*lastRich*integ1 + impot
impot = croissPop*croissRich*integ2 + impot
impot = tauxImp*impot

Et voilà qui règle enfin le problème posé par le calcul de la taxation. Smile

Note : vu comment j'ai conçu la population et la richesse il faut que les paramètres influençant sur eux donnent des modifications explicites des seuils correspondants. Ainsi, monter le taux d'imposition réduira le seuil de richesse et consommer des médicaments montera le seuil de population.

Edit : Il suffit d'écrire dans les règles par exemple "médicaments : population +50%" ou même "médicaments : population +2.5%*richesse" puisque le bonus est le même pour le seuil et le taux d'accroissement.
avatar
Apeiron
Grand Inquisiteur de la Cohérence
Grand Inquisiteur de la Cohérence

Masculin Nombre de messages : 5471
Age : 29
Date d'inscription : 09/11/2008

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: [conception] La taxation

Message  Contenu sponsorisé


Contenu sponsorisé


Revenir en haut Aller en bas

Voir le sujet précédent Voir le sujet suivant Revenir en haut

- Sujets similaires

 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum