Project Overview

Role: Programmer

Date: May 2020 - June 2020

Team Size: Solo project

Engine: Visual studio

Version Control: Git

Code Language: C#

My Role

I worked on these projects while interning at House of How. I was the only programmer on these tools with some help from my mentor when I got stuck with something that I could not solve or was spending too much time on.

Spell checker

The Minecraft spell checker is a command line and GUI interface tool that was integrated in House of How’s product shipping pipeline. The purpose of the tool is to find spelling errors in Minecraft maps to avoid failing certification and losing weeks of time waiting for approval.

The spell checker opens Minecraft bedrock worlds, searches for signs and command-blocks, takes the blocks text data, split the sentences into words and compare those to a dictionary. If the word is spelt incorrectly the tool will tell the user the word, the location of the sign or command-block and in the debug box it will also show the whole content of the sign or command-block. This way the user can easily determine if the word fits the context and the tool was wrong.

spellchecker_GUI

If an error is clicked on it will highlight the debug box's equivalent error to show the user more information

spellchecker_GUI
//Read the stream of data to get the writable blocks
if (memoryStream.Position >= memoryStream.Length)
    break;

NbtReader nbtReader = new NbtReader(memoryStream, false);
NbtTag tag = nbtReader.ReadAsTag();
NbtCompound compound = (NbtCompound)tag;
foreach (NbtTag compoundTag in compound)
{
    if (compoundTag.Name != "id")
        continue;

    if (compoundTag.StringValue.Equals("Chest")
        || compoundTag.StringValue.Equals("MobSpawner")
        || compoundTag.StringValue.Equals("EnderChest"))
        continue;

    //Isolate signs and command blocks into a list
    if (compoundTag.StringValue.Contains("Sign") && !readableCompounds.Contains(compound))
        readableCompounds.Add(compound);
    if (compoundTag.StringValue.Contains("CommandBlock") && !readableCompounds.Contains(compound))
        readableCompounds.Add(compound);
}



//Check for spelling errors in each word, Currently it will give errors for numbers!
string loweredClearedSplit = clearedSplit[i].ToLower();
//This is for checking words that end with 's. remove the 's and then 
//check the word itself and then add it back if the word doesnt exist in the dictionary
if (!wordDictionary.Contains(loweredClearedSplit))
{
    if (loweredClearedSplit.EndsWith("'s"))
    {
        string newClearedSplit = loweredClearedSplit.Remove(loweredClearedSplit.IndexOf("'s"), 2);
        if (newClearedSplit == string.Empty)
            continue;
        if (!wordDictionary.Contains(newClearedSplit))
        {
            newClearedSplit = clearedSplit[i];
            wrongWords.Add(newClearedSplit);
        }
    }
    else if (!wordDictionary.Contains(loweredClearedSplit))
    {
        wrongWords.Add(clearedSplit[i]);
    }
}
            

World renamer

The world renamer is a simple command-line tool that changes opens a Minecraft bedrock level.dat file to read and edit the name.

World renamer needs multiple arguments to change a level name. The first being a path to a Minecraft world and the second being the new name. There's also a third optional argument that also changes the levelname.txt file's name. If no new name is entered the program will compare the levelname.txt and level.dat file names to see if they match.

//validate that the leveldat file exists
private static bool ValidateMinecraftWorld(string levelDatPath)
{
    if (!levelDatPath.ToLowerInvariant().EndsWith("level.dat") &&
        !levelDatPath.ToLowerInvariant().EndsWith("level.dat" + Path.DirectorySeparatorChar) &&
        !levelDatPath.ToLowerInvariant().EndsWith("level.dat" + Path.AltDirectorySeparatorChar))
    {
        levelDatPath = Path.Combine(levelDatPath, "level.dat");
        if (File.Exists(levelDatPath))
            return true;
        else
        {
            //If file cannot be found maybe user put db folder or even deeper folders
            while(!File.Exists(levelDatPath))
            {
                levelDatPath = Directory.GetParent(levelDatPath).ToString();
                levelDatPath = Path.Combine(levelDatPath, "level.dat");
            }
            if (!File.Exists(levelDatPath))
            {
                Console.Out.WriteLine("Found no level.dat file found");
                return false;
            }
        }
    }
    else if (levelDatPath.ToLowerInvariant().EndsWith("level.dat") &&
             levelDatPath.ToLowerInvariant().EndsWith("level.dat" + Path.DirectorySeparatorChar) &&
             levelDatPath.ToLowerInvariant().EndsWith("level.dat" + Path.AltDirectorySeparatorChar))
    {
        if (File.Exists(levelDatPath))
            return true;
    }
        
    return false;
}



private static void ChangeDatLevelName(string leveldatPath, string newName)
{
    // read level.dat to get the tree
    NbtTree tree = ReadWriteBedrockLevelDat.ReadLevelDatTree(leveldatPath);

    // change level.dat
    tree.Root["LevelName"].ToTagString().Data = newName;
    Console.Out.WriteLine("Changed level.dat name to: " + newName);

    // write level.dat tree to a nbt file
    ReadWriteBedrockLevelDat.WriteLevelDat(leveldatPath, tree);
}