HOME ARCHIVES LINKS MAIL BANNERS MAP
francais anglais
MUSIC - MAO
2D/3D CREATION
COMPUTER SCIENCES
DOWNLOADS




PC-INFOGAME.COM: Making-of: Coding

A database in the middle of project

Games videos manipulate a big quantity of data it would be only to load models, to manage the statistics of entities... It is therefore necessary to have recourse to databases to stock this information. The heart of Singularity is a database Access exported in form of text files with délimiteurs. There is not directly module to manage bases Access and SQL under Dark Basic Pro. Tables are therefore loaded in pictures which are then exploited in the programme.

To construct a database rigorously is not always easy. How to avoid redundancy at the farthest while keeping some unit in information? It is the challenge of the programmer... The database of Singularity is composed of 42 tables, what represents 270 fields! Let us see how is structured database:

NAME NUMBER FONTION
MEDIA 5 Resource management (3D, 2D, sounds).
DB 20 The fixed data of game represent. They are not changed in game. It is notably about statistics of entities, of weapon but also messages, texts, positions of interface...
INFORMATION 6 These tables stock the fluctuating data of game which vary according to the player (life, ammunition, state of game).
INIT 11 It is about load tables which configurent game only in every of the beginning of part. They make link between media and fixed data.


This strict cutting up of data has many advantages:
  • There is not confusion between resources and pure data.
  • Stable and fluctuating data are separated. So to safeguard a part returns to keep only the fluctuating tables (INFORMATION). to Publish a patch, it is only to update the fixed tables (DB) without risk of corrupting the profile of the player.
The relational diagramme of database is available below. The entirety of relations was not shown for more legibility.


Click on the picture to show it in full screen




Include database into the engine of Dark Basic Pro

The choice came on the export of database in form of text files. A simple macro in Access allows to update fast the files of game. But how to treat these data without requests SQL? First of all, every table is entirely loaded in a classical picture composed of structures (=types user). Here is for example, the transfer to the memory of the file concerning entities:

REM DEFINITION OF DATABASE: INFO_ENTITES 
REM----------------------------------------------- 

FUNCTION BASE_DE_DONNEES_INFO_ENTITES (Ligne$ ace G-string) 
  place IDEM, Life, ID_PROJECTILE, Ammunition ace integer 

  IDEM =Val (Extraction (Ligne$,1)) 
  Life =Val (Extraction (Ligne$,2)) 
  ID_PROJECTILE =VAL (Extraction (Ligne$,3)) 
  Ammunition =Val (Extraction (Ligne$,4)) 

  ARRAY INSERT AT BOTTOM BD_INFO_ENTITES () 
  BD_INFO_ENTITES ().ID=ID 
  BD_INFO_ENTITES ().Vie=Vie 
  BD_INFO_ENTITES ().ID_Projectile=ID_Projectile 
  BD_INFO_ENTITES ().Munitions=Munitions 
  BD_INFO_ENTITES ().Action = "" 
  BD_INFO_ENTITES ().Animation = "" 
  BD_INFO_ENTITES ().Delai=0 

EndFunction 


Once all tables are loaded, another problem settles. How to achieve a recording fast (line of the table) while there are several hundred of lines? A simple research loop would be too heavy to manage given the consequent number of information to harvest every other minute game. A pressure on the filling of tables was therefore fixed. Every recording is therefore identified (primary key) by a number pointing its indication out exactly in the corresponding picture. So if they want to know the life of the entity identified by the number 23, it is enough to position in the indication 23 of the picture of entities. It is therefore possible to qualify this maneuver of direct access. The navigation in database is rather easy now while knowing that the joint between tables was avoided at the farthest.



The organisation of project under Dark Basic Pro

Some rigour at the level of files, names, of the way to program is necessary to make easier service tasks. In very constant, possible measure is defined in a variable at the beginning of programme. This allows to change fast data in one and single place of code. Here is an extract of the used constants:

        Constants. Camera. Vitesse_Depl=10 
        Constants. Camera. Vitesse_Angle=0.3 
        Constants. Camera. Angle_X_Min=60 
        Constants. Camera. Angle_X_Max=300 
        Player. Camera. Active=true 

        Player. Miscellaneouses. Saut_Delai=1000 
        Player. Miscellaneouses. Saut_Hauteur=200 

        Constants. Portee. ObjAnim=500 
        Constants. Portee. Actions=600 
        Constants. Portee. Objets=500 

        Constants. Sounds. Portee=5000 
        Constants. Sounds. ID_MUSIQUE =-1 
        Constants. Sounds. Indice_Temp=1 

        Constantes.Entites.Delai_Suppression=10000 

        Systeme. Stopwatch. FPS_BASE=50 

        Systeme.Environnement.Champ_Vision_Pres=1 
        Systeme.Environnement.Champ_Vision_Loin=3000 
        Systeme.Environnement.Lumiere_Ambiante=60 

        Systeme.Environnement.Gravite_Physique_X=0 
        Systeme. Environment. Gravite_Entites=30 
        Systeme. Environment. Rayon_AI=80 

        Systeme. Keys. Avancer=200 
        Systeme. Keys. Reculer=208 
        Systeme. Keys. Gauche=203 
        Systeme. Keys. Droite=205 


Project was divided into thematic files containing each group of functions. The orientated coding objects not being possible, it was necessary to adopt a functional approach in modules. 28 thematic modules were created:

ACTIONS, HAVE, ANIMATIONS, AUDIO, BILLBOARDING, CAMERA,  
CHAINS, LOAD, COLLISIONS, STATEMENT, DIALOGUE,  
MISCELLANEOUSES, SCREEN, ENTITES_AI, EVENTS, CAST IRON, CORRELATIONS,  
LISTBOX, MATHS, OBJECTS, OBJETS_ANIMES, PERIPHERALS, PHYSICAL APPEARANCE,  
PROJECTILES, SCRIPTS, SOURCE, SPRITES, SYSTEM 


Alone SCRIPTS module is entirely dependent on game since it takes care of the scénaristique holding of game. Other modules were create and tested séparemment. They are entirely réutilisables and their update is very easy. Here is for example an extract of the module linked to mathematics.

REM OUTDISTANCES BETWEEN TWO POINTS 
REM-------------------------- 

FUNCTION MATH_DISTANCE_2_POINTS (X1#, Y1#, Z1#, X2#, Y2#, Z2# float ace, Dimension ace integer) 
  place X#, Y#, Z#, Distance# float ace 

  Yew tree Dimension=3 
   vecteur=make vector3 (1) 
   X#=X1#-X2# 
   Y#=Y1#-Y2# 
   Z#=Z1#-Z2# 
   jeu vector3 1,X#,Y#,Z# 
   Distance#=length VECTOR3 (1) 
  EndIf 

  Yew tree Dimension=2 
   vecteur=make vector2 (1) 
   X#=X1#-X2# 
   Z#=Z1#-Z2# 
   jeu vector2 1,X#,Z# 
   Distance#=length VECTOR2 (1) 
  EndIf 

EndFunction Distance# 




The main loop of game

In a game, an "infinite" main loop manages permanently the holding of the part. The more length of execution of this one is quick, the more game is fluid. The optimisation of treatments performed am therefore primordial in a game. Here is the contents of the main loop of Singularity. To note that only calls of functions of update of every module is performed. Treatments under the same theme are so regrouped.

Do 
       SYSTEME_TEMPS_MAJ () 

       ACTIONS_CLAVIER () 
       ACTIONS_SOURIS () 

       OBJETS_ANIMES_MAJ () 

       SCRIPTS_TRIGGERS () 
       TRIGGERS_MAJ () 
       
       RunCollisionPRO () `COLLISIONS 

       PERIPHERIQUES_MAJ () 
       CAMERA_MAJ () `CAMERA 

       COLLISIONS_MAJ () 
       PROJECTILES_MAJ () 
       ENTITES_AI_MAJ () 

       ECRAN_INTERFACE () 
       ECRAN_INFORMATIONS () 

       AUDIO_MAJ () `AUDIO 
       BILLBOARDS_MAJ () 
       ANIMATIONS_MAJ () 

       HAVE update `IA 
       phy update `PHYSIQUE 

       SCRIPTS_SHADER_RENDU () 
       sync `RENDU 

Loop 




The collision system

A good management of collisions is primordial in a game there 3D of type FPS. I turned to the use of a plugin NuclearGloryCollision for time saving in a domain which I did not control. This tool allows to manage easily collisions of two types:
  • Ellipsoid: the model 3D is roughly represented by one ellipsoid. Collisions are so easier to calculate because the model has no complex form. Nevertheless precision is collisions am of course lesser. This was used for all entities including the hero and projectiles.
  • Mesh (mesh size): the precise form of the object is taken into account. It is about a collision detection in the polygon near. This is much more gourmand than simple one ellipsoid but precision is augmented. This mode of collision for the decor is generally reserved.
To differentiate the different elements entered in the engine, different types of groups were defined, each able to intéragir the one with other one:

TYPE_DECOR       
TYPE_OBJANIM     
TYPE_ENTITE      
TYPE_JOUEUR      
TYPE_ACTION      
TYPE_ARME        
TYPE_OBJET       
TYPE_PROJECTILE  
TYPE_PHYSIQUE    
TYPE_BILLBOARD   


The collision of projectiles is real what means that an impact takes place when the projectile and its target got into contact. It is not about a collision calculated by the method of "Raycasting" which consists in simulating a collision between a starting point and arriving point at given instant.



The physical engine

The management of physics is entirely assured by the plugin DarkPhysics. It is about a collision engine richer than precedent. He allows to manage forms of collision more adapted (cube, sphere, ground, mesh size). To avoid blocking memory with objects already in the collision NuclearGlory plugin, alone decor and objects says "physical" are loaded.

A problem settles when in the simultaneous functioning of the physical engine and of the collision system. How the projectiles of weapon belonging only to the collision system will be able to intéragir and move the physical objects? During a collision between a projectile and one object, a force to this object is manually applied. The engine undertakes then to manage corresponding displacements. Here is routine made responsible for making announce two plugins. They recover at first the co-ordinates of collisions with which they form a vector representing the trajectory of the projectile. After normalisation, it is possible to calculate force to be applied to every axle to reflect impact.

ID_COLLISION=COLLISIONHITOBJPRO (IDEM, Index_Collision) 
Collision=CollisionHitTypePro (IDEM, Index_Collision) 

Collision_X#=CollisionHitPointPro (IDEM, Index_Collision, 1) 
Collision_Y#=CollisionHitPointPro (IDEM, Index_Collision, 2) 
Collision_Z#=CollisionHitPointPro (IDEM, Index_Collision, 3) 

Pos_X#=CollisionHitPosPro (IDEM, Index_Collision, 1) 
Pos_Y#=CollisionHitPosPro (IDEM, Index_Collision, 2) 
Pos_Z#=CollisionHitPosPro (IDEM, Index_Collision, 3) 

Yew tree Collision=TYPE_PHYSIQUE 

   Force_Physique#=BD_Projectiles (Index).Force_Physique 
   temp = make vector3 (1) 
   jeu vector3 1,Collision_X#-Source_X#,Collision_Y#-Source_Y#, Collision_Z#-Source_Z# 
   normalise vector3 1,1 
   
   phy add rigid body forces ID_COLLISION, x vector3 (1) *Force_Physique#,y vector3 (1) *Force_Physique#, 
                                       z vector3 (1) *Force_Physique#, Collision_X#, Collision_Y#, Collision_Z#,1 
EndIf 


Physical appearance




Artificial intelligence

A plugin new, Dark HAVE, was used to make easier the installation of an artificial intelligence. A good IA is entirely based on an efficient pathfinding (=recherche of the shortest way between two points). The plugin uses algorithm A* to calculate a trajectory. His strong point is the way it determines the outlines of the decor and the passage points. Indeed, he calculates collisions between the decor and a horizontal plan to generate borders of level and waypoints. Then the whole panoply of actions can be developed (actions defined for entities, attitudes and behaviours). The weakness of the plugin is however based on the single management of environment in two dimensions. To define several floors or levels, it is necessary to point out manually in what game plan is necessary be entity (of container system).



The billboarding or the simulation of the 3D with the 2D

The method of the billboarding is still very fluently used in games videos (Command And Conquer 3 for example). It consists in showing an element there 2D which is always orientated towards the camera. An effect of volume is so simulated since the object swivels at the same time as the camera. It is so less fond of good food to manage a texture enlivened there 2D as its equivalent there 3D. Phantasm is however less strong when they are too much near the object in question. That is why they reserve that this technology generally for the distant elements which do not need a model in high resolution (trees in the distance). Explosions of projectiles, fire are very often simulated by the method of the billboarding.

Let us see his installation under Dark Basic Pro. There are 4 fundamental stages:
  • Creation of an even (=objet 3D without thickness)
  • Application of a texture with effect of transparency (Ghost)
  • Direction of the even towards the camera
  • Animation of texture if necessary
To note that the direction of the object towards the camera is facultative if they want to simulate stagnant objects (rain, not).

  `Création 
	even make object ID_OBJET, Breadth, Height 
	object ID_OBJET position, Pos_X#, Pos_Y#, Pos_Z# 
	rotate object ID_OBJET, Angle_X#, Angle_Y#, Angle_Z# 
	ID_OBJET, 0 are ghost object 
  
  `Boucle main 
        object ID_OBJET, ID_IMAGE texture 
	OBJECT ID_OBJET, Camera. Pos_X, object position Y (ID_Objet), Player. Camera. Pos_Z 


Billboarding




Sounds in an environment there 3D

To augment the realism of a game, sound effects have a primordial role. So that the immersion is complete, the volume of sounds and the sharing out on surrounding walls is entirely defined. Under Dark Basic Pro, the volume of the sound is determined according to a report between the position of the player and that of the sound. A so calculated percentage points out the volume of the sound.

FUNCTION AUDIO_SON_VOLUME (ID_Son ace integer, X#, Z# ace float) 
  place Volume_Min, Volume_Max ace integer 
  place Distance#, Result# float ace 

  Distance#=MATH_Distance_2_points (Player. Camera. Pos_X,-1, Player. Camera. Pos_Z, X#,-1, Z#,2) 

  Yew tree Distance#<=Constantes.Sons.Portee 
    Volume_Min=BD_Sons (ID_Son).Volume_Min 
    Volume_Max=BD_Sons (ID_Son).Volume_Max 

    Result#=1 - (Distance#/Constantes.Sons.Portee) 
    Result#=Result#* (Volume_Max-Volume_Min) +Volume_Min 
  Else 
    Result#=0 
  EndIf 

EndFunction Result# 


The calculation of the section, that is to say the sharing out of the sound on the left or right surrounding wall is more complex. Indeed, it is above all a question of determining if the sound was launched to the left or the right of the player. For it a calculation trigonométrique allows to determine the angle between the sound and the player. A report in form of percentage is then calculated to divide the sound on every surrounding wall.

FUNCTION MATH_ANGLEY (X#, Z# ace float) 
  place Angle# float ace 

  Yew tree X#>Joueur.Camera.Pos_X and Z#>Joueur.Camera.Pos_Z then  
		Angle#=abs (atan ((X#-Joueur.Camera.Pos_X) / (Z#-Joueur.Camera.Pos_Z)))  
  Yew tree X#>Joueur.Camera.Pos_X and Z#<Joueur.Camera.Pos_Z then 
		Angle#=abs (atan ((Z#-Joueur.Camera.Pos_Z) / (X#-Joueur.Camera.Pos_X))) +90   
  Yew tree X#<Joueur.Camera.Pos_X and Z#<Joueur.Camera.Pos_Z then  
		Angle#=abs (atan ((X#-Joueur.Camera.Pos_X) / (Z#-Joueur.Camera.Pos_Z))) +180 
  Yew tree X#<Joueur.Camera.Pos_X and Z#>Joueur.Camera.Pos_Z then  
		Angle#=abs (atan ((Z#-Joueur.Camera.Pos_Z) / (X#-Joueur.Camera.Pos_X))) +270 

  Angle#=wrapvalue (Angle#-Joueur.Camera.Angle_Y) 

EndFunction Angle# 

FUNCTION AUDIO_SON_PAN (X#, Z# ace float) 
  place temp#, Result#, Angle# float ace 

  Angle#=MATH_AngleY (X#, Z#) 

  `Enceinte left 
  Yew tree Angle#<=360 and Angle#>=180 
    temp#=abs (Angle#-270) 
    Result#= (temp#/90)-1 
  Else 
  `Enceinte right 
    temp#=abs (Angle#-90) 
    Result#= (90-temp#)/90 
  EndIf 

EndFunction Result# 


With Dark Basic Pro, it is impossible to load new resources dynamically. The not being available multi-threading. In the case of sounds, this means that it is necessary to load beforehand a number predefined by sound effects. In other words, it is necessary to load for example 5 noise of shooting of gun. But how make when more than 5 entities pull at the same time? Smartness has consist in maintaining that major sound differentiation between 5, 6 or 7 simultaneous sounds would not be made. As soon as the maximum sound number is attained and as soon as a new individual launches a new sound, that having the weakest volume is stopped to be to redeploy in the new individual. A weaker sound is therefore replaced with a stronger sound, the phantasm of the number is therefore improved!



The speed of execution of game - Timer Based Movement

To throw a game consists in carrying out always an "infinite" main loop which performs all treatments. The speed of execution of this loop depends entirely on the computer which carries it out (=sa shape). In other words, on a powerful computer the loop will comply more quickly than on a normal computer. This poses a major problem: that of the speed of game in full part. The character of will move more quickly, animations will be speeded up in short, it is necessary to set up a mechanism harmonising the speed of execution on all machines. The number of loops carried out a second is what is fluently called FPS: the number of frames per second.

Smartness consists in calculating an acceleration or slowing down coefficient to compensate for the speed of movements in game. Indeed, on a normal computer, coefficient will be 100 %. On a twice as quick PC, coefficient will be only 50 % to reduce by half the speed of movements. This coefficient is determined according to the length of execution of a main loop. It is applied as well to the movements of entities, of camera as to animations. This method has however tendency to cause starts when the number of frames per second is very low since the compensation of movement is very important.

FUNCTION SYSTEME_TEMPS_MAJ () 

     Systeme. Stopwatch. Temps=Timer () 
     Systeme.Chrono.Coefficient=Systeme.Chrono.FPS_Base* 
	                            (Systeme.Chrono.Temps-Systeme.Chrono.Temps_Precedent)/1000.0 
     Systeme.Chrono.Temps_Precedent=Systeme.Chrono.Temps 

     `Formule: 
     ` FPS_REEL = (Temps_Actuel-Temps_Precedent) / 1000.0 
     ` Coef = FPS_BASE / FPS_REEL 
     ` ==> Coef = [FPS_BASE * (Temps_Actuel-Temps_Precedent)] / 1000.0 

EndFunction 




Interface and management of resolutions

The management of a game interface is more complex than he parried there. Indeed, main preoccupation is born when it is a question of developing a game can imports the resolution of the screen. How to position elements? How to adapt their dimensions?

In Singularity, the positioning of elements is relating. This means that he is calculated according to the size of the screen, of the position of another element or by an absolute value according to following expression:

POSITION (calculated in the load) = % SCREEN [+/-BREADTH Of AN ELEMENT] [+/-VALUE FIXED]

In that way he resolution and even am very easy to position an object about is to write the text in a graphic zone envisaged with this effect. The management of the size of pictures was not envisaged because it was not necessary for this stadium. Different resolutions interfaces would have been able to be used rather than of agrossir or reduce elements.

The player must also intéragir with interface. A button remains a simple graphic element which has no properties which it would be possible to know it during the creation of a software. He is not our responsibility to implement his behaviour. To simulate different states (not clicked), enlivened sprites was used. Passage from a frame to the other one taking place in every click or support.

Main difficulty was to identify a click apparently. Indeed, during the same click, Dark Basic Pro launches event in regular interval "click ". It is therefore impossible to know precisely when starts or ends the click. An individual function was therefore necessary:

FUNCTION PERIPHERIQUES_MAJ_SOURIS () 
  `Systeme. Mouse. Clic_Actuel <= return the uninterrupted click 
  `Systeme. Mouse. Clic_Unique <= return an unique click 

  Systeme.Souris.Clic_Precedent=Systeme.Souris.Clic_Actuel 
  Systeme. Mouse. Clic_Actuel=MouseClick () 

  Systeme. Mouse. Clic_Unique=0 
  Yew tree Systeme. Mouse. Clic_Actuel <> 0 and Systeme.Souris.Clic_Actuel<>Systeme.Souris.Clic_Precedent 
    Systeme.Souris.Clic_Unique=Systeme.Souris.Clic_Actuel 
  EndIf 

EndFunction 

- COPYRIGHT 2008/2009 - ALL RIGHTS RESERVED - WEBMASTER : UDUN (GIRARD CYRIL) - DESIGN PAR : ANTYOZ