Lovely é um injetor lua que incorpora código em um jogo LÖVE 2d em tempo de execução. Ao contrário dos patchers executáveis, os mods podem ser instalados, atualizados e removidos repetidamente sem exigir a reinstalação parcial ou total do jogo. Isso é conseguido por meio do desvio da API lua no processo e de um sistema de patches fácil de usar (e distribuir).
lovely-x86_64-pc-windows-msvc.zip
x86_64-pc-windows-msvc.zip .version.dll
para o diretório do jogo. Você pode navegar até o diretório do jogo clicando com o botão direito no jogo no Steam, passando o mouse sobre "Gerenciar" e selecionando "Navegar pelos arquivos locais".%AppData%/Balatro/Mods
(se você estiver modificando o Balatro).WINEDLLOVERRIDES="version=n,b" %command%
.lovely-aarch64-apple-darwin.tar.gz
. Se você tiver uma CPU Intel, será lovely-x86_64-apple-darwin.tar.gz
liblovely.dylib
e run_lovely.sh
para o diretório do jogo. Você pode navegar até o diretório do jogo clicando com o botão direito no jogo no Steam, passando o mouse sobre "Gerenciar" e selecionando "Navegar pelos arquivos locais"./Users/$USER/Library/Application Support/Balatro/Mods
onde $USER
é o seu nome de usuário (se você estiver modificando o Balatro).Shift-Command-.
(ponto final) para mostrar arquivos ocultos no Finder.run_lovely.sh
em Terminal.app
em Aplicativos > Utilitários e pressionando Enter, ou executando sh run_lovely.sh
no terminal dentro do diretório do jogo. Observação: você não pode executar o jogo através do Steam no Mac devido a um bug no cliente Steam. Você deve executá-lo com o script run_lovely.sh
.
Importante : Mods com arquivos de patch Lovely ( lovely.toml
ou lovely/*.toml
) devem ser instalados em sua própria pasta dentro do diretório mod. Sem exceções!
Observe que o formato do patch é instável e propenso a mudanças até que o Lovely saia do início do desenvolvimento.
Os arquivos de patch definem onde e como a injeção de código ocorre no processo do jogo. Um bom exemplo (complexo) disso pode ser encontrado no repositório Steamodded aqui.
[ manifest ]
version = " 1.0.0 "
priority = 0
# Define a var substitution rule. This searches for lines that contain {{lovely:var_name}}
# (var_name from this example, it can really be anything) and replaces each match with the
# provided value.
# This example would transform print('{{lovely:var_name}}') to print('Hello world!').
#
# USEFUL: For when you want to reduce the complexity of repetitive injections, eg. embedding
# release version numbers in multiple locations.
[ vars ]
var_name = " Hello world! "
# Inject one or more lines of code before, after, or at (replacing) a line which matches
# the provided pattern.
#
# USEFUL: For when you need to add / modify a small amount of code to setup initialization
# routines, etc.
[[ patches ]]
[ patches . pattern ]
target = " game.lua "
pattern = " self.SPEEDFACTOR = 1 "
position = " after "
payload = '''
initSteamodded()
print('{{lovely:var_name}}')
'''
match_indent = true
times = 1
# Inject one or more lines of code before, after, at, or interwoven into one or more
# Regex capture groups.
# - I recommend you to use a Regex playground like https://regexr.com to build
# your patterns.
# - Regex is NOT EFFICIENT. Please use the pattern patch unless absolutely necessary.
# - This patch has capture group support.
# - This patch does NOT trim whitespace from each line. Take that into account when
# designing your pattern.
#
# USEFUL: For when the pattern patch is not expressive enough to describe how the
# payload should be injected.
[ patches . regex ]
target = " tag.lua "
pattern = " (?[ t ]*)if (?_context.type == 'eval' then) "
position = ' at '
line_prepend = ' $indent '
payload = '''
local obj = SMODS.Tags[self.key]
local res
if obj and obj.apply and type(obj.apply) == 'function' then
res = obj.apply(self, _context)
end
if res then
return res
elseif $cond
'''
times = 1
# Append or prepend the contents of one or more files onto the target.
#
# USEFUL: For when you *only* care about getting your code into the game, nothing else.
# This does NOT inject it as a new module.
[[ patches ]]
[ patches . copy ]
target = " main.lua "
position = " append "
sources = [
" core/core.lua " ,
" core/deck.lua " ,
" core/joker.lua " ,
" core/sprite.lua " ,
" debug/debug.lua " ,
" loader/loader.lua " ,
]
# Inject a new module into the game *before* a target file it loaded.
# USEFUL: For when you want to silo your code into a separate require-able module OR inject a "global" dependency before game / mod code begins execution.
[[ patches ]]
[ patches . module ]
source = " nativefs.lua "
before = " main.lua "
name = " nativefs "
pattern
para incorporar código cirurgicamente em locais específicos do alvo. Suporta *
(corresponde a 0 ou mais ocorrências de qualquer caractere) e ?
(corresponde exatamente a uma ocorrência de qualquer caractere) curingas.regex
somente quando o patch padrão não atender às suas necessidades. Este é basicamente o patch padrão, mas com um mecanismo de consulta regex de apoio, grupos de captura e tudo.copy
quando precisar copiar uma grande quantidade de código independente de posição no destino.module
para injetar um módulo lua no tempo de execução do jogo. Observe que atualmente isso suporta apenas módulos de arquivo único, mas isso deve mudar em breve. Os arquivos de patch são carregados dos diretórios mod dentro da pasta mod ( MOD_DIR
). Lovely irá carregar quaisquer arquivos de patch presentes em MOD_DIR/ModName/lovely/
ou carregar um único patch de MOD_DIR/ModName/lovely.toml
. Se vários patches forem carregados, eles serão injetados no jogo na ordem em que forem encontrados.
Os caminhos definidos no patch têm raiz no diretório do mod. Por exemplo, core/deck.lua
resolve para MOD_DIR/ModName/core/deck.lua
.
Cada definição de patch possui um único destino de patch. Esses alvos são os caminhos relativos dos arquivos de origem quando retirados do jogo com uma ferramenta como o 7zip. Por exemplo, pode-se direcionar um arquivo de nível superior como main.lua
ou um em um subdiretório como engine/event.lua
.
Lovely despeja arquivos de origem lua corrigidos em MOD_DIR/lovely/dump
. Os logs também são gravados em MOD_DIR/lovely/log
.
manifest.version