Files
shweets-sim/MODDING.md
T

22 KiB

Modding Shweet's Sim

Want to add characters or modify existing ones or mod Shweet's Sim in general or otherwise want to know how the game works? Here's how.

Animation Format

Shweet's Sim uses ".anm2" files for tweened character animations, sourced from spritesheets. The format comes from the game The Binding of Isaac: Rebirth (a game I mod on my own time), but the game reads the JSON flavor of it saved by my own animation editor, Anm2Ed. In Anm2Ed, turn on Save as JSON (Settings → Configure → Serialization), or convert an existing file with anm2ed convert file.anm2 --format json. Keep the .anm2 extension. Isaac's own editor can't open these.

Anm2Ed has "Regions", which let you set spritesheet regions (areas in the spritesheet that can be repurposed) to quickly reference in animations; previously, one would have to manually create a perfectly spaced spritesheet and then manually set values; this is no longer the case, so using "Regions" is recommended.

My process for making characters is that they're typically comprised of many "cells" (small graphics). I make these cells their own file, and then in the editor, I drag them onto "Spritesheets" and then right click -> merge them, with the "Make Spritesheet Regions" option enabled. Then, right click -> Pack on a spritesheet to optimize it all nice for one big spritesheet atlas with everything in one place. It won't produce a very comprehensible spritesheet, but it works just fine (not my problem). Make sure to save the spritesheets you're using once you're done. You can sort regions around by clicking, holding and moving them around.

If you'd like a quick primer on how to use the editor, check either of these videos out. They're a little out of date, but much of it still applies.

The game plays spritesheets, regions, layers, nulls, layer groups, events, trigger sounds, and the position, crop, pivot, scale, rotation, tint, color offset, visibility and easing of keyframes. It doesn't play skew, depth, blur, custom shaders or animation layers. Animation groups (the editor's folders) are fine; the game just looks animations up by name, so keep those unique.

Stage-specific character animations are controlled by animationSuffix on each stage in character.json. The base stage uses no suffix. Later stages append that stage's suffix.

Example:

  • stage 1: Look
  • stage 2 with "animationSuffix": "Stage2": LookStage2
  • stage 5 with "animationSuffix": "Stage5": LookStage5

Animation names in the JSON files should still use just the base name like Look, Neutral, or Eat. The game appends the current stage's suffix automatically.

Know that despite Anm2Ed supporting sounds for animations, don't expect these to work in context based on names; use the JSON sound lists when applicable. You can add sounds for fluff, though (trigger sounds play).

Resources

There's two folders inside resources; "characters" and "font".

"font" is just a font containing the font used in the selection screen. That's literally it.

"common" holds files characters share (sounds, particles, the cursor and so on). Whenever a character names a file, the game looks in the character's folder first, then in "common", so a character can use anything there as is, or replace it by having its own file at the same path. This includes the taskbar's icons, gfx/ui/icons.anm2: one region per icon, named after its button (talk, mood, spawn, autofeed, home, stats, catalog, settings, help, plus whatever icons the interaction types name). A character with its own gfx/ui/icons.anm2 gets its own icons.

EVERYTHING ELSE is stored inside character folders in the "characters" folder; one folder per character, named however you like (the folder name is also the name of its save file). This has all data associated with characters. Think of characters more as tailored game experiences rather than literally being just the characters. Not only is there the character graphics, but backgrounds, items, parameters, etc. These are intensely customizable to suit whatever experience you'd like (within the confines of the engine, of course).

Shweet's Sim uses JSON files for its data; make sure to brush up on the format. A character folder holds these files:

  • character.json
  • items.json
  • dialogue.json

character.json is required; a folder without one isn't listed. The other two are optional, but most real characters will want both.

Every path in these files is relative to the character's folder (e.g. "sfx/blip.ogg"), looked for there and then in "common". Paths inside an .anm2 are relative to the .anm2, and looked for the same way. Anything left out takes its default, so only write what you need.

Wherever sounds are listed, one is picked at random each time. A list can also be a single path, and a path with a * stands for every file it matches, e.g. "sfx/gurgle*.ogg"; drop a new variant in the folder and it's included.

Times are in seconds and chances in percent. The game warns (in its log) about keys it doesn't know, which are usually typos, and files it can't find.

If you're making your own character, your best bet would probably be just to copy the Snivy character and edit it based on your needs, just as a helpful start.

character.json

This is the main character file where much of the functionality is stored.

{
  "name": "Snivy",
  "anm2": "gfx/character/snivy.anm2",
  "weight": 8.1,
  "stages": [{"weight": 10, "dialoguePool": "Stage2", "animationSuffix": "Stage2"}],
  "animations": {"start": "Appear", "idle": "Neutral", "idleFull": "NeutralFull", "stageUp": "StageUp"},
  "sounds": {"digest": ["sfx/digest1.ogg"], "gurgle": ["sfx/gurgle1.ogg", "sfx/gurgle2.ogg"]}
}
Key Type Meaning
id string What the character's save is named after. Defaults to the folder name; set it to keep the save when renaming the folder.
name string Name of the character; will appear in dialogue, stats, etc. Defaults to the folder name.
description string A general description of the character; will show in the Select screen.
credits string Credits text shown in the Select screen's Credits tab.
render path Texture for the character's "render" (i.e., a typical full-body display), will show in the Select screen.
portrait path Texture for the character's "portrait" (i.e., a cropped profile view), will show in the Select screen.
anm2 path The character's anm2 file; should have all the character's animations.
color [r, g, b], 0-1 UI accent color for the character.
weight float, kg The character's starting weight.
weightMax float, kg Maximum weight the character can reach.
capacity float, kcal The character's starting capacity.
capacityMin, capacityMax float, kcal The range capacity stays within.
overstuffedMultiplier float The character can eat past capacity up to capacity times this.
overstuffedDigestBonus float Additional capacity gained on digest when the character was over capacity (scaled by how far over).
caloriesToKilogram float How many kilograms each calorie digested becomes.
digestionRate float, %/second The base digestion rate.
digestionRateMin, digestionRateMax float, %/second The range the digestion rate stays within.
digestionTime float, seconds When digesting, the digestion bar will count down, and then when it hits 0, the current calories will be digested. This determines how long this takes.
blinkChance float, % Chance each tick to blink.
gurgleChance float, % Chance each tick of a gurgle (see sounds), scaled by how full the character is.
gurgleCapacityMultiplier float Multiplies the gurgle chance at full capacity. Higher capacity = higher gurgle chance.
dialoguePool string The character's base dialogue pool for "How are you feeling?". This is effectively "Stage 1"'s dialogue; each stage should have its own dialogue pool.

alternate

The alternate spritesheet of the character, if applicable (in Pokemon terms, the "shiny").

Key Type Meaning
texture path The alternate spritesheet texture.
sound path Plays when the spritesheet is set to alternate (either on new game, or with an item that has isToggleSpritesheet).
spritesheet int The spritesheet of the character's anm2 it replaces. Defaults to 0.
chance float, % Chance of rolling the alternate spritesheet when starting a new game.

stages

A "stage" represents each visual change of the character as the weight increases. By default, there's always one stage; each entry in this list adds another.

Key Type Meaning
weight float, kg The weight threshold to reach this stage.
dialoguePool string The stage's dialogue pool for "How are you feeling?".
animationSuffix string Suffix appended to base animation names while this stage is active. Usually Stage2, Stage3, etc.
area int Switches to this area (from areas.list) from this stage on.

animations

The character's animations. Know that a lot of character animations are typically easily played through dialogue; this is just for animations that aren't reliant on that system. These are just the base names.

Key Meaning
start Plays first when starting a new game; used for like a character's introduction.
idle The idle animation that the character will regularly return to.
idleFull When over capacity, this idle animation will be used instead.
stageUp When going to a new stage after digestion goes over a stage's threshold, this animation will play.

"talk" and "blink" are animations tweaked by the game for effect. Typically, each animation will have an invisible blinking/talking layer (just the graphic that blinks), which will change when called for. All that's sourced is just the spritesheet crop in these cases; so don't worry about how the blink/talk layers are set up.

Key Meaning
source The layer in the animation which will be sourced.
destination The layer in the animation which the source will be applied to.

eatAreas

An "eat area" is where the food should be dragged to. I'm pretty much expecting this to only be a mouth for most characters but hey maybe you want the character to also eat through their butt or something.

Key Meaning
null The null in the animation where food will be checked for.
animation The animation that will play when food is dragged to it.
event The event that will be checked for, determining the time the food is actually eaten/chewed.

expandAreas

The areas which will expand based on how full the character is and their progress to the next stage (50/50); usually a stomach. This adds scale onto a layer and a null of every animation.

Key Meaning
layer The layer that will expand.
null The null that will expand.
scaleMax The scale (in percent) that will be added at maximum. Know that a scale of 100 is the normal scale of an animation.

interactTypes, interactAreas

interactTypes is an object of interaction types by name (each gets a button on the taskbar), giving each type's defaults. interactAreas is a list of the concrete areas on a character which can be interacted with; usually for belly rubs, kisses, etc. Each area names its type and takes all of that type's settings, changing whichever it gives itself.

Key Type Meaning
type string (Areas only) The interaction type to use.
null string (Areas) The null in which the interact area can be triggered.
layer string The layer that the scale effect (e.g. smacks) applies to.
icon string The region of gfx/ui/icons.anm2 shown on this type's taskbar button.
isHold bool If true, the interaction is held rather than clicked once.
cursorHover string The animation the cursor will play when hovering over the interact area.
cursorActive string The animation the cursor will play when interacting.
animation string A character animation to play on interacting, when the area has no dialogue pool.
idleOnEnd string The idle animation the character uses after interacting (e.g. turning around).
dialoguePool string The dialogue pool which will be drawn from when interacting.
dialoguePoolFull string Dialogue pool used when the character is over capacity.
dialogueCooldown float, seconds Time before interacting can start new dialogue again.
digestionClick float, % Digestion added each click.
digestionHover float, %/second Digestion added while the cursor moves, held.
scaleAmplitude float, % Size of the scale effect on clicking.
scaleCycles float How many oscillations the scale effect performs. Defaults to 1.
scaleTime float, seconds How long the scale effect lasts. Defaults to a third of a second.
sounds paths Sounds played when interacting.
particles strings Particles (see particles) spawned when interacting.

sounds

Key Meaning
digest Plays when the character begins digesting (digestion bar full).
gurgle Ambient sounds that play randomly based on capacity; see gurgleChance.

areas

"Areas" refers to the backgrounds of the game. Stages can switch between them (see stages).

Key Type Meaning
anm2 path The anm2 the areas use.
boundsNull string The null setting the world's bounds. Defaults to Bounds.
spawnNull string The null items spawn at random points within. If omitted or missing, boundsNull is used.
list list The areas. Each can set its own anm2, its gravity (applied to items' velocities per tick), friction (applied when items are grounded or hit walls) and airResistance.

cursor

Determines the cursor appearance and behavior. Without one, the system cursor is used.

Key Meaning
anm2 The anm2 file the cursor will use.
animations idle, click, hover (over an item), grab (an item), pan (with middle mouse), zoom (with the mouse wheel) and dispose (right clicking an item).
sounds grab (grabbing an item), release (letting go) and throw (letting go while dragging quickly).
particles grab: particles spawned when grabbing an item.

menu

Determines menu and general UI appearance and behavior.

Key Meaning
font The font the menu will use.
rounding The rounding of corners the UI will use.
sounds open and close (the taskbar or one of its windows), hover and select (a widget), and cheats (after entering a special code to activate cheats).

particles

An object of particles by name, each with the anm2 and animation it plays once where spawned.

items.json

Has all items and their parameters, alongside additional behavior. Items share one anm2, whose spritesheet holds every item as a region named after it (pack them in Anm2Ed with "Make Spritesheet Regions"). Each item shows its region in place of whatever the anm2's frames show, with the region's own size and pivot.

{
  "anm2": "gfx/items/item.anm2",
  "spawnDelay": 10,
  "rarities": {"Common": {"weight": 1, "sound": "sfx/common.ogg"}},
  "items": [
    {"name": "Apple", "category": "Food", "use": "edible", "rarity": "Common", "calories": 95}
  ]
}
Key Type Meaning
anm2 path The anm2 that items use.
spritesheet int The spritesheet of the anm2 holding the items' regions. Defaults to 0.
spawnDelay float, seconds Base cooldown before another item can be spawned.
spawnDelayMultiplier float Multiplies the spawn delay once per character stage. Values below 1.0 make item spawning faster as stage increases.
spawnLimit int Maximum number of items in the world at once.
sounds bounce (an item hitting a floor/wall/ceiling), dispose (an item disposed of), summon (an item spawned) and newItem (an item found for the first time).
particles dispose and summon.
rarities object Rarities, by name. Each has a weight (relative chance of spawning) and a sound that plays when one spawns.

items

Key Type Meaning
name string The name of the item.
id string What saves keep the item by. Defaults to its name; set it to keep saves when renaming the item.
description string Flavor text for the item.
region string The region of the items' spritesheet it shows. Defaults to its name.
anm2 path An anm2 of its own, if it animates differently.
category string The item's category, shown in the Catalog.
use string edible (food that can be eaten) or tool.
rarity string The item's rarity.
flavor string Flavor text (for food); honestly has no meaning but whatever.
calories float The amount of calories the item has (if food).
capacityBonus float Capacity increase granted as the item is eaten.
digestionBonus float, %/second The digestion rate added as the item is eaten.
gravity float The item's gravity, in pixels per tick (a 60th of a second); will use the area's if not given.
color [r, g, b], 0-1 Optional UI color for the item.
isToggleSpritesheet bool When used as a tool on the character, will toggle the character's spritesheet (in Pokemon terms, toggling normal/shiny palettes).

dialogue.json

The collection of character dialogue; likely the biggest file, depending on your needs.

{
  "speed": 30,
  "blipEvery": 2,
  "blip": "sfx/blip.ogg",
  "pauses": {".": {"delay": 0.08}},
  "hooks": {"Start": "Intro"},
  "entries": {
    "Intro": {
      "isScene": true,
      "lines": [
        {"animation": "Appear"},
        {"text": "Hey there, [shake]human[/shake]!", "animation": "Smug"}
      ],
      "choices": [{"text": "Hi!", "next": "Hello"}]
    },
    "Eat1": {
      "pools": ["Eat"],
      "lines": [{"text": "[big]Yum![/big]"}]
    }
  }
}
Key Type Meaning
speed float How many characters are revealed per second.
blipEvery int How many characters pass between blip sounds. 3 means every third character.
blip sounds Dialogue blip sounds, played periodically while text reveals.
pauses object Extra delay (in seconds) after particular characters. With isSilent, talking and blips also pause during it.
hooks object Gameplay events play the pool (or else the entry) named after them: Start, End, Help, StageUp, Random, Feed, FeedFull, Eat, EatFull, Full, Throw, LowCapacity, Digest, FoodTaken and FoodTakenFull. Hooks only lists ones that play something else. Random and Help add the "Let's chat!" and "Help" buttons.
entries object Each bit of dialogue is referred to as an "entry", by its label.

entries

An entry is lines played in order, after which it offers its choices or moves on to the next entry.

Key Type Meaning
lines list Each with its text and an animation (base name) that plays as it starts. A line without text just plays its animation, moving on once it ends.
choices list Dialogue can be branching; each choice has its text (shown as a button after the last line) and the next entry it leads to.
next string The entry that follows the last line. With neither choices nor next, the dialogue ends there.
pools strings The pools (lists of entries picked from at random) the entry is in.
isScene bool Hides windows and items and disables interaction until the dialogue reaches the end. A scene started in the middle of another is ignored.

markup

Effects go right in a line's text, as tags. A tag over part of the text has a closing tag: [shake]too bad[/shake]. The rest happen where they stand: [screenshake]BOOM. [[ is a plain [.

Tag Meaning
[color=r g b] Colors the text (0-1 each), e.g. [color=1 0.25 0.25].
[big], [small] Fixed text scales.
[wave], [shake] Moves the text, with engine defaults.
[silent] Suppresses blips and character talking.
[screenshake] Shakes the screen.
[sound=path] Plays a sound.
[animation=Name] Plays a character animation.
[delay=seconds] Changes the reveal speed to one character per this many seconds from here on.

Saves

Outside of resources, Shweet's Sim also has a few files it writes outside of the game. You will find these in %AppData%/shweets-sim on Windows and ~/.local/share/shweets-sim on Linux. Each is a plain text file of key=value lines.

settings.txt

Stores general game settings and configuration; beyond individual characters.

Key Meaning
measurement 0 for metric (kg/g), 1 for imperial (lb/oz).
volume Master volume, in percent.
mute 1 if all audio is muted.
color Red, green and blue (0-1) of the menu color.
character_color 1 to use the character's color while playing.
width, height Window size.
x, y Window position.
last_character The character being played at exit, which the game continues on start.
console 1 enables the developer console (the grave key).

saves/.txt

A character's progress: their weight, calories, capacity, digestion, totals and playtime, the camera, and the items found (discovered= lines) and lying in the world (item= lines, as position, velocity, rotation and id).