Prowl.Echo 2.1.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package Prowl.Echo --version 2.1.2
                    
NuGet\Install-Package Prowl.Echo -Version 2.1.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Prowl.Echo" Version="2.1.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Prowl.Echo" Version="2.1.2" />
                    
Directory.Packages.props
<PackageReference Include="Prowl.Echo" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Prowl.Echo --version 2.1.2
                    
#r "nuget: Prowl.Echo, 2.1.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Prowl.Echo@2.1.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Prowl.Echo&version=2.1.2
                    
Install as a Cake Addin
#tool nuget:?package=Prowl.Echo&version=2.1.2
                    
Install as a Cake Tool

Prowl.Echo Serializer

A high-performance, flexible serialization system built for the Prowl Game Engine. Echo creates an intermediate representation (an "Echo") of your objects, allowing fast inspection and modification before converting to and from Binary or Text.

Performance

Echo with source generation outperforms System.Text.Json and Newtonsoft.Json across all operations.

Benchmark run with [GenerateSerializer] and [FixedEchoStructure] on a complex object graph (20 nested objects, 100-element arrays, 50-entry dictionaries, collections):

  Serialize:
    MessagePack          Avg:   0.0297 ms  (1.64x faster)
    Echo                 Avg:   0.0487 ms
    System.Text.Json     Avg:   0.0708 ms  (2.39x slower)
    Newtonsoft.Json      Avg:   0.1040 ms  (3.51x slower)

  Deserialize:
    Echo                 Avg:   0.0200 ms
    MessagePack          Avg:   0.0470 ms  (2.35x slower)
    System.Text.Json     Avg:   0.1113 ms  (5.56x slower)
    Newtonsoft.Json      Avg:   0.1570 ms  (7.84x slower)

  Round-trip:
    Echo                 Avg:   0.0644 ms
    MessagePack          Avg:   0.0714 ms  (1.11x slower)
    System.Text.Json     Avg:   0.1776 ms  (2.76x slower)
    Newtonsoft.Json      Avg:   0.2533 ms  (3.93x slower)

Features

  • Type Support

    • Primitives (int, float, double, string, bool, etc.)
    • Complex objects and nested types
    • Collections (List, Arrays, HashSet, Stack, Queue, LinkedLists)
    • Dictionaries
    • Enums
    • DateTime and Guid
    • Nullable types
    • Circular references
    • Anonymous types
    • Multi-dimensional and jagged arrays
    • 470+ tests to ensure stability and reliability
  • Source Generation

    • [GenerateSerializer] attribute generates optimized ISerializable implementations at compile time
    • Inlines serialization for primitives, strings, enums, DateTime, Guid, TimeSpan, and common collections
    • Works alongside [FixedEchoStructure] for maximum performance, great for networking!
    • Zero reflection overhead for generated types
  • Flexible Serialization Control

    • Custom serialization through ISerializable interface
    • Attribute-based control ([FormerlySerializedAs], [IgnoreOnNull], [SerializeIf], [SerializeField])
    • [FixedEchoStructure] for compact positional serialization of stable types
    • Support for legacy data through attribute mapping
  • Misc

    • Battle tested in the Prowl Game Engine
    • Supports both String & Binary formats
    • Mimics Unity's Serializer

Usage

Basic Serialization

// Serialize an object
var myObject = new MyClass { Value = 42 };
var serialized = Serializer.Serialize(myObject);

// Deserialize back
var deserialized = Serializer.Deserialize<MyClass>(serialized);
[GenerateSerializer]
public partial class Player
{
    public string Name = "Player";
    public int Health = 100;
    public float Speed = 5.0f;
    public List<string> Inventory = new();
}

// Works exactly like basic serialization — but much faster
var player = new Player { Name = "Hero", Health = 200 };
var serialized = Serializer.Serialize(player);
var deserialized = Serializer.Deserialize<Player>(serialized);

The source generator automatically creates optimized Serialize/Deserialize methods that inline primitive construction and bypass the reflection pipeline entirely.

Serializing to Text

var serialized = Serializer.Serialize(myObject);

// Save to text
string text = serialized.WriteToString();

// Read back
var fromText = EchoObject.ReadFromString(text);
var deserialized = Serializer.Deserialize<MyClass>(fromText);

Custom Serialization

public class CustomObject : ISerializable
{
    public int Value = 42;
    public string Text = "Custom";
    public MyClass Obj = new();

    public void Serialize(ref EchoObject compound, SerializationContext ctx)
    {
        compound.Add("value", new EchoObject(Value));
        compound.Add("text", new EchoObject(Text));
        compound.Add("obj", Serializer.Serialize(typeof(MyClass), Obj, ctx));
    }

    public void Deserialize(EchoObject tag, SerializationContext ctx)
    {
        Value = tag.Get("value").IntValue;
        Text = tag.Get("text").StringValue;
        Obj = Serializer.Deserialize<MyClass>(tag.Get("obj"), ctx);
    }
}

Working with Collections

// Lists
var list = new List<string> { "one", "two", "three" };
var serializedList = Serializer.Serialize(list);

// Dictionaries
var dict = new Dictionary<string, int> {
    { "one", 1 },
    { "two", 2 }
};
var serializedDict = Serializer.Serialize(dict);

// Arrays
var array = new int[] { 1, 2, 3, 4, 5 };
var serializedArray = Serializer.Serialize(array);

Handling Circular References

var parent = new CircularObject();
parent.Child = new CircularObject();
parent.Child.Child = parent; // Circular reference
var serialized = Serializer.Serialize(parent);

Using Attributes

public class MyClass
{
    [FormerlySerializedAs("oldName")]
    public string NewName = "Test";

    [IgnoreOnNull]
    public string? OptionalField = null;

    [SerializeIf("ShouldSerializeDebug")]
    public string DebugInfo = "";

    public bool ShouldSerializeDebug => false;
}

// FixedEchoStructure tells the serializer this type has a stable shape
// and will never change. This allows compact positional serialization.
[GenerateSerializer]
[FixedEchoStructure]
public partial struct MyVector3
{
    public float X;
    public float Y;
    public float Z;
}

Performance Tips

For maximum serialization speed:

  1. Use [GenerateSerializer] on your types (requires partial class/struct), Or manually implement ISerializable
  2. Add [FixedEchoStructure] to small, stable value types (like vectors, colors), Or for network packets/messages
  3. Use binary format instead of text for I/O-bound workloads

For minimum serialized size:

  1. Use [FixedEchoStructure] wherever possible (skips field names)
  2. Use binary format with size encoding mode

Limitations

  • Properties are not serialized (only fields) this is by design.

License

This component is part of the Prowl Game Engine and is licensed under the MIT License. See the LICENSE file in the project root for details.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net6.0

    • No dependencies.
  • net7.0

    • No dependencies.
  • net8.0

    • No dependencies.
  • net9.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Prowl.Echo:

Package Downloads
Prowl.Origami

A production-ready UI widget library built on Prowl.Paper. Provides buttons, sliders, dropdowns, property grids, docking, modals, toasts, tooltips, tree views, color pickers, curve editors, and more with a consistent fluent builder API and full theming support.

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on Prowl.Echo:

Repository Stars
ProwlEngine/Prowl
An Open Source C# 3D Game Engine under MIT license, inspired by Unity and featuring a complete editor
Version Downloads Last Updated
2.2.1 132 5/13/2026
2.2.0 107 5/12/2026
2.1.2 190 4/8/2026
2.1.1 109 4/8/2026
2.1.0 113 4/8/2026
2.0.0 168 3/19/2026
1.8.0 313 11/5/2025
1.7.0 512 7/8/2025
1.6.1 309 4/3/2025
1.6.0 230 1/8/2025
1.5.1 177 1/7/2025
1.5.0 518 12/28/2024
1.4.4 205 12/25/2024
1.4.3 189 12/25/2024
1.4.2 181 12/25/2024
1.4.0 186 12/25/2024
1.3.0 179 12/23/2024
1.2.0 198 12/22/2024
1.1.0 188 12/22/2024
1.0.2 320 11/25/2024
Loading failed