Lovely est un injecteur Lua qui intègre du code dans un jeu LÖVE 2d au moment de l'exécution. Contrairement aux correctifs exécutables, les mods peuvent être installés, mis à jour et supprimés encore et encore sans nécessiter une réinstallation partielle ou totale du jeu. Ceci est accompli grâce à un détour par l'API Lua en cours et à un système de correctifs facile à utiliser (et à distribuer).
lovely-x86_64-pc-windows-msvc.zip
.version.dll
dans le répertoire du jeu. Vous pouvez accéder au répertoire du jeu en cliquant avec le bouton droit sur le jeu dans Steam, en survolant « Gérer » et en sélectionnant « Parcourir les fichiers locaux ».%AppData%/Balatro/Mods
(si vous modifiez Balatro).WINEDLLOVERRIDES="version=n,b" %command%
.lovely-aarch64-apple-darwin.tar.gz
. Si vous avez un processeur Intel, ce sera lovely-x86_64-apple-darwin.tar.gz
liblovely.dylib
et run_lovely.sh
dans le répertoire du jeu. Vous pouvez accéder au répertoire du jeu en cliquant avec le bouton droit sur le jeu dans Steam, en survolant « Gérer » et en sélectionnant « Parcourir les fichiers locaux »./Users/$USER/Library/Application Support/Balatro/Mods
où $USER
est votre nom d'utilisateur (si vous modifiez Balatro).Shift-Command-.
(point) pour afficher les fichiers cachés dans le Finder.run_lovely.sh
sur Terminal.app
dans Applications > Utilitaires, puis en appuyant sur Entrée, ou en exécutant sh run_lovely.sh
dans le terminal dans le répertoire du jeu. Remarque : vous ne pouvez pas exécuter votre jeu via Steam sur Mac en raison d'un bug dans le client Steam. Vous devez l'exécuter avec le script run_lovely.sh
.
Important : les mods avec des fichiers de patch Lovely ( lovely.toml
ou dans lovely/*.toml
) doivent être installés dans leur propre dossier dans le répertoire du mod. Aucune exception !
Notez que le format du correctif est instable et susceptible de changer jusqu'à ce que Lovely soit sorti des premiers stades de développement.
Les fichiers de correctifs définissent où et comment l'injection de code se produit dans le processus de jeu. Un bon exemple (complexe) de ceci peut être trouvé dans le dépôt Steamodded ici.
[ 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
pour intégrer chirurgicalement du code à des emplacements spécifiques de la cible. Prend en charge *
(correspond à 0 ou plusieurs occurrences de n'importe quel caractère) et ?
(correspond à exactement une occurrence de n'importe quel caractère) caractères génériques.regex
uniquement lorsque le correctif de modèle ne répond pas à vos besoins. Il s'agit essentiellement du correctif de modèle, mais avec un moteur de requête regex de support, des groupes de capture et tout.copy
lorsque vous devez copier une grande quantité de code indépendant de la position dans la cible.module
pour injecter un module Lua dans le runtime du jeu. Notez que cela ne prend actuellement en charge que les modules à fichier unique, mais cela devrait bientôt changer. Les fichiers de correctifs sont chargés à partir des répertoires mod à l'intérieur du dossier mod ( MOD_DIR
). Lovely chargera tous les fichiers de correctifs présents dans MOD_DIR/ModName/lovely/
ou chargera un seul correctif à partir de MOD_DIR/ModName/lovely.toml
. Si plusieurs correctifs sont chargés, ils seront injectés dans le jeu dans l'ordre dans lequel ils ont été trouvés.
Les chemins définis dans le patch sont enracinés dans le répertoire du mod. Par exemple, core/deck.lua
se résout en MOD_DIR/ModName/core/deck.lua
.
Chaque définition de correctif possède une seule cible de correctif. Ces cibles sont les chemins relatifs des fichiers sources lorsqu'ils sont vidés du jeu avec un outil comme 7zip. Par exemple, on peut cibler un fichier de niveau supérieur comme main.lua
, ou un fichier dans un sous-répertoire comme engine/event.lua
.
Lovely dumps les fichiers source Lua corrigés dans MOD_DIR/lovely/dump
. Les journaux sont également écrits dans MOD_DIR/lovely/log
.
manifest.version