2.4.0#
- Adds heart events. An NPC folder can have an
Events.tomlwith one table per event, written in plain words (Location,Hearts, optionalWeather,Time,DaysandAfter, where theFarmerand theNpcstand, andStepssuch asRei: Hello.,Rei walks down 2,Rei emotes heart). NPC Helper compiles it to the game's event script and key (event ID<Npc>_<EventName>, thef <Npc> <hearts x 250>condition, music, camera, actors,skippable,end) and adds it toData/Events/<Location>. An event with a problem is skipped with a message that names the step. A whole game script can still be given asScript. - Adds festival lines. A
Festivals.tomlwith one table per festival ID (spring13,summer11...) gives the NPC herDialogueandSpouseDialogueat that festival, added toData/Festivals/<id>the way the game's own NPCs have theirs. Placing the NPC on the festival map is not supported yet. See events. - A marriageable NPC whose sprite sheet has nothing drawn in the spouse-kiss frame (28) or the wedding frames (36-38), or whose sheet ends before them, now gets a warning that names the frame (the game shows an invisible NPC there). Generated placeholder sprite sheets are now 64x320 so they include the wedding frames.
- A heart event that gives both
ScriptandStepsnow says that onlyScriptis used. - Heart events and festival lines can be translated. A
locale/<code>/Events.tomlhas a[EventName]table withTexts, the translated lines in the order they are said (the scene stays the base pack's), and alocale/<code>/Festivals.tomlreplaces the festivalDialogueandSpouseDialogue. A wrong number of lines, an unknown event or an unknown festival is reported. Translation templates (TranslationPack.BuildTemplate),TranslationPackBuilder.FromNpcand the SDK'sLocaleBuilder.EventLines/Festivalinclude them, andTranslationPack.Validatecompares them with the base pack. - The pack-structure check ignores files a mod manager leaves in a pack (Vortex's
*.vortex_backup,__folder_managed_by_vortex,vortex.deployment.json, Mod Organizer'smeta.ini,desktop.ini,Thumbs.db,.DS_Store), so installing through Vortex no longer logs warnings, and a language folder holding only such files is not reported as empty. - The pack-structure check no longer reports ordinary folders such as
docsas a misspelledNPCsfolder.
2.3.0#
- The TOML parser now supports all of TOML 1.0: dotted keys and nested tables, inline tables, hex/octal/binary integers,
inf/nan, and date-time values, with a strict mode (TomlParseOptions.Strict). NPC files still load leniently. An unquoted key with a dot (a.b = 1) is now a dotted key; quote it to keep the dot. - Locale folders are now layered: a regional folder such as
locale/pt-BRonly needs the texts that differ fromlocale/pt, which in turn override the base text. Previously only the most specific folder was read, so a partialpt-BRfolder hid the rest ofpt. Switching betweenen,en-USand an empty locale no longer reloads every NPC. - Packs laid out by hand are checked for misspelled or misplaced folders and files (
NPCs,locale,sprites,portraits, language codes such asth_TH,Dialog.toml, non-.tomlfiles, top-level.tomlfiles, a misnamedmanifest.jsonormod.toml), for NPC files missing from theNPCslist, and for a pack that loads nothing. At startup NPC Helper also warns when a pack has translations for an NPC that is not loaded and suggests the NPC it probably meant. mod.tomltakes more optional settings:Exclude(skip drafts),LocalesandTranslates(declare a translation pack's languages and NPCs, so a translation whose NPC mod is missing is reported at startup), andStrictToml(read the pack as strict TOML 1.0). Every setting is optional, none repeatsmanifest.json(a copy there is reported and ignored), and unknown settings are now reported.- Translations in other mods are now found through SMAPI's list of content packs for NPC Helper instead of walking the whole Mods folder. Only
NPCs/<Npc>/locale/<code>inside those packs is checked. A translation mod that is not a content pack for NPC Helper, or sits in a folder without a manifest, is no longer detected; use the Manual install into the NPC's own mod folder or the Manager (content pack) archive. - A content pack that only holds translations no longer warns "No NPCs found"; it logs which NPCs it translates.
- The startup log is now one grouped entry (NPCs per pack, language, errors and warnings) without file-system paths.
- Fixes external locale packs not being found when the Mods folder is a symbolic link or junction.
2.2.1#
2.2.0#
- Adds combined location-and-season sprite and portrait variants, named
<Location>_<Season>.png(for example,Hospital_Summer.png), with selection priority: location + season, location, season, then the default image. - Supports 2× portrait source sheets with
PortraitScale = 2in the content pack's rootmod.toml; NPC Helper downsamples every selected portrait, including seasonal/location variants and marriage portraits, to the game's native 64×64 face tiles. - Bumps NPC Helper, the SDK and CLI packages to
2.2.0.
2.1.1#
- Avoids the no-NPC warning for translation-only content packs that declare
NPCs = []inmod.toml. - Packages a translation pack's
mod.tomlbeside its manifest when the manifest is placed in a separate folder.
2.1.0#
- Changes the runtime SMAPI
UniqueIDtoFramework.Mod.NpcHelper; content pack host references and SDK-generated manifests/API lookups use the new ID. The SDK and CLI package IDs remain unchanged. - Groups the NPC Helper startup summary and diagnostics into one SMAPI log entry.
- Fixes startup in Thai by supplying the English
Data/NPCGiftTastesasset using the game's explicit English language code when the Thai translation mod requests its missing localized asset; translation-mod edits still apply afterward. - Supplies custom NPC sprites and portraits for localized asset requests, avoiding fallback attempts to load nonexistent game
.xnbfiles. - Detects Thai from the localized asset suffix or locale code without treating the nested English fallback load as Thai.
- Finds separate NPC locale packs across supported renamed/wrapped mod-manager layouts, while stopping at each mod manifest and reading only
NPCs/<NpcName>/locale.
2.0.0#
Renamed: NPC Helper 2#
At the 2.0.0 release, the mod was renamed NPC Helper 2 (with a new logo in assets/branding/); only its display name changed then, while identifiers remained unchanged. The runtime ID was subsequently changed to Framework.Mod.NpcHelper.
A hardening and refactor release, plus an SDK and a cleaner file format. The NPC files are not compatible with 1.x: the format change is listed first, then the other breaking changes.
New file format (breaking)#
The NPC files were reorganised so they are shorter to write and easier to read. Nothing about what an NPC can do was removed except the path keys, which were not needed.
-
<Name>.tomlis grouped into tables. The flat keys moved:1.x key now Gender,Age,Manner,SocialAnxiety,Optimism[Personality]with the same namesBirthdaySeason,BirthdayDay[Birthday]Season,DayHomeRegion,DefaultMap,DefaultX,DefaultY,DefaultFacing[Home]Region,Map,X,Y,FacingDatable,Marriageable[Romance]with the same namesLanguage,SocialTab,Calendar,EndSlideShow,IsDarkSkinned,CanReceiveGifts,CanGreetNearbyCharacters,PerfectionScore,CanCommentOnPurchasedShopItems,IntroductionsQuest,FlowerDanceCanDance[Options]with the same namesName,DisplayName,[Dialogue],[GiftTastes]unchanged -
Schedules are lists of stops.
[[Schedule]]blocks (seven lines per stop) became one[Schedule]table: the key is the schedule key and each stop is one string in the game's own syntax,Weekday = ["600 Town 10 12 2", "2200 bed"].Days/Season/Day/Heartsmoved into the key (fall_Mon_4,summer_12),Arrivalis theaprefix,ActionandEndMessagefollow the facing,GotoandRaware plain string values andNotFriendshipis a first list item. The scheduler itself is unchanged; the same game strings come out. -
No path keys, and the images are in folders.
CustomSpritePath,CustomPortraitPath,DialoguePath,SchedulePath,[Sprites]and[Portraits]are gone. The files are found by name:Dialogue.toml,Schedule.toml,Marriage.toml, and all images insprites/andportraits/:Default.pngis the main sprite sheet / portrait (wassprite.png/portrait.png),portraits/Marriage.pngthe wedding portrait (wasportrait_marriage.png), any other name a variant by location or season. Asprite.png,portrait.pngorportrait_marriage.pngleft in the NPC folder is reported. -
A second, easier way to write a schedule stop. Besides the game's
"600 Town 10 12 2", a stop can be spelled out:"6:00 Town x=10 y=12 face=down", with clock times (6:00,1:30pm,12:30am),x=/y=,up/right/down/left(orface=),anim=, andby 12:00for "must have arrived by". Both forms can be mixed and give the same game schedule. -
One marriage file. The
marriage/folder (engagement.toml,spouse_dialogue.toml,spouse_schedule.toml) is nowMarriage.tomlnext to the NPC file, with[Engagement]and[Dialogue]tables; the spouse schedule is the[Marriage]table ofSchedule.toml(next to[Schedule], with the same stop syntax);portrait_marriage.pngsits in the NPC folder.locale/<lang>/Marriage.tomlworks the same way. The unsupportedwedding_event.toml,spouse_room.tomlandpatio.tomlare no longer even looked for. -
mod.tomlis no longer written by the SDK and the CLI (every NPC inNPCs/loads); it is still read when a pack has one. -
Every key of the old format is reported when the NPC loads, with where it lives now, so a half-converted file tells you what is left.
-
NpcDefinition.CustomSpritePath,CustomPortraitPath,DialoguePath,SchedulePath,SpriteVariantsandPortraitVariantsand the SDK'sSpriteVariant(...)/PortraitVariant(...)(the ones that took a path) were removed;SpriteVariantFileandPortraitVariantFileremain.
New: every fixed game option is available (checked against the real game)#
Values the game itself defines now offer the game's complete real set, with the game's own names (game-options). Friendlier spellings are aliases on top of the real values.
- New NPC options:
Language(Default/Dwarvish),SocialTab(all four values; it was fixed atAlwaysShown, which is still the default),Calendar,EndSlideShow,IsDarkSkinned,CanReceiveGifts,CanGreetNearbyCharacters,PerfectionScore,CanCommentOnPurchasedShopItems,IntroductionsQuest,FlowerDanceCanDance. All reach the game'sCharacterData. - Item categories: all 39 the game defines, by name (
category:Gem, orItemCategory.Gemin the SDK) or number. A negative number that is not a real category is reported. - Schedules now cover the game's whole vocabulary, read from the game's own parser:
<day>keys (every season), heart-gated keys,rain2,GreenRain, passive-festival keys,bed, location omitted, time0(start of day), arrival (a), end message, and theGOTO,NOT friendshipand raw/MAILcommands. Spouse keys include festivals. - The SDK enums mirror the catalog exactly (a test enforces it), and the schedule DSL has a scope for every key kind.
Changed behaviour from this (breaking)#
DaywithoutSeasonis the game's plain<day>key (every season). 1.x wrotespring_<day>.- Stop times must be
0or600-2600in 10-minute steps. A time such as605is rejected; the game matches times exactly against its 10-minute clock, so it could never fire. - Two stops at the same time: the later one is skipped with a warning (the game rejects the whole key, leaving the NPC with no schedule that day). Before, both were written.
Actionmust be a single animation name (the game splits on spaces); a numericMapis rejected (the game would read it as "location omitted").Mapis now optional on a stop, andX/Yare not needed forbed.marriageJobandbusare tied to specific vanilla NPCs; using them on a custom NPC is flagged.
New: SDK, CLI and a standard pack structure#
NpcHelper.StardewValley.Sdk(NuGet, no SMAPI/game dependency): define NPCs in C# withNpcBuilderand produce either a TOML content pack (NpcPackBuilder) or a DLL mod (api.Register(npc, folder)). Both run on the normal NPC Helper 2 runtime mod from Nexus.npchelperCLI (NpcHelper.StardewValley.Cli, dotnet tool):new pack,new npc,new dll-mod,validate,inspect,pack.- Schedule problems (invalid time, map, facing, unusable spouse keys) are now reported when the NPC loads (at launch, in
npchelper validate) instead of the first time the game asks for the schedule. - The runtime's API class is now
public, and the SDK'sINpcHelperApiis a strict subset of it using framework types only (checked by a test).
Breaking changes#
- Strict validation. An NPC with an invalid
Name,Gender,Age,Manner,SocialAnxiety,Optimism,BirthdaySeason,BirthdayDay,DefaultMaporDefaultFacingis rejected with a clear error. Before,Enum.Parsethrew inside theData/Charactersedit, which broke every NPC. - NPC names may only contain letters (any language), digits,
_and-. - Paths are sandboxed.
mod.tomlentries must be relative and stay inside the content pack. Absolute paths and..escapes are ignored with a warning. (The NPC files have no path keys any more.) - A stop needs a time and a tile (
X Y; not forbed). Stops missing them (previously silently sent to Town 10,10), or with invalid times/maps/facings, are skipped with a warning. HomeRegionmust be one of the game's three regions,Town,DesertorOther(NPC.region_*). Anything else becomesOtherwith a warning, because no game code would ever match it.Marriageable = trueimpliesDatable = true(1.6 has one flag,CanBeRomanced).- Spouse schedule is written under the game's
marriage_keys. In 1.x it replaced the NPC's whole schedule with plain keys that the game ignores for spouses. Seasonal weekday overrides (Days+Season) are expanded into the date keys the game reads, because it has nomarriage_<season>_<weekday>key; spouseRainand no-Daysentries are skipped with a warning. Details in the Marriage reference. - No longer injected (the game does not read them in 1.6):
Data/NPCDispositions,Data/SpouseRooms,Data/SpousePatios, and the per-NPCwedding_<Name>event inData/Events/Farm. The fileswedding_event.toml,spouse_room.tomlandpatio.tomlare no longer read. (The old wedding injection used a key without conditions and a shifted event script, so it could fire a malformed event on the farm.) - TOML escapes are now standard:
\n,\t,\uXXXXare interpreted (1.x only handled\"and\\). Locale files that define[Schedule]now replace the base schedule instead of appending to it. - API:
INpcHelperApigainedRegisterNpcFromToml,IsNpcRegistered,GetRegisteredNpcNames.RegisterNpcstill exists, but it now validates and deep-copies its argument. NpcDefinition.AbsoluteSpritePath/AbsolutePortraitPathwere replaced byResolved*Pathproperties.
Bug fixes#
-
Own
NPCs/folder: marriage files (spouse_dialogue.toml,Engagement.toml…) were registered as NPCs. -
mod.tomlwith several entries on one line (NPCs = ["a", "b"]) was read as a single bad path; multi-line arrays were dropped. -
Multi-line arrays and multi-line (
""") strings in NPC files were silently dropped; table headers with a trailing# commentattached their keys to the wrong table; quoted keys kept their quotes. -
Manner,SocialAnxietyandOptimismwere never written toData/Characters. -
Gift tastes: item names (
"Joja Cola") are now resolved to IDs (previously they were passed through and split on the space);Universal_*placeholders in empty lists were removed; a/in a gift message no longer corrupts the entry. -
Characters/Dialogue/MarriageDialogue<Name>usedEditon an asset that does not exist for custom NPCs; it is now loaded. -
Engagement dialogue keys that belong to other NPCs (e.g.
Abigail0in Rei's file) are no longer injected. -
Images are loaded through each pack's SMAPI
ModContenthelper (correct decoding and alpha premultiplication for SMAPI 4.4) instead of rawTexture2D.FromStream, which gave dark fringes on soft edges. -
Sprites/portraits were reloaded every time an NPC changed location and dialogue/schedule caches were flushed with them. Now only the affected image is reloaded, and only when the chosen file actually changes.
-
NPCs are spawned with the game's own
Game1.AddCharacterIfNecessaryinstead of a hand-builtNPC(the game already spawnsSpawnIfMissingNPCs on load and every morning). Farmhands no longer try to spawn/warp NPCs in multiplayer. -
OnAssetRequestedno longer builds ~10 strings per NPC per asset; an exception in one NPC no longer affects the others. -
Locale overlay files are read in a stable order.
-
Spouses were warped out of the farmhouse on every load. The 1.x "early morning" warp moved any NPC that was not at its
DefaultMapwhenevertimeOfDay < 630, and a loaded save always starts at 6:00. The warp was redundant (the game already places NPCs) and has been removed; the schedule bootstrap now only runs for an NPC NPC Helper 2 itself just added. -
A deeply nested array (
[[[[…) overflowed the stack and killed the game. Nesting is limited to 16 levels and TOML files to 4 MB. -
An unexpected exception while loading one NPC is now logged for that NPC instead of aborting
Entry(which makes SMAPI disable the whole mod). -
Gift tastes accept item context tags (
egg_item,category_fruit) without a misleading warning; the game matches them against the gifted item. -
After a language change, live NPCs drop their cached schedule data.
-
Data/Characters,Data/NPCGiftTastesandData/EngagementDialogueare edited atEarlypriority so Content Patcher patches apply to NPC Helper 2's NPCs. -
A
marriage/folder on an NPC that is notMarriageablenow logs a warning instead of being silently ignored.
Known limitations (verified against the 1.6.15 game code)#
Portraits/<Name>_Marriageis shown only while the NPC speaks their wedding vows; the game never selects it anywhere else by itself.MarriageDialogue<Name>Roommate, spouse rooms and patios are not provided (see the Marriage reference).- Gift reaction text comes from
AcceptGift_*keys in the NPC's dialogue, not from the gift-taste string.
[HP] ReiMod#
- Version
2.0.0, requires NPC Helper 22.0.0. - Gift taste
Algae→Green Algae(the real item name).
1.2.0#
NpcHelper#
- Bumped mod version to
1.2.0. - Added automatic deployment for
[HP] ReiModduring build whenEnableModDeploy=true. - Improved marriage systems:
- Correct engagement data target (
Data/EngagementDialogue). - Added spouse schedule asset injection and runtime cache invalidation.
- Added case-insensitive marriage file resolution.
- Added locale-aware marriage file loading (
locale/<lang>/marriage). - Reloads marriage data on locale change.
- Correct engagement data target (
- Improved schedule key generation for seasonal day patterns.
[HP] ReiMod#
- Bumped content pack version to
1.2.0. - Updated required
NpcHelperminimum version to1.2.0. - Cleaned and standardized marriage data files:
marriage/engagement.tomlmarriage/spouse_dialogue.tomlmarriage/spouse_schedule.tomlmarriage/wedding_event.toml
- Added file-by-file locale coverage for marriage content:
locale/th/marriage/*locale/es-ES/marriage/*
- Normalized dialogue key parity in locale files to match base dialogue keys.