Aller au contenu principal
Voir

Créer un System Tag personnalisé

PSDK permet d'apprendre au moteur de carte un System Tag entièrement nouveau, une tuile à soi avec ses propres rencontres sauvages, son arrière-plan de combat, son comportement pour les capacités liées au terrain et ses particules de marche. Ce guide parcourt les cinq points d'ancrage du moteur sur lesquels un nouveau tag se branche, écrit chaque redéfinition de méthode en prepend, et montre où peindre le tag terminé dans Tiled.

Le problème : un terrain que le moteur ne connaît pas encore

Les System Tags intégrés couvrent les terrains classiques : herbe, grotte, mer, glace, sable, etc. Chacun sait déjà lancer ses propres combats sauvages, choisir un arrière-plan de combat et projeter la bonne particule de marche. Mais dès qu'on veut quelque chose que le jeu de base n'a pas, par exemple une flaque luisante qui déclenche sa propre table de rencontres et affiche un battleback sur mesure, aucun tag existant ne convient.

Un System Tag personnalisé, c'est la façon d'ajouter ce terrain sans modifier le moteur. On déclare une nouvelle constante, puis on la branche dans la poignée de méthodes du moteur qui s'aiguillent déjà sur un tag, en ajoutant à chaque fois son cas et en revenant au comportement d'origine avec super. Le résultat se comporte comme un tag de première classe : on le peint dans Tiled et le moteur y réagit à chaque pas.

Ce guide suppose que l'on sait déjà comment un tag est lu et stocké. Sinon, commencer par Comprendre les System Tags. Chaque redéfinition de méthode ci-dessous suit la convention de monkey-patch, un module prepend appelant super, jamais un alias.

Sur quoi se branche un tag personnalisé

Un tag n'est pas un simple interrupteur : chaque comportement vit dans une partie différente du moteur. Ajouter un tag revient à en toucher jusqu'à cinq, la dernière étant facultative.

ÉtapePoint d'ancrage du moteurCe qu'il contrôle
1GameData::SystemTags.system_tag_db_symbolLe symbole lisible renvoyé pour la tuile.
2PFM::Environment#get_zone_type / #convert_zone_typeLe type de zone, qui pilote les rencontres sauvages.
3Battle::Logic::BattleInfo::BACKGROUND_NAMESL'arrière-plan de combat affiché quand un combat démarre sur la tuile.
4Game_Map::TERRAIN_TAGS_TABLELe lieu utilisé par les capacités LocationBased.
5Game_Character::PARTICLES_METHODS (facultatif)La particule générée quand un personnage marche sur la tuile.

Les cinq extraits peuvent vivre dans des fichiers de script séparés ou être fusionnés en un seul, du moment que la constante de l'étape 1 est définie avant que les étapes suivantes la référencent. L'emplacement de ces scripts dans un projet PSDK est traité dans monkey-patch.

Dans tout ce guide, le tag d'exemple s'appelle CustomPuddle, avec le symbole :custom_puddle.

1. Déclarer la constante et son symbole

Une constante de tag n'est qu'un identifiant produit par l'aide gen(x, y), où (x, y) est la position de la tuile sur le tileset des System Tags. On choisit une case qu'aucun tag existant n'utilise (les tags intégrés s'arrêtent à la ligne 7, donc toute case en dessous est libre) :

module GameData
module SystemTags
# Column 0, row 12 of the System Tags tileset, a free cell
CustomPuddle = gen 0, 12
end
end

Ensuite, on donne au tag un symbole lisible pour que le reste du moteur, et Pokémon Studio, puissent le désigner par son nom. Le moteur résout un tag en son symbole dans GameData::SystemTags.system_tag_db_symbol. On la redéfinit pour renvoyer son symbole pour le nouveau tag et déléguer l'original pour tout le reste. Par convention, un symbole personnalisé commence par custom_ :

module GameData
module SystemTags
# Adds the symbol of the custom tag without touching the engine method
module CustomPuddleSymbol
def system_tag_db_symbol(system_tag)
return :custom_puddle if system_tag == CustomPuddle

super
end
end
# system_tag_db_symbol is a module-level method (module_function),
# so the override is prepended onto the module's singleton class.
singleton_class.prepend(CustomPuddleSymbol)
end
end

L'appel à super garde chaque tag existant fonctionnel : seul CustomPuddle est traité ici, tout le reste retombe sur le case du moteur.

2. Donner un type de zone au tag

Un type de zone est l'entier que le moteur utilise pour classer le sol sur lequel se tient le joueur. C'est lui qui décide quelle liste de rencontres sauvages s'applique et, à l'étape suivante, quel arrière-plan de combat charger. Deux méthodes le produisent : get_zone_type, qui lit la tuile actuelle du joueur, et convert_zone_type, qui mappe un tag quelconque sur la même valeur. Les deux vivent sur PFM::Environment.

Les types de zone intégrés vont de 0 (bâtiment) à 10 (glace), donc la prochaine valeur libre est 11. On redéfinit les deux méthodes pour la renvoyer pour le tag personnalisé :

module PFM
class Environment
module CustomPuddleZone
def get_zone_type(ice_prio = false)
return 11 if custom_puddle?

super
end

def convert_zone_type(system_tag)
return 11 if system_tag == GameData::SystemTags::CustomPuddle

super
end

private

# Is the player standing on the custom puddle tag?
# @return [Boolean]
def custom_puddle?
@game_state.game_player.system_tag == GameData::SystemTags::CustomPuddle
end
end
prepend CustomPuddleZone
end
end

Deux détails comptent ici. Appeler super sans argument transmet ice_prio intact, donc la logique de priorité d'origine continue de fonctionner pour les tags intégrés. Et 11 n'est que la prochaine valeur libre dans cette version de PSDK : si une mise à jour future ajoute des terrains, ce nombre, ainsi que l'index de l'arrière-plan à l'étape suivante, devront être augmentés en conséquence.

3. Choisir l'arrière-plan de combat

Sans cette étape, un combat lancé sur la tuile s'affiche sur un fond noir. Le moteur choisit l'image dans BACKGROUND_NAMES, un tableau de noms de fichiers indexé par type de zone, dans Battle::Logic::BattleInfo. Comme le moteur décale l'index de un pour toute zone hors bâtiment (zone_type + 1), le type de zone 11 lit l'index 12. Le tableau contient actuellement douze entrées (indices 0 à 11), donc un seul push ajoute l'arrière-plan exactement à l'index 12 :

module Battle
class Logic
class BattleInfo
# zone type 11 reads index 12 after the engine's +1 shift,
# so this must be the entry pushed after the last built-in one
BACKGROUND_NAMES.push('back_custom_puddle')
end
end
end

La chaîne ajoutée est le nom d'une image dans le dossier graphics/battlebacks du projet, ici back_custom_puddle. L'ordre est déterminant : le nouveau nom doit atterrir à l'index que vise le type de zone, donc on l'ajoute une seule fois, après que le moteur a construit le tableau par défaut, et on ne l'insère pas ailleurs.

4. Brancher le tag pour les capacités LocationBased

Certaines capacités changent de comportement selon le sol où elles sont utilisées : leur logique LocationBased lit un symbole de lieu plutôt que le tag brut. Ce mappage vit dans Game_Map::TERRAIN_TAGS_TABLE. On ajoute une entrée pour que le moteur traite la tuile comme un lieu connu, ici de l'eau peu profonde :

class Game_Map
# LocationBased moves treat the custom puddle like shallow water
TERRAIN_TAGS_TABLE[GameData::SystemTags::CustomPuddle] = :shallow_water
end

On réutilise le symbole de lieu existant qui correspond au terrain modélisé ; :shallow_water est l'un des nombreux que le moteur comprend déjà.

5. Ajouter des particules de marche (facultatif)

Cette étape est purement cosmétique : elle génère une particule quand un personnage marche sur la tuile. On la saute entièrement si l'on n'en veut pas. Le moteur consulte PARTICLES_METHODS, un hash indexé par tag, pour savoir quelle méthode appeler : on ajoute donc son tag et on définit la méthode associée. Cette méthode demande à Yuki::Particles de générer une particule identifiée par son symbole :

class Game_Character
PARTICLES_METHODS[GameData::SystemTags::CustomPuddle] = :particle_push_custom_puddle

# Spawn the custom puddle particle when a character steps on the tag
def particle_push_custom_puddle
Yuki::Particles.add_particle(self, :custom_puddle)
end
end

La particule elle-même, l'animation :custom_puddle, se définit dans Data/Animations/Particles.rb. On ouvre ce fichier, on défile jusqu'en bas, juste au-dessus de la ligne save,, et on ajoute son animation à côté des nombreux exemples existants. Après l'avoir modifié, on régénère les données de particules compilées depuis un terminal ouvert dans Data/Animations :

ruby Particles.rb

Peindre le tag dans Tiled

La constante ne devient utile qu'une fois le tag peint sur une carte. Les System Tags se peignent dans Tiled sur le calque systemtags, à partir de l'image de tileset des System Tags située dans Data/Tiled/Assets/prio_w.png. On ajoute sa tuile sur la première case libre de cette image, en respectant la position (x, y) passée à gen, puis on la peint partout où le terrain doit s'appliquer. Le fonctionnement du calque systemtags est détaillé dans Comprendre les System Tags.

Conclusion

  • Un System Tag personnalisé est une constante produite par gen(x, y) que l'on branche dans les méthodes du moteur qui s'aiguillent déjà sur un tag.
  • Chaque redéfinition de méthode est un module prepend qui traite son tag et appelle super pour le reste, jamais un alias.
  • Les cinq points d'ancrage sont : le symbole (system_tag_db_symbol), le type de zone (get_zone_type / convert_zone_type), l'arrière-plan de combat (BACKGROUND_NAMES), le lieu LocationBased (TERRAIN_TAGS_TABLE) et, en option, la particule (PARTICLES_METHODS).
  • Le type de zone et l'index de l'arrière-plan sont des nombres propres à la version : 11 et l'index 12 sont les prochains emplacements libres aujourd'hui, et augmentent si PSDK ajoute des terrains.
  • On réutilise un symbole de lieu existant comme :shallow_water pour les capacités LocationBased plutôt que d'en inventer un.
  • On termine en peignant la tuile sur le calque systemtags depuis Data/Tiled/Assets/prio_w.png.