diff --git a/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Extensions/KnowledgeAdventure/Associations/BALDataFormat.xml b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Extensions/KnowledgeAdventure/Associations/BALDataFormat.xml
new file mode 100644
index 00000000..10538191
--- /dev/null
+++ b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Extensions/KnowledgeAdventure/Associations/BALDataFormat.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+ *.bal
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
index 9344e523..4be246af 100644
--- a/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
+++ b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
@@ -41,6 +41,7 @@
+
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.KnowledgeAdventure/DataFormats/FileSystem/KnowledgeAdventure/BALDataFormat.cs b/CSharp/Plugins/UniversalEditor.Plugins.KnowledgeAdventure/DataFormats/FileSystem/KnowledgeAdventure/BALDataFormat.cs
new file mode 100644
index 00000000..19e979d4
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.KnowledgeAdventure/DataFormats/FileSystem/KnowledgeAdventure/BALDataFormat.cs
@@ -0,0 +1,122 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using UniversalEditor.IO;
+using UniversalEditor.ObjectModels.FileSystem;
+
+namespace UniversalEditor.DataFormats.FileSystem.KnowledgeAdventure
+{
+ public class BALDataFormat : DataFormat
+ {
+ private static DataFormatReference _dfr = null;
+ protected override DataFormatReference MakeReferenceInternal()
+ {
+ if (_dfr == null)
+ {
+ _dfr = base.MakeReferenceInternal();
+ _dfr.Capabilities.Add(typeof(FileSystemObjectModel), DataFormatCapabilities.All);
+ }
+ return _dfr;
+ }
+
+ protected override void LoadInternal(ref ObjectModel objectModel)
+ {
+ FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel);
+ if (fsom == null) throw new ObjectModelNotSupportedException();
+
+ Reader reader = base.Accessor.Reader;
+
+ // Everything is loaded using this recursive function, so start it off by loading the root entry
+ LoadEntry(reader, null, fsom);
+ }
+
+ private void LoadEntry(Reader reader, BALDirectoryEntry entry, IFileSystemContainer parent)
+ {
+ if (entry == null || (entry.Attributes & BALDirectoryEntryAttributes.Directory) == BALDirectoryEntryAttributes.Directory)
+ {
+ List entries = new List();
+
+ int count = reader.ReadInt32();
+ for (int i = 0; i < count; i++)
+ {
+ BALDirectoryEntry entry1 = ReadDirectoryEntry(reader);
+ entries.Add(entry1);
+ }
+
+ int nameTableLength = reader.ReadInt32();
+ for (int i = 0; i < count; i++)
+ {
+ BALDirectoryEntry entry1 = entries[i];
+ entry1.Name = reader.ReadNullTerminatedString();
+ entries[i] = entry1;
+ }
+
+ if (entry == null)
+ {
+ for (int i = 0; i < count; i++)
+ {
+ if (entries[i].Name == "." || entries[i].Name == "..") continue;
+
+ reader.Seek(entries[i].Offset, SeekOrigin.Begin);
+ LoadEntry(reader, entries[i], parent);
+ }
+ }
+ else
+ {
+ Folder folder = new Folder();
+ folder.Name = entry.Name;
+ for (int i = 0; i < count; i++)
+ {
+ if (entries[i].Name == "." || entries[i].Name == "..") continue;
+
+ reader.Seek(entries[i].Offset, SeekOrigin.Begin);
+ LoadEntry(reader, entries[i], folder);
+ }
+ parent.Folders.Add(folder);
+ }
+ }
+ else
+ {
+ File file = new File();
+ file.Name = entry.Name;
+ file.Size = entry.Length;
+ file.Properties.Add("reader", reader);
+ file.Properties.Add("offset", entry.Offset);
+ file.Properties.Add("length", entry.Length);
+ file.DataRequest += file_DataRequest;
+ parent.Files.Add(file);
+ }
+ }
+
+ private BALDirectoryEntry ReadDirectoryEntry(Reader reader)
+ {
+ BALDirectoryEntry entry = new BALDirectoryEntry();
+ entry.UnknownA1 = reader.ReadInt32();
+ entry.Offset = reader.ReadInt32();
+ entry.Length = reader.ReadInt32();
+ entry.Attributes = (BALDirectoryEntryAttributes)reader.ReadInt32();
+ entry.UnknownA3 = reader.ReadInt32();
+ return entry;
+ }
+
+ void file_DataRequest(object sender, DataRequestEventArgs e)
+ {
+ File file = (sender as File);
+ Reader reader = (Reader)file.Properties["reader"];
+ int offset = (int)file.Properties["offset"];
+ int length = (int)file.Properties["length"];
+
+ reader.Seek(offset, SeekOrigin.Begin);
+ byte[] data = reader.ReadBytes(length);
+ e.Data = data;
+ }
+
+ protected override void SaveInternal(ObjectModel objectModel)
+ {
+ FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel);
+ if (fsom == null) throw new ObjectModelNotSupportedException();
+
+ Writer writer = base.Accessor.Writer;
+ }
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.KnowledgeAdventure/DataFormats/FileSystem/KnowledgeAdventure/BALDirectoryEntry.cs b/CSharp/Plugins/UniversalEditor.Plugins.KnowledgeAdventure/DataFormats/FileSystem/KnowledgeAdventure/BALDirectoryEntry.cs
new file mode 100644
index 00000000..42e4bc89
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.KnowledgeAdventure/DataFormats/FileSystem/KnowledgeAdventure/BALDirectoryEntry.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.KnowledgeAdventure
+{
+ public class BALDirectoryEntry
+ {
+ public int UnknownA1;
+ public BALDirectoryEntryAttributes Attributes;
+ public int UnknownA3;
+ public int Offset;
+ public int Length;
+
+ public string Name;
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append(Name);
+ sb.Append(" @ " + Offset + " : " + Length);
+ sb.Append(" [ ");
+ sb.Append(Attributes);
+ sb.Append(" ]");
+ return sb.ToString();
+ }
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.KnowledgeAdventure/DataFormats/FileSystem/KnowledgeAdventure/BALDirectoryEntryAttributes.cs b/CSharp/Plugins/UniversalEditor.Plugins.KnowledgeAdventure/DataFormats/FileSystem/KnowledgeAdventure/BALDirectoryEntryAttributes.cs
new file mode 100644
index 00000000..e039fffa
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.KnowledgeAdventure/DataFormats/FileSystem/KnowledgeAdventure/BALDirectoryEntryAttributes.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.KnowledgeAdventure
+{
+ public enum BALDirectoryEntryAttributes
+ {
+ None = 0,
+ Directory = 32768
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.KnowledgeAdventure/Properties/AssemblyInfo.cs b/CSharp/Plugins/UniversalEditor.Plugins.KnowledgeAdventure/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..f7603c76
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.KnowledgeAdventure/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("UniversalEditor.Plugins.KnowledgeAdventure")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("City of Orlando")]
+[assembly: AssemblyProduct("UniversalEditor.Plugins.KnowledgeAdventure")]
+[assembly: AssemblyCopyright("Copyright © City of Orlando 2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("83556f5f-ed59-465a-8180-4b672af2414e")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.KnowledgeAdventure/UniversalEditor.Plugins.KnowledgeAdventure.csproj b/CSharp/Plugins/UniversalEditor.Plugins.KnowledgeAdventure/UniversalEditor.Plugins.KnowledgeAdventure.csproj
new file mode 100644
index 00000000..27245951
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.KnowledgeAdventure/UniversalEditor.Plugins.KnowledgeAdventure.csproj
@@ -0,0 +1,61 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {991F734F-D659-4252-8D2D-E6F828474861}
+ Library
+ Properties
+ UniversalEditor
+ UniversalEditor.Plugins.KnowledgeAdventure
+ v3.5
+ 512
+
+
+
+ true
+ full
+ false
+ ..\..\Output\Debug\Plugins\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ ..\..\Output\Release\Plugins\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {2d4737e6-6d95-408a-90db-8dff38147e85}
+ UniversalEditor.Core
+
+
+ {30467e5c-05bc-4856-aadc-13906ef4cadd}
+ UniversalEditor.Essential
+
+
+
+
+
\ No newline at end of file
diff --git a/CSharp/UniversalEditor.WindowsForms.sln b/CSharp/UniversalEditor.WindowsForms.sln
index 82bd67e7..42a342de 100644
--- a/CSharp/UniversalEditor.WindowsForms.sln
+++ b/CSharp/UniversalEditor.WindowsForms.sln
@@ -153,6 +153,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversalEditor.Plugins.Ark
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AwesomeControls.Content.PlatformIndependent", "..\..\AwesomeControls\AwesomeControls.Content.PlatformIndependent\AwesomeControls.Content.PlatformIndependent.csproj", "{FAE48F29-DB35-4CD6-8A55-6C1FDDFBE6AF}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversalEditor.Plugins.KnowledgeAdventure", "Plugins\UniversalEditor.Plugins.KnowledgeAdventure\UniversalEditor.Plugins.KnowledgeAdventure.csproj", "{991F734F-D659-4252-8D2D-E6F828474861}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -416,6 +418,10 @@ Global
{FAE48F29-DB35-4CD6-8A55-6C1FDDFBE6AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FAE48F29-DB35-4CD6-8A55-6C1FDDFBE6AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FAE48F29-DB35-4CD6-8A55-6C1FDDFBE6AF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {991F734F-D659-4252-8D2D-E6F828474861}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {991F734F-D659-4252-8D2D-E6F828474861}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {991F734F-D659-4252-8D2D-E6F828474861}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {991F734F-D659-4252-8D2D-E6F828474861}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -490,5 +496,6 @@ Global
{21D14362-103A-4B38-8FB8-EEA6C7C89E09} = {71CFF024-26F7-4626-A526-B435FDF8D64E}
{CF83423B-800F-4EF9-8955-E7A8C2C5C057} = {D3CE7A47-3989-4B6D-9867-0EA3C8DD7AB1}
{FAE48F29-DB35-4CD6-8A55-6C1FDDFBE6AF} = {5A423A3E-51C5-4188-8AD5-FB5C0CB76C6A}
+ {991F734F-D659-4252-8D2D-E6F828474861} = {71CFF024-26F7-4626-A526-B435FDF8D64E}
EndGlobalSection
EndGlobal