• 17 Mai 2024, 00:13:27


Auteur Sujet: [TUTO] Conseils concernant le codage SA-MP [niveau: moyen - avancé]  (Lu 8354 fois)

0 Membres et 1 Invité sur ce sujet

Hors ligne S!m

  • *
  • Messages: 2341
    • Voir le profil
Trucs de scripting

Table des matières
Présentation

1 - Normes de programmations

2 - Utilisation des directives de précompilations
   2.1 - Les define
   2.2 - Les if
   2.3 - Les pragma

3 - Arrangement des variables
   3.1 - Qu'es-ce qu'une variable?
   3.2 - Déclaration correcte de variable
   3.3 - Utilisation d'enum
   3.4 - Local ou global?

4 - La validations de fonctions
   4.1 - Vérifier l'effectivité d'une fonction
   4.2 - Vérifier la vitesse d'exécution
   4.3 - Vérifier les possibilités gérées

5 - Les fonctionnalités du langage
   5.1 - Les state

6 - Conseils généraux
   6.1 - L'utilisation du pseudo-code

7 - Conclusion

Présentation

J'ai cru remarqué que bien des gens utilisent certaines "fonctionnalités" à tord et à travers, de façon pas très pratique ou les ignorent carrément. Notez bien que ceci n'est qu'une ébauche, ce post sera modifié selon ce qui est demandé et intéresse les gens, d'ailleurs, merci de passer vos commentaires suggestions afin de rendre ce tuto plus pertinent et complet.

1 - Normes de programmation

Certaines normes existent en programmation, ceci est valable pour TOUS les langages de programmations.
Je vais en présenter quelques une, mais il en existe une multitude d'autres:

#1 - Les constantes sont en MAJUSCULES
#2 - Les variables sont en minuscules, et débutent avec une majuscules.
#3 - Dans les noms de variables et de fonctions, les différents mots sont séparés par l'underscore ("_") ou débutent avec une minuscule.
#4 - Les variables globales débutent par un g.
#5 - Les accents ne sont pas acceptés (pas une norme, mais tout se fait en anglais et les compilateurs ne prennent pas les accents, pour la plupart)

Exemple:
#define CARACTERE_INCONNU    (43)
new gVariableGlobale;

forward maFonction();
forward autre_fonction(text[]);

main()
{
    new variable_locale;
    new héhé;//erreur!
    new trucBizarre;
}

2 - Utilisation des directives de précompilations

Les directives de précompilation sont les expressions généralement précédées par le caractère '#'.
Il s'agit de directives s'adressant au compilateur (le programme qui traduit le code pour qu'il soit compréhensible par la machine).
Ces directives peuvent servir à donner des précisions, annuler des bouts de code, modifier les paramètre de compilation (stack alloué lors de l'exécution par exemple), etc.

2.1 - Les defines

La directive #define est probablement la directive la plus utile. Sa structure est la suivante:

#define EXPRESSION VALEUR
Le terme valeur n'est pas le meilleur terme, un terme plus approprié serait EXPRESSION_RÉSULTANTE.
Il faut bien comprendre que lorsque le compilateur rencontre cette directive, il remplacera EXPRESSION par VALEUR partout dans le code suivant la directive (à moins d'ordre contraire, la directive #undef EXPRESSION permet de stopper la directive #define correspondante).
Simplement en sachant ceci, je suis certains que vous pouvez identifier de multiples usages de cette directive.

Normalement, EXPRESSION est considéré comme une constante, on se doit donc de l'écrire en majuscules.

#define SALUT_CA_VA
#define TRUC_PEU_UTILE
#define COULEUR_INUTILE 0xF1054

En voici quelques un avec un petit exemple:

Création de fonctions (macro):

Je sais que je viens de dire de toujours utiliser des majuscules, mais comme il s'agit d'une technique afin de discerner les defines, les fonctions de defines n'entrent que partiellement dans cette catégorie (d'ailleurs POINT_TO_POINT c'est laid et peu pratique).

Fonctions de calcul de distance:
#define PointToPoint(%0,%1,%2,%3,%4,%5,%6) ((%0 - %3) * (%0 - %3) + (%1 - %4) * (%1 - %4) + (%2 - %5) * (%2 - %5) <= (%6 * %6))
#define GetDistance(%0,%1,%2,%3,%4,%5) floatsqroot((%0 - %3) * (%0 - %3) + (%1 - %4) * (%1 - %4) + (%2 - %5) * (%2 - %5))

Fonctions simplifiant l'envoi de message:
#define MsgBlanc(%0,%1) SendClientMessage(%0, 0xFFFFFFFF, %1)
#define TypoMsg(%0,%1) MsgBlanc(%0, "FORMULATION: " #%1)
#define MsgBlancFormat(%0,%1,%2)\
    {\
        new msg_tmp[128];\
        format(msg_tmp, sizeof(msg_tmp), %1, %2);\
        MsgBlanc(%0, msg_tmp);\
    }
#define Kill(%0) SetPlayerHealth(%0, 0.0)

Qui se traduisent comme suit (pour mettre dans un include par exemple):
forward PointToPoint(Float:X1, Float:Y1, Float:Z1, Float:X2, Float:Y2, Float:Z2, Float:Distance);
forward Float:GetDistancet(Float:X1, Float:Y1, Float:Z1, Float:X2, Float:Y2, Float:Z2);
forward MsgBlanc(playerid, text[]);
forward TypoMsg(playerid, commande[]);
forward MsgBlancFormat(playerid, text[], _:liste..);
forward Kill(playerid);

Pour ceux qui n'ont pas identifié les fonctions:
»La première permet de savoir si deux points sont à une distance inférieure ou égale au paramètre distance.
»La seconde retourne en nombre à virgule la distance entre deux points.
»La troisième permet de raccourci un SendClientMessage et le mettre blanc
»...

PS. la première est plus rapide que la seconde car elle ne comporte aucun appel à une fonction qui est nécessairement plus lente que de simples multiplications de variables, de plus une racine carrée est nécessairement complexe.

Définition de constantes

Par ailleurs, une autre fonction des defines est de rendre les valeurs redondantes plus lisible et simple à modifier:

Par exemple, disons que vous désirez utiliser la couleur rouge : 0xFF0000FF
utilisée une fois ça va, mais disons que l'on retrouve partout dans votre code une telle chose:

SendClientMessage(playerid, 0xFF0000FF, "Salut");La couleur en question n'est pas simple à voir, l'utilisation d'un define est recommandée.

La définition de constante, bien que très simple, comporte quelques subtilités.

[!]Ne pas oublier la règle des majuscules dans ce cas-ci.

Exemples:

#define COLOR_BLUE (0x00FF00FF)
#define COLOR_GREEN (0x0000FFFF)
#define COLOR_RED (0xFF0000FF)
#define COULEUR_JAUNE 0xFFFF00AA

Notez bien que les parenthèses sont optionnelles, le define peut se faire en français ou en anglais (ou une autre langue) au choix.

2.2 - Les #if

Les #if peuvent d'avérés particulièrement utiles dans les gros scripts.
Ils permettent de faire des test avant même la compilation du script.

Un exemple simple que tous connaissent est le #if defined FILTERSCRIPT au début du new.pwn
Il permettait d'activer/désactiver une section du script simplement en modifiant un #define en haut du script.

Ce genre d'application est le plus fréquent.
Toutefois, il est possible de les utiliser avec des valeurs (qui doivent être constantes).

Par exemple, au début du streamer Y_OBJECTS on peut voir:

#if !defined OBJECT_SECTOR_SIZE
#if OBJECT_DISTRIBUTION <= 10
#define OBJECT_SECTOR_SIZE (1)
#endif
#endif

#if !defined OBJECT_SECTOR_SIZE
#if OBJECT_DISTRIBUTION <= 100
#define OBJECT_SECTOR_SIZE (5)
#endif
#endif

#if !defined OBJECT_SECTOR_SIZE
#if OBJECT_DISTRIBUTION <= 1000
#define OBJECT_SECTOR_SIZE (10)
#endif
#endif
La taille des secteurs dépend de la valeur de OBJECT_DISTRIBUTION (qui est définie plus tôt dans le script à l'aide de define).

Je n'irai pas plus en détail dans cette partie puisque peu de gens utilisent vraiment...
Si jamais vous avez besoin de détails, posez vos questions à la suite du topic.

2.3 - Les #pragma

Pour la plupart, les gens ne comprennent pas ce que font les différentes directives des pragma, nous allons donc les aborder une à une.

#pragma dynamic:

Cette directive permet d'augmenter le stack (mémoire locale) accessible au script. Faire bien attention avec celle si si vous allouez trop de stack à vos fs vous pourriez atteindre la limite (et oui il y en a une, il y a toujours une limite, mais peu probable que vous l'atteignez).

Vous utilisez trop de variables locales lorsque vous obtenez un avertissement de mémoire, comme ceci:

Citation de: PAWN Compiler Output
Pawn compiler 3.2.3664           Copyright (c) 1997-2006, ITB CompuPhase

Header size: 1592 bytes
Code size: 63816 bytes
Data size: 119508 bytes
Stack/heap size: 16384 bytes; estimated max. usage=4108 cells (16432 bytes)
Total requirements: 201300 bytes

Vous avez alors trois options:

 - réduire vos variable (mieux)
 - passer vos variables en global
 - utiliser un #pragma dynamic

Réduire les variables est malheureusement une option partielle (parfois ne s'applique pas), mais surtout compliquée, les gens n'aiment pas ça....
Passer les variables en global est une technique très simple qui est toutefois relativement peu utilisée à cause des conflits de noms de variable possiblement générés.
Utiliser un pragma dynamic semble être une technique très prisé. De plus, le message d'erreur nous indique déjà combien de mémoire est nécessaire à la bonne exécution du programme (selon la mesure du compilo).
Dans ce cas-ci, un #pragma dynamic 210000 est parfait (il est recommandé de mettre un peu plus que la valeur indiqué par le compilo).

#pragma unused

La directive unused permet d'enlever un avertissement disant qu'une expression est inutilisée, ceci peut arriver avec des variables, des fonctions ou des paramètres.
Cette directive ne devrait être utilisée que dans un seul cas: une fonction dont un paramètre est inutilisé.

Pour les variables et les fonctions, s'il y a possibilité de les utiliser ou non selon par exemple un define, vous devriez savoir que vous pouvez les déclaré en stock ce qui annule leur compilation dans ce cas.

#pragma tabsize

Cette directive permet de modifier la taille du TAB, attention, elle ne s'adresse qu'au compilateur. Utiliser un tabsize de 0 permet d'éliminer les avertissements concernant l'indentation, ce n'est toutefois pas recommandé car les scripts mal indentés peuvent aisément devenir illisibles.

J'en profite pour le répéter: L'INDENTATION EST TRÈS IMPORTANTE! ELLE FAIT TOUTE LA DIFFÉRENCE ENTRE UN SCRIPT FACILE À CORRIGER ET PRESQUE IMPOSSIBLE À CORRIGER.

Notez qu'il existe bien d'autres directives #pragma, la plupart sont toutefois inutiles je ne les ai donc pas abordés

3 - Les variables

3.1 - Qu'es-ce qu'une variable?

Une variable, c'est simplement un espace dans la mémoire qui sert à retenir une information.
En PAWN, toutes les variables sont semblables. Elles font toutes 32 bits (ou 4 octets) et ne sont que faiblement typées.
Bref, vous voulez réutiliser une information plus tard? Stockez-la dans une variable!

Les variables se séparent en deux catégories en PAWN:

 - les variables locales
 - les variables globales (ou static, qui pourrait être une 3e catégorie)

Les variables Locales:

Les variables locales demeurent généralement seulement un court instant dans la mémoire de la machine, elles sont stockées sur le stack. Il faut faire attention à la mémoire utilisée par les variables locales, si jamais elles représentent trop de mémoire, le compilateur vous avertira d'un usage excessif de la mémoire par ce message donc j'ai parlé précédemment dans la partie sur la directive #pragma dynamic.

Toutefois, il faut faire attention avec les fonction récursives. Puisque la fonction s’appelle elle-même, à chaque appel elle recrée les variables ce qui risque d'entrainer un dépassement de la mémoire allouée.
Or, ce genre de dépassement est difficilement détectable pour le compilateur.
Il ne peut vous indiquer une quantité de mémoire utilisé puisqu'il ne peut savoir combien de fois la fonction sera appelée.
Ces fonctions sont très pratiques pour résoudre certains problèmes, toutefois il ne faut pas en abuser.

Les variables globales:

Ces variables peuvent être aussi nombreuses que désiré (jusqu'à une certaine limite déterminée par la machine bien sûr). D'ailleurs vous pourrez remarquez en compilant un script comprenant une grande variable locale qu'elle est directement présente dans le fichier .amx. Ceci permet l'initialisation de la variable, c'est à dire lui attribuer une valeur de départ. Dans le cas bien particulier de l'initialisation dans l'en-tête du script, la valeur de départ est présente dès l'allocation de la mémoire à la variable, contrairement à l'initialisation dans une fonction.

Les static:

La directive static permet de créer une variable qui n'est ni globale ni locale.

Si la variable est déclaré comme une variable globale, elle sera accessible dans toute la section de code correspondante.
Par exemple, une variable static déclarée dans une bibliothèque(include) est accessible partout dans la bibliothèque mais n'est pas accessible dans le script qui utilise la bibliothèque en question.

Si la variable est déclaré comme une variable locale, elle sera accessible de la même façon qu'une variable locale normale, mais elle ne sera pas effacée de la mémoire à chaque appel et sa valeur précédente ne sera donc pas perdue.

3.2 - Déclaration de variables:

Pour déclarer une nouvelle variable, un seul mot clé est nécessaire: new
Le nom de la variable (l'expression qui suit new) doit être non-utilisée par le langage lui-même, par exemple on ne peut utiliser state comme nom de variable.

[!] N'oubliez pas la norme: une variable commence toujours par une minuscule. De plus, on ajoute g au début des variables globales.

Exemple:

new gJoueursConnectes[MAX_PLAYERS];//crée un tableau pour savoir si les joueurs sont connectés
new gCompteDeJoueurs;
new Float:gValeurQuelconque = 234.231;

3.3 - Utilisation d'enum:

Les enum peuvent être utilisés de plusieurs façons, dans certains cas il peuvent remplacer des defines (comme pour des teams) de la façon suivante:

enum
{
NO_TEAM,
TEAM_1,
TEAM_2,
TEAM_3,
...
}
PS. il n'existe aucune norme de majuscule ou autre dans les enum, il faut toutefois s'arranger pour éviter les conflits de noms.

L'avantage des enum dans les variables est très simple, ils permettent de faire un tableau dont les différentes colonnes/rangées ne sont pas de même types/taille.
Par exemple, dans un même tableau il est possible de retrouver des entiers, des nombres à virgules, des mots...
Toutefois, pour pouvoir utiliser un enum dans une fonction/variable, il faut le nommer, voici un exemple de variable utilisant un enum:

enum enum_stats
{
Float:Pos_X,
Float:Pos_Y,
Float:Pos_Z,
  player_name[MAX_PLAYER_NAME],
  kills,
  death
}
new gPlayerStats[MAX_PLAYERS][enum_stats]

Nous pouvons ensuite utiliser cette variable comme suit:
GetPlayerPos(playerid, gPlayerStats[playerid][Pos_X], gPlayerStats[playerid][Pos_Y], gPlayerStats[playerid][Pos_Z]);
GetPlayerName(playerid, gPlayerStats[playerid][player_name], MAX_PLAYER_NAME);

3.4 - Local ou global?

Cette partie est sans doute la plus simple, il faut toutefois faire une nuance. Il existe des situations où il est préférable d'utiliser des variables globales, d'autres locales.
Personnellement, je tente de limiter le plus possible l'utilisation de variables globales pour des usages locaux. Un bon exemple est le ystring dans le script de course yrace. il faut éviter ce genre de choses car il serait possible que la variable soit utilisées par deux bouts de code en même temps (même si très peu probable et le tout dépend de la façon que vous l'utilisez)).
Lorsque vous n'avez pas besoin de conserver la valeur d'une variable hors de la fonction (excluant les appels à d'autres fonctions par la fonction elle-même), la variable devrait être locale.
Les variables qui peuvent être utilisés à plusieurs endroits dans le scripts n'étant pas nécessairement directement liés (par des appels entre-eux disons) devraient être globales. il faut noter que l'on marque généralement les variable globale en utilisant la lettre g devant elles (g pour global).

Comment savoir si une variable est locale ou globale?

C'est très simple, les variables déclarées hors de tout bloc d'instruction (par exemple en haut complètement du script) sont globales. Celle qui sont déclarées dans des blocs d'instructions (fonctions, callback etc..) sont généralement locales.

Bref,
globales : en-tête (hors de tout bloc d'instruction)
locales : variables déclarées dans des blocs d'instructions

petit exemple:
new test;//cette variable est globale car elle est de niveau 0 (hors de toute fonction)
public OnPlayerCommandText(playerid, cmdtext[])
{
new test2 = 12;//cette variable est locale car déclarée dans la fonction, elle n'est valide que dans le bloc d'instruction (entre les {})
//la variable test est toujours valable
if(strcmp("text", cmdtext[1], true, 4) == 0)
{
//les deux variables sont valides
GameTextForAll(cmdtext[6], 4000, 5);
return 1;
}
return 0;
}

4 - La validation de fonctions

J’entends par validation la vérification d'une fonction, s'assurer qu'elle est relativement efficace et pourra gérer la plupart, voir tous les cas possibles.

4.1 - Vérifier l'effectivité d'une fonction

J'entends ici de vérifier le fonctionnement d'une fonction, si tout se déroule normalement.

Il n'y a pas de technique magique, il faut marquer les différentes parties des fonctions.
Pour marquer, une seule fonction suffit, printf.
À chaque action, il faut pouvoir savoir si elle est réussie ou non.
Donc un print avant et après.
Bien sûr, certaines actions ne sont pas à risque de rater comme un simple SendClientMessage.
Si des variables sont modifiées, il est recommandé d'en faire un print avant et après le moindre changement.

[!] Si votre fonction ne rencontre pas de problème à l'exécution et donne le bon résultat, ceci n'est pas nécessaire.

Un petit exemple?
En voici un très simple:
IsMoto(vehicleid)
{
new model = GetVehicleModel(vehicleid);
printf("model vehicle: %d", model);
switch(model)
{
case 448,461,462,463,468,471/*(quad)*/,481,509,510,521,522,523,581,586:
{
model = 1;
}

default:
{
model = 0;
}
}
printf("IsMoto: %d", model);
return model;
}
Donc en regardant le log il est assez aisé de savoir si la fonction fonctionne correctement. Vous y verrez le modèle du véhicule suivit de la valeur de retour.

4.2 - Vérifier le temps d'exécution d'une fonction

Toujours pas de technique magique. Toutefois, il faut faire une distinction.
Le but est de déterminer la rapidité d'exécution d'une fonction et de l'améliorer, mais pour se faire il faut faire un benchmark.

Il existe tout plein de petites defines déjà faites pour le faire.
Syg en avait donnée une très intéressante dans le topic des scripts utiles: Benchmark macro

Sinon vous pouvez faire votre test par vous même, il suffit d'exécuter la fonction à répétition sur un serveur et de mesurer le temps nécessaire à son exécution.
PS. il est préférable de faire les test sur un serveur vide (aucun script chargé autre que le test)

4.3 - Vérifier les valeurs prises en charge

Encore une fois, il n'y a pas de technique magique.
Je vais toutefois ressortir certains terme que l'on voit en calcul différentiel/intégral.
La meilleur technique afin de vérifier une telle chose est de simplement vérifier les valeurs critiques.

Par exemple, sur une fonction GetVehicleModelName(modelid) il ne sert absolument à rien de vérifier tous les véhicules. Par contre, il pourrait être intéressant de regarder les valeurs -1, 0, 1, 399, 400, 611, et 612.
Pourquoi?

-1 : une valeur négative
0 : il s'agit d'une valeur particulière que je recommande de toujours testé, elle est unique.
1 : +/- utile mais simplement au cas où
399 et 400 : vérifier le début du fonctionnement de la fonction, qu'elle commence bien à 400
611 et 612 : comme 399 et 400 mais pour la fin.
Il serait aussi possible d'ajouter une autre valeur plus grande pour être certains qu'elle le gère

Comment déterminer ses valeurs critiques?

Il s'agit simplement de déterminer qu'elles sont les valeurs pour lesquelles la fonction agit différemment.
Pour faire référence au calcul différentiel, il s'agit des "points d'inflexions" de la fonction.

Par exemple, pour un switch chaque case représente une exécution différente, il faudrait donc vérifier chacun d'entre-eux en plus d'une valeur extérieure (sauf dans le cas de présence d'un default qui est cette valeur autre).

Si l'on revient au cas de la fonction GetVehicleModelName(modelid), il est évident qu'il faut vérifier 399, 400, 611 et612 puisque ce sont les valeurs de fin et de début de la plage de modèles.
Il faut noter aussi qu'il existe deux méthodes afin de voir ces valeurs à vérifier. Par le code de la fonction elle même, ou en se basant sur ce qu'elle fait. Pour la fonction cité ci-dessus, en se basant sur le fonctionnement et ce qu'elle fait nous obtenons toujours les valeurs 399, 400, 611 et 612, les autres sont quelque peu superflues mais peuvent être testées pour plus de sécurité.

Selon l'action de la fonction:

Puisqu'elle permet de savoir le nom d'un modèle de véhicules, quels sont les endroits où la plage de données change? La fin et le début des modèles.

Selon le fonctionnement:

En regardant le tableau des noms de véhicules, on voit qu'il fait 212 par un nombre variable dépendant de l'initialisation (la longueur du nom du véhicule).
Puisque l'on utilise le modèle-400 pour déterminer où se trouve le nom du modèle, les points névralgiques sont lorsque l'on sort du tableau (-1 et 212 soit 399 et 612).

5 - Les fonctionnalités du langage

5.1 - Les State

Les state sont une fonction très intéressante du PAWN, ils sont toutefois très peu utilisés sur SA-MP. Ils peuvent remplacer des variables globales et permettre un code beaucoup plus lisible et facile à comprendre. Afin de les utiliser de façon optimale, il vaut mieux prévoir quels seront les statuts dans le script. Prenons un petit exemple simple:

public OnPlayerCommandtext(playerid, cmdtext[]) <test:statuton>
{
state (strcmp("toggle", cmdtext[1]) == 0) test:statutoff;
Debug("Ce message n'apparaitra pas);
}

public OnPlayerCommandtext(playerid, cmdtext[]) <test:statutoff>
{
state (strcmp("toggle", cmdtext[1]) == 0) test:statuton;
Debug("ce message sera affiché");
}

Debug(text[]) <test:statuton>
{
return print(text);
}

Debug(text[]) <test:statutoff>
{
return 0;//on ne fait rien, on pourrais retirer le return 0...
}

Dans ce cas-ci, nous pourrions définir statutoff comme aucun debug, et statuton comme débug activé
Il est possible de faire plein de statuts différents.
Il faut toutefois faire attention, les state (ou automata) sont les mêmes pour tous.
Il n'est pas possible, par exemple, de faire un state qui soit différent pour chaque joueurs (possible mais trop complexe et sans intérêt, préférable d'utiliser des tableaux0.

Section en construction

6 - Conseils généraux

6.1 - L'utilisation de pseudo-code

Le pseudo-code, c'est simplement une abstraction du langage de programmation afin de revenir au niveau le plus simple.
Il s'agit d'écrire en mot clairs ce que le code doit faire.
Le plus important est de séparé la solution en sous parties.
Le tout doit être fait étape par étape.

Par exemple, si je veut coder une fonction calculant la factorielle d'un nombre, je vais décrire son fonctionnement ainsi:
Citer
1 - Tant que la (valeur - 1) est supérieure à 0
    1.1 - On diminue de 1 valeur
    1.2 - Multiplie le résultat par cette valeur

Il est interessant d'organiser le texte un peu comme dans mon exemple, de lui donner les mêmes niveaux/blocs d'instructions que ce que l'on ferait en codant normalement.
Le pseudo code ainsi écrit est plus facile à implanter.

Le code résultant se ferait ainsi:
Factorielle(valeur)
{
    new factorielle = 1;
    while(valeur > 1)//équivalent à ( valeur - 1 )> 0
    {
        factorielle *= --valeur;
    }
    return factorielle;
}

Cette fonction n'est pas très intéressante car sa valeur monte trop rapidement et dépasse très rapidement la valeur limite d'un entier 32 bit standard, donc ne s'utilise pas sur une grande plage de valeur.

Lorsque l'on écrit son pseudo-code, on peut aussi ajouter des descriptions plus poussées, telles que:

 - les entrées (paramètre(s))
 - les sorties (référence(s), valeur de retour)
 - les entrées acceptées
 - les variables locales utilisées (~)

Le principal avantage du pseudo-code, c'est qu'il permet de déterminer le fonctionnement grossiers d'une fonction/d'un fs/d'un gm avant même de la coder.
Le script résultant est généralement mieux organisé et mieux programmé.
Cela permet de réfléchir à l'algorithme utilisé puisqu'il y a abstraction du langage.

Section en construction

7 - Conclusion

Voilà, j'espère vous avoir appris quelques trucs.
J'ai fait ce tutoriel dans le but d'aider les codeurs intermédiaires à passer à l'étape suivante.
Si vous avez des  commentaires/questions/suggestions, n'hésitez pas à les laisser à la suite de ce fil de discussion :P

Crédits:
Sim
Syg (pour tout ce qu'il m'a appris)
Sasuke (comme Syg)
Y_LESS (pour tous ces tutoriels très clairs qui m'ont permis de progresser)
Tous ceux que j'ai oubliés

Historique:

16 mai 2011 :
 - Ajout de la section 1 et 6.
 - Multiples corrections / ajouts

13 Janvier 2010:
Publication originale
« Modifié: 20 Juin 2011, 23:30:09 par Sim »





Hors ligne Barto

  • Aiiiiiiirght
  • *
  • GTAOnline Addict
  • Messages: 4205
    • Voir le profil
Re : [TUTO] Petits trucs de codages intéressants
« Réponse #1 le: 13 Janvier 2010, 19:14:43 »
Moi j'dis GG.
J'ai pas tout compris puisque je débute en pawn et j'ai encore du mal...
Les filles, c'est comme les échappées en cyclisme, faut en tenter plusieurs pour en réussir une.

Gifs interdit dans les avatars/signs

Hors ligne Ssk

  • *
  • Lulu's Stunt - Le serveur stunt de Lulu !
  • Messages: 8154
    • Voir le profil
Re : [TUTO] Petits trucs de codages intéressants
« Réponse #2 le: 13 Janvier 2010, 19:25:45 »
GG à toi Sim bon tuto ^^

Tu ma appris quelque truc sur les pragma ^^



Derrière tout programme se cache un programmeur, je considère le monde comme un programme.
Mon blog

Hors ligne Franky™

  • Franky™ est bien la
  • *
  • Gangster
  • Messages: 1058
    • Voir le profil
Re : [TUTO] Conseils concernant le codage SA-MP
« Réponse #3 le: 13 Janvier 2010, 20:21:14 »
Woua super, très beau tuto, j'ai aussi après des choses sur les Pragma mdr ...

++ Franky


°°((Franky's WebSite
Désolé pour mes fautes d'orthographes

Hors ligne BuBuNo

  • Radio Guingamp - Bien plus qu'une radio !
  • *
  • Grand Banditisme
  • La radio bien plus qu'une passion !
  • Messages: 840
    • Voir le profil
    • Radio Guingamp - Bien plus qu'une radio !
Re : [TUTO] Conseils concernant le codage SA-MP
« Réponse #4 le: 13 Janvier 2010, 20:37:50 »
Très beau tuto Sim GG ;)
ıllıllı вυвυησ ıllıllı


Hors ligne cristab

  • *
  • Messages: 8379
    • Voir le profil
Re : [TUTO] Conseils concernant le codage SA-MP
« Réponse #5 le: 13 Janvier 2010, 21:45:10 »
GG  tres simpas apparament on va avoir des tuto comme ceux de Y_less en fr nice :)
pas d'aide en PM, vous êtes sur un forum est il me semble que vous êtes la pour avoir de l'aide donc pourquoi MP une seul personne qui ne vous répondra pas alors qu'il y a plein de membre ici

Hors ligne Dauvix

  • *
  • Tueur en série
  • Messages: 134
    • Voir le profil
Re : [TUTO] Conseils concernant le codage SA-MP
« Réponse #6 le: 13 Janvier 2010, 23:52:37 »
Bravo pour ce Tuto,
Merci

Hors ligne S!m

  • *
  • Messages: 2341
    • Voir le profil
Re : Re : [TUTO] Conseils concernant le codage SA-MP
« Réponse #7 le: 05 Juillet 2010, 04:52:19 »
Salut,

Wow merci  :cheers ! Mais tu pourrais rajouté un tutorials sur le dcmd ou le strtok silteplait

merci de la suggestion, je vais essayer de composer un tuto sur les commandes dans mes temps libre. Faudra me donner un certains délai pour le sortir, mais normalement ça devrait se faire assez rapidement.

++Sim++





Hors ligne Barto

  • Aiiiiiiirght
  • *
  • GTAOnline Addict
  • Messages: 4205
    • Voir le profil
Re : Re : [TUTO] Conseils concernant le codage SA-MP
« Réponse #8 le: 05 Juillet 2010, 06:06:04 »
Wow merci  :cheers ! Mais tu pourrais rajouté un tutorials sur le dcmd ou le strtok silteplait

Il existe déjà un bon tuto sur le dcmd fait par FuSion, le titre est : Commandes rapides, un truc du genre ;)
Les filles, c'est comme les échappées en cyclisme, faut en tenter plusieurs pour en réussir une.

Gifs interdit dans les avatars/signs

Hors ligne S!m

  • *
  • Messages: 2341
    • Voir le profil
Re : [TUTO] Conseils concernant le codage SA-MP
« Réponse #9 le: 17 Mai 2011, 03:18:00 »
Salut,

j'annonce une petite mise à jour du tutoriel.
N'hésitez pas à passer vos commentaires.

++Sim++