{"id":"metauni/metaboard","name":"metaboard","scope":"metauni","platform":"roblox","description":"Mirrored from the Wally registry.","version":"1.4.0-rc.1","latest":"1.4.0-rc.1","versions":["1.4.0-rc.1"],"license":"AGPL-3.0","licenseRating":"unsafe","licenseCaveats":["Strongest copyleft: even network use counts as distribution, so running this in a live game plausibly requires releasing your game's entire source under AGPL-3.0. Not recommended for closed-source projects.","License identified from the packaged LICENSE file; the manifest declared none."],"licenseVerified":true,"dependencies":{"blinkybool/feather":{"version":"^0.1.0","alias":"Feather"},"stravant/goodsignal":{"version":"^0.2.1","alias":"GoodSignal"},"evaera/promise":{"version":"^4.0.0","alias":"Promise"},"roblox/roact":{"version":"^1.4.4","alias":"Roact"},"csqrl/sift":{"version":"^0.0.4","alias":"Sift"}},"integrity":"2624b89619566488470baa8a4edcc0caa834a5bfd42daea21d7038788ff72779","likes":0,"downloads":0,"install":"forest install metauni/metaboard","url":"https://forest.dev/p/roblox/metauni/metaboard","files":"https://api.forest.dev/ai/package/roblox/metauni/metaboard/files","readme":"# metaboard\n\nMultiplayer drawing boards for sharing knowledge in Roblox.\n\n![](./metaboard-cover.png)\n\n## Installation\n\nThere are two components to install: the metaboard backend code, and a metaboard model to draw on.\n\n### From Github Releases\nDownload the [latest release](https://github.com/metauni/metaboard/releases/latest) (look for `metaboard-v*.rbxm`). In Roblox Studio, right click on `ServerScriptService`, click `Insert from File` and insert the `metaboard-v*.rbxm` file.\nThis is a startup script that puts the metaboard ModuleScript in ReplicatedStorage, and then gets the server and clients to call `metaboard.Client:Start()` and the server to call `metaboard.Server:Start()`.\nYou will need to manually update this file if you want the newest release.\n\n### With Wally\n\nAdd metaboard as a dependency of your project in your wally.toml file\n```bash\n# wally.toml\n\n[dependencies]\nmetaboard = \"metauni/metaboard@X.X.X\" # Replace with current version number\n```\n\nInstall it\n```bash\nwally install\n```\n\nCall the startup methods from the client and server\n```lua\nlocal metaboard = require(path.to.metaboard)\n\n-- From Server\nmetaboard.Server:Start()\n\n-- From Client\nmetaboard.Client:Start()\n```\n\n### With Rojo\nClone/download the repository, and ensure you have [Rojo](https://rojo.space) and [Wally](https://wally.run) installed (you can install them with `aftman install` if you have [Aftman](https://github.com/LPGhatguy/aftman))\n\nInstall the dependencies (see [License](#license))\n```bash\nwally install\n```\n\nTo build the latest release (as a startup script),\n```bash\nrojo build release.project.json -o metaboard.rbxm\n```\n\nTo sync the latest release into Roblox Studio (at ServerScriptService > metaboardStartup)\n```bash\nrojo serve dev.project.json\n```\n\nTo build metaboard as a ModuleScript (no startup logic)\n```bash\nrojo build module.project.json -o metaboard.rbxm\n```\n\nNote: the `default.project.json` is for Wally. On its own it will not build\nmetaboard with its package dependencies.\n\n## Adding boards to your game\n\n[metauni](https://www.roblox.com/groups/13108882/metauni#!/about) maintains a few example boards you can use.\nThe easiest method to add these in Roblox Studio is to go to `Toolbox > Marketplace` and search \"metaboard\".\n\n- [WhiteBoard](https://www.roblox.com/library/8543134618/metaboard-WhiteBoard)\n- [BlackBoard](https://www.roblox.com/library/8542483968/metaboard-BlackBoard)\n- [TechBoard](https://www.roblox.com/library/8543176248/metaboard-TechBoard)\n\t- This is really two boards, both the `FrontBoard` and `BackBoard` are tagged as metaboards.\n\nDon't be afraid to resize and stretch these boards as you please!\n\n## Board Structure\n\nTo turn a `Part` into a metaboard, use the [Tag Editor](https://devforum.roblox.com/t/tag-editor-plugin/101465)\nplugin to give it the tag \"metaboard\".\nIf your board is a `Model`, make the drawing surface the PrimaryPart, and tag the PrimaryPart as \"metaboard\".\nA StringValue called \"Face\" parented to the `Part` (not the Model) will define which face\nof the part is used as the drawing surface.\n\n| Object      | Name        | Value | Description |\n| ----------- | ----------- | ----------- | ----- |\n| StringValue | Face        | `String` (one of \"Front\" (default), \"Back\", \"Left\", \"Right\", \"Top\", \"Bottom\") | The surface of the part that should be used as the board |\n\nFor more customised positioning of the board, make an invisible part for the board and size/position it on your model however you like.\n\n## Custom Configuration\n\nAll of the configuration values used in metaboard are stored in a ModuleScript at `lib -> Config`. There are cases where you may want to\nuse different config values on a per-place basis. Instead of modifying the `Config` script, you can copy the ModuleScript called `metaboardPlaceConfig` from `lib` to `ReplicatedStorage`. This ModuleScript returns a function which takes the config table as its argument and modifies the keys (no return value). All scripts that import the original Config file will receive the table with these edits applied (but only if `metaboardPlaceConfig` is a child of `ReplicatedStorage`).\n\nYou can keep this same config file around when you update the metaboard package.\n\n## Persistent Boards\n\nAny metaboard can be synced to a DataStore so that it retains its contents across server restarts.\n\nBy default, metaboard uses a datastore called `\"MetaboardPersistence\"` to save and restore board data. You can configure which datastore is used in `metaboardPlaceConfig`. For example you could use a different datastore for each place. There you can also set `Config.Persistence.ReadOnly` to `true`, so that you can see and draw on the existing boards in Studio without modifying anything in the datastore.\n\nNote that `Config.Persistence.DataStoreName` is ignored in pockets, where automatic naming is used.\n\nTo enable persistence for a board, create an `IntValue` under the board called `PersistId` and choose a unique value. This value is used to determine the key in the datastore where the board data will be saved, so it must be unique to prevent overwriting another board's data. You should also keep track of keys you've used in the past for the same reason.\n\nSince persistent boards use the Roblox DataStore API there are several limitations you should be aware of:\n\n<!-- * In private servers the DataStore key for a board is of the form \"ps<ownerId>:metaboard<PersistId>\". Since keys for DataStores cannot exceed `50` characters in length, and player Ids are (currently) eight digits, that means that you should keep `PersistId`'s to `30` digits or less. -->\n\n* The DataStore keys for persistent boards are the same in any live server, and `SetAsync` is currently used rather than `UpdateAsync`, so there is a risk of data corruption if two players in different servers attempt to the use the \"same\" persistent board. We strongly recommend therefore that you reserve use of persistent boards to *private servers*.\n\n* Changed persistent boards are autosaved by default every `30sec` - this can be modified (see [Custom Configuration](#custom-configuration)).\n\n* On server shutdown there is a 30sec hard limit, within which all boards which have changed after the last autosave must be saved if we are to avoid dataloss. A full board costs about 1.2sec to save under adversarial conditions (i.e. many other full boards). So if we assume we have 20 of those 30 seconds for metaboard shutdown, we can afford at most 16 changed boards per autosave period. There is a budget for datastore requests, but the more likely bottleneck is save time per-board.\n\n## License\n\nmetaboard uses the MPL-2.0 License. See [LICENSE](./LICENSE).\n\nExternal packages used in metaboard can be found in [wally.toml](./wally.toml), and license information for those packages in [PACKAGE-LICENSES.md](./PACKAGE-LICENSES.md).","readmeTruncated":false}