Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/chickensoft-games/savefilebuilder
Compose chunks of save data into a single data type by creating loosely coupled save chunks at various points in the scene tree.
https://github.com/chickensoft-games/savefilebuilder
chickensoft csharp godot save serialization
Last synced: 14 days ago
JSON representation
Compose chunks of save data into a single data type by creating loosely coupled save chunks at various points in the scene tree.
- Host: GitHub
- URL: https://github.com/chickensoft-games/savefilebuilder
- Owner: chickensoft-games
- License: mit
- Created: 2024-06-10T03:17:51.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2025-01-10T06:05:37.000Z (26 days ago)
- Last Synced: 2025-01-17T15:56:47.779Z (18 days ago)
- Topics: chickensoft, csharp, godot, save, serialization
- Language: C#
- Homepage: https://www.nuget.org/packages/Chickensoft.SaveFileBuilder
- Size: 74.2 KB
- Stars: 11
- Watchers: 1
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# 👽 SaveFileBuilder
[![Chickensoft Badge][chickensoft-badge]][chickensoft-website] [![Discord][discord-badge]][discord] [![Read the docs][read-the-docs-badge]][docs] ![line coverage][line-coverage] ![branch coverage][branch-coverage]
Compose chunks of save data into a single data type by creating loosely coupled save chunks at various points in the scene tree.
---
## 🥚 Getting Started
Find the latest version of [`Chickensoft.SaveFileBuilder`][nuget] on nuget.
```sh
dotnet add package Chickensoft.SaveFileBuilder
```## 📄 SaveFile and Root SaveChunk
Find the highest node in your scene tree that needs to be concerned with save data to use as the root of your save file. Use [AutoInject] to provide the root save chunk to all its descendant nodes.
> [!TIP]
> Check out the Chickensoft [Game Demo] for a complete, working example of using SaveFileBuilder to save composed states of everything that needs to be persisted in a game.```csharp
using Chickensoft.Introspection;
using Chickensoft.AutoInject;
using Chickensoft.SaveFileBuilder;
using Godot;[Meta(typeof(IAutoNode))]
public partial class Game : Node3D {
public SaveFile SaveFile { get; set; } = default!;// Provide the root save chunk to all descendant nodes.
ISaveChunk IProvide>.Value() => SaveFile.Root;public void Setup() {
SaveFile = new SaveFile(
root: new SaveChunk(
onSave: (chunk) => {
// Use root chunk to get child chunks that were added to us
// lower in the scene tree.
var gameData = new GameData() {
MapData = chunk.GetChunkSaveData(),
PlayerData = chunk.GetChunkSaveData(),
PlayerCameraData = chunk.GetChunkSaveData()
};return gameData;
},
onLoad: (chunk, data) => {
// Break up the game data and send it to the child chunks so that
// they can load the data into the nodes they belong to.
chunk.LoadChunkSaveData(data.MapData);
chunk.LoadChunkSaveData(data.PlayerData);
chunk.LoadChunkSaveData(data.PlayerCameraData);
}
),
onSave: async (GameData data) => {
// Save the game data to disk.
var json = JsonSerializer.Serialize(data, JsonOptions);
await FileSystem.File.WriteAllTextAsync(SaveFilePath, json);
},
onLoad: async () => {
// Load the game data from disk.
if (!FileSystem.File.Exists(SaveFilePath)) {
GD.Print("No save file to load :'(");
return null;
}var json = await FileSystem.File.ReadAllTextAsync(SaveFilePath);
return JsonSerializer.Deserialize(json, JsonOptions);
}
);...
}
}
```## 🍪 Defining Save Chunks
SaveChunks are smaller pieces of save data that are composed together into the overall save file's data. Simply add a chunk to a descendant node of the scene with the root SaveChunk and register it with the root save chunk once you've resolved dependencies with AutoInject.
```csharp
[Meta(typeof(IAutoNode))]
public partial class Player : CharacterBody3D {
[Dependency]
public ISaveChunk GameChunk => this.DependOn>();
public ISaveChunk PlayerChunk { get; set; } = default!;public void Setup() {
...PlayerChunk = new SaveChunk(
onSave: (chunk) => new PlayerData() {
GlobalTransform = GlobalTransform,
StateMachine = (PlayerLogic)PlayerLogic,
Velocity = Velocity
},
onLoad: (chunk, data) => {
GlobalTransform = data.GlobalTransform;
Velocity = data.Velocity;
PlayerLogic.RestoreFrom(data.StateMachine);
PlayerLogic.Start();
}
);...
}public void OnResolved() {
// Add a child to our parent save chunk (the game chunk) so that it can
// look up the player chunk when loading and saving the game.
GameChunk.AddChunk(PlayerChunk);...
}
}
```Once a save chunk has been added to a parent save chunk, the parent save chunk can access it from the callbacks specified by `onSave` and `onLoad`, querying its data or forcing it load data into its node.
> [!TIP]
> You can define easily serializable types, as well as serialize entire [LogicBlocks] with [Chickensoft.Serialization].---
🐣 Package generated from a 🐤 Chickensoft Template —
[chickensoft-badge]: https://raw.githubusercontent.com/chickensoft-games/chickensoft_site/main/static/img/badges/chickensoft_badge.svg
[chickensoft-website]: https://chickensoft.games
[discord-badge]: https://raw.githubusercontent.com/chickensoft-games/chickensoft_site/main/static/img/badges/discord_badge.svg
[discord]: https://discord.gg/gSjaPgMmYW
[read-the-docs-badge]: https://raw.githubusercontent.com/chickensoft-games/chickensoft_site/main/static/img/badges/read_the_docs_badge.svg
[docs]: https://chickensoft.games/docs
[line-coverage]: Chickensoft.SaveFileBuilder.Tests/badges/line_coverage.svg
[branch-coverage]: Chickensoft.SaveFileBuilder.Tests/badges/branch_coverage.svg[AutoInject]: https://github.com/chickensoft-games/AutoInject
[Game Demo]: https://github.com/chickensoft-games/GameDemo
[LogicBlocks]: https://github.com/chickensoft-games/LogicBlocks
[Chickensoft.Serialization]: https://github.com/chickensoft-games/Serialization
[nuget]: https://www.nuget.org/packages/Chickensoft.SaveFileBuilder