{"id":13661422,"url":"https://github.com/sigtrapgames/SmartData","last_synced_at":"2025-04-25T02:33:00.966Z","repository":{"id":71531672,"uuid":"148310639","full_name":"sigtrapgames/SmartData","owner":"sigtrapgames","description":"A designer-friendly, editor-driven Unity3D framework for connecting data and events.","archived":false,"fork":false,"pushed_at":"2019-12-14T11:54:29.000Z","size":405,"stargazers_count":272,"open_issues_count":3,"forks_count":14,"subscribers_count":23,"default_branch":"master","last_synced_at":"2024-12-06T22:23:51.419Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sigtrapgames.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2018-09-11T12:02:56.000Z","updated_at":"2024-11-28T04:47:41.000Z","dependencies_parsed_at":"2023-02-22T01:45:50.153Z","dependency_job_id":null,"html_url":"https://github.com/sigtrapgames/SmartData","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sigtrapgames%2FSmartData","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sigtrapgames%2FSmartData/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sigtrapgames%2FSmartData/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sigtrapgames%2FSmartData/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sigtrapgames","download_url":"https://codeload.github.com/sigtrapgames/SmartData/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250742059,"owners_count":21479722,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T05:01:34.401Z","updated_at":"2025-04-25T02:33:00.652Z","avatar_url":"https://github.com/sigtrapgames.png","language":"C#","funding_links":[],"categories":["C\\#","Game Development"],"sub_categories":["Unity Engine: Resources"],"readme":"# SmartData for Unity\n\u003e A designer-friendly, editor-driven framework for connecting data and events.\n\nNeed a flexible way to connect everything in your game without singletons, hard-coding or overly-complex architecture? *SmartData* might be what you're looking for. It is based on Ryan Hipple's ([twitter](https://twitter.com/roboryantron) | [github](https://github.com/roboryantron)) amazing talk from Unite Austin 2017, which you are ***strongly*** recommended to watch before proceeding.\n\n[![Game Architecture with Scriptable Objects](http://img.youtube.com/vi/raQ3iHhE_Kk/0.jpg)](http://www.youtube.com/watch?v=raQ3iHhE_Kk \"Game Architecture with Scriptable Objects\")\n\n### UPDATE NOTE\nThe type generator / regenerator has changed slightly. Please make sure you're backed up, update to the latest commit, use *Create \u003e SmartData \u003e Generate Types \u003e Regenerate...* and double check the changes made. This update is to support moving generated files around - SmartData will from now on regenerate files in-place.\n\n### INSTALLATION\n* Grab *SmartData.unitypackage* from the [Releases page](https://github.com/sigtrapgames/SmartData/releases) for everything you need!\n* OR, to use the *git* repository, you'll need our events implementation, *Relay*\u003csup\u003e[1]\u003c/sup\u003e. [github.com/SixWays/Relay](https://github.com/SixWays/Relay)\n* Requires Unity 2018.2 or above.\n\n*If you have issues with anything not discussed in this readme, please let us know - but check [the wiki](https://github.com/sigtrapgames/SmartData/wiki) first!*  \n*SmartData also has a [Unity forum thread here](https://forum.unity.com/threads/open-source-smartdata-an-editor-driven-designer-friendly-framework-for-data-and-events.560065/) for further discussion.*\n\n# What is SmartData?\nFirstly, ***SmartData*** **is in beta**. With that out of the way, *SmartData* is a framework that uses `ScriptableObject`s to pass data around a game at the global level. Let's take a common example - showing the player's HP on the HUD. Let's assume the Player and the HUD are prefabs, dynamically instantiated at runtime, rather than placing them in each scene at edit-time and manually dragging references.\n\nNote that the following pros and cons are entirely subjective. And there are many more methods we could use!\n\n### Traditional method A - Singletons\nOur `Player` class is a singleton. We instantiate the Player prefab, then the HUD prefab, and the HUD uses `Player.instance.hp`.\n\n***Pros***: *Easy to code.*  \n***Cons***: *Encourages spaghetti code. Rigid coupling between classes. HUD depends on the Player instance existing. Not exposed to designers.*\n\n-----\n\n### Traditional method B - Find reference at runtime\nWe don't like singletons, so instead the HUD searches for the Player using `GameObject.Find` in `Awake()`.\n\n***Pros***: *Coupling is slightly less rigid.*  \n***Cons***: *Player must be called the right thing. HUD depends on the Player instance existing. Not exposed to designers.*\n\n-----\n\n### SmartData method\nWe create a `FloatVar` asset called *PlayerHp*. In `Player` we declare a `FloatWriter` and in `HUD` a `FloatReader`.\n\n\u003cimg src=\"https://i.imgur.com/7Pu4ueH.png\" width=\"540\" /\u003e\n\u003cimg src=\"https://i.imgur.com/nzMGlvM.png\" width=\"340\" /\u003e\n\nIn-editor, each script now has a field in which we can drag-and-drop our *PlayerHp* asset. Now they both refer to the same data.\n\n![](https://i.imgur.com/vD93Hr3.png)\n\n`HUD` now has three ways to get the player's health:\n* Get `playerHp.value` in an update loop - the *PlayerHp* asset value will stay up-to-date with `Player`\n* Use the exposed `UnityEvent` in the editor and check *Auto Listen* - the event will fire when `Player` updates the value\n* Use `playerHp.BindListener()` to register for the event in code when `Player` updates the value\n\n***Pros***: *No code coupling. HUD can exist without Player (PlayerHp asset always exists). Exposed to designers.*  \n***Cons***: *More complex.*\n\n-----\n\nWhile *SmartData* takes a little more setup, it's far more flexible, powerful, safe and designer-friendly - and after a couple of uses, that setup is easy.\n\nNow imagine a real codebase. You have dozens of singletons, your code is spaghetti, you need a coder every time a designer wants to get any of that data, and unless you instantiate everything in your scene - *in the right order!* - your game explodes, making low-level testing and iteration hellish.\n\nWith *SmartData*, global data is just a set of assets. Designers can access it at will with a set of Components, modify its behaviour and select at edit-time what references point to what data. Coders still retain control of their code, specifying read-only or read/write access from a given reference, with attributes to control what options a designer sees in the editor.\n\n*SmartData* supports any underlying data type via its code generator GUI. It comes with a selection of basic *SmartTypes* pre-built such as `float` and `string` amongst others.\n\n![](https://pbs.twimg.com/media/DmQhR6lW4AAwtNx.jpg:small)\n\nNote that any single *SmartType* only has **one** underlying data type. The multi-type editor above is simply for generating multiple *SmartTypes* at once for convenience.\n\n### SmartEvents\n`EventVars`, accessible via `EventListener` and `EventDispatcher` references, simply raise events without any data payload. These are particularly useful for game-level events, such as starting, pausing the game, a player dying etc.\n\n### SmartComponents\nDesigners can use components which give code-free access to SmartObjects. Read/Listen components give a list of SmartRefs with UnityEvents. Write/Dispatch components give one SmartRef and the ability to set values and/or dispatch events from UnityEvents or other third-party design tools.\n\n![Imgur](https://i.imgur.com/ud1BZgM.png)\n\n### Debugging\n*SmartData* includes a visual debugger graph which shows all the current connections between `SmartRef`s (`FloatReader`, `FloatWriter` etc) and `SmartObject`s (`FloatVar` etc)\u003csup\u003e[2]\u003c/sup\u003e. At runtime, it will also animate to show updates and events.\n\n`SmartObject`s will also show a list of connections in the inspector, and at runtime a list of objects listening to events from code.\n\n\u003cimg src=\"https://thumbs.gfycat.com/JoyousAnyAfricangroundhornbill-size_restricted.gif\" width=\"550\" /\u003e\n\u003cimg src=\"https://i.imgur.com/WOMHGth.jpg\" width=\"310\" /\u003e\n\n**NOTE**: Plain references to *SmartObjects* will not show up in the node graph. You must use *SmartRefs* - e.g. `FloatReader`, `FloatWriter`.\n\n### Advanced Features\nThe above is just scratching the surface. *SmartData* has many other features which will gradually be documented in [the wiki](https://github.com/sigtrapgames/SmartData/wiki).\n* *SmartSet* - List of data with OnAdd and OnRemove events\n  * e.g. a list of all AIs - AIs add/remove themselves and the AI manager (and anything else) listens.\n* *SmartMulti* - List of SmartVars created on demand\n  * e.g. for local multiplayer games - PlayerHp[0-3]\n* Decorators - Like components for *SmartObject* assets, these modify behaviour\n  * e.g. for clamped/ranged values or even automatic network replication\n* Code generation templates\n  * Add your own templates to the Generate Types editor to generate custom code for each type.\n\n# What is SmartData *not*?\n* A visual scripting language / editor\n* A coding-free solution\n* Particularly good at runtime-instantiated *SmartObjects* - **yet** (see *What's Next*)\n* The answer to all your problems\u003csup\u003e[3]\u003c/sup\u003e\n\n# What's next?\nThe first focus will be more documentation and examples, since there's a lot here.\n\nThe next major planned feature is *SmartGroups* - a comprehensive solution for dynamically instantiating *SmartObjects*. Currently *SmartData* is all about edit-time data - make assets, link them by hand, profit. At runtime, you can create *SmartObjects* *in code*, and link to them *in code*, and destroy them *in code*, and unlink from them *in code*. You may have noticed a pattern.\n\nFor example, if you want an *OnHit* `EventVar` for every AI spawned, there's no easy edit-time way to specify what *will* be interested in these events, or how they will be indexed. *SmartGroups* aim to fix that. More later.\n\nNote that *SmartMultis* are not intended to supply this functionality - they're a convenience for cases when there will be multiple long-lived instances of something. For example, with local multiplayer, your HUD elements can all reference a single \"PlayerHp\" `FloatMulti` asset by index. There's no good way to destroy one of the underlying `FloatVar`s and no way to automatically stop listening to it.\n\n# Notes\n* Namespaces are generated for each underlying type. For example, `SmartData.SmartFloat.FloatReader`.\n* As mentioned, you'll need `Relay` in your project to use `SmartData`.\n* If you use Odin Inspector, you must disable it for the SmartData namespace.\n* Userspace code (generated classes etc) is nice and neat. The underlying hierarchy though is crazy complex, largely due to Unity's serialization quirks. It looks horrible, but it's all there for a reason. Sorry in advance.\n\n# Credits\nDeveloped and maintained by Luke Thompson ([@six_ways](https://twitter.com/six_ways) | [github](https://github.com/SixWays))  \nSmartGraph developed by Luca Mefisto ([@LucaMefisto](https://twitter.com/LucaMefisto) | [github](https://github.com/MephestoKhaan)) based on his [UnityEventVisualizer](https://github.com/MephestoKhaan/UnityEventVisualizer)\n\n## Acknowledgements\n*SmartData*, as previously mentioned, owes its existence and inspiration to Ryan Hipple (see above)  \nDevelopment assistance, feedback and ideas provided by Eric Provencher ([@prvncher](https://twitter.com/prvncher)) and Dustin Chertoff ([@dbchertoff](https://twitter.com/dbchertoff))\n\n\n### Footnotes\n[1] *Relay* is not linked as a submodule for three main reasons. Firstly, you're fairly likely to be using *SmartData* as a submodule itself, and sub-submodules tend to confuse lots of *git* clients. Secondly, if you're already using *Relay* (you should be, but we're biased) it could get messy. Finally, *Relay* is pretty stable now so you should be able to grab a zip and forget about it.  \n[2] The graph is not editable!  \n[3] but only because nothing ever can be\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsigtrapgames%2FSmartData","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsigtrapgames%2FSmartData","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsigtrapgames%2FSmartData/lists"}