News

le 05 juillet 2018, 20:51:15 par Leikt
Historique
05/07/2018 - Création du sujet
05/07/2018 - Release de la version 1.3
08/07/2018 - Release de la version 1.3.1 (Correction du bug de la semi-transparence)
17/07/2018 - Release de la version 1.3.1EN (Version anglaise) / Release of the english version 1.3.1

Tileset Carver


Présentation française
Comme le montre l'image, Tileset Carver est un outil pour les maker qui vous donne la possibilité de prendre découper des tilesets de différents formats et de les adapter à RPG Maker tout en sélectionnant les tiles que vous voulez sur autant de tileset que vous voulez. A partir de maintenant, couper, arranger, corriger les grands tilesets prendra dorénavant beaucoup beaucoup moins de temps que manuellement. Je vous laisse essayer par vous-même :

Voici le lien de téléchargement : http://www.mediafire.com/file/5qq7cgtdengz944/TilesetCarver_v1.3.1.exe
Et le lien vers le tutoriel et guide d'utilisation : https://docs.google.com/document/d/10w6xNiksis1jZ_STbPCStehMvMy70axTw59U1T3z26c/edit?usp=sharing

Fonctionnalités actuelles :
  • Création de tileset à partir d'autres tileset
  • Gestion de la transparence des tilesets importés
  • Gestion de mise à échelle des tilesets importés
  • Gestion des marges et offset des tilesets importés
  • Recadrage basique des éléments mal placés
  • Modification du tileset final avant exportation
  • Tri des tiles par catégories personnalisables
En espérant que cet outil vous simplifie la vie.
Bon making à tous !
English presentation
Tileset Carver is a tool for RPG Maker XP. It allows you to slice tilesets from differents formats and convert them to RPG Maker XP. You also can select wich tiles you want to keep, on decide the order of them. From now : slice, arrange and correct the biggest tilesets is faster than ever ! I let you try :

Download link : http://www.mediafire.com/file/6qmlkp1tqt26j51/TilesetCarver_v1.3.1EN.exe
Here is the guide link (in french) : https://docs.google.com/document/d/10w6xNiksis1jZ_STbPCStehMvMy70axTw59U1T3z26c/edit?usp=sharing

Current features :
  • Tileset creation from other tilesets
  • Use transparency colors on imported tilesets
  • Correct scale of imported tilesets
  • Correct margins and offsets of imported tilesets
  • Basic crop of misplaced tiles
  • Reorganise the tileset before final export
  • Sort tiles by categories
I hope the tool will easy your life !

le 14 mai 2018, 21:36:58 par AEliso19
Bonjour ou Bonsoir à tous !

Il y a un projet (non pas celui des Avengers mais presque) : celui d'avoir une BDD pour PSDK complète et sans erreurs ! Pour cela on cherche des personnes qui soient prêtent à donner un peu de leur temps.
Le but étant d'avancer assez rapidement, de manière organisé et d'avoir un suivit sur le long terme.

Cette mise à jour apportera une nouveauté : les DataPack ! Chaque génération aura droit à son DataPack, ainsi nous aurons les 7 DP correspondant aux 7 générations de jeux sorties + un DP custom.

Le but du DP custom sera pour les maker qui soit ont fait d'énorme modification dans RH (modif attaque, fakedex, etc..) et souhaiterai les garder, soit mixer plusieurs fichier des DP ensemble (ex : PokemonData 2G avec ItemData 4G et SkillData 7G).

Donc quand je sélectionnerai le DP 2G qu'est ce que j'aurai à disposition ?
Tu auras les 251 premier pokémon, tous les objets et attaques jusqu'à 7G seront présent, mais paramétrés :
- Pour les Objets apparut avec la 1G et 2g ils seront configuré comme dans les jeux OAC.
- Pour les autres ils seront configuré selon leur génération, les objets 4G comme dans DPP, les 5G comme dans BW/B2W2, etc...
Exception faite pour la liste des CT/CS qui correspondra à la génération choisis.

Que reste t-il à faire pour aboutir au résultat final ?
Actuellement il reste à paramétrer entièrement les Pokémon pour les 5 premier DP. Pour le DP 6G il faut vérifier ce qui est et compléter les breedmove. Pour le DP 7G il faut paramétrer les 6 premières générations, et compléter la 7G (il manque les breedmoves).
Il reste aussi à paramétrer les objets pour chaque génération.

Si vous souhaitez aider contactez moi dans un 1er temps, un groupe privé est à notre disposition sur discord ;)

le 01 mai 2018, 14:24:18 par Nuri Yuri
Salut à tous, aujourd’hui, je vais vous présenter comment réaliser correctement une interface sous PSDK (à partir de Alpha 23.0).

Comme vous pouvez vous en douter, beaucoup de choses ont changé, surtout au niveau du dessin de texte, il est désormais plus possible de dessiner du texte dans un Bitmap. A la place de la vieille méthode bancale du RGSS il y a un type d’objet dédié à l’affichage de Text : la classe Text ! (Qui a plusieurs variantes).

1 – Principe de fonctionnement d’une interface sous PSDK

Sous PSDK, une interface est souvent codé dans le module GamePlay, ceci pour une raison assez simple, il existe une classe de base nommé « Base » qui intègre les fonctions de base vous permettant de ne pas avoir à faire une grande partie du boulot et réduisant considérablement la taille des scripts. Dans ce tutoriel nous allons suivre les étapes de programmation du script « QuestBookMenu » qui affiche le menu principal du journal des quêtes.

Script de base :
module GamePlay
  # Menu to choose which list of quest to show
  class QuestBookMenu < Base
    include UI #Add the UI functions to the current interface
    # Create a new QuestBookMenu
    def initialize
      super() # Call the Base initialize method ignoring the argument of the current initialize
      @viewport = Viewport.create(:main, 1000) # Viewport that holds the sprites of the interface
    end
   
    # Updates the interface
    def update
      return unless super # The update method from base tells if the update can continue or not (message display)
     
    end
   
    # Dispose the viewports of the interface
    def dispose
      super # Call the dispose from Base to dispose the messagebox
      @viewport.dispose #Under LiteRGSS Viewport#dispose disposes all the sprite it holds
    end
  end
end
Pour développer votre interface, je vous conseille d’utiliser un module dédié de Pokémon SDK : Tester ! Ce module vous permet de déposer des scripts Ruby dans le dossier « Tests » et de les tester au fur et à mesure à l’aide de l’option --test=NomDuFichierSansLextension de Game.exe.

Bien entendu pour que ce module fonctionne, vous devez lui signaler quoi tester :

La ligne « Tester.start(GamePlay::QuestBookMenu) » indique au module Tester de démarrer l’interface GamePlay::QuestBookMenu, ceci vous permettra de développer votre script au fur et à mesure sans avoir à forcément redémarrer le jeu ou faire plein de trucs chiants comme passer l’écran titre (ça affiche directement l’interface désiré).

2 – Explication du script de base

Avant d’aller plus loin je vais expliquer le script de base au fur et à mesure, certaines choses sont importantes à comprendre.
Ligne 1 : « module GamePlay » Cette ligne indique que vous travaillez dans le module GamePlay, ceci vous permet d’accéder à toutes les composantes de ce menu (notamment la classe Base).
Ligne 3 : « class QuestBookMenu < Base » Cette ligne vous permet de définir votre classe « QuestBookMenu » et de charger les fonctions de la classe « Base ».
Ligne 4 : « include UI » Cette ligne n’est pas vraiment obligatoire mais sachez que si vous avez besoin d’éléments définis dans le module UI (comme SpriteStack ou PokemonIconSprite) il peut être utile d’ajouter cette ligne, ça ajoute toute les classes définies dans le module UI à votre classe.
Ligne 6 : « def initialize » Cette ligne vous permet de définir la fonction qui crée votre objet d’interface, il ne faut jamais l’oublier car c’est après cette ligne que vous définirez tous les éléments à afficher dans votre interface.
Ligne 7 : « super() » Cette ligne appelle la méthode initialize de la classe Base, ça permet entre autre d’avoir une boite de message sur demande. Si vous ne désirez pas explicitement de boite de message, tapez « super(true) » à la place.
Ligne 8 : « @viewport = Viewport.create(:main, 1000) » Cette ligne crée le viewport principal de votre interface (vous en aurez besoin pour les textes et sprites). Le viewport sera à la coordonnée z = 1000.
Ligne 9 : « end » Cette ligne indique à Ruby que vous avez terminé de définir la méthode initialize de votre classe.
Ligne 12 : « def update » Cette ligne définit la méthode appelée à chaque frame, c’est destiné aux interactions avec l’utilisateur (actuellement nous ne faisons rien).
Ligne 13 : « return unless super » Cette ligne appelle la méthode update de « Base » et sort de la méthode update si quelque chose comme l’affichage d’un message doit empêcher au joueur d’interagir avec l’interface. (Si vous oubliez cette ligne, vos messages ne fonctionneront pas).
Ligne 15 : « end » Cette ligne indique à Ruby que vous avez terminé de définir la méthode update.
Ligne 18 : « def dispose » Cette ligne indique que vous commencez à définir la méthode d’effacement des sprites / texte et autres entités de votre interface (lorsque son travail est terminé).
Ligne 19 : « super » Cette ligne permet d’appeler la méthode dispose de la classe « Base », le but est d’effacer la boite de message si elle a été créée.
Ligne 20 : « @viewport.dispose » Cette ligne permet d’efface le viewport principal ainsi que tous les sprites et textes qui sont affiché dedans. De ce fait, vous n’avez pas besoin d’effacer séparément les sprites et textes qui sont affichés dedans. (Attention, c’est valable que depuis Alpha 23.0 et pour les sprites/textes réellement affichés dans le viewport désigné !)
Ligne 21 à 23 : Ces lignes disent à Ruby que vous avez terminé de définir la méthode « dispose », la classe QuestBookMenu et que vous quittez le module GamePlay.

3 – Test du script de base

Pour le test, j’ai enregistré le script dans Tests/Quest.rb, la commande que je dois donc entrer pour le tester est « Game.exe --test=Quest »


Comme vous pouvez le voir, ça affiche une fenêtre noir qui tourne à 60FPS, c’est normal nous n’avons pas défini de choses à afficher.
Si la fenêtre ne s’affiche pas, lisez la console, il se peut qu’il y ait une erreur de syntaxe ou une autre erreur. La plupart du temps en cas d’erreur, vous pouvez relancer le script en écrivant « reload and restart » dans la console. Si cela ne fonctionne pas ou que le jeu se freeze complètement (on sait jamais) appuyez sur CTRL+C dans la console et relancez le test avec la ligne présenté avant l’image.

4 – Ajoutons un fond

Pour ajouter le fond, j’ai placé deux lignes dans la méthode initialize :
  • « @is_showing_failed = isf = $quests.failed_quests.size > 0 » Cette ligne permet de détecter si l’interface doit afficher l’option des quêtes échouée. (C’est purement informatif).
  • « Sprite.new(@viewport).set_bitmap(isf ? "quest/quest_bg_1" : "quest/quest_bg_1_2", :interface) » Cette ligne affiche le fond, nous allons la détailler après l’image qui montre comment j’ai placé ces lignes.


La ligne de création du fond est composée de deux parties :
  • La création du sprite à afficher dans le viewport principal « Sprite.new(@viewport) »
  • Le chargement de l’image à afficher depuis le cache d’interface : « set_bitmap(isf ? "quest/quest_bg_1" : "quest/quest_bg_1_2", :interface) »

Comme nous avons deux fonds différents en fonction de si on affiche l’option des quêtes échouées on utilise la variable définie quelques lignes plus haut dans une condition ternaire. Sachez que la plupart des fonctions en .set_qqch de Sprite peuvent se chaîner.
Notez par ailleurs que le sprite n’a pas été stocké dans une variable, c’est normal puis-ce que nous n’agirons jamais dessus et que le viewport se charge de conserver le sprite jusqu’à son effacement.

5 – Ajouter du texte

Maintenant nous allons ajouter du texte sur l’interface, mais avant cela, je vais vous présenter une fonctionnalité qui pourrait vous intéresser. Lorsque vous testez une interface, la touche F9 vous donne les coordonnées de la souris sur l’écran. Nous nous en servirons pour positionner nos textes.


Nous utilisons une interface basique (sans SpriteStack) du coup nous devons demander les fonctionnalités d’affichage de texte.
  • Après « include UI » nous ajoutons « include Text::Util » ceci charge les fonctionnalités d’affichage de texte pour les interfaces.
  • Après « @viewport = Viewport.create(:main, 1000) » on ajoute « init_text(0, @viewport) » ceci permet d’indiquer aux texte d’utiliser la Font 0 (défaut) et d’afficher les textes dans le viewport (nous permettant de ne pas avoir à les effacer à la main).

Une fois ces lignes ajoutées nous ajoutons les lignes qui permettent de définir les textes que l’interface affiche


Les choses à savoir : add_text permet d’ajouter un texte, il faut donc appeler cette méthode dans initialize (sauf cas particulier), cette méthode fonctionne exactement comme bitmap.draw_text (qui a été supprimé). La seule variation qu’il y a avec cette fonction c’est qu’elle retourne l’objet Text que vous pouvez stocker ou utiliser par exemple pour définir la couleur de celui-ci. (.set_color(id))
La liste des couleurs est la même que celle des couleurs des messages, en effet la boite des messages utilise également add_text pour afficher les mots du message.

Maintenant je vais attirer votre attention sur la ligne suivante :
« add_text(0, 129, 320, 23, "Quêtes échouées", 1, 1).load_color(9) if isf »
Cette ligne affiche le texte « Quêtes échouées » si et seulement si l’interface doit les afficher. Notez par ailleurs qu’à cause d’une fonction dans update nous allons déplacer cette ligne avant la précédente. (Les coordonnées y sont ajustées en fonction d’isf pour les autres textes).

6 – Ajouter un sélecteur

Maintenant que nous avons placé les textes, nous devons placer le sélecteur, il permettra au joueur de savoir quel menu il ouvre. Comme le sélecteur est un objet qui se déplace, nous devons l’enregistrer dans une variable d’instance « @selector »


Comme vous le voyez, j’ai créé le sprite, positionné et affiché l’image de celui-ci en trois lignes sans rappeler la variable d’instance. Ceci mérite explication.
En Ruby, le point-virgule des langages comme C/C++ est optionnel, cela-dit il peut être utilisé et ça a un sens particulier. Si une ligne termine par point-virgule, alors l’instruction est terminée, sinon, Ruby interprète selon ses propres règles. Dans le cas présent, la ligne suivante commence par un point, de ce fait pour Ruby c’est comme si vous n’aviez pas sauté de ligne (rappelez-vous les .load_color(9)). Ca voudra aussi dire que tant que vous continuez à chainer des appels de fonction sur l’objet crée, la variable d’instance @selector ne contient pas l’objet c’est pourquoi vous devez bien faire attention à ce que les méthodes que vous chaînez renvoient l’objet que vous voulez enregistrer.

Maintenant détaillons un peu les trois lignes :
  • « @selector = Sprite.new(@viewport) » nous créons un sprite dans le viewport principal, le résultat final sera stocké dans la variable d’instance @selector.
  • « .set_position(0, @texts[@index].y + FOY) » nous positionnons le sprite à la coordonnée 0, coordonnée du texte @index plus un petit offset dû aux fonctions de positionnement des textes sur l’écran. Notez qu’avec Text::Util les textes sont tous enregistré dans @texts dans l’ordre où les add_text ont été exécutés. C’est pourquoi sur le screenshot j’ai déplacé le texte des quêtes échouées. (On s’en servira pour le positionnement du sélecteur).
  • « .set_bitmap("quest/quest_selector", :interface) » on charge l’image quest_selector dans le dossier quest du cache d’interface.
7 – Actions du joueur sur le sélecteur

Après avoir créé le sélecteur nous allons gérer les interactions du joueur dessus, son déplacement entre autre. Pour cela, la classe Base défini une méthode très utile « index_changed » que nous appellerons dans la méthode update.
La méthode index_changed est définie ainsi : index_changed(varname, sub_key, add_key, max, min = 0)
  • varname correspond au symbole de la variable d’instance affecté par la méthode ( :@index pour nous)
  • sub_key correspond au symbole de la touche qui soustraira 1 à l’index, ici :UP
  • add_key correspond au symbole de la touche qui ajoutera 1 à l’index, ici :DOWN
  • max correspond à la valeur maximale que l’index peut prendre (2 ou 3 selon si on affiche le choix échoué ou pas).
  • min correspond à la valeur minimale que l’index peut prendre (on le spécifiera pas car pour nous c’est 0)
Notez que cette fonction est rotative, si vous arrivez en bas de la liste, ça retourne en haut, pour ne pas avoir cet effet, utilisez « index_changed! » à la place.


Quand l’index change, nous changeons évidemment la position du sélecteur.

8 – Choix de l’utilisateur

Une fois que l’utilisateur a positionné le sélecteur au bon endroit, il voudrait surement ouvrir le menu qui correspond (ou quitter). Pour cela il appuiera sur la touche virtuelle « A » qui est en fait la touche « C » ou « Entrée » du clavier. Pour gérer la fermeture du menu, nous allons devoir enregistrer l’index maximal dans une variable et comparer l’index à l’index maximal, si la comparaison est valide, on arrête l’interface à l’aide de la variable d’instance « @running » qui pour toute les interfaces de GamePlay indique si l’interface tourne toujours ou pas.


Pour détecter un appui de touche nous utilisons Input.trigger?(symbol) où symbol est le symbole de la touche virtuelle. Par exemple pour quitter en toute circonstances on appuie sur « B » (X sur le clavier).

9 – Test final

Une fois que tout est codé, on peut faire un test final de l’interface. Vous pouvez entrer des lignes de code, sur le screen suivant je vais entrer « $quests.failed_quests[0] = {} », ça aura pour effet d’activer les quêtes échouées, si on entre ensuite « restart » l’interface va s’afficher avec l’option d’affichage de l’échec des quêtes et lorsqu’on appuiera sur Entrée ça devrait ouvrir le menu désiré (là ça l’affiche à l’écran car pas encore codé).


Bonus – Démarrer une autre interface.

Pour démarrer une autre interface, il existe une fonction spécifique « call_scene(Nom, *args) ». Cette fonction crée un objet en appelant « Nom.new(*args) », rend le viewport principal de la scene actuelle invisible redonne la priorité à votre interface une fois que la scene « Nom » a terminé son boulot. Attention, il se peut que votre scene soit automatiquement arrêté si par exemple la scène Nom décide de retourner sur la carte ou alors qu’elle appelle la fonction « return_to_scene(AutreNom) » (vous pouvez aussi le faire).
Pour vous rendre compte de call_scene, regarde les scripts dans PSDK, c’est la version Alpha 23.0 du système de quêtes (ouvrez Data/__.rxdata pour lire le script).

le 03 avril 2018, 21:48:07 par Deakcor
Bonjour, ce tuto va vous donner les clefs pour créer des sprites animés grâce au logiciel d’animation 2D Spriter.

Sommaire
  • Prérequis
  • Le découpage
  • Finitions des parties
  • Importation et réglages
  • L’animation
  • Prévisualisation et export


I. Prérequis

Le logiciel Spriter (la version free suffit) : https://brashmonkey.com/
Et un sprite fixe (ici un sprite de Ze-Kray)



Assurez-vous d’avoir le droit d’utiliser le sprite fixe si vous l’avez récupéré et n’oubliez pas de créditer la personne.

II. Le découpage

Ensuite nous allons découper le sprite fixe en plusieurs parties indépendantes. Le corps, les pattes, la tête, la queue… En bref tout ce que vous voudrez bouger indépendamment. Chaque partie sera dans un fichier image séparé.


Mais attention, il ne faut pas juste découper mais il faut également remplacer les parties manquantes.

Exemple (sprite statique par Noscium)


La tête et les bras sont des parties mobiles et indépendantes par rapport au corps. En découpant j’ai donc remplis grossièrement celui-ci pour éviter de voir des trous lors de l’animation.

III. Finitions des parties

Certaines parties sont impossibles à animer qu’en appliquant de simple rotation ou translation, c’est pourquoi nous devons préparer ces frames à l’avance.

Exemple, des yeux qui se ferment ou une flamme.


Autre exemple avec les pattes de ce raichu d’alola (sprite statique par FrenchOrange)


Une fois que vous avez toutes vos parties dans un dossier, allons sur Spriter.

IV. Importation et réglages

Une fois dans le logiciel, la première chose à faire est de se mettre en mode pixel art.


Puis créer un nouveau fichier et sélectionner le dossier avec nos différentes parties.


A droite nous avons toutes les parties de notre sprite. Vous pouvez les placer sur la zone centrale, je conseille de mettre le sprite statique en premier pour être sûr de bien respecter les emplacements.


Si vous vous êtes trompé sur l’ordre des parties de votre sprite pas de problème. Vous pouvez régler leur position à gauche. Et également sélectionner le sprite statique pour le supprimer.


Vous devez avoir maintenant votre sprite assemblé et assurez-vous que vous êtes bien à la frame zéro.



Créons maintenant le squelette. Pour chaque partie vous devrez créer un os. Pour ce faire laissez la touche alt enfoncé et clique gauche, vous pourrez ainsi gérer sa position et sa hauteur.
Commencez par celui du corps. Sélectionnez cet os et laissez la touche B enfoncé pour sélectionner la partie correspondante (semi transparent = non sélectionné).
Puis continuez avec les pattes, la tête etc. Toujours avec la touche B en sélectionnant l’os du corps vous pourrez sélectionner d’autres os en tant que fils. Lorsque le père bougera, le fils le suivra.

Vous dévirez maintenant avoir quelque chose comme ceci.


On a fini le set up passons à l’animation!

V. L’animation

Tout d’abord, faut savoir que les animations à la noir et blanc sont composés de 2/3 mouvements qui se répètent et un mouvement spécial trop stylé.
Plaçons nous à la frame 200. J’ai effectué plusieurs choses ici. Le corps a été un tout petit peu levé mais j’ai pris garde de laisser les pattes fixés au sol. La queue bouge également. (et pour la flamme on verra plus tard).


Ceci va donc être le mouvement qui se répétera.

Pour copier une frame faites double clic sur celle ci pour la sélectionner, Edit/copy current frame (ctrl + shift + c) et collez la à une frame plus élevée avec Edit/past (ctrl + v). Faites ça avec la frame 0 et 200 plusieurs fois en alternant (0 / 200 / 400 / 600).

Passons maintenant au move trop stylé. J’ai choisi de faire lever le Pokémon sur ses pattes arrières.

Donc il commence par se baisser puis se lever, retomber et revenir à la position initiale. (C’est en fait un plus complexe pour éviter des mouvements trop raides etc... Mais ça viendra avec de l’entrainement)

Ce qu’il faut savoir c’est que chaque mouvement doit être compensé. Si il saute, il devra amortir le choc pas juste revenir à sa position d’origine.

Vous pourrez maintenant changer les parties qui devront être animées manuellement. Pour ce faire vous devrez sélectionner l’objet à modifier et faire clic droit sur le nouveau sprite et  remplacer. Toutes les X frames à intervalle régulier pour une flamme.


VI. Prévisualisation et export

Une fois l’animation fini, n’hésitez pas à cacher le squelette pour mieux la voir. Assurez-vous également que l’animation est en mode repeat. Vous pouvez également régler la vitesse de celle-ci.


Maintenant que l’animation vous plait, exportons-la en gif pour ainsi l’insérer dans votre jeu. Pour ce faire rien de plus simple. File/export to et sélectionnez animated gif. Vous pourrez choisir le nombre d’image et la vitesse d’une frame. (En moyenne un gif noir et blanc à environs 100 images voire plus).


Voici le rendu final de l’Hippopotas.


Finalement vous pouvez donc créer un sprite animé avec une solution bien plus simple que faire frame par frame avec un logiciel comme Aseprite. J’espère que le tutoriel vous sera utile. N’hésitez pas à demander des précisions et de laisser un message si vous voyez des fautes. Si vous faites des tests n'hésitez pas également à les poster ici si vous voulez des avis et des conseils.

Pour d'autres exemples, n'hésitez pas à aller voir ma galerie https://pokemonworkshop.com/forum/index.php?topic=4035.0

le 31 mars 2018, 20:16:54 par Nuri Yuri
Bonjour à tous.

Comme vous avez pu le remarquer, le forum a une limite d'espace concernant les fichiers envoyés, ceci nous oblige à faire un ménage de temps en temps... Pour résoudre ce léger soucis, j'ai mis en place un WordPress qui a pour unique but de servir de module d'upload de fichier.

Le lien de ce Wordpress est le suivant : https://image.communityscriptproject.com/wp/

Si vous allez poster un tutoriel, un script, un plugin, une présentation de projet relativement avancé et que vous souhaitez que vos fichier restent définitivement sur PW, demandez moi un compte.

Note : Wordpress est un truc que j'ai trouvé qui correspond aux critères suivants :
- Permet d'uploader des fichiers à l'aide d'utilisateurs enregistrés.
- Ne cache pas les fichiers derrière un script php.
- La limite d'upload est raisonnable.