using System.IO.Compression;
using System.Collections.Generic;
using System.Globalization;
static List<string> words = new List<string>() {
"month", "freckle", "rock", "arrow",
"exclude", "sailor", "safari", "pastel",
"staircase", "distinct", "disappoint", "pollution",
"isolation", "card", "mathematics", "executive",
"lineage", "title", "licence", "torch",
"mastermind", "word", "priority", "feminine",
"aspect", "cart", "lounge", "obligation",
"father", "cutting", "painter", "swing",
"burial", "suitcase", "paralyzed", "convulsion",
"asset", "lackey", "rough", "waiter",
"handlebar", "mustache", "like", "maam",
"mum", "doctor", "magic", "box",
"toy", "shelf", "money", "leggings",
"hairband", "water", "bottle", "mouse",
"pad", "planet", "glass", "tissue",
"paper", "wallet", "storage", "leaf",
"severance", "show", "television",
"radio", "puppet", "giggle", "laugh",
"emote", "chair", "airplane", "heart",
"arrow", "swim", "rainbow", "cheese",
"pizza", "hamburger", "barn", "silo",
"ranch", "computer", "station", "police",
"steal", "theft", "handler", "jar",
"cash", "coins", "cook", "chef",
"chief", "detective", "inspector", "fire",
"murder", "time", "clock", "tea",
"kettle", "baby", "parent", "child",
"birthday", "holiday", "celebrate", "cake",
"people", "family", "anniversary", "wedding",
"engagement", "shower", "bride", "groom",
"maid", "honor", "best", "smosh",
"words", "cards", "board", "bored",
"irish", "accent", "funny", "humour",
"friend", "culture", "pop", "push",
"pull", "peel", "peek", "dock",
"one", "two", "talk", "breakup",
"fiance", "wife", "husband", "duck",
"cube", "listen", "hourglass", "hour",
"day", "minute", "second", "random",
"pack", "blueprint", "structure", "format"
public static void Main() {
List<string> wordsPacks = words.Distinct().ToList();
List<string> wordsBlueprints = words.Distinct().ToList();
int count = rand.Next(1, 4);
for (int a = 0; a < count; a++) {
int nameIndex = rand.Next(0, wordsPacks.Count);
string name = wordsPacks[nameIndex];
wordsPacks.RemoveAt(nameIndex);
PackBlueprint pack = new(name);
int blueprintCount = rand.Next(2, 3);
for (int b = 0; b < blueprintCount; b++) {
nameIndex = rand.Next(0, wordsBlueprints.Count);
string blueprintName = wordsBlueprints[nameIndex];
wordsBlueprints.RemoveAt(nameIndex);
DataBlueprint blueprint = new(blueprintName);
int xSize = rand.Next(2, 32);
int ySize = rand.Next(2, 32);
int zSize = rand.Next(2, 32);
int blocks = xSize * ySize * zSize;
for (int v = 0; v < blocks; v++) {
int solid = rand.Next(0, 2);
blockID += solid.ToString();
blockID += '-' + rand.Next(1, 256).ToString();
blueprint.bulbs.Add(blockID);
AssetArchive<DataBlueprint>.Add(blueprintName, blueprint);
pack.datas.Add(blueprint);
AssetArchive<PackBlueprint>.Add(name, pack);
var biotaPacks = ArchiveCache.Get(1).GetContents();
string[] packContentArray = new string[biotaPacks.Length];
for (int i = 0; i < biotaPacks.Length; i++) {
biotaPacks[i].Write("", out string packContents, out string packDestination);
packContentArray[i] = packContents;
float rawSize = (float)packContents.ToByteArray().Length / 1000f;
Logger.Header($"The '{biotaPacks[i].packName}' Pack had {biotaPacks[i].files.Length} Files : Size {rawSize} kb");
Logger.WriteLine(packContents);
for (int i = 0; i < packContentArray.Length; i++) {
string packContents = packContentArray[i];
string compressedContents = Serializer.CompressString(packContents);
float rawSize = (float)packContents.ToByteArray().Length / 1000f;
float compressedSize = (float)compressedContents.ToByteArray().Length / 1000f;
Logger.Header($"Compressed '{biotaPacks[i].packName}' : Size {compressedSize} kb : Reduction of {MathF.Floor((rawSize - compressedSize) / rawSize * 100f)}%");
Logger.WriteLine(compressedContents);
public static class ArchiveCache {
private static Dictionary<Type, ISecureArchive> archives;
private static List<Type> types;
public static int Count => archives.Count;
public static ISecureArchive Get(int index)
=> archives[types[index]];
public static void RegisterArchive(Type t, ISecureArchive archive) {
archives.Add(t, archive);
public interface ISecureArchive {
bool isRootArchive { get; }
BiotaAssetPack[] GetContents();
public class AssetArchive<T> : ISecureArchive
where T : ArchivableAsset {
public bool isRootArchive { get => typeof(IFileRoot).IsAssignableFrom(typeof(T)); }
private static AssetArchive<T> archive;
private List<string> legend;
private Dictionary<string, T> cache;
ArchiveCache.RegisterArchive(typeof(T), archive);
public static T Lookup(string name) {
if (archive.legend.Contains(name)) {
return archive.cache[name];
public static void Add(string name, T obj) {
archive.legend.Add(name);
archive.cache.Add(name, obj);
public BiotaAssetPack[] GetContents() {
if (!isRootArchive) return new BiotaAssetPack[0];
List<BiotaAssetPack> packs = new();
for (int i = 0; i < archive.legend.Count; i++) {
var data = archive.cache[archive.legend[i]];
packs.Add(((IFileRoot)data).WrapPack());
public class PackBlueprint : ArchivableAsset, IFileRoot {
public string zipExtension { get => "packdef"; }
public override string extension { get => "pdef"; }
[JsonIgnore] public List<DataBlueprint> datas;
public PackBlueprint(string name) : base() {
public BiotaAssetPack WrapPack() {
List<BiotaAssetFile> files = new() { Wrap<PackBlueprint>(packName) };
for (int i = 0; i < datas.Count; i++) {
if (datas[i] == null) continue;
string assetName = datas[i].dataName;
var assetFile = datas[i].Wrap<DataBlueprint>(assetName);
return new(packName, zipExtension) {
public class DataBlueprint : ArchivableAsset {
[JsonIgnore] public override string extension { get => "ddef"; }
public List<string> bulbs;
public DataBlueprint(string name) : base() {
public interface IArchivable {
string extension { get; }
public abstract class ArchivableAsset : IArchivable {
public abstract string extension { get; }
public ArchivableAsset() { }
public BiotaAssetFile Wrap<T>(string assetName)
where T : ArchivableAsset {
BiotaAssetFile file = new();
file.extension = extension;
file.contents = Serializer.ToJson((T)this, false);
public interface IFileRoot {
string zipExtension { get; }
BiotaAssetPack WrapPack();
public class BiotaAssetPack {
public string packExtension;
public BiotaAssetFile[] files;
public BiotaAssetPack() : this("", "") { }
public BiotaAssetPack(string packName, string packExtension) {
this.packName = packName;
this.packExtension = packExtension;
files = new BiotaAssetFile[0];
public void Write(string directory, out string fileContents, out string fileDestination) {
fileContents = Serialize(this);
fileDestination = Path.Combine(directory, packName + '.' + packExtension);
private static string Serialize(BiotaAssetPack assetPack) {
if (assetPack == null) return "";
assetPack.files ??= new BiotaAssetFile[0];
BiotaAssetFile packFile = new BiotaAssetFile() {
name = assetPack.packName,
extension = assetPack.packExtension,
List<BiotaAssetFile> files = assetPack.files.ToList();
files.Insert(0, packFile);
return Serializer.ToJson(files.ToArray(), true);
public void Read(string compressed) {
string fileContents = Serializer.DecompressString(compressed);
Deserialize(fileContents);
public void Deserialize(string fileContent) {
BiotaAssetFile[] jsonFiles = Serializer.FromJson<BiotaAssetFile[]>(fileContent);
jsonFiles ??= new BiotaAssetFile[0];
List<BiotaAssetFile> fileList = jsonFiles.ToList();
if (fileList.Count > 0) {
packName = rootFile.name;
packExtension = rootFile.extension;
files = fileList.ToArray();
public class BiotaAssetFile {
public static class Serializer {
public static int FileSize(string input) {
byte[] bytes = UnicodeEncoding.UTF8.GetBytes(input);
public static string CompressString(string input) {
byte[] bytes = UnicodeEncoding.UTF8.GetBytes(input);
var resultBytes = CompressBytes(bytes);
return Convert.ToBase64String(resultBytes);
public static string DecompressString(string input) {
byte[] bytes = Convert.FromBase64String(input);
var resultBytes = DecompressBytes(bytes);
var chars = UnicodeEncoding.UTF8.GetChars(resultBytes);
public static byte[] CompressBytes(byte[] input) {
using (var source = new MemoryStream(input))
using (var result = new MemoryStream()) {
using (var Compress = new GZipStream(result, CompressionMode.Compress)) {
public static byte[] DecompressBytes(byte[] input) {
using (var source = new MemoryStream(input))
using (var result = new MemoryStream()) {
using (var Decompress = new GZipStream(source, CompressionMode.Decompress)) {
Decompress.CopyTo(result);
public static string ToSingleString(this byte[] bytes)
=> UnicodeEncoding.UTF8.GetChars(bytes).ToString();
public static byte[] ToByteArray(this string input)
=> UnicodeEncoding.UTF8.GetBytes(input);
public static string ToJson<T>(T value, bool format = true)
=> ToJson(typeof(T), value, format ? Formatting.Indented : Formatting.None);
public static string ToJson(Type t, object value, Formatting formatting = Formatting.Indented) {
JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(new());
jsonSerializer.Formatting = formatting;
StringBuilder sb = new StringBuilder(256);
StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture);
using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) {
jsonWriter.Formatting = jsonSerializer.Formatting;
jsonSerializer.Serialize(jsonWriter, value, t);
public static T FromJson<T>(string value)
=> (T)FromJson(typeof(T), value);
public static object FromJson(Type t, string value) {
JsonSerializer jsonSerializer = JsonSerializer.CreateDefault();
jsonSerializer.CheckAdditionalContent = false;
using (JsonTextReader reader = new JsonTextReader(new StringReader(value)) { SupportMultipleContent = false }) {
return jsonSerializer.Deserialize(reader, t);
public interface IIdentifier { string Read(); }
public struct Label : IIdentifier { public string label; public string Read() => label; }
public interface IArchivable<T>
public abstract class ArchivableAsset<T> : IArchivable<T>
{ public abstract T GetID(); public abstract string GetValue(); }
public class DataAsset : ArchivableAsset<Label> {
[JsonProperty] private Label label;
[JsonProperty] private string[] values;
public DataAsset(Label label, params string[] values) {
public DataAsset(string label, params string[] values) {
public override Label GetID() {
public override string GetValue()
public static class DataArchive<Tid, Tobj>
where Tobj : ArchivableAsset<Tid> {
Logger.WriteLine($"Created an Archive for {t.Name}.");
private static Dictionary<string, Tobj> saved;
private static List<string> ids;
public static void Add(Tobj obj) {
string id = obj.GetID().Read();
public static Tobj[] Load() {
Tobj[] array = new Tobj[saved.Count];
for (int i = 0; i < saved.Count; i++) {
array[i] = saved[ids[i]];
public static class DataStreamer {
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
List<Type> dataFileTypes = new();
var dataArchive = typeof(DataArchive<,>);
var loadMethod = dataArchive.GetMethod("Load", 2, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, new Type[0]);
var target = typeof(ArchivableAsset<>);
var valueMethod = target.GetMethod("GetValue", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
var idMethod = target.GetMethod("GetID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (var assembly in assemblies) {
if (!x.IsGenericType) return false;
var genericType = x.GetGenericTypeDefinition();
if (genericType != null) {
if (target.IsAssignableFrom(genericType)) {
Console.WriteLine(genericType.Name);
for (int i = 0; i < dataFileTypes.Count; i++) {
Type[] generics = dataFileTypes[i].GenericTypeArguments;
if (generics == null) Console.WriteLine("Null generic arguments");
Type idType = generics.Length > 0 ? generics[0] : null;
string genericName = generics.Length > 0 ? generics[0].Name : "";
Logger.WriteLine($"DataStreamer - Located ArchivableAsset of the type {dataFileTypes[i].Name}, implementing the IIdentifier type '{genericName}'");
var properLoadMethod = loadMethod.MakeGenericMethod(idType,dataFileTypes[i]);
var properIdMethod = idMethod.MakeGenericMethod(idType);
var savedInArchive = (Array)properLoadMethod.Invoke(null, new object[0]);
for (int j = 0; j < savedInArchive.Length; j++) {
var archiveEntry = savedInArchive.GetValue(j);
float value = (float)valueMethod.Invoke(archiveEntry, new object[0]);
IIdentifier id = (IIdentifier)properIdMethod.Invoke(archiveEntry, new object[0]);
Logger.WriteLine($"\tThe {dataFileTypes[i].Name} instance named {id.Read()} has a value of {value}.");
public static void Stream() {
public static class Logger {
static int _height = 1024;
public static int Width => _width;
public static int Height => _height;
public static int Spacing = 1;
public static int Padding = 2;
public readonly int width;
public List<List<char>> logs;
int xStart { get => padClamp; }
int xMax { get => width - padClamp; }
int colMax { get => column.width - padClamp; }
int padClamp { get => Math.Clamp(Padding, 0, (int)Math.Round((double)width * 0.5)); }
int yAdvance { get => 1 + Math.Max(Spacing, 0); }
readonly List<char> emptyLineList;
public int x { get; private set; }
public int y { get; private set; }
public int realY { get; private set; }
public bool complete { get; private set; }
public Column(int width, int height) {
foreach(var ch in emptyLine)
var newLine = new List<char>();
newLine.AddRange(emptyLineList);
while (realY >= logs.Count - 1) {
bool ReachedEnd() => realY >= height;
public bool Write(string text, out string remaining) {
if (complete) return complete;
List<string> chunks = new();
for (int i = 0; i < text.Length; i++) {
if (!wasSpace || chunk.Length > 1) chunks.Add(chunk);
for (int p = 0; p < chunks.Count; p++) {
string stem = p == chunks.Count - 1 ? "" : " ";
WriteWord(chunks[p] + stem, remaining, out remaining);
if (complete) return complete;
private void WriteWord(string text, string all, out string remaining) {
if (x + text.Length > colMax) {
for (int i = 0; i < text.Length; i++) {
for (int t = 0; t < 4; t++) {
remaining = remaining.Prim();
static (int width, int height) column;
static List<List<char>> final;
static string headingLine;
static readonly string dottedLine = "- --- -";
final = new List<List<char>>();
public static void Header(string header, bool centered = true) {
int headerLength = header.Length;
int half = (int)MathF.Round((float)column.width * 0.5f - (float)headerLength * 0.5f - 2);
for (int i = 0; i < half; i++)
WriteLine($"{offset}{header}");
static void SetupColumn() {
column = (_width, _height);
for (int i = 0, l = 0; i < column.width; i++, l = (l + 1) % dottedLine.Length) {
if (i < Padding || i >= column.width - Padding) { }
headingLine += dottedLine[l];
writer = new(column.width, column.height);
static List<(int, int)> cols;
public static void WriteRandom(string stem = "", int words = -1) {
words = rand.Next(12, 64);
string text = $"\t{stem} : \n\t";
const int commaChance_OneIn = 6;
int sentenceLength = rand.Next(3, 16);
if (sentenceLength > available) sentenceLength = available;
available -= sentenceLength;
for (int s = 0; s < sentenceLength; s++) {
int letters = rand.Next(2, 8);
bool lastWord = s == sentenceLength - 1;
for (int l = 0; l < letters; l++) {
if (firstWord && l == 0) {
char letter = (char)rand.Next(start, end + 1);
&& rand.Next(0, commaChance_OneIn) == 1) {
public static void WriteLine(string text = "") {
public static void Write(string text) {
if (writer.Write(text, out string remaining)) {
writer.Write(remaining, out string _);
public static void NextLine() {
public static void NextColumn() {
NextColumn(_width, _height);
public static void NextColumnWithWidth(int width) {
NextColumn(width, _height);
public static void NextColumnWithHeight(int height) {
NextColumn(_width, height);
public static void NextColumn(int width, int height) {
static void AddLineToLog(int i) {
var newLine = new List<char>();
for (int ci = 0; ci < cols.Count; ci++) {
int cWidth = cols[ci].Item1;
int cHeight = cols[ci].Item2;
char space = cHeight < column.height ? '-' : ' ';
char divider = cHeight < column.height ? '-' : '|';
bool isPriorCol = ci == cols.Count - 1;
if (ci == 0) newLine.Add(divider);
for (int cx = 0; cx < cWidth; cx++)
newLine.Add(isPriorCol ? priorDivider : divider);
static void AddPreviousUnderline() {
if (final.Count <= column.height) final.Add(new());
List<char> fullLine = new();
fullLine.AddRange(final[column.height]);
int start = fullLine.Count;
for (int ci = 0; ci < cols.Count; ci++) {
for (int cx = 0; cx <= cols[ci].Item1; cx++) {
if (lx >= start) fullLine.Add(' ');
for (int x = 0; x < column.width; x++)
final[column.height] = fullLine;
final.Add(new List<char>());
static void CommitWriterToFinal(bool drawSeparator = true) {
for (int i = 0; i < column.height; i++) {
if (final.Count <= i) AddLineToLog(i);
if (cols.Count == 0) final[i].Add('|');
int currentLineLength = final[i].Count;
foreach(var col in cols) idealLineLength += col.Item1 + 1;
if (currentLineLength < idealLineLength) {
int mark = idealLineLength;
for (int l = currentLineLength; l < idealLineLength; l++) {
if (i == cols[cols.Count - 1].Item2) {
final[i][final[i].Count - 1] = '|';
? new string(writer.logs[i].ToArray())
if (drawSeparator) final[i].Add('|');
var underline = new List<char>();
for (int i = 0; i < column.width; i++)
var prevHeight = cols[cols.Count - 1].Item2;
if (column.height != prevHeight)
if (column.height <= prevHeight) {
int underIndex = Math.Min(final.Count, column.height);
final[underIndex].AddRange(underline);
} else if (column.height > prevHeight)
underline.Insert(0, '|');
static bool padded = false;
public static void Read() {
if (final.Count == 0) return;
int size = final[0].Count;
if (writer.y > 0) size += column.width + 1;
CommitWriterToFinal(true);
char[] topLine = new char[0];
char[] bottomLine = new char[0];
topLine = new char[size];
for (int i = 0; i < size; i++)
string _topLine = new string(topLine);
Console.WriteLine(_topLine);
for (int i = 0; i < final.Count; i++) {
var str = final[i].ToArray();
var _str = new string(str);
public static string Prim(this string str)
=> str.Length > 2 ? str.Substring(1, str.Length - 1) : "";