diff --git a/src/DotTiled.Example/DotTiled.Example.csproj b/src/DotTiled.Example/DotTiled.Example.csproj
new file mode 100644
index 0000000..89e9d09
--- /dev/null
+++ b/src/DotTiled.Example/DotTiled.Example.csproj
@@ -0,0 +1,29 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
+
diff --git a/src/DotTiled.Example/Program.cs b/src/DotTiled.Example/Program.cs
new file mode 100644
index 0000000..0f0f806
--- /dev/null
+++ b/src/DotTiled.Example/Program.cs
@@ -0,0 +1,78 @@
+using DotTiled.Serialization;
+
+namespace DotTiled.Example;
+
+class Program
+{
+ static void Main(string[] args)
+ {
+ Quick();
+ Manual();
+ }
+
+ // QUICK START
+ // Automatic and easy way to load tilemaps.
+ static void Quick()
+ {
+ var loader = Loader.Default();
+ var map = loader.LoadMap("tilemap.tmx");
+
+ // You can do stuff with it like...
+ Console.WriteLine($"Tile width and height: {map.TileWidth}x{map.TileHeight}");
+ TileLayer layer0 = (TileLayer)map.Layers[0]; // Get a layer
+ Console.WriteLine($"Tile in layer 0 at 0, 0: {layer0.Data.Value.GlobalTileIDs.Value[0]}");
+ }
+
+ // MANUAL
+ // Manually load a map, if you need to load from a custom source
+ static void Manual()
+ {
+ using var mapFileReader = new StreamReader("tilemap.tmx");
+ var mapString = mapFileReader.ReadToEnd();
+ using var mapReader = new MapReader(mapString, ResolveTileset, ResolveTemplate, ResolveCustomType);
+ var map = mapReader.ReadMap();
+
+ // Now do some other stuff with it...
+ StringProperty hello = (StringProperty)map.Properties.FirstOrDefault(property => property.Name == "hello");
+ Console.WriteLine($"Layer 1 name: {map.Layers[0].Name}");
+ Console.WriteLine($"Property 'hello': {hello.Value}");
+
+ // Now with tileset
+ Tileset tileset = map.Tilesets[0];
+ Console.WriteLine($"Tileset 0 source: {tileset.Source.Value}");
+ Console.WriteLine($"Tileset 0 image 0 source: {tileset.Image.Value.Source.Value}");
+ }
+
+ /* This function is responsible for loading all tilesets required by a tilemap, if you
+ want to use a custom source. */
+ static Tileset ResolveTileset(string source)
+ {
+ string tilesetPath = Path.Combine(Directory.GetCurrentDirectory(), source); // Resolve path to a tileset.
+ using var tilesetFileReader = new StreamReader(tilesetPath); // Read tileset file itself.
+ var tilesetString = tilesetFileReader.ReadToEnd(); // You can replace this with any custom function
+ // to load data from any source, eg. .zip file.
+ using var tilesetReader = new TilesetReader(tilesetString, ResolveTileset, ResolveTemplate, ResolveCustomType); // Parse loaded tileset.
+
+ return tilesetReader.ReadTileset(); // Return loaded tileset
+ }
+
+ // This is pretty similar to above, but instead it loads templates, not tilesets.
+ static Template ResolveTemplate(string source)
+ {
+ string templatePath = Path.Combine(Directory.GetCurrentDirectory(), source);
+ using var templateFileReader = new StreamReader(templatePath);
+ var templateString = templateFileReader.ReadToEnd();
+ using var templateReader = new TemplateReader(templateString, ResolveTileset, ResolveTemplate, ResolveCustomType);
+ return templateReader.ReadTemplate();
+ }
+
+ static ICustomTypeDefinition ResolveCustomType(string name)
+ {
+ CustomClassDefinition[] allDefinedTypes =
+ [
+ new CustomClassDefinition() { Name = "a" },
+ ];
+ return allDefinedTypes.FirstOrDefault(type => type.Name == name);
+ }
+
+}
diff --git a/src/DotTiled.Example/tilemap.tmx b/src/DotTiled.Example/tilemap.tmx
new file mode 100644
index 0000000..7a9a294
--- /dev/null
+++ b/src/DotTiled.Example/tilemap.tmx
@@ -0,0 +1,12 @@
+
+
diff --git a/src/DotTiled.Example/tileset.png b/src/DotTiled.Example/tileset.png
new file mode 100644
index 0000000..67b9eee
Binary files /dev/null and b/src/DotTiled.Example/tileset.png differ
diff --git a/src/DotTiled.Example/tileset.tsx b/src/DotTiled.Example/tileset.tsx
new file mode 100644
index 0000000..9fc1b9b
--- /dev/null
+++ b/src/DotTiled.Example/tileset.tsx
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/DotTiled.sln b/src/DotTiled.sln
index 421e996..3eec160 100644
--- a/src/DotTiled.sln
+++ b/src/DotTiled.sln
@@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotTiled.Tests", "DotTiled.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotTiled.Benchmark", "DotTiled.Benchmark\DotTiled.Benchmark.csproj", "{510F3077-8EA4-47D1-8D01-E2D538F1B899}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotTiled.Example", "DotTiled.Example\DotTiled.Example.csproj", "{31D5D3EB-67E1-4C8F-BB59-5BC32817C0FF}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -30,5 +32,9 @@ Global
{510F3077-8EA4-47D1-8D01-E2D538F1B899}.Debug|Any CPU.Build.0 = Debug|Any CPU
{510F3077-8EA4-47D1-8D01-E2D538F1B899}.Release|Any CPU.ActiveCfg = Release|Any CPU
{510F3077-8EA4-47D1-8D01-E2D538F1B899}.Release|Any CPU.Build.0 = Release|Any CPU
+ {31D5D3EB-67E1-4C8F-BB59-5BC32817C0FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {31D5D3EB-67E1-4C8F-BB59-5BC32817C0FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {31D5D3EB-67E1-4C8F-BB59-5BC32817C0FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {31D5D3EB-67E1-4C8F-BB59-5BC32817C0FF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal