Touhou: Fading Illusion

Touhou: Fading Illusion

Not enough ratings
Guia para a criação de mods
By GiMark
Nesse guia, você encontrará todas as informações necessárias para criar um mod simples.
   
Award
Favorite
Favorited
Unfavorite
Prefácio
Bem-vindos, modders! Neste guia, você encontrará as informações básicas necessárias para criar um mod. Antes de começar a criar mods, recomendamos que você se familiarize com as regras para a criação de conteúdo feito por fãs.

AVISO: Atualmente, a ferramenta de upload de mods está disponível apenas para usuários de Windows.

NOTA: As imagens na pasta "_game_resources" e algumas partes deste guia podem conter spoilers.
Restrições de conteúdo
Diretrizes do criador da série de jogos original
Como Touhou: Fading Illusion é uma obra de fãs baseada no universo do Projeto Touhou, seus mods também devem seguir os requisitos estabelecidos pelo criador da série original, ZUN. Especificamente, seus mods NUNCA devem incluir:
  • Qualquer coisa que tenha a intenção de prejudicar a reputação do Projeto Touhou.

  • Qualquer coisa que viole a propriedade intelectual de terceiros.

  • Qualquer coisa que possa confundir seu Conteúdo de Fã com um dos títulos oficiais do Projeto Touhou.

  • Qualquer material extraído dos jogos oficiais do Projeto Touhou.

  • Cenas finais dos jogos oficiais do Projeto Touhou.

  • Qualquer coisa que tenha como objetivo promover crenças pessoais além dos limites da ficção.

  • Outro conteúdo de fãs de Touhou sem a permissão do criador.

  • Conteúdo sexual excessivo que seja considerado ilegal.

  • Qualquer coisa que promova ódio contra indivíduos ou grupos.

  • Qualquer fotografia do próprio ZUN sem a permissão dele.
Você pode revisar a lista completa de requisitos neste website[touhou-project.news].

Além disso, seus mods não devem conter nenhum código malicioso. Se você não deseja distribuir o código-fonte, você deve nos contatar, e permitiremos que você publique seu mod após uma análise privada do código-fonte. Ao começar a criar um mod, você confirma que leu este aviso e concorda com ele. Em caso de violações, nós reservamos o direito de esconder ou bloquear seu mod.

Se você tiver alguma dúvida, sugerimos que entre em contato através do servidor do Discord da nossa equipe[discord.gg].
Começando
Bem, se você concorda com tudo mencionado acima, vamos trabalhar. Primeiramente, você precisará de um editor de texto prático, já que você trabalhará MUITO com texto e código. Os arquivos ".rpy" que você irá usar podem ser abertos com o Bloco de Notas padrão integrado, mas nós recomendamos algo mais avançado, como VS Code ou Notepad++. Ambos os programas são gratuitos e estão disponíveis publicamente.

Depois disso, certifique-se de que Touhou: Fading Illusion está instalado no seu computador, e assine o mod oficial, que vai te ajudar a entender como o código funciona e fornecer ferramentas para fazer o upload.
Criando uma pasta de mod
Navegue até a pasta Steam ou SteamLibrary na mesma unidade onde Touhou: Fading Illusion está instalado, e então localize a pasta no caminho "steamapps\workshop\content\2132480\3565758917". Esta pasta deverá aparecer assim que você baixar nosso mod.
Não se intimide com os números nos nomes das pastas – esses são os identificadores da Steam, e você também receberá um para o seu mod quando o criar.

Dentro da pasta do nosso mod, abra a pasta "_upload_app" e inicie o aplicativo. No aplicativo, digite o nome do seu mod no menu à esquerda e clique no botão "Create Item" no canto inferior esquerdo. Em seguida, uma pasta para o conteúdo do seu mod aparecerá na pasta WorkshopContent, junto com um arquivo chamado *nome do seu mod*.workshop.json – esse é o arquivo que precisamos (recomendamos salvá-lo em algum lugar depois que você o preencher).
Abra esse arquivo, copie o valor do campo "publishedfileid", e crie uma pasta com o mesmo nome no diretório "steamapps\workshop\content\2132480". Como os usuários vão baixar seu mod para este mesmo caminho, faz sentido desenvolvê-lo diretamente neste local. Crie os arquivos mod_info.rpy e script.rpy na pasta do seu mod, em seguida, abra o arquivo correspondente mod_info.rpy na pasta do nosso mod usando um editor de texto.
Informação sobre o mod
Dentro de mod_info.rpy, você poderá ver o código a seguir:
init 99 python:
    tfi_official_mod_path = os.path.join(os.path.dirname(os.path.dirname(renpy.config.basedir)), "workshop/content/2132480/3565758917").replace("\\","/")
    global_game_mods["tfi_official_mod"] = {
      "start_scene": "tfi_official_mod_scene1",
      "description": _("This is a tutorial mod that also serves as a template for creating other mods. Open the folder steam/steamapps/workshop/content/2132480/3565758917 to look at the code and images in more detail."),
      "name": _("Tutorial mod"),
      "image": os.path.join(tfi_official_mod_path, "images/preview.png").replace("\\","/"),
    }
Para o seu mod, você precisará copiar este código em seu próprio arquivo mod_info.rpy e fazer algumas alterações:
  • Substitua tfi_official_mod em global_game_mods["tfi_official_mod"] com outro nome exclusivo de sua escolha, usando caracteres latinos. Esse é o identificador do seu mod dentro dos arquivos do jogo, e para evitar conflitos com outros mods, recomendamos usar esse nome em caracteres latinos para nomear suas variáveis e cenas.

  • Altere o valor do campo start_scene – esse campo define a primeira cena que o jogador verá ao iniciar o seu mod. Para simplificar, copie o nome do seu mod mencionado acima e adicione "_scene1" a ele, visto que os nomes das cenas também precisam ser únicos.

  • Os campos descrição e nome correspondem ao texto que será visível aos usuários no menu de seleção de mods dentro do jogo. Você pode preenchê-los como desejar, mas lembre-se de que o espaço é limitado. É possível usar a tag {size} para aumentar ou diminuir o tamanho do texto.
    "{size=+2}Este texto está maior.{/size}"
    "{size=-2}Este texto está menor.{/size}"

  • O campo imagem é a prévia do seu mod, que também será exibida no menu de seleção de mods. Você pode deixar este campo vazio ou removê-lo completamente se você não tiver uma imagem – nesse caso, um espaço reservado com um ponto de interrogação será exibido.

No final, você deveria ter algo assim:

Depois de terminar com mod_info.rpy, copie as informações do nosso arquivo script.rpy para o seu. Vamos analisar todo o código fornecido.
Bloco "init:"
Esta seção contém variáveis que você vai querer definir para o seu mod. Por exemplo, o comando "define tfi_official_mod_dev = Character(_('TFI Main Dev'))" cria um novo personagem chamado "TFI Main Dev". Você pode criar quantos personagens quiser, mas garanta que os nomes das variáveis dos seus personagens sejam únicos e não entrem em conflito com as nossas variáveis ou com as de outros mods. Recomendamos também usar um prefixo exclusivo do seu mod nos nomes aqui.

Se um personagem é situacional, você pode pular a definição de uma variável e usar diretamente o nome do personagem antes do diálogo.
"TFI Main Dev" "Hello!"
"TFI Player" "Hey!"
A tabela abaixo lista as variáveis atualmente usadas em nosso jogo, que você pode consultar conforme necessário. À medida que novos personagens forem sendo introduzidos na história, adicionaremos novas variáveis.

Personagens oficiais da série

Name
Tag
Name
Tag
Name
Tag
Name
Tag
Name
Tag
Reimu
rei
Marisa
mar
Byakuren
byak
Rin
orin
Rinnosuke
korin
Yukari
yuk
Mokou
moko
Kanako
kan
Youmu
youmu
Sanae
san
Kasen
kas
Clownpiece
clown
Eirin
eirin
Reisen
reisen
Nazrin
naz
Satori
sat
Utsuho
okuu
Suwako
suwa
Komachi
koma
Eiki
eiki
Chen
chen
Ran
ran
Aya
aya
Yuugi
yuugi
Mima
mima
Mamizou
mami
Sumireko
sum
Meiling
mei
Kokoro
kokoro
Sakuya
sak
Koishi
koi
Remilia
remi
Mizuchi
mizu
Seija
seija
Flandre
flan
Hecatia
heca

Personagens secundários ou originais

Name
Tag
Name
Tag
Name
Tag
Name
Tag
Name
Tag
Girl
girl
Hitomu
hito
Bake-danuki
bake
Rabbit
usausa
Tengu
tengu
Kappa
kappa
Yamaraja
yamaraja
Itime-kozo
itime

A variável "tfi_official_mod_path" serve como um atalho para o caminho da pasta do seu mod a partir da pasta principal do jogo. Se você usar qualquer imagem personalizada, essa variável será útil. Tudo o que você precisa fazer é substituir "tfi_official_mod" no nome da variável pelo nome do seu mod, como antes, e atualize o nome da última pasta no caminho "workshop/content/2132480/3565758917". Você pode referenciar todos os arquivos da pasta "3565758917/_game_resourses" sem usar esta variável, já que fazem parte do jogo principal. Porém, para seus arquivos específicos, você precisará usá-la.
define mod_name_path = os.path.join(os.path.dirname(os.path.dirname(renpy.config.basedir)), "workshop/content/2132480/your_folder").replace("\\","/")
show image("[mod_name_path]/images/your_image1.png")
show image(Transform("images/backgrounds/hakurei_shrine_inter_d1.jpg", zoom=0.5))
Cenas e linhas
Depois vem o começo de uma cena, definida por um rótulo ao qual você atribui um nome único. Anteriormente, você especificou a cena inicial como "*seu mod*_scene1", então agora substitua o nome deste rótulo por ele.

Se tudo estiver pronto, a única coisa que resta é criar um enredo e escrevê-lo. O texto será exibido na tela em partes, para se encaixar na janela de diálogo. Se o identificador de um personagem for colocado antes de uma fala, o nome dele será exibido junto com o texto. Se não houver identificador, apenas o texto será exibido.

O jogo também suporta falas simultâneas de dois ou três personagens. Tudo o que você precisa fazer é adicionar (multiple = 2) ou (multiple = 3) à direita da fala:
rei "Boa sorte." (multiple = 2)
mar "Tchau." (multiple = 2)
Imagens
Vamos dizer que você já escreveu seu diálogo, mas e as imagens? Elas são um pouco mais complexas. Recomendamos verificar a seção relevante da documentação do RenPy[www.renpy.org] se você não encontrar as respostas para suas perguntas nos exemplos abaixo.

Fundos e Imagens Estáticas
Você pode mostrar uma imagem na tela usando o comando show image("caminho para a imagem"). Como a resolução alvo do jogo é 1920x1080 e muitas imagens são criadas em resoluções maiores, elas precisam ser redimensionadas usando o comando Transform() antes de serem mostradas. Para fundos e algumas CGs, nós usamos um fator de escala de 0.5, e para sprites, 0.6, mas você pode usar qualquer valor que preferir. Também é recomendado usar o comando scene no começo de uma cena, que substitui todas as outras imagens.
scene image(Transform("images/backgrounds/human_village1_m.jpg", zoom=0.5))
show image(Transform(tfi_official_mod_reimu_happy, zoom=0.6))

Sprites Dinâmicos
Além disso, em Touhou: Fading Illusion, usamos alguns métodos não tradicionais do RenPy para otimizar o jogo ou adicionar novas possibilidades para a direção. Especificamente, adicionamos uma nova camada no sistema de exibição de imagens onde sprites de personagens em camadas são exibidos.

Em nosso mod, você pode ver o código a seguir:
$ chars = 2
$ elems = 13
$ scale = 0.6

$ pict_ = [
["none.png","none.png","none.png","none.png","none.png","none.png","none.png","none.png","none.png","none.png","none.png","none.png","none.png",],
["none.png","none.png","none.png","none.png","none.png","none.png","none.png","none.png","none.png","none.png","none.png","none.png","none.png",],
]

$ pict_1 = [
[
"none.png",
"none.png",
"none.png",
"sprites/Sakuya/sak_body1.png",
"sprites/Sakuya/sak_body1_brow1.png",
"sprites/Sakuya/sak_body1_eyes1_d.png",
"sprites/Sakuya/sak_body1_mouth2.png",
"sprites/Sakuya/sak_body1_leftarm2.png",
"sprites/Sakuya/sak_body1_rightarm6.png",
"none.png",
"none.png",
"none.png",
"none.png",
],
[
"none.png",
"none.png",
"none.png",
"sprites/Nazrin/naz_body1.png",
"sprites/Nazrin/naz_body1_brow1.png",
"sprites/Nazrin/naz_body1_eyes5_f.png",
"sprites/Nazrin/naz_body1_mouth18.png",
"sprites/Nazrin/naz_body1_arms1.png",
"none.png",
"none.png",
"none.png",
"none.png",
"none.png",
],
]

$ xp = [111000, 111000, 111000]
$ yp = [-130, -130, -130]
$ copy()
show screen _Pers_ onlayer add_l
Aqui, você pode ver no código como os sprites da Sakuya e da Nazrin são montados: usamos a renderização em camadas para facilitar a mudança de expressões faciais ou posições das mãos, sem limitar as variações. Antes de especificar elementos dos sprites específicos, você precisa definir as variáveis chars (número de personagens), elems (número de elementos), e scale (fator de escala do sprite). Além disso, atribua arrays semelhantes aos dos sprites à variável pict_, mas utilizando imagens "none.png".

As posições dos sprites são controladas por duas variáveis – xp e yp, responsáveis pelo posicionamento horizontal e vertical, respectivamente. Essas variáveis podem ser atribuídas individualmente a cada sprite, por exemplo, xp[1] = …, ou configuradas simultaneamente para todos os sprites usando um array, por exemplo, xp = […, …, …].

Além disso, esse método utiliza uma camada separada para exibir os sprites: "show screen _Pers_ onlayer add_l". Essa camada fica à frente da camada padrão de imagens, garantindo que os sprites apareçam sempre à frente de todas as outras imagens. Se você quiser exibir uma imagem à frente dos sprites, será necessário adicionar "onlayer add_l".

No entanto, tudo isso é opcional. Você pode pré-montar um único sprite a partir das camadas, atribuí-lo à variável pict_1 de maneira similar e, em seguida, alternar para qualquer outro sprite, ou utilizar os métodos padrão do RenPy.

O código abaixo mostra exemplos de como alterar elementos de sprites ou exibir um sprite 'completo' da Reimu a partir dos arquivos do mod.
$ pict_[0][4] = "sprites/Sakuya/sak_body1_brow3.png" # 4
$ pict_[0][5] = "sprites/Sakuya/sak_body1_eyes3_f.png" # 5
$ pict_[0][6] = "sprites/Sakuya/sak_body1_mouth6.png" # 6
$ pict_[0][7] = "sprites/Sakuya/sak_body1_leftarm3.png" # 7
$ pict_[0][8] = "sprites/Sakuya/sak_body1_rightarm1.png" # 8

$ pict_[1][4] = "sprites/Nazrin/naz_body1_brow3.png" # 4
$ pict_[1][5] = "sprites/Nazrin/naz_body1_eyes3_f.png" # 5
$ pict_[1][6] = "sprites/Nazrin/naz_body1_mouth10.png" # 6
$ pict_[1][7] = "sprites/Nazrin/naz_body1_leftarm1.png" # 7
$ pict_[1][8] = "sprites/Nazrin/naz_body1_rightarm4.png" # 8

hide image(Transform(tfi_official_mod_reimu_happy, zoom=0.6))

show image(Transform(tfi_official_mod_reimu_sad, zoom=0.6)):
    xalign 0.8
    yalign -0.1
with dissolve

Mudanças de cor
Você também tem a opção de alterar o esquema de cores de uma imagem usando a função blur() com três parâmetros – matiz, brilho e saturação. Por exemplo, blur(image, 320, 120, 100) mudará a matiz para 320, brilho para 120, a saturação para 100 da image.
$ pict_[0][3] = blur("sprites/Sakuya/sak_body1.png", -10, -0.22, 0.9) # 3
$ pict_[0][4] = blur("sprites/Sakuya/sak_body1_brow3.png", -10, -0.22, 0.9) # 4
$ pict_[0][5] = blur("sprites/Sakuya/sak_body1_eyes3_f.png", -10, -0.22, 0.9) # 5
$ pict_[0][6] = blur("sprites/Sakuya/sak_body1_mouth6.png", -10, -0.22, 0.9) # 6
$ pict_[0][7] = blur("sprites/Sakuya/sak_body1_leftarm3.png", -10, -0.22, 0.9) # 7
$ pict_[0][8] = blur("sprites/Sakuya/sak_body1_rightarm1.png", -10, -0.22, 0.9) # 8
Efeitos
O RenPy oferece diversos efeitos visuais para imagens que aparecem ou desaparecem. Você pode ter percebido que muitos comandos nos exemplos fornecidos terminam com "with dissolve". Isso é usado para fazer as imagens aparecerem ou desaparecerem com uma transição de 1 segundo, em vez de instantaneamente. Existe também outra versão incorporada, dissolve_f, que dura 0.25 segundos e é usada ao alterar elementos de sprites, para evitar prolongar excessivamente o tempo de jogo. Você pode criar sua própria versão de transição usando uma variável semelhante:
define dissolve_five = Dissolve(5) # a 5-second transition
Na maior parte das vezes, usamos apenas esses efeitos, mas você pode utilizar outros efeitos aplicados de forma semelhante. Você pode ler mais sobre os efeitos na documentação do RenPy[www.renpy.org].
Musica e Sons
Você pode reproduzir ou parar músicas usando os comandos renpy.music.play e renpy.music.stop. Após especificar o caminho do arquivo, é possível indicar o canal em que a música será reproduzida, assim como o efeito para iniciar ou diminuir o volume da música gradualmente.
$ renpy.music.play("sounds/ambience/crowd_medium1.ogg", channel="music_2", synchro_start=True, fadein=2.0)
$ renpy.music.stop(channel="music_2", fadeout=1.5)
Existem três canais para música – music, music_1 e music_2, além de um canal para reprodução de sons únicos – sound.
Escolhas
Modificamos o menu de escolhas padrão para exibir não apenas as opções disponíveis, mas também a pergunta feita ao jogador. Para exibir a pergunta, é necessário atualizar a variável menu_question:
$ menu_question = _("Do you need an extra round?")

$ quick_menu = False
window hide dissolve

menu:
    with dissolve
    "Yes, please!":
      $ quick_menu = True
      window show dissolve
      jump tfi_official_mod_scene1
    "Nah, I got it.":
      $ quick_menu = True
      window show dissolve
Usando variáveis
Você pode usar variáveis, por exemplo, para acompanhar as escolhas do jogador. As variáveis podem ser texto (= "one"), numérico (= 1) ou lógico (= True), e você pode manipulá-las com diferentes condições, como if ou for. Você pode ler mais sobre variáveis na seção correspondente da documentação do RenPy[www.renpy.org].
$ menu_question = _("Um ou dois?")

menu:
    with dissolve
    "One!":
      $ mod_name_player_choice = 1
      jump mod_name_scene_player_pick_one
    "Two!":
      $ mod_name_player_choice = 2
      jump mod_name_scene_player_pick_two
if your_mod_condition == 2:
    jump destitute1_scene2_5
else:
    jump destitute1_scene1_5
Tradução
OBS: Alguns membros da nossa equipe demonstraram interesse em traduzir mods que eles gostam, além do jogo principal. Portanto, se você estiver interessado, pode contatá-los no nosso servidor do Discord[discord.gg].

Se você planeja criar um mod em múltiplos idiomas, será necessário gerar arquivos de tradução. Para gerá-los, você precisará baixar o RenPy 8.3.7[www.renpy.org], especificar o caminho do jogo nas configurações e gerar a tradução para o idioma desejado.
Você pode traduzir não apenas linhas de diálogo, mas também variáveis e nomes de personagens: para isso, coloque o texto entre aspas de underscore _(...) ao declarar a variável:
define tfi_official_mod_dev = Character(_('TFI Main Dev'))
No entanto, alertamos que algumas variáveis podem causar erros, portanto, recomenda-se gerar apenas os arquivos de tradução para linhas de diálogo, que exigem um identificador de tradução, enquanto o próprio texto traduzível serve como identificador para as variáveis.
# linha traduzível
translate english prologue_scene_0_89ef4bf6:
    "Humanity has always been afraid of the unknown."

# variável traduzível
translate english strings:
    old "Продолжение следует..."
    new "To be continued..."
Após gerar, mova a pasta tl para a pasta do seu mod e preencha os campos de tradução em todos os novos arquivos.
Também recomendamos criar um menu semelhante no início do seu mod, para que os usuários saibam quais idiomas estão disponíveis e que eles realmente estão acessíveis.
menu:
    with dissolve
    "{font=fonts/Merriweather-Regular.ttf}Я хочу играть на Русском{/font}":
      $ renpy.change_language("russian")
    "{font=fonts/Merriweather-Regular.ttf}I want to play in English{/font}":
      $ renpy.change_language("english")
    "{font=fonts/SourceHanSansCN-Regular.otf}{size=26}以简体中文开始{/size}{/font}":
      $ renpy.change_language("schinese")
    "{font=fonts/NotoSansJP-Regular.ttf}{size=26}日本語でプレイする{/size}{/font}":
      $ renpy.change_language("japanese")
Na data em que este guia foi feito, o jogo suporta 9 idiomas: Russo (russian), Inglês (english), Francês (french), Espanhol (spanish), Português do Brasil (portuguese), Chinês Tradicional (tchinese), Chinês Simplificado (schinese), Coreano (korean) e Japonês (japanese). Se você utilizar um idioma que não utilize os alfabetos de nenhum desses idiomas, será necessário incluir novas fontes em seu mod.
Recursos adicionais
Trabalhando com a câmera
Como os personagens são exibidos em uma tela separada, será necessário mover essa tela simultaneamente com a camada da câmera padrão caso você queira aplicar zoom (aproximar ou afastar) na imagem.
camera:
    perspective True
    gl_depth True
    zpos -1100 xpos -375 ypos -380
    easein 3.0 zpos 0 xpos 0 ypos 0
show layer add_l:
    perspective True
    gl_depth True
    zpos -1100 xpos -375 ypos -380
    easein 3.0 zpos 0 xpos 0 ypos 0

Tela de data e hora
O jogo inclui um recurso incorporado para exibir uma tela com a localização, a data e a hora, caso sua história também envolva dividir os eventos em dias e horas.
$ date_place = _("Muenzuka")
$ date_date = _("17 de abril de 2018")
$ date_time = _("Noite, algumas horas depois")
show screen date with dissolve

Tela de carregamento
Se a 'montagem' ou alterações de cores dos sprites forem significativas, elas podem causar um leve atraso no jogo, pois o RenPy precisa de tempo para processar e posicionar todas as imagens individualmente na tela. Para tornar esses momentos menos perceptíveis, criamos uma tela de transição com o texto "As garotas estão rezando…". Para acioná-la, será necessário usar o comando show screen loading, seguido de hide screen loading. Para transições mais suaves, escondemos e, em seguida, mostramos as janelas de diálogo com os seguintes comandos.
$ quick_menu = False
window hide dissolve

$ quick_menu = True
window show dissolve
Testando o Mod
Antes de publicar seu mod, você precisa garantir que ele funcione corretamente. O modo de desenvolvedor pode ajudar com isso. Para ativá-lo, adicione o seguinte código no seu bloco init:
define config.developer = True
define config.default_developer = True
Agora, se você pressionar a combinação de teclas Shift + R, o jogo será recarregado no mesmo ponto sempre que forem feitas alterações nos arquivos. Isso significa que você pode editar seu código rapidamente e ver os resultados imediatamente. No entanto, lembre-se de excluir esse trecho antes de enviar o mod.
Enviando o Mod
Depois de concluir todas as etapas, você precisará:
1. Colocar os arquivos do mod na pasta do mod dentro do aplicativo de envio. Não se esqueça da imagem de pré-visualização, que deve ser quadrada e ter pelo menos 500x500 pixels de resolução.
2. Insira todas as informações necessárias. Recomendamos mover toda a pasta _upload_app para algum lugar fora da pasta 2132480 para evitar conflitos com os arquivos de outros mods no futuro.
3. Adicione um comentário e clique no botão Submit. Todas as informações inseridas serão salvas no seu arquivo .workshop.json.

Se você ainda tiver alguma dúvida, sugerimos escrevê-la nos comentários deste guia para que possamos atualizar as informações. Esperamos que tudo dê certo para você, e boa sorte na criação de uma histórias de qualidade!