{"id":23752329,"url":"https://github.com/akikurisu/ceres","last_synced_at":"2025-09-20T07:03:15.119Z","repository":{"id":270218096,"uuid":"909587150","full_name":"AkiKurisu/Ceres","owner":"AkiKurisu","description":"Powerful visual scripting toolkit for Unity inspired from Unreal Blueprint.","archived":false,"fork":false,"pushed_at":"2025-09-07T15:31:17.000Z","size":5200,"stargazers_count":88,"open_issues_count":2,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-20T07:02:16.559Z","etag":null,"topics":["blueprint","gameplay","graphview","nodeeditor","toolkit","unity","unity3d","visual-scripting","visualscripting"],"latest_commit_sha":null,"homepage":"https://akikurisu.github.io/Ceres/","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/AkiKurisu.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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-12-29T06:53:45.000Z","updated_at":"2025-09-19T06:07:09.000Z","dependencies_parsed_at":"2024-12-29T13:36:11.456Z","dependency_job_id":"e895557a-75f6-40e6-bbf3-0b82a61d3918","html_url":"https://github.com/AkiKurisu/Ceres","commit_stats":null,"previous_names":["akikurisu/ceres"],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/AkiKurisu/Ceres","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AkiKurisu%2FCeres","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AkiKurisu%2FCeres/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AkiKurisu%2FCeres/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AkiKurisu%2FCeres/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AkiKurisu","download_url":"https://codeload.github.com/AkiKurisu/Ceres/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AkiKurisu%2FCeres/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276058102,"owners_count":25577867,"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","status":"online","status_checked_at":"2025-09-20T02:00:10.207Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["blueprint","gameplay","graphview","nodeeditor","toolkit","unity","unity3d","visual-scripting","visualscripting"],"created_at":"2024-12-31T17:28:30.405Z","updated_at":"2025-09-20T07:03:15.111Z","avatar_url":"https://github.com/AkiKurisu.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# Ceres\nPowerful visual scripting toolkit for Unity.\n\n![banner](./Documentation~/resources/Images/ceres_banner.png)\n\n\u003c/div\u003e\n\n## Table of Contents\n\n- [Install](#install)\n- [Highlights](#highlights)\n- [Platform](#platform)\n- [Core Concepts](#core-concepts)\n- [Quick Start Guide](#quick-start-guide)\n- [Flow Visual Scripting](#flow-visual-scripting)\n- [ExecutableReflection](#executablereflection)\n- [Debugging](#debugging)\n- [Advanced Features](#advanced-features)\n- [Type Preservation](#type-preservation)\n- [Code Generation](#code-generation)\n- [Documentation](#documentation)\n- [Implementation](#implementation)\n- [Articles](#articles)\n- [License](#license)\n\n## Install\n\nAdd following dependencies to `manifest.json`.\n\n```json\n\"dependencies\": {\n    \"com.kurisu.chris\": \"https://github.com/AkiKurisu/Chris.git\",\n    \"com.cysharp.unitask\":\"https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask\"\n}\n```\n\nUse git URL to download package by Unity Package Manager ```https://github.com/AkiKurisu/Ceres.git```.\n\n## Highlights\n\n- Generic and delegate support\n- Graph and C# integration\n- Editor debugging\n- Easy implementation\n- Optimized runtime performance\n- IL2CPP compatible\n\n## Platform\n\nUnity 2022.3 LTS or later.\n\n## Core Concepts\n\nUnderstanding the fundamental concepts of Ceres will help you get started quickly.\n\n### Node\n`CeresNode` is the logic and data container that forms the building blocks of your visual scripts.\n\n### Port\n`CeresPort` enables you to get data from other nodes. Ceres uses `CeresPort\u003cT\u003e` to get generic data from other nodes and `NodePort` to get a `NodeReference` which can convert to `CeresNode` at runtime.\n\n### Graph\n`CeresGraph` contains everything and acts as a virtual machine that executes your visual scripts.\n\n### Data\nCeres serializes node, port and graph to additional data structures: `CeresNodeData`, `CeresPortData` and `CeresGraphData` which contain the actual serialized data and metadata.\n\n### Variable\n`SharedVariable` is a data container that can be shared between nodes and graphs. Compared with `CeresPort`, `SharedVariable` can be edited outside of the graph and doesn't contain any connection data since it doesn't need to know where the data comes from.\n\n![Variables](./Documentation~/resources/Images/variables.png)\n\n### Execution Path\nNodes can be executed in two ways:\n\n**Forward**: Graph can execute nodes one by one.\n\n**Dependency**: Graph should execute node's dependencies before executing the node.\n\n![Execution Path](./Documentation~/resources/Images/ceres_concept_execution_path.png)\n\nAs shown in the figure, to execute `Log String`, we need to first get the variable `message`. However, since `Get message` has no outer connection, it has not been executed before. So the graph needs to consider `Get message` as a dependency and execute it before executing `Log String`.\n\n## Quick Start Guide\n\nHere's a step-by-step example of using Flow to output a \"Hello World\" message:\n\n### 1. Create a Flow Object\nCreate a new C# script `MyFlowObject.cs` and make it inherit from `FlowGraphObject`:\n\n```csharp\nusing Ceres.Graph.Flow;\nusing Ceres.Graph.Flow.Annotations;\n\npublic class MyFlowObject: FlowGraphObject\n{\n    [ImplementableEvent]\n    private void Start()\n    {\n\n    }\n}\n```\n\n### 2. Setup in Scene\nCreate a new GameObject in the scene and attach the `MyFlowObject` component to it.\n\n### 3. Open Flow Graph Editor\nClick `Open Flow Graph` in the Inspector panel to open the Flow Graph Editor.\n\n![Open Flow Graph](./Documentation~/resources/Images/flow_quick_start_1.png)\n\n### 4. Create Start Event\nRight click the graph and click `Create Node/Select Events/Implement Start`.\n\n![Create Node](./Documentation~/resources/Images/flow_quick_start_2.png)\n\n### 5. Add Log String Node\nClick `Create Node` and search `Log String`, then connect the white port (exec) to the `Start` node's output (exec). Fill in \"Hello World!\" in the `In String` field of the `Log String` node.\n\n![Log String](./Documentation~/resources/Images/flow_quick_start_3.png)\n\n### 6. Save and Test\nClick the save button in the left upper corner, then play the game. You will see \"Hello World!\" in the console.\n\n## Flow Visual Scripting\n\nFlow thinks of game logic as an execution chain to let game objects do things in order according to your design. Flow visualizes these executions as nodes so that you can connect them to implement gameplay and functionality.\n\n### Events\nEach execution chain starts from an event which can contain input data.\n\n![Events](./Documentation~/resources/Images/flow_events.png)\n\nYou can define events in Flow Graph or C# scripts.\n\n### Functions\nFunctions are components that implement game functions. They complete specified functions by calling the engine or your custom API. Through wiring, you can combine these method calls to complete your creativity.\n\n### Container\nFor any FlowGraph instance, there needs to be a specified Container at runtime. It can be your custom `MonoBehaviour` (need to implement interface) or inherit from a series of parent classes provided by Ceres.\n\n## ExecutableReflection\n\nExecutableReflection allows you to expose C# methods to Flow graphs, making them available as nodes. There are three main ways to define executable functions:\n\n### 1. Instance Functions\n\nFor instance methods, add `ExecutableFunctionAttribute` directly to your method:\n\n```csharp\nusing Ceres.Graph.Flow.Annotations;\nusing UnityEngine;\n\npublic class MyComponent : MonoBehaviour\n{\n    [ExecutableFunction]\n    public void DoSomething(int arg1, float arg2)\n    {\n        Debug.Log($\"Doing something with {arg1} and {arg2}\");\n    }\n    \n    [ExecutableFunction]\n    public string GetPlayerName()\n    {\n        return \"Player\";\n    }\n}\n```\n\n### 2. Static Functions\n\nFor static methods, create a **partial** class that inherits from `ExecutableFunctionLibrary` and add `ExecutableFunctionAttribute`:\n\n```csharp\nusing Ceres.Graph.Flow;\nusing Ceres.Graph.Flow.Annotations;\nusing Ceres.Annotations;\nusing UnityEngine;\n\npublic partial class GameplayFunctionLibrary : ExecutableFunctionLibrary\n{\n    [ExecutableFunction(IsScriptMethod = true, IsSelfTarget = true)]\n    [CeresLabel(\"Get GameObject Name\")]\n    public static string Flow_GetGameObjectName(GameObject gameObject)\n    {\n        return gameObject.name;\n    }\n    \n    [ExecutableFunction(ExecuteInDependency = true)]\n    public static float Flow_CalculateDistance(Vector3 pointA, Vector3 pointB)\n    {\n        return Vector3.Distance(pointA, pointB);\n    }\n    \n    [ExecutableFunction]\n    public static Component Flow_FindComponent(\n        GameObject target,\n        [ResolveReturn] SerializedType\u003cComponent\u003e componentType)\n    {\n        return target.GetComponent(componentType);\n    }\n}\n```\n\n\u003e **Important**: You must add the `partial` modifier to let the source generator work. The source generator registers static function pointers to enhance runtime performance instead of using MethodInfo.\n\n### 3. Always Included Assemblies\n\nFlow automatically includes assemblies matched by `Always Included Assembly Wildcards` in `Project Settings/Ceres/Flow Settings`. Methods in these assemblies can be invoked without adding attributes:\n\n```csharp\npublic class UtilityClass\n{\n    public void AutomaticallyIncludedMethod(string message)\n    {\n        Debug.Log($\"Auto-included: {message}\");\n    }\n}\n```\n\n### Best Practices and Conventions\n\n1. **Unique Method Names**: Methods with the same name and parameter count in the same class hierarchy can only have one `ExecutableFunctionAttribute`.\n\n2. **Method Overloads**: For methods with the same name but different parameters, use `CeresLabelAttribute` to distinguish them:\n\n```csharp\n[ExecutableFunction, CeresLabel(\"Log Message\")]\npublic static void Flow_Log(string message)\n{\n    Debug.Log(message);\n}\n\n[ExecutableFunction, CeresLabel(\"Log Message with Color\")]\npublic static void Flow_Log(string message, Color color)\n{\n    Debug.Log($\"\u003ccolor=#{ColorUtility.ToHtmlStringRGB(color)}\u003e{message}\u003c/color\u003e\");\n}\n```\n\n3. **Parameter Limits**: Keep input parameters ≤ 6 for optimal editor performance. Methods with more parameters use Uber nodes with greater runtime overhead.\n\n4. **Generic Methods**: Generic methods are not supported with `ExecutableFunctionAttribute`. Use [Generic Nodes](#generic-nodes) instead.\n\n## Debugging\n\nCeres provides powerful debugging capabilities to help you troubleshoot your visual scripts.\n\n### Enable Debug Mode\nTo enable and disable debug mode, click the `debug` button in the upper right corner. Then, you can click `Next Frame` to execute the graph node by node.\n\n### Breakpoints\nYou can right click any node and select `Add Breakpoint`, then click `Next Breakpoint` in the toolbar to execute the graph breakpoint by breakpoint.\n\n![Debug](./Documentation~/resources/Images/flow_debugger.png)\n\n### Graph Tracker\n`FlowGraphTracker` is a class that can be used to track the execution of the graph for advanced debugging scenarios.\n\n## Advanced Features\n\n### Port Implicit Conversion\nFor reference type objects, such as `MonoBehaviour` and `Component`, ports can be converted based on the inheritance hierarchy automatically. For value types, you need to register conversions manually.\n\n### Generic Nodes\nGeneric nodes define type restrictions through template classes, allowing argument types to be obtained in the editor and generic node instances to be constructed at runtime.\n\n### Custom Functions\nYou can define both local functions within your flow graph and shared functions across multiple graph containers using `FlowGraphFunctionAsset`.\n\n### Port Arrays\nFor nodes that need resizable port arrays, you can implement `IPortArrayNode` to define dynamic port collections.\n\n\n## Type Preservation\n\nCeres provides an automatic type preservation system that prevents IL2CPP code stripping from removing types used in your visual scripts. \n\n### How It Works\n\n`CeresLinker` will cache types used in nodes during your development and identifies all types that need to be preserved. It will generate a temporal `link.xml` file in build time to prevent IL2CPP from stripping these essential types.\n\n### Manual Type Registration\n\nYou can manually register additional types that should be preserved using the `CeresLinker` API:\n\n```csharp\nusing Ceres.Editor;\n\n// Register a single type\nCeresLinker.LinkType(typeof(MyCustomClass));\n\n// Register multiple types\nCeresLinker.LinkTypes(new Type[] { \n    typeof(MyCustomClass), \n    typeof(AnotherClass) \n});\n\n// Save the registered types to settings\nCeresLinker.Save();\n```\n\n### Editor Integration\n\nYou can view and manage preserved types through Unity's Project Settings:\n\n1. Go to `Edit \u003e Project Settings \u003e Ceres`\n2. Check the \"Preserved Types\" section to see all registered types\n3. Manually add type names if needed\n\n## Code Generation\n\nCeres uses multiple code generation techniques to enhance runtime performance:\n\n### Source Generator\nAnalyzes partial classes annotated with `GenerateFlowAttribute` and generates their implementation automatically, reducing code duplication.\n\n### IL Post Process (ILPP)\nUses ILPP to emit IL for initialization logic of `CeresNode` and methods annotated with `ImplementableEventAttribute` to enhance runtime performance.\n\n## Documentation\n\nFor more detailed information, you can also visit:\n\n- [Online Tutorial](https://akikurisu.github.io/Ceres/docs/ceres_concept.html)\n- [API Reference](https://akikurisu.github.io/Ceres/api/Ceres.html)\n- [Ceres Wiki](https://deepwiki.com/AkiKurisu/Ceres/) generated by [DeepWiki](https://deepwiki.com)\n\n## Implementation\n\n### Flow\n\nPowerful visual scripting solution inspired from Unreal's Blueprint.\n  \nIncluded in this repository. \n\nSee [Startup Flow](https://akikurisu.github.io/Ceres/docs/flow_startup.html)\n\n![Flow](./Documentation~/resources/Images/ceres_flow.png)\n\n### Flow Hotupdate\n\nImplement a Data-Driven and Per-Actor hotupdate solution.\n\nSee [Chris.Gameplay](https://github.com/AkiKurisu/Chris.Gameplay) for more details.\n\n![Hotupdate](./Documentation~/resources/Images/flow_hotupdate.png)\n \n### Next Gen Dialogue\n\nAI powered dialogue visual designer for Unity.\n\nSee [Next-Gen-Dialogue](https://github.com/AkiKurisu/Next-Gen-Dialogue).\n\n![Next-Gen-Dialogue](./Documentation~/resources/Images/ceres_ngd.png)\n\n## Articles\n\nTechnique articles related to Ceres.\n\n[如何设计一个Unity可视化脚本框架（一）](https://zhuanlan.zhihu.com/p/20500696157)\n\n[如何设计一个Unity可视化脚本框架（二）](https://zhuanlan.zhihu.com/p/20711259559)\n\n[如何设计一个Unity可视化脚本框架（三）](https://zhuanlan.zhihu.com/p/23323693948)\n\n[让Unity IL2CPP下的反射性能提高100倍的方法](https://zhuanlan.zhihu.com/p/25806713882)\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakikurisu%2Fceres","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fakikurisu%2Fceres","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakikurisu%2Fceres/lists"}