Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
NobleMod
Mod pour REPO (BepInEx), menu in-game (MenuLib), overrides de spawn optionnels. Dossier CustomSounds inclus ; config BepInEx au premier lancement.
| Date uploaded | 5 months ago |
| Version | 1.0.2 |
| Download link | raisery-NobleMod-1.0.2.zip |
| Downloads | 51 |
| Dependency string | raisery-NobleMod-1.0.2 |
This mod requires the following mods to function
BepInEx-BepInExPack
BepInEx pack for Mono Unity games. Preconfigured and ready to use.
Preferred version: 5.4.2305loaforc-loaforcsSoundAPI
A general use library to replace sounds in Unity games.
Preferred version: 2.0.11README
NobleMod
Mod BepInEx / Harmony pour R.E.P.O. — remplacement audio configurable, overrides optionnels du mob principal par niveau, et réglages in-game (nécessite MenuLib).
Auteur : Raisery
Français
Dépendances
- BepInEx (pack Thunderstore recommandé pour REPO)
- MenuLib (nickklmao) — menu NobleMod Settings dans les paramètres du jeu
Fonctionnalités principales
Contenu par défaut du paquet (Thunderstore)
- Sons : le paquet inclut déjà un mapping qui remplace certains sons du Huntsman par des extraits de vidéos d’Hervé Reigner (fichiers audio +
CustomSounds/replacements.jsonfournis). Tu peux tout modifier ou supprimer selon tes goûts. - Spawn : le
SpawnConfigfourni (ex.level_enemy_overrides.json) configure le Huntsman comme mob principal pour le niveau 1. Ce mapping s’applique lorsque l’optionEnableSpawnOverridesest activée dansBepInEx/config/raisery.noblemod.cfg(elle est désactivée par défaut).
Avertissement : les sons par défaut sont extraits de vidéos au langage grossier (contenu vulgaire). Prudence en stream, en public ou avec des mineurs : désactive les remplacements audio ou remplace les fichiers par du contenu adapté.
Sons personnalisés (CustomSounds)
- Remplacement des clips audio vanilla par tes fichiers
.ogg, décrits dansCustomSounds/replacements.json(fourni avec le paquet ou éditable après installation). - Correspondance par nom exact de clip vanilla, ou règles
contains:/exact:sur le nom du clip. - Tirages pondérés : pour une même règle, tu peux définir plusieurs variantes (fichiers custom et/ou conservation du son vanilla avec
{ "vanilla": true, "weight": … }). Les poids sont normalisés automatiquement. - Filtre optionnel sur la hiérarchie Unity (
AudioSourceHierarchyFilterdans la config) pour ne traiter que certaines sources (sinon : tout le jeu). - Découverte : en jeu, le mod peut enregistrer les noms de clips rencontrés dans un JSON hiérarchique pour t’aider à compléter ton mapping (voir options dans
raisery.noblemod.cfg).
Overrides de spawn (SpawnConfig, optionnel)
- Fichier JSON (par défaut
SpawnConfig/level_enemy_overrides.json) : associe un numéro de niveau à l’identifiant du mob principal à forcer. - Désactivé par défaut (
EnableSpawnOverrides) ; une fois activé, le mod applique le mapping si le mob existe pour le niveau, sinon fallback vanilla avec log.
Menu in-game
- Entrée dédiée (NobleMod Settings / NOBLEMOD selon version) dans les paramètres du jeu.
- Permet notamment d’activer ou désactiver à chaud les sons personnalisés et les overrides de spawn, avec sauvegarde dans la config BepInEx.
Configuration avancée
- Fichier généré automatiquement :
BepInEx/config/raisery.noblemod.cfg. - Nombreuses options : logs de remplacement, découverte de clips, debug audio, logs des choix pondérés, etc. (sections General, Spawning, Debug).
Installation (Thunderstore)
Avec le Thunderstore Mod Manager / app Thunderstore, les dépendances sont installées avec le paquet. Le gestionnaire extrait le contenu du zip (DLL + dossiers à la racine du paquet) dans le profil du jeu : tout ce qui se trouve à côté de NobleMod.dll (CustomSounds, SpawnConfig, …) est utilisé par le mod.
Notes
- Pour éditer
replacements.jsonou les overrides après installation, ouvre les fichiers dans le dossier du mod créé par ton gestionnaire (même répertoire que la DLL). - Le dépôt du projet contient une documentation développeur plus longue (mapping JSON détaillé, spawn, build).
English
Dependencies
- BepInEx (Thunderstore pack recommended for REPO)
- MenuLib (nickklmao) — NobleMod Settings entry in the game’s settings menu
Main features
Default package content (Thunderstore)
- Audio : the package ships with a mapping that replaces certain Huntsman sounds with excerpts from Hervé Reigner’s videos (audio files + supplied
CustomSounds/replacements.json). You are free to edit or remove any of it. - Spawn : the included
SpawnConfig(e.g.level_enemy_overrides.json) sets the Huntsman as the main mob for level 1. This mapping applies whenEnableSpawnOverridesis turned on inBepInEx/config/raisery.noblemod.cfg(it is off by default).
Warning: the default sounds are taken from videos with crude / vulgar language. Use discretion when streaming, in public, or around minors—turn off custom sound replacement or swap the files for content that fits your context.
Custom sounds (CustomSounds)
- Replace vanilla audio clips with your
.oggfiles, declared inCustomSounds/replacements.json(shipped with the package or editable after install). - Match clips by exact name, or use
contains:/exact:rules on clip names. - Weighted picks: one rule can list several variants (custom files and/or keep vanilla with
{ "vanilla": true, "weight": … }). Weights are normalized automatically. - Optional Unity hierarchy filter (
AudioSourceHierarchyFilter) so only certainAudioSourcepaths are processed (default: game-wide). - Discovery: while playing, the mod can write encountered clip names to a hierarchical JSON to help you extend your mapping (see
raisery.noblemod.cfg).
Spawn overrides (SpawnConfig, optional)
- JSON file (default
SpawnConfig/level_enemy_overrides.json) maps a level index to a main mob id to force. - Off by default (
EnableSpawnOverrides); when enabled, applies the mapping when valid, otherwise vanilla fallback with logging.
In-game menu
- Dedicated entry (NobleMod Settings / NOBLEMOD depending on build) under the game settings.
- Toggle custom sounds and spawn overrides at runtime; changes are saved to the BepInEx config file.
Advanced configuration
- Auto-generated config:
BepInEx/config/raisery.noblemod.cfg. - Many toggles: replacement logs, clip discovery, audio debug, weighted-pick logging, etc. (General, Spawning, Debug sections).
Installation (Thunderstore)
With Thunderstore Mod Manager / the Thunderstore app, dependencies install with the package. The manager extracts the zip (DLL + folders at package root) into your game profile; anything next to NobleMod.dll (CustomSounds, SpawnConfig, …) is what the mod loads.
Notes
- To edit
replacements.jsonor spawn overrides after install, use the files in your manager’s mod folder (same directory as the DLL). - The project repository has fuller developer docs (JSON mapping details, spawn rules, build steps).
CHANGELOG
Changelog
[1.1.1] - 2026-05-13
Ajouté
- Interrupteurs ON/OFF par fichier replacer (menu NobleMod, section « Replacer : … »), modifiables en pleine partie. Un
ConfigEntry<bool>par fichier sous[Replacers](Enable_<nom_fichier>, défauttrue).- Filtrage runtime : postfix Harmony sur
SoundReplacementHandler.TryGetReplacementClip— si le toggle du fichier source est OFF, le remplacement est annulé (__result = false) et le son vanilla s’applique aux prochains déclenchements. - Coupure locale : passage OFF →
AudioSource.Stop()sur les sources suivies pour ce fichier ; pas de réplication réseau (le pool multijoueur continue de tourner pour les autres joueurs).
- Filtrage runtime : postfix Harmony sur
- Sound pack : extension des replacers (
headman.json,hunter.json,noblemod.json,object-destroy.json,player.jsondansreplacers/) — chaque fichier apparaît automatiquement comme toggle au prochain démarrage après installation.
Technique
- Découverte fiable : SoundAPI ne remplit pas
SoundPack.ReplacementCollectionspour les JSON sousreplacers/; le scan parcourt le dictionnaire interneSoundPackDataHandler.SoundReplacementset regroupe parSoundReplacementCollection.FilePathsous le dossier deNobleMod.dll. - Correctifs : réflexion
LoadedPacksavec getter interne ; postfixAddLoadedPackavec typeSoundPackqualifié (conflit de namespaceNobleMod.SoundPack) ; reconstruction de la popup menu si des replacers sont découverts après la première construction du cache.
[1.1.0] - 2026-05-13
Ajouté
- Cohérence multijoueur des sons aléatoires : tous les joueurs entendent désormais la même variante quand un son a plusieurs candidats. Le master diffuse un pool d'entiers partagé via REPOLib
NetworkedEvent(Photon,EventCaching.AddToRoomCacheGlobalpour que les joueurs qui rejoignent en cours de partie reçoivent immédiatement le dernier pool), chaque client l'indexe localement via une clé stable (matches du groupe + ViewID du PhotonView le plus proche + clip vanilla + occurrence temporelle quantifiée sur PhotonNetwork.Time) — pas de trafic réseau par tirage, juste un broadcast initial + topup périodique. Couvre :- Les tirages
NobleMod:random_slot(mode plageRet mode slot, sticky et non-sticky). - Les tirages internes SoundAPI (
UnityEngine.Random.RangedansSoundReplacementHandler.TryGetReplacementClip: choix du groupe quand plusieurs matchent + choix pondéré du son). Patch Harmony qui sauvegarde/restaureRandom.stateautour d'unInitStatedéterministe — couvre par exemplenoblemod_headman.jsonoù chacarron / smash-mouth étaient tirés indépendamment chez chaque joueur.
- Les tirages
- Config (fichier seul, pas de toggle menu) section
[Multiplayer]:EnableMultiplayerSoundSync(défauttrue).MultiplayerSoundPoolSize(défaut256, borne[16..4096]).MultiplayerSoundPoolRefreshIntervalSeconds(défaut300,0= jamais après init / changement de niveau).LogMultiplayerSoundSync(défautfalse) — log VERBEUX par évaluation. Les événements critiques (broadcast pool, réception, transitions room/master/player count, heartbeat 15 s) sont toujours loggés.
- Architecture :
- Driver de polling branché via Harmony postfix sur
Photon.Pun.PhotonHandler.LateUpdateplutôt que surBaseUnityPlugin.Update(non invoqué de façon fiable dans le contexte BepInEx / REPO observé). - Patch SoundAPI installé manuellement (résolution
TryGetReplacementClippar nom, sans contrainte de signature) pour rester silencieusement no-op si une future version de loaforcsSoundAPI change l'API — pas d'exception qui casseraitHarmony.PatchAll.
- Driver de polling branché via Harmony postfix sur
- Fallback automatique : si la sync est OFF, pas en room, room solo (≤ 1 joueur), pool pas encore reçu, ou clé non identifiable → retour à
UnityEngine.Random.Rangelocal (comportement actuel, aucune régression). - Validé en multijoueur réel (2 PC, master + client distant) : même
eventCodenégocié, génération de pool alignée, sons synchronisés sans latence perceptible.
[1.0.3] - 2026-05-12
Ajouté
- Ce fichier
CHANGELOG.mdpour suivre les changements entre releases. - Condition SoundAPI
NobleMod:random_slot: mode slot (slot,count,slot_weightsoptionnel pour pondération), mode plage (random_match/random_number, syntaxe value-range SoundAPI, tirageRuniforme 1..1000 partagé,..et normalisation...→..), optionsticky; Harmony surloaforcsSoundAPI.Core.AudioSourceAdditionalData.Updatepour le contexte d’évaluation + clampAudioSource.timeaprès swap de clip. - Config :
EnableNobleModSoundPackConditions([SoundPack], défauttrue) + toggle menu « Conditions pack NobleMod (SoundAPI) » ;LogRandomSlotRange(défautfalse) — logR = … -> son ….ogguniquement quandRchange par source ;LogStickyAttachDetach(défautfalse) — logs Sticky plage|slot : branché / débranché (premier attache, nouveau clip, boucle) ;LogSoundPickEachMatch(défautfalse) + toggle « Log chaque son selectionne (random_slot) » — à chaque évaluation où la ligne matche, log du nom du fichiersound(très verbeux avecupdate_every_frame). - Sound pack :
replacers/noblemod_hunter_hum.jsonavecupdate_every_frame, conditions plage +sticky: true pour le clipenemy hunter humming loop.
Modifié
- Audio : délégation à loaforcsSoundAPI (sound pack) ; suppression de l’ancien reshuffle humming côté DLL au profit de
update_every_framedans le JSON. - Dépôt : arborescence
src/,content/(sound-pack,spawn,samples),build/; code C# déplacé hors racine (anciensPlugin.cs,SoundBank, patches audio internes, parseurs remplacements, etc. supprimés au profit du sound pack) ;BepInDependencyme.loaforc.soundapi; référence de buildme.loaforc.soundapi.dll(copie viabuild/Copy-RepoRefs.ps1). - Spawn : helper
RunLevel.TryGetCurrentLevelNumber()(src/RunLevel.cs) partagé avec les patches d’override pour lire le niveau courant viaRunManager/levelsCompleted. .gitignore: ignore les assets lourds ou locaux (content/sound-pack/sounds/,content/spawn/,refs/,dist/,bin/,obj/,thunderstore/,.cursor/, etc.) pour garder le dépôt léger.- Thunderstore :
descriptiondumanifest.jsoncourte ; détails dans le README ; pas de dépendance au paquet deprecatedloaforcsSoundAPI_REPO(BepInEx + REPOLib + loaforcsSoundAPI + MenuLib) ; REPOLib en dépendance BepInEx dure côté plugin etZehs-REPOLib-4.0.2épinglé dans le manifest. - Sound pack :
matchesau format trois segments*:*:nom du clip.
Corrigé
- Audio (clamp) : le clamp sur chaque écriture de
AudioSource.timeet la marge sous la fin du clip coupaient souvent le son avant la fin et perturbaient le début ; désormais correction seulement si la position est hors clip (< 0,≥ length, NaN). Patch du settertimeretiré. LogSoundPickEachMatch: résolution du nom du fichier viaSoundInstance.Soundou réflexion surParent(propriétés/champs courants) ; si introuvable, log du typeParentpour diagnostic.- Retrait du cycle « hold après débranchement + une frame de latch » sur le sticky plage : il forçait des conditions à
falsetrop longtemps et provoquait des sons qui ne démarrent pas au début et coupures avant la fin avec SoundAPI. NobleMod:random_slot(sticky) : siisPlayingétait faux un court instant, le code retirait un nouveauR(coalesced) au lieu de garderChosenPick→ coupure de son ; réutilisation deChosenPickavec le même clip ; seuil de saut arrière0.18s. Idem mode slot sticky. Warmup par groupe : tant que la source n’est pas prête (null/ pas de clip /!isPlayingsans état pause), un mêmeR(ou slot) est figé parSoundReplacementGroupau lieu du tirage coalescé par frame, pour éviter plusieurs changements de tirage avant le premier play réel. Anti-churn : pendant 64 frames après un attache complet, une empreinte qui fluctue encore trop vite ne déclenche pas refresh deR/logs. Anti-faux « boucle » : 40 frames après attache, pas de détection boucle ;jumpedBackexige en plus une position inférieure à 0,4 s. Identité logique : nom normalisé (sans préfixeNobleMod) ⇒ empreinte = hash du nom seul (les copies vanilla / pack ne divergent plus sur la durée) ; clip au nom vide ⇒ même empreinte si longueur à ≤ 0,35 s près du dernier nom vu ; sinon hash longueur/fréquence/canaux ; reset d’ancre sur vrai changement de clip.- Packaging : zip Thunderstore via ZipArchive et chemins relatifs explicites.
Note
- L’expérimentation reshuffle humming en DLL a été retirée au profit du sound pack SoundAPI documenté ci-dessus.
[1.0.2] - 2026-05-09
Modifié
- Audio : délégation à loaforcsSoundAPI (sound pack :
sound_pack.json,replacers/,sounds/). Suppression du remplacement audio Harmony interne (SoundBank, patches dédiés). - Dépôt : arborescence
src/,content/(sound-pack,spawn,samples),build/(scripts PowerShell). - Thunderstore : archive avec chemins
BepInEx/plugins/NobleMod/...(aligné sur les paquets REPO courants).
Corrigé
- Génération du zip Thunderstore via ZipArchive et chemins relatifs explicites (évite les soucis de
Compress-Archiveselon les versions PowerShell).
[1.0.1] - 2026-05-08
Modifié
- Itérations sur le packaging Thunderstore et les scripts d’installation profil (voir 1.0.2 pour la forme stabilisée).
[1.0.0]
Ajouté
- Première base publique du mod : plugin BepInEx, intégration menu (MenuLib), config spawn, remplacements audio (format interne, remplacé en 1.0.2 par un sound pack SoundAPI).