Developer Data Storage
Where each kind of data belongs. (Oxide equivalent: “Data Storage” + “Data Files” + “Configuring Plugins”.)
Decision table
Section titled “Decision table”| Data | Lua API | C# API | File | Notes |
|---|---|---|---|---|
| User settings | greg.config.* |
GregModSettingsService / GregConfigService |
config.json / MelonPreferences |
Survives updates; shown in Settings Hub |
| Runtime state | greg.save.* |
GregModSave, GregSaveEngine |
save.json / sidecars |
Write-through; save_now() forces flush |
| Bulk files | greg.io.* |
— | <modId>/data/… |
Sandboxed; JSON helpers included |
| Structured data | greg.json.* |
Newtonsoft.Json | — | parse / stringify (Lua) |
| World/grid state | — | GregSaveEngine (LiteDB), GregModPack |
gregSave_<guid>.greg.db, pack DTOs |
Gated writes; array bridges for Il2Cpp |
Lua APIs (exact)
Section titled “Lua APIs (exact)”-- config (config.json) and save (save.json): same shapegreg.config.get(key) / greg.config.get_or(key, default)greg.config.set(key, value) -- write-throughgreg.config.delete(key) -- -> boolgreg.config.has(key) -- -> boolgreg.config.keys() -- -> tablegreg.save.save_now() -- -> bool (force flush)
-- files, sandboxed to <modId>/data/greg.io.read_file(path) -- alias: read_textgreg.io.write_file(path, content) -- alias: write_textgreg.io.append_file(path, content)greg.io.delete_file(path)greg.io.file_exists(path) -- -> boolgreg.io.list_files(pattern?) -- -> tablegreg.io.read_json(path) -- -> table or nilgreg.io.write_json(path, table) -- -> boolgreg.io.data_dir -- read-only string
-- jsongreg.json.parse(text) -- -> table/string/number/boolean or nilgreg.json.stringify(value) -- -> string ("" on failure)
-- modulesrequire("name") -- <modDir>/<name>.lua, cachedrequire("@shared/name") -- shared folderSandbox: CoreModules.Preset_SoftSandbox; ResolveSafe rejects traversal (.., /, \); search patterns are sanitized; migrated legacy data/data nesting is handled automatically. Anything outside <modId>/data/ is rejected by design.
C# APIs
Section titled “C# APIs”GregConfigService.LoadConfig<T> / SaveConfig<T>— typed JSON, directories auto-created.GregPersistenceService.Set<T> / Get<T> / Has / Delete—%AppData%/gregCore/Saves/<key>.json, traversal-guarded names.GregModSave.Create / Fill / Read / ReadAll / Upsert / Remove— vanilla-list items keyed bymodFolderName(ItemSaveDTO with position/rotation/float+int arrays).GregModPackbuilder + reader —ShopItem / StaticItem / DllRef / SnapshotDTOs with Il2Cpp array bridges (To/FromFloat/Int/BoolArray).GregSaveEngine(LiteDB) —Initialize / SaveAll (gated) / LoadAll / SaveGridState / LoadGridState / GetCollection<T>;IsGregSavevalidates the header. Only grid/wall state belongs here.GregSaveGuard.RegisterSidecar / RegisterVanillaModuleMap— hook your world edits into backup → write → sanitize → load (see Core Save Engine).
- Never write vanilla save structures directly — go through sidecars/DTOs.
- Never reuse shop/item IDs or GUIDs (ranges:
100, 1000/2000/3000, 9001+— see Developer Shop Items). - Keep settings (user edits) separate from state (game writes).
- Validate on load: one bad entry must never abort the whole load (per-entry null-guards, like
GregNetworkIdHealing).