Ship a disk example pack so last-wins, patches and create-with-a-mod are tested for real.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Leonid Pershin
2026-08-20 01:06:12 +03:00
co-authored by Cursor
parent edd3d35c79
commit 505b1429ab
20 changed files with 405 additions and 14 deletions
+36
View File
@@ -0,0 +1,36 @@
# Example pack
A tiny fixture, not content. It sits next to `core` and is **off until the player ticks it**.
Vanilla play does not change without that tick.
## Layout
```
example/
pack.jsonc # version + requires: ["core"]
localizations/{ru,en}.jsonc
defs/traits/traits.jsonc # two traits
defs/namesets/example.jsonc
defs/rooms/store.jsonc # one placeable room
defs/things/chair.jsonc # last-wins: same defName as core
patches/principals-office.jsonc
README.md # this file
```
The pack name is the `example` key in the locale files, not a field in `pack.jsonc`.
## How to add something
1. New type: a JSONC file under `defs/<kind>/`. The folder chooses the kind (`traits`, `rooms`, …);
the object needs a `defName`.
2. Label: the same `defName` (or the pack id) in both locale files. Missing keys load, but the UI
shows the raw id and the loader warns.
3. Edit a core type without copying it: a file in `patches/` with `target` and `add` / `replace` /
`remove`. Patches run after inheritance, in pack order.
4. Same `defName` as `core` (or an earlier pack): the later file wins and the log warns. That is
what `defs/things/chair.jsonc` is for — a sample of last-wins, not a better chair.
5. Default map: only `maps/default.jsonc` replaces the layout, last file wins. This pack does not
ship one, so a school with the pack still uses core's yard.
There is no `maps/` folder here on purpose. A layout that uses `ExampleStore` is a create-dialog
map, not a second default school.
@@ -0,0 +1,17 @@
{
"defName": "ExampleNames",
"patronymicRule": "slavic",
"defaultGivenDeclension": "hard",
"defaultSurnameDeclension": "ov",
"nativeLanguages": ["RussianLanguage"],
"relatedLanguageChance": 0,
"maleGiven": [
{ "form": "Иван" },
],
"femaleGiven": [
{ "form": "Анна", "declension": "a" },
],
"surnames": [
{ "male": "Тестов", "female": "Тестова" },
],
}
@@ -0,0 +1,7 @@
{
"defName": "ExampleStore",
"slots": [
{ "key": "lockers", "thing": "Locker", "count": 4 },
],
"travelMinutes": 0.5,
}
@@ -0,0 +1,2 @@
// Same defName as core: the last pack wins and the loader warns. Chat is already a core action.
{ "defName": "Chair", "actions": ["Sit", "Chat"] }
@@ -0,0 +1,14 @@
[
{
"defName": "ExampleEarlyRiser",
"weight": 1,
"incompatible": ["ExampleNightOwl"],
"commuteMinutes": 2,
},
{
"defName": "ExampleNightOwl",
"weight": 1,
"incompatible": ["ExampleEarlyRiser"],
"commuteMinutes": -2,
},
]
@@ -0,0 +1,7 @@
{
"example": "Example pack",
"ExampleEarlyRiser": "Early riser",
"ExampleNightOwl": "Night owl",
"ExampleNames": "Example names",
"ExampleStore": "Storeroom",
}
@@ -0,0 +1,7 @@
{
"example": "Пример мода",
"ExampleEarlyRiser": "Ранняя пташка",
"ExampleNightOwl": "Сова",
"ExampleNames": "Примерные имена",
"ExampleStore": "Кладовая",
}
@@ -0,0 +1,4 @@
{
"version": "1.0",
"requires": ["core"],
}
@@ -0,0 +1,6 @@
{
"target": "PrincipalsOffice",
"ops": [
{ "op": "add", "path": "/slots/-", "value": { "key": "exampleLocker", "thing": "Locker" } },
],
}