diff --git a/Engine.Core/Primitives/ColorHSV.cs b/Engine.Core/Primitives/ColorHSV.cs
new file mode 100644
index 0000000..716cc1b
--- /dev/null
+++ b/Engine.Core/Primitives/ColorHSV.cs
@@ -0,0 +1,186 @@
+using System;
+
+namespace Syntriax.Engine.Core;
+
+///
+/// Represents an HSV color.
+///
+/// Hue of the .
+/// Saturation of the .
+/// Value of the .
+///
+/// Initializes a new instance of the struct with the specified values.
+///
+[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")]
+public readonly struct ColorHSV(float hue, float saturation, float value)
+{
+ ///
+ /// The Hue value of the .
+ ///
+ public readonly float Hue = hue;
+
+ ///
+ /// The Saturation value of the .
+ ///
+ public readonly float Saturation = saturation;
+
+ ///
+ /// The Value value of the .
+ ///
+ public readonly float Value = value;
+
+ public static ColorHSV operator -(ColorHSV color) => new(1f - color.Hue, 1f - color.Saturation, 1f - color.Value);
+ public static ColorHSV operator +(ColorHSV left, ColorHSV right) => new(left.Hue + right.Hue, left.Saturation + right.Saturation, left.Value + right.Value);
+ public static ColorHSV operator -(ColorHSV left, ColorHSV right) => new(left.Hue - right.Hue, left.Saturation - right.Saturation, left.Value - right.Value);
+ public static ColorHSV operator *(ColorHSV left, ColorHSV right) => new(left.Hue * right.Hue, left.Saturation * right.Saturation, left.Value * right.Value);
+ public static ColorHSV operator *(ColorHSV color, float value) => new(color.Hue * value, color.Saturation * value, color.Value * value);
+ public static ColorHSV operator *(float value, ColorHSV color) => new(color.Hue * value, color.Saturation * value, color.Value * value);
+ public static ColorHSV operator /(ColorHSV color, float value) => new(color.Hue / value, color.Saturation / value, color.Value / value);
+ public static bool operator ==(ColorHSV left, ColorHSV right) => left.Hue.ApproximatelyEquals(right.Hue) && left.Saturation.ApproximatelyEquals(right.Saturation) && left.Value.ApproximatelyEquals(right.Value);
+ public static bool operator !=(ColorHSV left, ColorHSV right) => !left.Hue.ApproximatelyEquals(right.Hue) || !left.Saturation.ApproximatelyEquals(right.Saturation) || !left.Value.ApproximatelyEquals(right.Value);
+
+ public static implicit operator ColorHSV(ColorRGBA rgba) => (ColorRGB)rgba;
+ public static implicit operator ColorHSV(ColorRGB rgb)
+ {
+ float hue;
+ float saturation;
+ float value;
+
+ float rd = rgb.R / 255f;
+ float gd = rgb.G / 255f;
+ float bd = rgb.B / 255f;
+
+ float max = Math.Max(rd, Math.Max(gd, bd));
+ float min = Math.Min(rd, Math.Min(gd, bd));
+ float delta = max - min;
+
+ if (delta.ApproximatelyEquals(0))
+ hue = 0f;
+ else if (max.ApproximatelyEquals(rd))
+ hue = 60f * ((gd - bd) / delta % 6f);
+ else if (max.ApproximatelyEquals(gd))
+ hue = 60f * (((bd - rd) / delta) + 2f);
+ else
+ hue = 60f * (((rd - gd) / delta) + 4f);
+
+ if (hue < 0f)
+ hue += 360f;
+
+ saturation = max.ApproximatelyEquals(0f) ? 0f : delta / max;
+ value = max;
+
+ return new(hue, saturation, value);
+ }
+
+ ///
+ /// Inverts the given .
+ ///
+ /// The .
+ /// The inverted .
+ public static ColorHSV Invert(ColorHSV color) => -color;
+
+ ///
+ /// Adds two s.
+ ///
+ /// The first .
+ /// The second .
+ /// The sum of the two s.
+ public static ColorHSV Add(ColorHSV left, ColorHSV right) => left + right;
+
+ ///
+ /// Subtracts one from another.
+ ///
+ /// The to subtract from.
+ /// The to subtract.
+ /// The result of subtracting the second from the first.
+ public static ColorHSV Subtract(ColorHSV left, ColorHSV right) => left - right;
+
+ ///
+ /// Multiplies a by a scalar value.
+ ///
+ /// The .
+ /// The scalar value.
+ /// The result of multiplying the by the scalar value.
+ public static ColorHSV Multiply(ColorHSV color, float value) => color * value;
+
+ ///
+ /// Divides a by a scalar value.
+ ///
+ /// The .
+ /// The scalar value.
+ /// The result of dividing the by the scalar value.
+ public static ColorHSV Divide(ColorHSV color, float value) => color / value;
+
+ ///
+ /// Calculates the from one point to another.
+ ///
+ /// The starting point.
+ /// The ending point.
+ /// The from the starting point to the ending point.
+ public static ColorHSV FromTo(ColorHSV from, ColorHSV to) => to - from;
+
+ ///
+ /// Performs linear interpolation between two s.
+ ///
+ /// The starting (t = 0).
+ /// The ending (t = 1).
+ /// The interpolation parameter.
+ /// The interpolated .
+ public static ColorHSV Lerp(ColorHSV from, ColorHSV to, float t) => from + FromTo(from, to) * t;
+
+ ///
+ /// Converts the to its string representation.
+ ///
+ /// A string representation of the .
+ public override string ToString() => $"{nameof(ColorHSV)}({Hue}, {Saturation}, {Value})";
+
+ ///
+ /// Checks if two s are approximately equal within a specified epsilon range.
+ ///
+ /// The first .
+ /// The second .
+ /// The epsilon range.
+ /// if the s are approximately equal; otherwise, .
+ public static bool ApproximatelyEquals(ColorHSV left, ColorHSV right, float epsilon = float.Epsilon)
+ => left.Hue.ApproximatelyEquals(right.Hue, epsilon) && left.Saturation.ApproximatelyEquals(right.Saturation, epsilon) && left.Value.ApproximatelyEquals(right.Value, epsilon);
+
+ ///
+ /// Determines whether the specified object is equal to the current .
+ ///
+ /// The object to compare with the current .
+ /// if the specified object is equal to the current ; otherwise, .
+ public override bool Equals(object? obj) => obj is ColorHSV objVec && Hue.Equals(objVec.Hue) && Saturation.Equals(objVec.Saturation) && Value.Equals(objVec.Value);
+
+ ///
+ /// Generates a hash code for the .
+ ///
+ /// A hash code for the .
+ public override int GetHashCode() => HashCode.Combine(Hue, Saturation, Value);
+}
+
+///
+/// Provides extension methods for type.
+///
+public static class ColorHSVExtensions
+{
+ ///
+ public static ColorHSV Add(this ColorHSV color, ColorHSV value) => ColorHSV.Add(color, value);
+
+ ///
+ public static ColorHSV Subtract(this ColorHSV color, ColorHSV value) => ColorHSV.Subtract(color, value);
+
+ ///
+ public static ColorHSV Multiply(this ColorHSV color, float value) => ColorHSV.Multiply(color, value);
+
+ ///
+ public static ColorHSV Divide(this ColorHSV color, float value) => ColorHSV.Divide(color, value);
+
+ ///
+ public static ColorHSV FromTo(this ColorHSV from, ColorHSV to) => ColorHSV.FromTo(from, to);
+
+ ///
+ public static ColorHSV Lerp(this ColorHSV from, ColorHSV to, float t) => ColorHSV.Lerp(from, to, t);
+
+ ///
+ public static bool ApproximatelyEquals(this ColorHSV left, ColorHSV right, float epsilon = float.Epsilon) => ColorHSV.ApproximatelyEquals(left, right, epsilon);
+}
diff --git a/Engine.Core/Primitives/ColorRGB.cs b/Engine.Core/Primitives/ColorRGB.cs
new file mode 100644
index 0000000..099b6b9
--- /dev/null
+++ b/Engine.Core/Primitives/ColorRGB.cs
@@ -0,0 +1,163 @@
+using System;
+
+namespace Syntriax.Engine.Core;
+
+///
+/// Represents an RGB color.
+///
+/// Red value of the .
+/// Green value of the .
+/// Blue value of the .
+///
+/// Initializes a new instance of the struct with the specified values.
+///
+[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")]
+public readonly struct ColorRGB(byte r, byte g, byte b)
+{
+ ///
+ /// The Red value of the .
+ ///
+ public readonly byte R = r;
+
+ ///
+ /// The Green value of the .
+ ///
+ public readonly byte G = g;
+
+ ///
+ /// The Blue value of the .
+ ///
+ public readonly byte B = b;
+
+ public static ColorRGB operator -(ColorRGB color) => new((byte)(255 - color.R), (byte)(255 - color.G), (byte)(255 - color.B));
+ public static ColorRGB operator +(ColorRGB left, ColorRGB right) => new((byte)(left.R + right.R), (byte)(left.G + right.G), (byte)(left.B + right.B));
+ public static ColorRGB operator -(ColorRGB left, ColorRGB right) => new((byte)(left.R - right.R), (byte)(left.G - right.G), (byte)(left.B - right.B));
+ public static ColorRGB operator *(ColorRGB left, ColorRGB right) => new((byte)(left.R * right.R), (byte)(left.G * right.G), (byte)(left.B * right.B));
+ public static ColorRGB operator *(ColorRGB color, float value) => new((byte)(color.R * value), (byte)(color.G * value), (byte)(color.B * value));
+ public static ColorRGB operator *(float value, ColorRGB color) => new((byte)(color.R * value), (byte)(color.G * value), (byte)(color.B * value));
+ public static ColorRGB operator /(ColorRGB color, float value) => new((byte)(color.R / value), (byte)(color.G / value), (byte)(color.B / value));
+ public static bool operator ==(ColorRGB left, ColorRGB right) => left.R == right.R && left.G == right.G && left.B == right.B;
+ public static bool operator !=(ColorRGB left, ColorRGB right) => left.R != right.R || left.G != right.G || left.B != right.B;
+
+ public static implicit operator ColorRGB(ColorRGBA rgba) => new(rgba.R, rgba.G, rgba.B);
+ public static implicit operator ColorRGB(ColorHSV hsv)
+ {
+ float c = hsv.Value * hsv.Saturation;
+ float x = c * (1 - Math.Abs(hsv.Hue / 60 % 2 - 1));
+ float m = hsv.Value - c;
+
+ float r1 = 0, g1 = 0, b1 = 0;
+
+ if (hsv.Hue >= 0 && hsv.Hue < 60) { r1 = c; g1 = x; b1 = 0; }
+ else if (hsv.Hue >= 60 && hsv.Hue < 120) { r1 = x; g1 = c; b1 = 0; }
+ else if (hsv.Hue >= 120 && hsv.Hue < 180) { r1 = 0; g1 = c; b1 = x; }
+ else if (hsv.Hue >= 180 && hsv.Hue < 240) { r1 = 0; g1 = x; b1 = c; }
+ else if (hsv.Hue >= 240 && hsv.Hue < 300) { r1 = x; g1 = 0; b1 = c; }
+ else if (hsv.Hue >= 300 && hsv.Hue < 360) { r1 = c; g1 = 0; b1 = x; }
+
+ byte r = (byte)Math.RoundToInt((r1 + m) * 255);
+ byte g = (byte)Math.RoundToInt((g1 + m) * 255);
+ byte b = (byte)Math.RoundToInt((b1 + m) * 255);
+
+ return new(r, g, b);
+ }
+
+ ///
+ /// Inverts the given .
+ ///
+ /// The .
+ /// The inverted .
+ public static ColorRGB Invert(ColorRGB color) => -color;
+
+ ///
+ /// Adds two s.
+ ///
+ /// The first .
+ /// The second .
+ /// The sum of the two s.
+ public static ColorRGB Add(ColorRGB left, ColorRGB right) => left + right;
+
+ ///
+ /// Subtracts one from another.
+ ///
+ /// The to subtract from.
+ /// The to subtract.
+ /// The result of subtracting the second from the first.
+ public static ColorRGB Subtract(ColorRGB left, ColorRGB right) => left - right;
+
+ ///
+ /// Multiplies a by a scalar value.
+ ///
+ /// The .
+ /// The scalar value.
+ /// The result of multiplying the by the scalar value.
+ public static ColorRGB Multiply(ColorRGB color, float value) => color * value;
+
+ ///
+ /// Divides a by a scalar value.
+ ///
+ /// The .
+ /// The scalar value.
+ /// The result of dividing the by the scalar value.
+ public static ColorRGB Divide(ColorRGB color, float value) => color / value;
+
+ ///
+ /// Calculates the from one point to another.
+ ///
+ /// The starting point.
+ /// The ending point.
+ /// The from the starting point to the ending point.
+ public static ColorRGB FromTo(ColorRGB from, ColorRGB to) => to - from;
+
+ ///
+ /// Performs linear interpolation between two s.
+ ///
+ /// The starting (t = 0).
+ /// The ending (t = 1).
+ /// The interpolation parameter.
+ /// The interpolated .
+ public static ColorRGB Lerp(ColorRGB from, ColorRGB to, float t) => from + FromTo(from, to) * t;
+
+ ///
+ /// Converts the to its string representation.
+ ///
+ /// A string representation of the .
+ public override string ToString() => $"{nameof(ColorRGB)}({R}, {G}, {B})";
+
+ ///
+ /// Determines whether the specified object is equal to the current .
+ ///
+ /// The object to compare with the current .
+ /// if the specified object is equal to the current ; otherwise, .
+ public override bool Equals(object? obj) => obj is ColorRGB objVec && R.Equals(objVec.R) && G.Equals(objVec.G) && B.Equals(objVec.B);
+
+ ///
+ /// Generates a hash code for the .
+ ///
+ /// A hash code for the .
+ public override int GetHashCode() => HashCode.Combine(R, G, B);
+}
+
+///
+/// Provides extension methods for type.
+///
+public static class ColorRGBExtensions
+{
+ ///
+ public static ColorRGB Add(this ColorRGB color, ColorRGB value) => ColorRGB.Add(color, value);
+
+ ///
+ public static ColorRGB Subtract(this ColorRGB color, ColorRGB value) => ColorRGB.Subtract(color, value);
+
+ ///
+ public static ColorRGB Multiply(this ColorRGB color, float value) => ColorRGB.Multiply(color, value);
+
+ ///
+ public static ColorRGB Divide(this ColorRGB color, float value) => ColorRGB.Divide(color, value);
+
+ ///
+ public static ColorRGB FromTo(this ColorRGB from, ColorRGB to) => ColorRGB.FromTo(from, to);
+
+ ///
+ public static ColorRGB Lerp(this ColorRGB from, ColorRGB to, float t) => ColorRGB.Lerp(from, to, t);
+}
diff --git a/Engine.Core/Primitives/ColorRGBA.cs b/Engine.Core/Primitives/ColorRGBA.cs
new file mode 100644
index 0000000..bc5b35d
--- /dev/null
+++ b/Engine.Core/Primitives/ColorRGBA.cs
@@ -0,0 +1,149 @@
+using System;
+
+namespace Syntriax.Engine.Core;
+
+///
+/// Represents an RGBA color.
+///
+/// Red value of the .
+/// Green value of the .
+/// Blue value of the .
+/// Alpha value of the .
+///
+/// Initializes a new instance of the struct with the specified values.
+///
+[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")]
+public readonly struct ColorRGBA(byte r, byte g, byte b, byte a = 255)
+{
+ ///
+ /// The Red value of the .
+ ///
+ public readonly byte R = r;
+
+ ///
+ /// The Green value of the .
+ ///
+ public readonly byte G = g;
+
+ ///
+ /// The Blue value of the .
+ ///
+ public readonly byte B = b;
+
+ ///
+ /// The Alpha value of the .
+ ///
+ public readonly byte A = a;
+
+ public static ColorRGBA operator -(ColorRGBA color) => new((byte)(255 - color.R), (byte)(255 - color.G), (byte)(255 - color.B), (byte)(255 - color.A));
+ public static ColorRGBA operator +(ColorRGBA left, ColorRGBA right) => new((byte)(left.R + right.R), (byte)(left.G + right.G), (byte)(left.B + right.B), (byte)(left.A + right.A));
+ public static ColorRGBA operator -(ColorRGBA left, ColorRGBA right) => new((byte)(left.R - right.R), (byte)(left.G - right.G), (byte)(left.B - right.B), (byte)(left.A - right.A));
+ public static ColorRGBA operator *(ColorRGBA left, ColorRGBA right) => new((byte)(left.R * right.R), (byte)(left.G * right.G), (byte)(left.B * right.B), (byte)(left.A * right.A));
+ public static ColorRGBA operator *(ColorRGBA color, float value) => new((byte)(color.R * value), (byte)(color.G * value), (byte)(color.B * value), (byte)(color.A * value));
+ public static ColorRGBA operator *(float value, ColorRGBA color) => new((byte)(color.R * value), (byte)(color.G * value), (byte)(color.B * value), (byte)(color.A * value));
+ public static ColorRGBA operator /(ColorRGBA color, float value) => new((byte)(color.R / value), (byte)(color.G / value), (byte)(color.B / value), (byte)(color.A / value));
+ public static bool operator ==(ColorRGBA left, ColorRGBA right) => left.R == right.R && left.G == right.G && left.B == right.B && left.A == right.A;
+ public static bool operator !=(ColorRGBA left, ColorRGBA right) => left.R != right.R || left.G != right.G || left.B != right.B || left.A != right.A;
+
+ public static implicit operator ColorRGBA(ColorRGB rgb) => new(rgb.R, rgb.G, rgb.B, 255);
+ public static implicit operator ColorRGBA(ColorHSV hsv) => (ColorRGB)hsv;
+
+ ///
+ /// Inverts the given .
+ ///
+ /// The .
+ /// The inverted .
+ public static ColorRGBA Invert(ColorRGBA color) => -color;
+
+ ///
+ /// Adds two s.
+ ///
+ /// The first .
+ /// The second .
+ /// The sum of the two s.
+ public static ColorRGBA Add(ColorRGBA left, ColorRGBA right) => left + right;
+
+ ///
+ /// Subtracts one from another.
+ ///
+ /// The to subtract from.
+ /// The to subtract.
+ /// The result of subtracting the second from the first.
+ public static ColorRGBA Subtract(ColorRGBA left, ColorRGBA right) => left - right;
+
+ ///
+ /// Multiplies a by a scalar value.
+ ///
+ /// The .
+ /// The scalar value.
+ /// The result of multiplying the by the scalar value.
+ public static ColorRGBA Multiply(ColorRGBA color, float value) => color * value;
+
+ ///
+ /// Divides a by a scalar value.
+ ///
+ /// The .
+ /// The scalar value.
+ /// The result of dividing the by the scalar value.
+ public static ColorRGBA Divide(ColorRGBA color, float value) => color / value;
+
+ ///
+ /// Calculates the from one point to another.
+ ///
+ /// The starting point.
+ /// The ending point.
+ /// The from the starting point to the ending point.
+ public static ColorRGBA FromTo(ColorRGBA from, ColorRGBA to) => to - from;
+
+ ///
+ /// Performs linear interpolation between two s.
+ ///
+ /// The starting (t = 0).
+ /// The ending (t = 1).
+ /// The interpolation parameter.
+ /// The interpolated .
+ public static ColorRGBA Lerp(ColorRGBA from, ColorRGBA to, float t) => from + FromTo(from, to) * t;
+
+ ///
+ /// Converts the to its string representation.
+ ///
+ /// A string representation of the .
+ public override string ToString() => $"{nameof(ColorRGBA)}({R}, {G}, {B}, {A})";
+
+ ///
+ /// Determines whether the specified object is equal to the current .
+ ///
+ /// The object to compare with the current .
+ /// if the specified object is equal to the current ; otherwise, .
+ public override bool Equals(object? obj) => obj is ColorRGBA objVec && R.Equals(objVec.R) && G.Equals(objVec.G) && B.Equals(objVec.B) && A.Equals(objVec.A);
+
+ ///
+ /// Generates a hash code for the .
+ ///
+ /// A hash code for the .
+ public override int GetHashCode() => HashCode.Combine(R, G, B, A);
+}
+
+///
+/// Provides extension methods for type.
+///
+public static class ColorRGBAExtensions
+{
+ ///
+ public static ColorRGBA Add(this ColorRGBA color, ColorRGBA value) => ColorRGBA.Add(color, value);
+
+ ///
+ public static ColorRGBA Subtract(this ColorRGBA color, ColorRGBA value) => ColorRGBA.Subtract(color, value);
+
+ ///
+ public static ColorRGBA Multiply(this ColorRGBA color, float value) => ColorRGBA.Multiply(color, value);
+
+ ///
+ public static ColorRGBA Divide(this ColorRGBA color, float value) => ColorRGBA.Divide(color, value);
+
+ ///
+ public static ColorRGBA FromTo(this ColorRGBA from, ColorRGBA to) => ColorRGBA.FromTo(from, to);
+
+ ///
+ public static ColorRGBA Lerp(this ColorRGBA from, ColorRGBA to, float t) => ColorRGBA.Lerp(from, to, t);
+}
diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorHSVConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorHSVConverter.cs
new file mode 100644
index 0000000..b5bb4ca
--- /dev/null
+++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorHSVConverter.cs
@@ -0,0 +1,28 @@
+using System;
+
+using Syntriax.Engine.Core;
+
+using YamlDotNet.Core;
+using YamlDotNet.Core.Events;
+using YamlDotNet.Serialization;
+
+namespace Syntriax.Engine.Serializers.Yaml;
+
+public class ColorHSVConverter : EngineTypeYamlSerializerBase
+{
+ private static readonly int SUBSTRING_START_LENGTH = nameof(ColorHSV).Length + 1;
+
+ public override ColorHSV Read(IParser parser, Type type, ObjectDeserializer rootDeserializer)
+ {
+ string value = parser.Consume().Value;
+ string insideParenthesis = value[SUBSTRING_START_LENGTH..^1];
+ string[] values = insideParenthesis.Split(", ");
+ return new ColorHSV(float.Parse(values[0]), float.Parse(values[1]), float.Parse(values[2]));
+ }
+
+ public override void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer)
+ {
+ ColorHSV hsv = (ColorHSV)value!;
+ emitter.Emit(new Scalar($"{nameof(ColorHSV)}({hsv.Hue}, {hsv.Saturation}, {hsv.Value})"));
+ }
+}
diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBAConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBAConverter.cs
new file mode 100644
index 0000000..8243a0b
--- /dev/null
+++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBAConverter.cs
@@ -0,0 +1,28 @@
+using System;
+
+using Syntriax.Engine.Core;
+
+using YamlDotNet.Core;
+using YamlDotNet.Core.Events;
+using YamlDotNet.Serialization;
+
+namespace Syntriax.Engine.Serializers.Yaml;
+
+public class ColorRGBAConverter : EngineTypeYamlSerializerBase
+{
+ private static readonly int SUBSTRING_START_LENGTH = nameof(ColorRGBA).Length + 1;
+
+ public override ColorRGBA Read(IParser parser, Type type, ObjectDeserializer rootDeserializer)
+ {
+ string value = parser.Consume().Value;
+ string insideParenthesis = value[SUBSTRING_START_LENGTH..^1];
+ string[] values = insideParenthesis.Split(", ");
+ return new ColorRGBA(byte.Parse(values[0]), byte.Parse(values[1]), byte.Parse(values[2]), byte.Parse(values[3]));
+ }
+
+ public override void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer)
+ {
+ ColorRGBA rgb = (ColorRGBA)value!;
+ emitter.Emit(new Scalar($"{nameof(ColorRGBA)}({rgb.R}, {rgb.G}, {rgb.B}, {rgb.A})"));
+ }
+}
diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBConverter.cs
new file mode 100644
index 0000000..809db2a
--- /dev/null
+++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/ColorRGBConverter.cs
@@ -0,0 +1,28 @@
+using System;
+
+using Syntriax.Engine.Core;
+
+using YamlDotNet.Core;
+using YamlDotNet.Core.Events;
+using YamlDotNet.Serialization;
+
+namespace Syntriax.Engine.Serializers.Yaml;
+
+public class ColorRGBConverter : EngineTypeYamlSerializerBase
+{
+ private static readonly int SUBSTRING_START_LENGTH = nameof(ColorRGB).Length + 1;
+
+ public override ColorRGB Read(IParser parser, Type type, ObjectDeserializer rootDeserializer)
+ {
+ string value = parser.Consume().Value;
+ string insideParenthesis = value[SUBSTRING_START_LENGTH..^1];
+ string[] values = insideParenthesis.Split(", ");
+ return new ColorRGB(byte.Parse(values[0]), byte.Parse(values[1]), byte.Parse(values[2]));
+ }
+
+ public override void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer)
+ {
+ ColorRGB rgb = (ColorRGB)value!;
+ emitter.Emit(new Scalar($"{nameof(ColorRGB)}({rgb.R}, {rgb.G}, {rgb.B})"));
+ }
+}