{"id":"ericplane/scribe","name":"scribe","scope":"ericplane","platform":"roblox","description":"Persistent, fully-typed, automatically-replicated player data for Roblox Luau, built on ProfileStore.","version":"2.0.0","latest":"2.0.0","versions":["1.0.6","1.0.7","1.0.8","1.0.9","1.0.10","1.0.11","1.0.12","1.1.0","1.2.0","1.2.1","1.3.0","1.3.1","1.3.2","2.0.0"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{},"integrity":"0a7fa7872a8f75accce332e1f8ae195ea173e7d626a5372768a61306f9098e22","likes":0,"downloads":0,"install":"forest install ericplane/scribe","url":"https://forest.dev/p/roblox/ericplane/scribe","files":"https://api.forest.dev/ai/package/roblox/ericplane/scribe/files","readme":"# Scribe\n\n**Persistent, fully-typed, automatically-replicated player data for Roblox Luau, built on [ProfileStore](https://madstudioroblox.github.io/ProfileStore/).**\n\n📖 **[Full documentation → ericplane.github.io/Scribe](https://ericplane.github.io/Scribe/)**\n🔌 **[Studio plugin → Scribe Studio](https://create.roblox.com/store/asset/113609038046646/Scribe-Studio)**\n\n```toml\n# wally.toml\n[dependencies]\nScribe = \"ericplane/scribe@2.0.0\"\n```\n\n- **Fully typed.** A type-solver-generated accessor tree types your data end to end (`data.Coins.Increment(50)`, nested containers, arrays, and datatype fields), checked at compile time.\n- **Schemas all the way down.** `Scribe.ArrayOf` and `Scribe.DictOf` give array and dictionary *entries* a schema, so `data.Plots[1].Origin` is a typed `CFrame` that packs to 13 bytes, with per-element bounds and size caps.\n- **Replication for free.** Schema-compressed batched diffs stream to clients over a pluggable transport, and you read the same data on the client with the same API, with no RemoteEvents to wire up.\n- **Production-grade.** Migrations, a wipe guard, version history, GDPR export and erase, leaderboards, gifting and perks, and fail-closed monetization all sit on top of ProfileStore's session locking.\n\n> [!IMPORTANT]\n> The typed API needs the **new Luau type solver** (Studio: select **Workspace** and set `UseNewLuauTypeSolver` to `Enabled`; or enable it in your Luau LSP settings). Scribe runs correctly without it. `Data.Raw` is the untyped escape hatch.\n\n## Quick start\n\nOne shared module declares the template and options and returns `{ Server, Client }`:\n\n```lua\n-- ReplicatedStorage/Shared/Data.luau\nlocal Scribe = require(game:GetService(\"ReplicatedStorage\").Packages.Scribe)\n\nreturn Scribe({\n    Template = { Coins = 0, Settings = { Music = true } },\n    ProfileStoreIndex = \"PlayerData\", -- required: your DataStore name\n    ProfileKeyPrefix = \"PLAYER_\",     -- required: per-player key prefix\n})\n```\n\n```lua\n-- Server: wait for the profile to load, then use the typed accessor\nlocal Data = require(game:GetService(\"ReplicatedStorage\").Shared.Data).Server\n\ngame:GetService(\"Players\").PlayerAdded:Connect(function(player)\n    local data = Data.WaitForData(player) -- yields until Ready (default 60s timeout)\n    if data then\n        data.Coins.Increment(50)\n    end\nend)\n```\n\n```lua\n-- Client: read the same data reactively (writes are local-only; server wins)\nlocal Data = require(game:GetService(\"ReplicatedStorage\").Shared.Data).Client\n\nData.Coins.Observe(function(coins)\n    coinsLabel.Text = tostring(coins)\nend)\n```\n\nFor declarators, replication + visibility, monetization, leaderboards, migrations, diagnostics, and the full API, see the **[documentation](https://ericplane.github.io/Scribe/)**.\n\n## Development\n\n```bash\nrokit install              # wally + rojo + selene + luau-lsp + lune + stylua toolchain\nwally install              # dependencies\nselene src test lune       # lint\nstylua --check src test lune  # formatting (drop --check to apply)\nlune run lune/run-tests    # run the test suite (headless, ~2s)\n```\n\nThe same lint, format, test, and type-check (luau-lsp) checks run in CI on every\npull request (`.github/workflows/ci.yml`), and releases are gated on a green run.\nMark the `test`, `lint`, `format`, `analyze`, and `version-check` checks as\nrequired in the repository's branch-protection settings to enforce them on merge.\n\nDocs are built with Material for MkDocs from the doc-comments in `src/` and the guides in `docgen/guides/`. See [docgen/README.md](docgen/README.md) for details.\n\n## License\n\nMIT\n","readmeTruncated":false}