Dialogue markup and lines, shared common folder, item atlases, ids, seconds and key checks

This commit is contained in:
shweet committed 2026-11-12 22:51:11 -05:00
1 parent 3e9a0cbd34
commit f900a0d01f
217 files changed
+6833 -6426

No files matched your search

+68 -54
View File
@@ -32,6 +32,8 @@ 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.
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](https://en.wikipedia.org/wiki/JSON) files for its data; make sure to brush up on the format. A character folder holds these files:
@@ -42,7 +44,11 @@ Shweet's Sim uses [JSON](https://en.wikipedia.org/wiki/JSON) files for its data;
`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"` or `"gfx/items/apple.png"`). Paths inside an .anm2 are relative to the .anm2. Anything left out takes its default, so only write what you need. Wherever sounds are listed, one is picked at random each time.
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.
@@ -63,6 +69,7 @@ This is the main character file where much of the functionality is stored.
| 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. |
@@ -79,9 +86,9 @@ This is the main character file where much of the functionality is stored.
| `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` | int, ticks | 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. |
| `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 | How often the character will gurgle (see `sounds`) per tick, scaled by how full they are. |
| `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. |
@@ -157,12 +164,12 @@ The areas which will expand based on how full the character is and their progres
| `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` | int, ticks | Ticks before interacting can start new dialogue again. |
| `dialogueCooldown` | float, seconds | Time before interacting can start new dialogue again. |
| `digestionClick` | float, % | Digestion added each click. |
| `digestionHover` | float, % | Digestion added each tick the cursor moves while held. |
| `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, ticks | How long the scale effect lasts. Defaults to 20. |
| `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. |
@@ -208,46 +215,46 @@ An object of particles by name, each with the `anm2` and `animation` it plays on
# items.json
Has all items and their parameters, alongside additional behavior.
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.
```json
{
"anm2": "gfx/items/item.anm2",
"spawnDelay": 600,
"categories": {"Food": "edible", "Tool": "tool"},
"spawnDelay": 10,
"rarities": {"Common": {"weight": 1, "sound": "sfx/common.ogg"}},
"items": [
{"name": "Apple", "texture": "gfx/items/apple.png", "category": "Food", "rarity": "Common", "calories": 95}
{"name": "Apple", "category": "Food", "use": "edible", "rarity": "Common", "calories": 95}
]
}
```
| Key | Type | Meaning |
|---|---|---|
| `anm2` | path | The base anm2 file that items will use. |
| `spritesheet` | int | The spritesheet of the anm2 that an item's `texture` replaces. Defaults to 0. |
| `spawnDelay` | int, ticks | Base cooldown before another item can be spawned. |
| `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`. |
| `categories` | object | The kinds of items, by name; will appear in Catalog tooltips. Each says how its items are used: `edible` (food that can be eaten) or `tool`. |
| `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. Saves keep items by name. |
| `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. |
| `texture` | path | The texture the item uses. |
| `anm2` | path | The item's own anm2, if needed. |
| `category` | string | The item's category. |
| `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; will use the area's if not given. |
| `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). |
@@ -257,18 +264,23 @@ The collection of character dialogue; likely the biggest file, depending on your
```json
{
"delay": 2,
"blipDelay": 2,
"blip": ["sfx/blip.ogg"],
"pauses": {".": {"delay": 5}},
"hooks": {"Start": "Start", "Eat": "Eat"},
"pools": {"Eat": ["Eat1", "Eat2"]},
"speed": 30,
"blipEvery": 2,
"blip": "sfx/blip.ogg",
"pauses": {".": {"delay": 0.08}},
"hooks": {"Start": "Intro"},
"entries": {
"Start": {
"text": "Hey there, human!",
"animation": "Smug",
"choices": [{"text": "Hi!", "next": "Start2"}],
"effects": [{"type": "shake", "start": 4, "end": 9}]
"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]"}]
}
}
}
@@ -276,35 +288,37 @@ The collection of character dialogue; likely the biggest file, depending on your
| Key | Type | Meaning |
|---|---|---|
| `delay` | int, ticks | How many ticks pass before the next dialogue character is revealed. |
| `blipDelay` | int | How many displayed dialogue characters pass between blip sounds. `3` means every third displayed character. |
| `blip` | paths | Dialogue blip sounds, played periodically while text reveals. |
| `pauses` | object | Extra `delay` (in ticks) after particular characters. With `isSilent`, talking and blips also pause during it. |
| `hooks` | object | Connects gameplay events to a pool (or else an entry) by name. The hook names are `Start`, `End`, `Help`, `StageUp`, `Random`, `Feed`, `FeedFull`, `Eat`, `EatFull`, `Full`, `Throw`, `LowCapacity`, `Digest`, `FoodTaken` and `FoodTakenFull`. `Random` and `Help` add the "Let's chat!" and "Help" buttons. |
| `pools` | object | A "pool" of dialogue is a list of entry labels, one picked at random when used. |
| `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 |
|---|---|---|
| `text` | string | The actual dialogue content of the entry. Supports Unicode, provided the font contains the characters. An entry without text just plays its animation. |
| `animation` | string | A character animation that will play at the beginning of the dialogue. Again, just the base name for the animation, no stage numbers. |
| `next` | string | The label of the entry that will follow this one. If no next entry, the text will not continue. Make sure to connect these. |
| `choices` | list | Dialogue can be branching; each choice has its `text` (shown as a button) and the `next` entry it leads to. |
| `effects` | list | Effects over the text, each with a `type`, and a `start` and `end` (the characters it covers, from `start` up to `end`). |
| `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. |
### effects
| Type | Meaning |
### 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` | Colors the text, by `color` ([r, g, b], 0-1). |
| `big`, `small` | Fixed text scales. |
| `oscillation`, `shake` | Moves the text, with engine defaults. |
| `silent` | Suppresses blips and character talking for its range. |
| `screenshake` | Shakes the screen when its `start` comes up. |
| `sound` | Plays its `sound` (a path) when its `start` comes up. |
| `animation` | Plays its `animation` when its `start` comes up. |
| `delay` | Changes the reveal speed to its `delay` (in ticks) from its `start` on. |
| `scene` | Hides windows and items and disables interaction until the dialogue chain reaches and finishes its last entry. If another scene appears while one is active, it is ignored. |
| `[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
@@ -325,5 +339,5 @@ Stores general game settings and configuration; beyond individual characters.
| `last_character` | The character being played at exit, which the game continues on start. |
| `console` | `1` enables the developer console (the grave key). |
## saves/<character>.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 name).
## saves/<character id>.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).