SkillAgentSearch skills...

BakingSheet

Easy datasheet management for C# and Unity. Supports Excel, Google Sheet, JSON and CSV format.

Install / Use

/learn @cathei/BakingSheet
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Nuget GitHub release (latest by date) openupm GitHub Discord

BakingSheet 🍞

Easy datasheet management for C# and Unity. Supports Excel, Google Sheet, JSON and CSV format. It has been used for several mobile games that released on Google Play and AppStore.

Table of Contents

Concept

Throughout all stage of game development, you'll need to deal with various data. Characters, stats, stages, currencies and so on! If you're using Unity, scriptable object and inspector is not good enough for mass edition and lacks powerful features like functions or fill up. With BakingSheet your designers can use existing spreadsheet editor, while you, the programmer, can directly use C# object without messy parsing logics or code generations.

Let's say your team is making a RPG game. Your game has 100 characters and 10 stats for each character. If your team use Unity's scriptable object, designers will have to spend lots of time adding and editing from Unity inspector. And after setup what if you need mass edit, like to double ATK stat of all characters? Will you go through all characters with Unity inspector, or make Editor script for every time mass edit is required? With BakingSheet, designers can work easily with spreadsheet functions and fill ups without programmer help!

Concept

BakingSheet's core concept is controlling datasheet schema from C# code, make things flexible while supporting multiple sources like Excel files or Google sheets. You can think it as datasheet version of ORM. Also, you won't have to include source Excel files or parsing libraries for production builds. BakingSheet supports JSON serialization by default, you can ship your build with JSON or your custom format.

BakingSheet's basic workflow is like this:

  1. Programmers make C# schema that represents Datasheet. (They can provide sample Excel files or Google Sheet with headers.)
  2. Designers fill up the Datasheet, using any powerful functions and features of spreadsheet.
  3. Edit-time script converts Datasheet to JSON (or any custom format) with your C# schema and validates data.
  4. Runtime script reads from JSON (or any custom format) with your C# schema.
  5. Your business logic directly uses C# instance of your schema.
  6. Profit!

Don't trust me that it's better than using ScriptableObject? You might change your mind if you see how famous SuperCell ships their games with CSV, like Clash Royale or Brawl Stars. Though of course, their games aren't made with Unity, still a very good example to show how you can utilize spreadsheet!

Sample1 Sample2

Features

Install

For C# projects or server, download with NuGet.

For Unity projects, add git package from Package Manager.

https://github.com/cathei/BakingSheet.git?path=UnityProject/Packages/com.cathei.bakingsheet#v4.1.3

Or install it via OpenUPM.

openupm add com.cathei.bakingsheet

Sample .unitypackage is available in releases. (Main package should be installed first.)

If you are planning to use StreamingAssets folder on Android, install BetterStreamingAssets as well.

Need help?

Before you start, we want to mention that if you have problem or need help, you can always ask directly on Discord Channel!

Contribution

We appreciate any contribution. Please create issue for bugs or feature requests. Any contribution to feature, test case, or documentation through pull requests are welcome! Any blog posts, articles, shares about this project will be greatful!

First Step

BakingSheet manages datasheet schema as C# code. Sheet class represents a table and SheetRow class represents a record. Below is example content of file Consumables page in MySheets.xlsx. Also, any column starts with $ will be considered as comment and ignored.

Plain Sample

<details> <summary>Markdown version</summary>

| Id | Name | Price | $Comment | |------------|-------------------|-------|------------| | LVUP_001 | Warrior's Shield | 10000 | Warrior Lv up material | | LVUP_002 | Mage's Staff | 10000 | Mage Lv up material | | LVUP_003 | Assassin's Dagger | 10000 | Assassin Lv up material | | POTION_001 | Health Potion | 30 | Heal 20 Hp | | POTION_002 | Mana Potion | 50 | Heal 20 Mp |

</details>

Code below is corresponding BakingSheet class.

public class ConsumableSheet : Sheet<ConsumableSheet.Row>
{
    public class Row : SheetRow
    {
        // use name of matching column
        public string Name { get; private set; }
        public int Price { get; private set; }
    }
}

You can see there are two classes, ConsumableSheet and ConsumableSheet.Row. Each represents a page of sheet and a single row. ConsumableSheet is surrounding Row class (It is not forced but recommended convention). Important part is they will inherit from Sheet<TRow> and SheetRow.

Id column is mandatory, so it is already defined in base SheetRow class. Id is string by default, but you can change type. See this section to use non-string type for Id.

To represent collection of sheets, a document, let's create SheetContainer class inherits from SheetContainerBase.

public class SheetContainer : SheetContainerBase
{
    public SheetContainer(Microsoft.Extensions.Logging.ILogger logger) : base(logger) {}

    // property name matches with corresponding sheet name
    // for .xlsx or google sheet, **property name matches with the name of sheet tab in workbook**
    // for .csv or .json, **property name matches with the name of file**
    public ConsumableSheet Consumables { get; private set; }

    // add other sheets as you extend your project
    public CharacterSheet Characters { get; private set; }
}

You can add as many sheets you want as properties of your SheetContainer. This class is designed to be "fat", means single SheetContainer should contain all your sheets unless there is specific reason to partition your sheets. For example when you want to deploy some Sheet only exclusive to server program, you might want to partition ServerSheetContainer and ClientSheetContainer.

Supported Column Type

  • string
  • Numeric primitive types (int, long, float, double, and so on)
  • bool ("TRUE" or "FALSE")
  • Custom enum types
  • DateTime and TimeSpan
  • Cross-sheet reference (Sheet<>.Reference)
  • Nullable for any other supported value type (for example int?)
  • List<> and Dictionary<,>
  • Custom struct and class as nested column
  • Custom type converted with ValueConverter

Note
When using JsonConverter, enum is serialized as string by default so you won't have issue when reordering them.

Converters

Converters are simple implementation import/export records from datasheet sources. These come as separated library, as it's user's decision to select datasheet source. User can have converting process, to convert datasheet to other format ahead of time and not include heavy converters in production applications.

BakingSheet

View on GitHub
GitHub Stars434
CategoryCustomer
Updated6d ago
Forks44

Languages

C#

Security Score

100/100

Audited on Mar 24, 2026

No findings