diff --git a/Content/InstanceMaterial.uasset b/Content/InstanceMaterial.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..2fb267b53bfd278ae16752cd0e518422e251670e
--- /dev/null
+++ b/Content/InstanceMaterial.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fd8257ab5d1829b9ff175b290de9ffed71b9cb974d838f525de39089fdda5e02
+size 49757
diff --git a/Content/textmaterial.uasset b/Content/textmaterial.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..ecb4b3901b8284e446d840a556f5dc86a565083c
--- /dev/null
+++ b/Content/textmaterial.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:28e0e621930bd6cfba91edf24730fcf6cde5528501d697e984309a2d4447753f
+size 24983
diff --git a/Source/DasherVR/Private/Dasher3DWidget.cpp b/Source/DasherVR/Private/Dasher3DWidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..74980edc57a08939c5efe6dd4ef822208be4a773
--- /dev/null
+++ b/Source/DasherVR/Private/Dasher3DWidget.cpp
@@ -0,0 +1,302 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#include "Dasher3DWidget.h"
+#include "Math/Rotator.h"
+#include "Engine/Texture2DArray.h"
+// Sets default values
+ADasher3DWidget::ADasher3DWidget() : DasherParents()
+{
+ 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
+	PrimaryActorTick.bCanEverTick = true;
+
+	ActorRootComponent = CreateDefaultSubobject<UStaticMeshComponent>("Root");
+	SetRootComponent(ActorRootComponent);
+
+	CubeInstances = CreateDefaultSubobject<UInstancedStaticMeshComponent>("Cubes");
+	CubeInstances->SetupAttachment(GetRootComponent());
+	CubeInstances->SetFlags(RF_Transactional);
+	CubeInstances->NumCustomDataFloats = 6; //Full Linear Color
+	CubeInstances->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);
+	this->AddInstanceComponent(CubeInstances);
+
+	LetterInstances = CreateDefaultSubobject<UInstancedStaticMeshComponent>("Letters");
+	LetterInstances->SetupAttachment(GetRootComponent());
+	LetterInstances->SetFlags(RF_Transactional);
+	LetterInstances->NumCustomDataFloats = 5; //Full Linear Color
+	LetterInstances->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);
+	this->AddInstanceComponent(LetterInstances);
+
+}
+
+// Called when the game starts or when spawned
+void ADasher3DWidget::BeginPlay()
+{
+	Super::BeginPlay();
+	//Setting up Dasher
+	InitializeDasher();
+	//Setting up the Texture array for the font
+	InitializeTextureArray();	
+}
+
+// Called every frame
+void ADasher3DWidget::Tick(float DeltaTime)
+{
+	Super::Tick(DeltaTime);
+	DasherMainInterface->Tick(static_cast<unsigned long>(GetGameTimeSinceCreation() * 1000.0)); //we need to provide ticks in milliseconds
+
+	//TODO subscribe to some resizing event
+  const FVector AbsoluteSize = GetActorScale();
+	if (SlateSize.X != AbsoluteSize.X || SlateSize.Y != AbsoluteSize.Y) {
+		SlateSize.X = AbsoluteSize.X;
+		SlateSize.Y = AbsoluteSize.Y;
+		resize(SlateSize.X * DrawingSize.X, SlateSize.Y * DrawingSize.Y);
+		DefaultTranslation = FVector(-SlateSize.X * DrawingSize.X / 2.0f, -SlateSize.Y / 2.0f * DrawingSize.Y, 0);
+		//tell dasher we resized the screen, but only if there's actually a screen
+		if (SlateSize.X && SlateSize.Y) DasherMainInterface->ScreenResized(this);
+	};
+	
+
+	//TODO: REMOVE, DEBUG LINES
+	//CursorPosition = FVector2D(500, 500);
+	DasherMainInterface->KeyDown(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), 100);
+}
+
+std::pair<Dasher::screenint, Dasher::screenint> ADasher3DWidget::TextSize(Label* label, unsigned iFontSize)
+{
+	const char letter = label->m_strText[0];
+	int letterindex = letter;
+	if (letterindex < 33) letterindex = 33;
+
+	const int TextureIndex = DisplayFont->Characters[letterindex].TextureIndex;
+	const float emWidth = DisplayFont->Characters['M'].USize; //To get width of an emdash
+	const float TextureSizeU = TextureArray->SourceTextures[TextureIndex]->GetSizeX(); // Pixel Sizes
+	const float TextureSizeV = TextureArray->SourceTextures[TextureIndex]->GetSizeY(); // Pixel Sizes
+	const float CharacterOffsetU = DisplayFont->Characters[letterindex].StartU; //Upper left corner
+	const float CharacterOffsetV = DisplayFont->Characters[letterindex].StartV; //Upper left corner
+	const float CharacterSizeU = DisplayFont->Characters[letterindex].USize; // Pixel Sizes for actual character without blank space
+	const float CharacterSizeV = DisplayFont->Characters[letterindex].VSize; // Pixel Sizes for actual character without blank space
+	const float CharacterVerticalOffset = DisplayFont->Characters[letterindex].VerticalOffset; //vertical offset in pixels
+	FVector2D FontToPixels = FVector2D(iFontSize, iFontSize); // Since Font to meter was font * (meters/pixel) assumption: font in pixels
+	const FVector2D Scale = FontToPixels * FVector2D(
+			CharacterSizeU / emWidth, // width
+			(CharacterSizeV / CharacterSizeU) * (CharacterSizeU / emWidth)); // (Height/Width * Width)
+	return { static_cast<Dasher::screenint>(Scale.X), static_cast<Dasher::screenint>(Scale.Y) };
+	
+}
+
+void ADasher3DWidget::DrawString(Label* label, Dasher::screenint x, Dasher::screenint y, unsigned iFontSize, int iColour){}
+
+void ADasher3DWidget::DrawCube(Dasher::screenint posX, Dasher::screenint posY, Dasher::screenint sizeX, Dasher::screenint sizeY, Dasher::myint extrusionLevel, int Colour, int iOutlineColour, int iThickness) {
+		
+	if (sizeX == 0 || sizeY == 0) return;
+	const FVector Scale = FVector(sizeX, sizeY, sqrt(extrusionLevel * 10)) / DrawingSize;
+	const FVector Translation = FVector(posX, posY, 0) + DefaultTranslation - FVector(SlateSize / 2.0f, 0);
+	
+	FLinearColor RectColor;
+
+	if (ColorPalette) {
+			RectColor = FLinearColor(ColorPalette->Colors[Colour].Red / 255.0, ColorPalette->Colors[Colour].Green / 255.0, ColorPalette->Colors[Colour].Blue / 255.0);
+	}
+	else {
+			RectColor = FLinearColor::Blue;
+	}
+
+	BackBuffer->first.Add(FTransform(FQuat::Identity, Translation / DrawingSize * 100.0f, Scale));
+	BackBuffer->second.Add(RectColor.R);
+	BackBuffer->second.Add(RectColor.G);
+	BackBuffer->second.Add(RectColor.B);
+	BackBuffer->second.Add(Scale.X);
+	BackBuffer->second.Add(Scale.Y);
+	BackBuffer->second.Add(Scale.Z);
+}
+
+
+auto ADasher3DWidget::GetLetterTransformData(int letterindex, int iFontSize, int x, int y, int extrusionLevel, int position) {
+		if (letterindex < 32) letterindex = 32; // replace non-printable characters with spaces.
+
+		const int TextureIndex = DisplayFont->Characters[letterindex].TextureIndex;
+		const float emWidth = DisplayFont->Characters['M'].USize; //To get width of an emdash
+		const float TextureSizeU = TextureArray->SourceTextures[TextureIndex]->GetSizeX(); // Pixel Sizes
+		const float TextureSizeV = TextureArray->SourceTextures[TextureIndex]->GetSizeY(); // Pixel Sizes
+		const float CharacterOffsetU = DisplayFont->Characters[letterindex].StartU; //Upper left corner
+		const float CharacterOffsetV = DisplayFont->Characters[letterindex].StartV; //Upper left corner
+		const float CharacterSizeU = DisplayFont->Characters[letterindex].USize; // Pixel Sizes for actual character without blank space
+		const float CharacterSizeV = DisplayFont->Characters[letterindex].VSize; // Pixel Sizes for actual character without blank space
+		const float CharacterVerticalOffset = DisplayFont->Characters[letterindex].VerticalOffset; //vertical offset in pixels
+		const FVector FontToMeters = FVector(iFontSize / DrawingSize.X, iFontSize / DrawingSize.Y, 1); // From Font to Meter
+
+		TArray<float> FontData = {
+		CharacterOffsetU / TextureSizeU, // Upper Left Corner given in UV
+		CharacterOffsetV / TextureSizeV, // Upper Left Corner given in UV
+		CharacterSizeU / TextureSizeU, // Size given in UV
+		CharacterSizeV / TextureSizeV, // Size given in UV
+		static_cast<float>(TextureIndex) }; // Texture Page
+		// X & Y are given as upper left corner of the character
+
+
+		const FVector Scale = FontToMeters * FVector(
+				CharacterSizeU / emWidth, // width
+				(CharacterSizeV / CharacterSizeU) * (CharacterSizeU / emWidth), // (Height/Width * Width)
+				1);
+
+
+		const FVector Translation = FVector(
+				x / DrawingSize.X * 100.0f + Scale.X * 0.5f * 100.0f + position * emWidth, // offsetting by position for multpile character strings
+				y / DrawingSize.Y * 100.0f + CharacterVerticalOffset / emWidth * iFontSize / DrawingSize.Y * 100.0f, //+ Scale.Y * 0.5f * 100.0f 
+				sqrt(extrusionLevel * 10 + 1))
+				+ (-FVector(SlateSize / 2.0f, 0) + DefaultTranslation) / DrawingSize * 100.0f; // Move to upper left corner
+
+
+		const FTransform Transform = FTransform(FQuat::Identity, Translation, Scale);
+
+		struct LetterData {
+				FTransform transform;
+				TArray<float> FontData;
+		};
+		return LetterData{ Transform, FontData };
+}
+
+
+void ADasher3DWidget::Draw3DLabel(Label* label, Dasher::screenint x, Dasher::screenint y, Dasher::myint extrusionLevel, unsigned int iFontSize, int iColour) {
+		//TODO: expand to all Labels
+		const std::string labeltext = label->m_strText;
+		
+		for (int i = 0; i < labeltext.size(); i++)
+		{
+				int letterindex = labeltext[i];
+				auto [Transform, FontData] = GetLetterTransformData(letterindex, iFontSize, x, y, extrusionLevel, i);
+				LabelBackBuffer->first.Add(Transform);
+				LabelBackBuffer->second.Add(FontData);
+		}
+}
+
+
+
+
+
+
+void ADasher3DWidget::DrawRectangle(Dasher::screenint x1, Dasher::screenint y1, Dasher::screenint x2, Dasher::screenint y2, int Colour, int iOutlineColour, int iThickness)
+{
+		// we're not drawing rectangles
+}
+
+void ADasher3DWidget::DrawCircle(Dasher::screenint iCX, Dasher::screenint iCY, Dasher::screenint iR, int iFillColour, int iLineColour, int iLineWidth)
+{
+	//Todo
+}
+
+void ADasher3DWidget::Polyline(point* Points, int Number, int iWidth, int Colour)
+{
+	//Todo
+}
+
+void ADasher3DWidget::Polygon(point* Points, int Number, int fillColour, int outlineColour, int lineWidth)
+{
+	//Todo
+}
+
+void ADasher3DWidget::Display()
+{
+	std::swap(FrontBuffer, BackBuffer);
+	BackBuffer->first.Empty();
+	BackBuffer->second.Empty();
+	CubeInstances->ClearInstances();
+	CubeInstances->AddInstances(FrontBuffer->first, false);
+
+	TArray<float> ColorScale = {0,0,0,0,0,0};
+	for(int i = 0; i < FrontBuffer->first.Num(); i++)
+	{
+		ColorScale = {
+			FrontBuffer->second[i*CubeInstances->NumCustomDataFloats],
+			FrontBuffer->second[i*CubeInstances->NumCustomDataFloats+1],
+			FrontBuffer->second[i*CubeInstances->NumCustomDataFloats+2],
+			FrontBuffer->second[i*CubeInstances->NumCustomDataFloats+3],
+			FrontBuffer->second[i*CubeInstances->NumCustomDataFloats+4],
+			FrontBuffer->second[i*CubeInstances->NumCustomDataFloats+5]
+		};
+		CubeInstances->SetCustomData(i, ColorScale);
+	}
+
+
+	std::swap(LabelFrontBuffer, LabelBackBuffer);
+	LabelBackBuffer->first.Empty();
+	LabelBackBuffer->second.Empty();
+	LetterInstances->ClearInstances();
+	LetterInstances->AddInstances(LabelFrontBuffer->first, false);
+
+	for (int i = 0; i < LabelFrontBuffer->first.Num(); i++)
+	{
+			TArray<float> data = LabelFrontBuffer->second[i];
+			LetterInstances->SetCustomData(i, data);
+	}
+
+}
+
+void ADasher3DWidget::SetColourScheme(const Dasher::CColourIO::ColourInfo* pColourScheme)
+{
+	ColorPalette = pColourScheme;
+}
+
+bool ADasher3DWidget::IsPointVisible(Dasher::screenint x, Dasher::screenint y)
+{
+	return true;
+}
+
+bool ADasher3DWidget::GetScreenCoords(Dasher::screenint& iX, Dasher::screenint& iY, Dasher::CDasherView* pView)
+{
+	const FVector2D Position = GetCursorPosition();
+	
+	iX = Position.X;
+	iY = Position.Y;
+
+	return true;
+}
+
+void ADasher3DWidget::SetMouseLocation(FVector2D InputVector)
+{		
+	  CursorPosition = FVector2D((InputVector.X * 10 + DrawingSize.X/2.0f) * SlateSize.X, (InputVector.Y * 10 + DrawingSize.Y / 2.0f) * SlateSize.Y);//FVector2D(500, 500);//		
+}
+
+void ADasher3DWidget::InitializeTextureArray()
+{
+		TextureArray = NewObject<UTexture2DArray>();
+		for (int i = 0; i < DisplayFont->Textures.Num(); i++)
+		{
+				TextureArray->SourceTextures.Add(DisplayFont->Textures[i]);
+		}
+		TextureArray->UpdateSourceFromSourceTextures(true);
+		MaxVSize = 0;
+		MaxUSize = 0;
+		for (int i = 65; i < 91; i++)
+		{
+				if (DisplayFont->Characters[i].VSize > MaxVSize) MaxVSize = DisplayFont->Characters[i].VSize;
+				if (DisplayFont->Characters[i].USize > MaxUSize) MaxUSize = DisplayFont->Characters[i].USize;
+		}
+}
+
+void ADasher3DWidget::InitializeDasher() {
+		SlateSize = FVector2D(GetActorScale().X, GetActorScale().Y);
+		DefaultTranslation = FVector(-SlateSize.X * DrawingSize.X / 2.0f, -SlateSize.Y / 2.0f * DrawingSize.Y, 0);
+		resize(SlateSize.X * DrawingSize.X, SlateSize.Y * DrawingSize.Y);
+
+		static Dasher::XMLErrorDisplay display;
+		Dasher::XmlSettingsStore* Settings = new Dasher::XmlSettingsStore("Settings.xml"/*, &fileUtils*/, &display); //Gets deleted somewhere else
+		Settings->Load();
+		Settings->Save();
+		DasherMainInterface = MakeShared<Dasher::DasherInterface>(Settings);
+		DasherMainInterface->SetDefaultInputDevice(this);
+		//change dasher parameters
+		DasherMainInterface->SetBoolParameter(Dasher::BP_AUTO_SPEEDCONTROL, false);  //Auto Speed Control
+		DasherMainInterface->SetLongParameter(Dasher::LP_DASHER_FONTSIZE, 22);
+		DasherMainInterface->SetLongParameter(Dasher::LP_MAX_BITRATE, 400);			//Maximum Speed
+		//DasherMainInterface->SetStringParameter(Dasher::SP_INPUT_FILTER, "Normal");	//On Hold
+		DasherMainInterface->SetStringParameter(Dasher::SP_ALPHABET_ID, "German without punctuation");
+		DasherMainInterface->SetLongParameter(Dasher::LP_MIN_NODE_SIZE, 15);
+		DasherMainInterface->SetLongParameter(Dasher::LP_SHAPE_TYPE, Dasher::Options::CUBE);
+
+		DasherMainInterface->SetScreen(this);
+		DasherMainInterface->SetBuffer(0);
+		DasherMainInterface->KeyDown(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), 100);
+
+		DasherMainInterface->SetLongParameter(Dasher::LP_ORIENTATION, Dasher::Options::ScreenOrientations::LeftToRight);
+}
\ No newline at end of file
diff --git a/Source/DasherVR/Private/DasherFileUtils.cpp b/Source/DasherVR/Private/DasherFileUtils.cpp
index 8f346a33bc02e3dee5e606b181ea025213995991..8e1f40a87d2f571c44af9affe5bd94e1cea891da 100644
--- a/Source/DasherVR/Private/DasherFileUtils.cpp
+++ b/Source/DasherVR/Private/DasherFileUtils.cpp
@@ -2,6 +2,8 @@
 #include "DasherCoreWrapper.h"
 #include "HAL/FileManagerGeneric.h"
 #include "Misc/FileHelper.h"
+#include "Misc/Paths.h"
+#include "Internationalization/Regex.h"
 
 namespace Dasher
 {
diff --git a/Source/DasherVR/Private/DasherInterface.cpp b/Source/DasherVR/Private/DasherInterface.cpp
index 9eaea7b3d89e0c61bf010850ada712ac7c84353a..bf2a2eb4c6c2d4e3105b84f382138ba1038cad70 100644
--- a/Source/DasherVR/Private/DasherInterface.cpp
+++ b/Source/DasherVR/Private/DasherInterface.cpp
@@ -129,7 +129,7 @@ namespace Dasher
 		NewFrame(time, true);
 	}
 
-	void DasherInterface::SetScreen(SDasherWidget* screen)
+	void DasherInterface::SetScreen(CDasherScreen* screen)
 	{
 		//set the widget as screen that dasher will be displayed on
 		ChangeScreen(screen);
diff --git a/Source/DasherVR/Private/DasherVRPrivatePCH.h b/Source/DasherVR/Private/DasherVRPrivatePCH.h
new file mode 100644
index 0000000000000000000000000000000000000000..e9cda3f89f2a68c2afdae9ce7dc82a88b39841fb
--- /dev/null
+++ b/Source/DasherVR/Private/DasherVRPrivatePCH.h
@@ -0,0 +1,3 @@
+#pragma once
+#include "CoreMinimal.h"
+#include "DasherVR.h"
\ No newline at end of file
diff --git a/Source/DasherVR/Private/SDasherWidget.cpp b/Source/DasherVR/Private/SDasherWidget.cpp
index 3e770e343de12e02f56c4f435d14aed58303401e..dc69aa944c744f8b58e626cd678c7eb8fbc0e293 100644
--- a/Source/DasherVR/Private/SDasherWidget.cpp
+++ b/Source/DasherVR/Private/SDasherWidget.cpp
@@ -6,6 +6,7 @@
 #include "DasherInterface.h"
 
 #include "Components/SlateWrapperTypes.h"
+#include "Framework/Application/SlateApplication.h"
 
 BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
 
@@ -16,331 +17,375 @@ BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
 //Set the state if we're in the editor or not.
 void SDasherWidget::SetEditor(bool EditorState)
 {
-	IsEditor = EditorState;
+  IsEditor = EditorState;
+}
+//Pause the input
+void SDasherWidget::PauseInput()
+{
+    InputPaused = true;
+}
+//Unpause the input
+void SDasherWidget::UnpauseInput()
+{
+    InputPaused = false;
 }
 
+
 //Event Handlers
 //Mouse position saved for mouse Input
 FReply SDasherWidget::HandleMouseMoveEvent(const FGeometry& Geometry, const FPointerEvent& MouseEvent)
 {
-	if (CurrentlyUsingVectorInput) return FReply::Unhandled();
-	//The mouse event only contains the Screen Space Position
-	CursorPosition = Geometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition());
-	return FReply::Handled();
+    if (!InputPaused)
+    {
+        if (CurrentlyUsingVectorInput) return FReply::Unhandled();
+        //The mouse event only contains the Screen Space Position
+        CursorPosition = Geometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition());
+    }
+    return FReply::Handled();
 }
 
 FReply SDasherWidget::HandleMouseDownEvent(const FGeometry& Geometry, const FPointerEvent& MouseEvent)
 {
-	if (CurrentlyUsingVectorInput)
-	{
-		CurrentlyUsingVectorInput = false;
-		return FReply::Handled().LockMouseToWidget(AsShared());
-	}
-	DasherMainInterface->KeyDown(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), 100); //100 is the keycode for LMB
-	MouseDownListeners.ExecuteIfBound();
-	return FReply::Handled().LockMouseToWidget(AsShared());
+  if (!InputPaused)
+  {
+    if (CurrentlyUsingVectorInput)
+    {
+        CurrentlyUsingVectorInput = false;
+        return FReply::Handled().LockMouseToWidget(AsShared());
+    }
+    DasherMainInterface->KeyDown(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), 100); //100 is the keycode for LMB
+    MouseDownListeners.ExecuteIfBound();
+  }
+  return FReply::Handled().LockMouseToWidget(AsShared());
 }
 
 FReply SDasherWidget::HandleMouseUpEvent(const FGeometry& Geometry, const FPointerEvent& MouseEvent)
 {
-	if (CurrentlyUsingVectorInput)
-	{
-		CurrentlyUsingVectorInput = false;
-		return FReply::Handled().ReleaseMouseLock();
-	}
-	DasherMainInterface->KeyUp(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), 100); //100 is the keycode for LMB
+    if (CurrentlyUsingVectorInput)
+    {
+        CurrentlyUsingVectorInput = false;
+        return FReply::Handled().ReleaseMouseLock();
+    }
+    DasherMainInterface->KeyUp(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), 100); //100 is the keycode for LMB
     MouseUpListeners.ExecuteIfBound();
-	return FReply::Handled().ReleaseMouseLock();
+
+    return FReply::Handled().ReleaseMouseLock();
 }
 
 FReply SDasherWidget::HandleMouseDoubleClickEvent(const FGeometry& Geometry, const FPointerEvent& MouseEvent)
 {
-	if(CurrentlyUsingVectorInput)
-	{
-		CurrentlyUsingVectorInput = false;
-		return FReply::Handled();
-	}
-	DasherMainInterface->KeyUp(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), 100); //100 is the keycode for LMB
-	return FReply::Handled();
+    if (!InputPaused)
+    {
+        if (CurrentlyUsingVectorInput)
+        {
+            CurrentlyUsingVectorInput = false;
+            return FReply::Handled();
+        }
+        DasherMainInterface->KeyUp(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), 100); //100 is the keycode for LMB
+    }
+        return FReply::Handled();
 }
 
 //Set in the HandleMouseMoveEvent or via Set InputVector
 //See tick for geometry things that could be use to modify this.
 FVector2D SDasherWidget::GetCursorPosition()
 {
-	return CursorPosition;
+  return CursorPosition;
 }
 
 bool SDasherWidget::GetScreenCoords(screenint& iX, screenint& iY, Dasher::CDasherView* pView)
 {
-	const FVector2D Position = GetCursorPosition();
-	
-	iX = Position.X;
-	iY = Position.Y;
+  const FVector2D Position = GetCursorPosition();
+  
+  iX = Position.X;
+  iY = Position.Y;
 
-	return true;
+  return true;
 }
 
 void SDasherWidget::InputVector(const FVector2D InputVector)
 {
-	if (!CurrentlyUsingVectorInput) return;
-	CursorPosition = DasherMainInterface->ConvertDasher2Screen(Dasher::CDasherModel::ORIGIN_X, Dasher::CDasherModel::ORIGIN_Y)
-					+ InputVector * FVector2D(1.0f,-1.0f) * (GetHeight() / 2);
+    if (!InputPaused) {
+        if (!CurrentlyUsingVectorInput) return;
+        CursorPosition = DasherMainInterface->ConvertDasher2Screen(Dasher::CDasherModel::ORIGIN_X, Dasher::CDasherModel::ORIGIN_Y)
+            + InputVector * FVector2D(1.0f, -1.0f) * (GetHeight() / 2);
+    }
 }
 
 void SDasherWidget::InputButton(bool Pressed)
 {
-	CurrentlyUsingVectorInput = true;
-	if(Pressed)
-	{
-		DasherMainInterface->KeyDown(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), 100); //100 is the keycode for LMB	
-	}
-	else {
-		DasherMainInterface->KeyUp(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), 100); //100 is the keycode for LMB
-	}
+    if (!InputPaused) {
+        CurrentlyUsingVectorInput = true;
+        if (Pressed)
+        {
+            DasherMainInterface->KeyDown(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), 100); //100 is the keycode for LMB	
+        }
+        else {
+            DasherMainInterface->KeyUp(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), 100); //100 is the keycode for LMB
+        }
+    }
 }
 
 //The construction of the Dasher Widget, Dasher parameters are set here, a function to set them outside is not provided, but can be easily implemented
 void SDasherWidget::Construct(const FArguments& InArgs)
 {	
-	//Initial resize, needed for setup
-	Width = InArgs._width;
-	Height = InArgs._height;
-	resize(Width, Height);
+  //Initial resize, needed for setup
+  Width = InArgs._width;
+  Height = InArgs._height;
+  resize(Width, Height);
 
-	//initialize the font measuring service.
-	FontMeasureService = FSlateApplication::Get().GetRenderer()->GetFontMeasureService();
+  //initialize the font measuring service.
+  FontMeasureService = FSlateApplication::Get().GetRenderer()->GetFontMeasureService();
 
-	//Setting up Dasher
-	static Dasher::XMLErrorDisplay display;
+  //Setting up Dasher
+  static Dasher::XMLErrorDisplay display;
     Dasher::XmlSettingsStore* Settings = new Dasher::XmlSettingsStore("Settings.xml", &display); //Gets deleted somewhere else
     Settings->Load();
-	Settings->Save();
+  Settings->Save();
     DasherMainInterface = MakeShared<Dasher::DasherInterface>(Settings);
-	DasherMainInterface->SetDefaultInputDevice(this);
+  DasherMainInterface->SetDefaultInputDevice(this);
 
-	DasherMainInterface->SetScreen(this);
-	DasherMainInterface->SetBuffer(0);
+  DasherMainInterface->SetScreen(this);
+  DasherMainInterface->SetBuffer(0);
 
-	DasherMainInterface->SetCharEnteredCallback([this](FString Char, FString Buffer){CharacterEntered.ExecuteIfBound(Char, Buffer);});
-	DasherMainInterface->SetCharDeletedCallback([this](FString Char, FString Buffer){CharacterDeleted.ExecuteIfBound(Char, Buffer);});
+  DasherMainInterface->SetCharEnteredCallback([this](FString Char, FString Buffer) {CharacterEnteredFlag = true; AlteredChar = Char; });
+  DasherMainInterface->SetCharDeletedCallback([this](FString Char, FString Buffer) {CharacterDeletedFlag = true; AlteredChar = Char; });
 
-	//Set up the Event Handlers for Mouse Movement etc.
-	SetOnMouseMove(FPointerEventHandler::CreateLambda([this](const FGeometry& Geometry, const FPointerEvent& MouseEvent) {return HandleMouseMoveEvent(Geometry, MouseEvent) ; }));
-	SetOnMouseButtonDown(FPointerEventHandler::CreateLambda([this](const FGeometry& Geometry, const FPointerEvent& MouseEvent) {return HandleMouseDownEvent(Geometry, MouseEvent); }));
-	SetOnMouseButtonUp(FPointerEventHandler::CreateLambda([this](const FGeometry& Geometry, const FPointerEvent& MouseEvent) {return HandleMouseUpEvent(Geometry, MouseEvent); }));
-	SetOnMouseDoubleClick(FPointerEventHandler::CreateLambda([this](const FGeometry& Geometry, const FPointerEvent& MouseEvent) {return HandleMouseDoubleClickEvent(Geometry, MouseEvent); })); //We treat a double click of the mouse as a lift of the mouse button.
+  //Set up the Event Handlers for Mouse Movement etc.
+  SetOnMouseMove(FPointerEventHandler::CreateLambda([this](const FGeometry& Geometry, const FPointerEvent& MouseEvent) {return HandleMouseMoveEvent(Geometry, MouseEvent) ; }));
+  SetOnMouseButtonDown(FPointerEventHandler::CreateLambda([this](const FGeometry& Geometry, const FPointerEvent& MouseEvent) {return HandleMouseDownEvent(Geometry, MouseEvent); }));
+  SetOnMouseButtonUp(FPointerEventHandler::CreateLambda([this](const FGeometry& Geometry, const FPointerEvent& MouseEvent) {return HandleMouseUpEvent(Geometry, MouseEvent); }));
+  SetOnMouseDoubleClick(FPointerEventHandler::CreateLambda([this](const FGeometry& Geometry, const FPointerEvent& MouseEvent) {return HandleMouseDoubleClickEvent(Geometry, MouseEvent); })); //We treat a double click of the mouse as a lift of the mouse button.
     //You could add Slate Code here for child slots etc.
 }
 
-void SDasherWidget::SetBoolParamter(FString ParameterName, bool Value)
-{
-	for(Dasher::Settings::bp_table Setting : Dasher::Settings::boolparamtable)
-	{
-		if(FString(Setting.regName).Compare(ParameterName, ESearchCase::IgnoreCase))
-		{
-			DasherMainInterface->SetBoolParameter(Setting.key, Value);
-			return;
-		}
-	}
+void SDasherWidget::SetParameter(FString ParameterName, bool Value) {
+    for (auto param = Dasher::Settings::parameter_defaults.begin(); param != Dasher::Settings::parameter_defaults.end(); ++param)
+        if (param->second.name == TCHAR_TO_UTF8(*ParameterName)) {
+            DasherMainInterface->SetBoolParameter(param->first, Value);
+            return;
+        }						
 }
 
-void SDasherWidget::SetLongParamter(FString ParameterName, int64 Value)
-{
-	for(Dasher::Settings::bp_table Setting : Dasher::Settings::boolparamtable)
-	{
-		if(FString(Setting.regName).Compare(ParameterName, ESearchCase::IgnoreCase))
-		{
-			DasherMainInterface->SetLongParameter(Setting.key, Value);
-			return;
-		}
-	}
+void SDasherWidget::SetParameter(FString ParameterName, int64 Value) {
+    for (auto param = Dasher::Settings::parameter_defaults.begin(); param != Dasher::Settings::parameter_defaults.end(); ++param)
+        if (param->second.name == TCHAR_TO_UTF8(*ParameterName)) {
+            DasherMainInterface->SetLongParameter(param->first, Value);
+            return;
+        }
 }
 
-void SDasherWidget::SetStringParamter(FString ParameterName, FString Value)
-{
-	for(Dasher::Settings::bp_table Setting : Dasher::Settings::boolparamtable)
-	{
-		if(FString(Setting.regName).Compare(ParameterName, ESearchCase::IgnoreCase))
-		{
-			DasherMainInterface->SetStringParameter(Setting.key, TCHAR_TO_UTF8(*Value));
-			return;
-		}
-	}
+void SDasherWidget::SetParameter(FString ParameterName, FString Value) {
+    for (auto param = Dasher::Settings::parameter_defaults.begin(); param != Dasher::Settings::parameter_defaults.end(); ++param)
+        if (param->second.name == TCHAR_TO_UTF8(*ParameterName)) {
+            DasherMainInterface->SetStringParameter(param->first, TCHAR_TO_UTF8(*Value));
+            return;
+        }
 }
 
+
+
 //Set the colour Scheme for dasher
 void SDasherWidget::SetColourScheme(const Dasher::CColourIO::ColourInfo* pcolours) {
-	ColorPalette = pcolours;
+  ColorPalette = pcolours;
 }
 
 //paints our stuff, then lets compoundwidget (super::) draw its stuff
 //This draws from bottom to top rectangles->lines->labels, this is enough for our use, but for more complex scenarios a proper layering system might have to be implemented
 int32 SDasherWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const
 {
-	//this doesn't draw anything red, we just need a brush. Could probably find a better "empty" brush
-	auto MyBrush = FSlateColorBrush(FColor::Red);
-
-	FFilledRect* RectObject;
-	FWriting* WritingObject;
-	FPolyLine* LineObject;
-	FVector2D Size;
-	FString Text;
-	FSlateFontInfo Font;
-
-	TArray<TUniquePtr<DasherDrawGeometry>>& GeometryBuffer = *FrontBuffer;
-	for(TUniquePtr<DasherDrawGeometry>& GeneralObject : GeometryBuffer) {
-		switch(GeneralObject->Type)
-		{
-			case Rectangle:
-				RectObject = static_cast<FFilledRect*>(GeneralObject.Get());
-				Size = {FMath::Abs(RectObject->top.X - RectObject->bottom.X), FMath::Abs(RectObject->top.Y - RectObject->bottom.Y)};
-				FSlateDrawElement::MakeBox(OutDrawElements, LayerId++, AllottedGeometry.ToPaintGeometry(Size, FSlateLayoutTransform(1, RectObject->top)), &MyBrush, ESlateDrawEffect::None, RectObject->color); //actually adds the box to the geometry
-				break;
-			case Writing:
-				WritingObject = static_cast<FWriting*>(GeneralObject.Get());
-				Text = FString(UTF8_TO_TCHAR(WritingObject->label->m_strText.c_str()));
-
-		        Font = FCoreStyle::GetDefaultFontStyle("Roboto", WritingObject->size, FFontOutlineSettings::NoOutline); //get the font
-				FSlateDrawElement::MakeText(OutDrawElements, LayerId++, AllottedGeometry.ToPaintGeometry(FSlateLayoutTransform(1, FVector2D(WritingObject->pos.X, WritingObject->pos.Y))), Text , Font, ESlateDrawEffect::None, WritingObject->color);
-				break;
-			case PolyLine:
-				LineObject = static_cast<FPolyLine*>(GeneralObject.Get());
-				FSlateDrawElement::MakeLines(OutDrawElements, LayerId++, AllottedGeometry.ToPaintGeometry(), LineObject->points, ESlateDrawEffect::None, LineObject->color, true, LineObject->linewidth);
-				break;
-			default: break;
-		}
-	}
-
-	return SCompoundWidget::OnPaint(Args, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle,  bParentEnabled); //call the parent onPaint
+  //this doesn't draw anything red, we just need a brush. Could probably find a better "empty" brush
+  auto MyBrush = FSlateColorBrush(FColor::Red);
+
+  FFilledRect* RectObject;
+  FWriting* WritingObject;
+  FPolyLine* LineObject;
+  FVector2D Size;
+  FString Text;
+  FSlateFontInfo Font;
+
+  TArray<TUniquePtr<DasherDrawGeometry>>& GeometryBuffer = *FrontBuffer;
+  for(TUniquePtr<DasherDrawGeometry>& GeneralObject : GeometryBuffer) {
+    switch(GeneralObject->Type)
+    {
+      case Rectangle:
+        RectObject = static_cast<FFilledRect*>(GeneralObject.Get());
+        Size = { FMath::Abs(RectObject->top.X - RectObject->bottom.X), FMath::Abs(RectObject->top.Y - RectObject->bottom.Y) };
+        FSlateDrawElement::MakeBox(OutDrawElements, LayerId++, AllottedGeometry.ToPaintGeometry(Size, FSlateLayoutTransform(1, RectObject->top)), &MyBrush, ESlateDrawEffect::None, RectObject->color); //actually adds the box to the geometry
+        break;
+      case Writing:
+        WritingObject = static_cast<FWriting*>(GeneralObject.Get());
+        Text = FString(UTF8_TO_TCHAR(WritingObject->label->m_strText.c_str()));
+
+            Font = FCoreStyle::GetDefaultFontStyle("Roboto", WritingObject->size, FFontOutlineSettings::NoOutline); //get the font
+        FSlateDrawElement::MakeText(OutDrawElements, LayerId++, AllottedGeometry.ToPaintGeometry(FSlateLayoutTransform(1, FVector2D(WritingObject->pos.X, WritingObject->pos.Y))), Text , Font, ESlateDrawEffect::None, WritingObject->color);
+        break;
+      case PolyLine:
+        LineObject = static_cast<FPolyLine*>(GeneralObject.Get());
+        FSlateDrawElement::MakeLines(OutDrawElements, LayerId++, AllottedGeometry.ToPaintGeometry(), LineObject->points, ESlateDrawEffect::None, LineObject->color, true, LineObject->linewidth);
+        break;
+      default: break;
+    }
+  }
+
+  return SCompoundWidget::OnPaint(Args, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle,  bParentEnabled); //call the parent onPaint
 }
 
 //The tick function, we tick dasher in it and update the screen size for dasher
 void SDasherWidget::Tick(const FGeometry& AllotedGeometry, const double InCurrentTime, const float InDeltaTime) {
-	//don't tick in the editor
-	if (!IsEditor) {
-		SCompoundWidget::Tick(AllotedGeometry, InCurrentTime, InDeltaTime);
+  //don't tick in the editor
+  if (!IsEditor && !InputPaused) {
+    SCompoundWidget::Tick(AllotedGeometry, InCurrentTime, InDeltaTime);
 
-		DasherMainInterface->Tick(static_cast<unsigned long>(InCurrentTime * 1000.0)); //we need to provide ticks in milliseconds
+    DasherMainInterface->Tick(static_cast<unsigned long>(InCurrentTime * 1000.0)); //we need to provide ticks in milliseconds
 
 
-		//This probably doesn't have to be done every tick, but it does not seem to have a huge hit on performance
+    //This probably doesn't have to be done every tick, but it does not seem to have a huge hit on performance
         const FGeometry Geometry = GetTickSpaceGeometry();
         const FIntPoint AbsoluteSize = Geometry.Size.IntPoint();
-		if (Width != AbsoluteSize.X || Height != AbsoluteSize.Y) {
-			Width = AbsoluteSize.X;
-			Height = AbsoluteSize.Y;
-			resize(Width, Height);
-			//tell dasher we resized the screen, but only if there's actually a screen
-			if (Width && Height) DasherMainInterface->ScreenResized(this);
-		};
-	}
+    if (Width != AbsoluteSize.X || Height != AbsoluteSize.Y) {
+      Width = AbsoluteSize.X;
+      Height = AbsoluteSize.Y;
+      resize(Width, Height);
+      //tell dasher we resized the screen, but only if there's actually a screen
+      if (Width && Height) DasherMainInterface->ScreenResized(this);
+    };
+  }
 }
 
 std::pair<SDasherWidget::screenint, SDasherWidget::screenint> SDasherWidget::TextSize(CDasherScreen::Label* Label, unsigned Size)
 {
-	const FSlateFontInfo Font = FCoreStyle::GetDefaultFontStyle("Roboto", Size, FFontOutlineSettings::NoOutline); //get the font
-	const FVector2D TextSize = FontMeasureService->Measure(FString(UTF8_TO_TCHAR(Label->m_strText.c_str())), Font, 1); //get the real size of the text, using the fontmeasuring service
-	return {static_cast<screenint>(TextSize.X), static_cast<screenint>(TextSize.Y)};
+  const FSlateFontInfo Font = FCoreStyle::GetDefaultFontStyle("Roboto", Size, FFontOutlineSettings::NoOutline); //get the font
+  const FVector2D TextSize = FontMeasureService->Measure(FString(UTF8_TO_TCHAR(Label->m_strText.c_str())), Font, 1); //get the real size of the text, using the fontmeasuring service
+  return {static_cast<screenint>(TextSize.X), static_cast<screenint>(TextSize.Y)};
 }
 
 //Double Buffers are rotated here.
 void SDasherWidget::Display() {
-	std::swap(FrontBuffer, BackBuffer);
-	BackBuffer->Empty();
+  std::swap(FrontBuffer, BackBuffer);
+  BackBuffer->Empty();
+
+  if (CharacterEnteredFlag && CharacterDeletedFlag) {
+      CharacterSwitched.ExecuteIfBound(AlteredChar, GetBuffer());
+  }
+  else if (CharacterEnteredFlag) {
+      CharacterEntered.ExecuteIfBound(AlteredChar, GetBuffer());
+  }
+  else if (CharacterDeletedFlag) {
+      CharacterDeleted.ExecuteIfBound(AlteredChar, GetBuffer());
+  }
+
+  CharacterEnteredFlag = false;
+  CharacterDeletedFlag = false;
 }
 
-
 //Functions for Drawing
 void SDasherWidget::DrawRectangle(Dasher::screenint x1, Dasher::screenint y1, Dasher::screenint x2, Dasher::screenint y2, int colour, int iOutlineColour, int iThickness)
 {
-	const FVector2D Top(x1, y1);
-	const FVector2D Bottom(x2, y2);
-	
-	FLinearColor RectColor;
-
-	if (ColorPalette) {
-		RectColor = FLinearColor(ColorPalette->Colors[colour].Red/255.0, ColorPalette->Colors[colour].Green / 255.0, ColorPalette->Colors[colour].Blue / 255.0);
-	}
-	else {
-		RectColor = FLinearColor::Blue;
-	}
-	
-	BackBuffer->Add(MakeUnique<FFilledRect>(Top, Bottom, RectColor));
+   FLinearColor RectColorFG = FLinearColor(0, 0, 0);
+   FLinearColor RectColorBG = FLinearColor(0, 0, 0);
+
+   FVector2D TopBG = FVector2D(x1, y1);
+   FVector2D BottomBG = FVector2D(x2, y2);
+   FVector2D TopFG(x1, y1);
+   FVector2D BottomFG(x2, y2);
+
+   if (iThickness && !(colour == 99 || colour == 96))
+   {
+       const int BGColour = iOutlineColour == -1 ? 3 : iOutlineColour;
+       TopFG = FVector2D(x1+iThickness, y1+iThickness);
+       BottomFG = FVector2D(x2-iThickness, y2-iThickness);
+
+       RectColorBG = FLinearColor(ColorPalette->Colors[BGColour].Red / 255.0, ColorPalette->Colors[BGColour].Green / 255.0, ColorPalette->Colors[BGColour].Blue / 255.0);
+       BackBuffer->Add(MakeUnique<FFilledRect>(TopBG, BottomBG, RectColorBG));
+   }
+
+ 
+    if (colour == 99 || colour == 96)
+    {
+        RectColorFG = FLinearColor(ColorPalette->Colors[colour].Red / 255.0, ColorPalette->Colors[colour].Green / 255.0, ColorPalette->Colors[colour].Blue / 255.0, 0.5);
+    }
+    else
+    {
+        RectColorFG = FLinearColor(ColorPalette->Colors[colour].Red / 255.0, ColorPalette->Colors[colour].Green / 255.0, ColorPalette->Colors[colour].Blue / 255.0);
+    }
+
+    BackBuffer->Add(MakeUnique<FFilledRect>(TopFG, BottomFG, RectColorFG));
 }
 
 void SDasherWidget::DrawString(CDasherScreen::Label* lab, screenint x1, screenint y1, unsigned int iSize, int colour) {
-	const FVector2D Pos(x1, y1);
-
-	FLinearColor TextColor;
-
-	if (ColorPalette) {
-		TextColor = FLinearColor(ColorPalette->Colors[colour].Red / 255.0, ColorPalette->Colors[colour].Green / 255.0, ColorPalette->Colors[colour].Blue / 255.0);
-	}
-	else {
-		TextColor = FLinearColor::Black;
-	}
-	
-	BackBuffer->Add(MakeUnique<FWriting>(lab, Pos, static_cast<int>(iSize), TextColor));
+  const FVector2D Pos(x1, y1);
+
+  FLinearColor TextColor;
+
+  if (ColorPalette) {
+    TextColor = FLinearColor(ColorPalette->Colors[colour].Red / 255.0, ColorPalette->Colors[colour].Green / 255.0, ColorPalette->Colors[colour].Blue / 255.0);
+  }
+  else {
+    TextColor = FLinearColor::Black;
+  }
+  
+  BackBuffer->Add(MakeUnique<FWriting>(lab, Pos, static_cast<int>(iSize), TextColor));
 }
 
 void SDasherWidget::Polyline(CDasherScreen::point* points, int number, int iwidth, int colour) {
-	
-	FLinearColor LinearColor;
-
-	if (ColorPalette) {
-		LinearColor = FLinearColor(ColorPalette->Colors[colour].Red / 255.0, ColorPalette->Colors[colour].Green / 255.0, ColorPalette->Colors[colour].Blue / 255.0);
-	}
-	else {
-		LinearColor = FLinearColor::Blue;
-	}
-
-	TArray<FVector2D> PointArray;
-	for (int i = 0; i < number; i++) {
-		FVector2D Point(points[i].x, points[i].y);
-		PointArray.Add(Point);
-	}
-	
-	BackBuffer->Add(MakeUnique<FPolyLine>(PointArray, static_cast<float>(iwidth), LinearColor));
+  
+  FLinearColor LinearColor;
+
+  if (ColorPalette) {
+    LinearColor = FLinearColor(ColorPalette->Colors[colour].Red / 255.0, ColorPalette->Colors[colour].Green / 255.0, ColorPalette->Colors[colour].Blue / 255.0);
+  }
+  else {
+    LinearColor = FLinearColor::Blue;
+  }
+
+  TArray<FVector2D> PointArray;
+  for (int i = 0; i < number; i++) {
+    FVector2D Point(points[i].x, points[i].y);
+    PointArray.Add(Point);
+  }
+  
+  BackBuffer->Add(MakeUnique<FPolyLine>(PointArray, static_cast<float>(iwidth), LinearColor));
 }
 
 //techincally polygons are just multiple polylines. Dasher doesn't actually draw polygons in our case.
 void SDasherWidget::Polygon(CDasherScreen::point* points, int number, int fillcolour, int outlinecolour, int iwidth) {
-	FLinearColor LinearColor;
-
-	if (ColorPalette) {
-		LinearColor = FLinearColor(ColorPalette->Colors[outlinecolour].Red / 255.0, ColorPalette->Colors[outlinecolour].Green / 255.0, ColorPalette->Colors[outlinecolour].Blue / 255.0);
-	}
-	else {
-		LinearColor = FLinearColor::Blue;
-	}
-
-	TArray<FVector2D> PointArray;
-	for (int i = 0; i < number; i++) {
-		FVector2D Point(points[i].x, points[i].y);
-		PointArray.Add(Point);
-	}
-	PointArray.Add(FVector2D(points[0].x, points[0].y));
-
-	BackBuffer->Add(MakeUnique<FPolyLine>(PointArray, static_cast<float>(iwidth), LinearColor));
+  FLinearColor LinearColor;
+
+  if (ColorPalette) {
+    LinearColor = FLinearColor(ColorPalette->Colors[outlinecolour].Red / 255.0, ColorPalette->Colors[outlinecolour].Green / 255.0, ColorPalette->Colors[outlinecolour].Blue / 255.0);
+  }
+  else {
+    LinearColor = FLinearColor::Blue;
+  }
+
+  TArray<FVector2D> PointArray;
+  for (int i = 0; i < number; i++) {
+    FVector2D Point(points[i].x, points[i].y);
+    PointArray.Add(Point);
+  }
+  PointArray.Add(FVector2D(points[0].x, points[0].y));
+
+  BackBuffer->Add(MakeUnique<FPolyLine>(PointArray, static_cast<float>(iwidth), LinearColor));
 }
 
 //We pass through the contents of the dasher buffer
 FString SDasherWidget::GetBuffer() const
 {
-	return DasherMainInterface->GetBuffer();
+  return DasherMainInterface->GetBuffer();
 }
 
 void SDasherWidget::ResetBuffer()
 {
-	DasherMainInterface->ResetBuffer();
+  DasherMainInterface->ResetBuffer();
 }
 
 void SDasherWidget::StartTraining(FString PathToTextFile)
 {
-	DasherMainInterface->ImportTrainingFile(TCHAR_TO_UTF8(*FPaths::ConvertRelativePathToFull(PathToTextFile)));
+  DasherMainInterface->ImportTrainingFile(TCHAR_TO_UTF8(*FPaths::ConvertRelativePathToFull(PathToTextFile)));
 }
 
+
 // ++ We need to undefine this namespace after we finish creating the Slate widget
 #undef LOCTEXT_NAMESPACE
 
diff --git a/Source/DasherVR/Private/UDasherWidget.cpp b/Source/DasherVR/Private/UDasherWidget.cpp
index 29031715ffeb8bf132a0e7b038f7b8eeec9bfcec..b5482574059a07465e738949d71e87d5c52e0c1d 100644
--- a/Source/DasherVR/Private/UDasherWidget.cpp
+++ b/Source/DasherVR/Private/UDasherWidget.cpp
@@ -1,5 +1,5 @@
 /*
-	Adapted from JoySoftEdgeImage by Rama https://nerivec.github.io/old-ue4-wiki/pages/umg-custom-widget-components-and-render-code-usable-in-umg-designer.html
+  Adapted from JoySoftEdgeImage by Rama https://nerivec.github.io/old-ue4-wiki/pages/umg-custom-widget-components-and-render-code-usable-in-umg-designer.html
 */
 #include "UDasherWidget.h"
 
@@ -9,89 +9,105 @@
 /////////////////////////////////////////////////////
 // UDasherWidget
 UDasherWidget::UDasherWidget(const FObjectInitializer& ObjectInitializer)
-	: Super(ObjectInitializer)
+  : Super(ObjectInitializer)
 {
-	//Default Values Set Here, see above
+  //Default Values Set Here, see above
 }
 
 //Rebuild using custom Slate Widget 
 TSharedRef<SWidget> UDasherWidget::RebuildWidget()
 {
-	if (!DasherScreen)
-	{
-		DasherScreen = SNew(SDasherWidget).height(1080).width(1920);
-	}
-	return DasherScreen.ToSharedRef();
+  if (!DasherScreen)
+  {
+    DasherScreen = SNew(SDasherWidget).height(1080).width(1920);
+  }
+  return DasherScreen.ToSharedRef();
 }
 
 void UDasherWidget::SynchronizeProperties()
 {
-	Super::SynchronizeProperties();
-
-	//Check if we're in Editor
-	DasherScreen->SetEditor(IsDesignTime());
-	DasherScreen->CharacterEntered.BindLambda([this](FString Char, FString Buffer)
-	{
-		CharacterEntered.Broadcast(Char, Buffer);
-		BufferAltered.Broadcast(Buffer);
-	});
-	DasherScreen->CharacterDeleted.BindLambda([this](FString Char, FString Buffer)
-	{
-		CharacterDeleted.Broadcast(Char, Buffer);
-		BufferAltered.Broadcast(Buffer);
-	});
-	DasherScreen->MouseUpListeners.BindLambda([this]() {MouseEvent.Broadcast(false); });
-	DasherScreen->MouseDownListeners.BindLambda([this]() {MouseEvent.Broadcast(true); });
+  Super::SynchronizeProperties();
+
+  //Check if we're in Editor
+  DasherScreen->SetEditor(IsDesignTime());
+  DasherScreen->CharacterEntered.BindLambda([this](FString Char, FString Buffer)
+  {
+    CharacterEntered.Broadcast(Char, Buffer);
+    BufferAltered.Broadcast(Buffer);
+  });
+  DasherScreen->CharacterDeleted.BindLambda([this](FString Char, FString Buffer)
+  {
+    CharacterDeleted.Broadcast(Char, Buffer);
+    BufferAltered.Broadcast(Buffer);
+  });
+  DasherScreen->CharacterSwitched.BindLambda([this](FString Char, FString Buffer)
+    {
+        CharacterSwitched.Broadcast(Char, Buffer);
+        BufferAltered.Broadcast(Buffer);
+    });
+  DasherScreen->MouseUpListeners.BindLambda([this]() {MouseEvent.Broadcast(false); });
+  DasherScreen->MouseDownListeners.BindLambda([this]() {MouseEvent.Broadcast(true); });
 }
 
 void UDasherWidget::ReleaseSlateResources(bool bReleaseChildren)
 {
-	Super::ReleaseSlateResources(bReleaseChildren);
+  Super::ReleaseSlateResources(bReleaseChildren);
 
-	DasherScreen.Reset();
+  DasherScreen.Reset();
 }
 
 FString UDasherWidget::GetBuffer()
 {
-	return DasherScreen->GetBuffer();
+  return DasherScreen->GetBuffer();
 }
 
 void UDasherWidget::ResetBuffer()
 {
-	DasherScreen->ResetBuffer();
-	BufferAltered.Broadcast("");
+  DasherScreen->ResetBuffer();
+  BufferAltered.Broadcast("");
 }
 
 void UDasherWidget::StartTraining(FString PathToTextFile)
 {
-	DasherScreen->StartTraining(PathToTextFile);
+  DasherScreen->StartTraining(PathToTextFile);
 }
 
 void UDasherWidget::SetBoolParamter(FString ParameterName, bool Value)
 {
-	DasherScreen->SetBoolParamter(ParameterName, Value);
+  DasherScreen->SetParameter(ParameterName, Value);
 }
 
 void UDasherWidget::SetLongParamter(FString ParameterName, int64 Value)
 {
-	DasherScreen->SetLongParamter(ParameterName, Value);
+  DasherScreen->SetParameter(ParameterName, Value);
 }
 
 void UDasherWidget::SetStringParamter(FString ParameterName, FString Value)
 {
-	DasherScreen->SetStringParamter(ParameterName, Value);
+  DasherScreen->SetParameter(ParameterName, Value);
 }
 
 void UDasherWidget::InputButton(bool Pressed)
 {
-	DasherScreen->InputButton(Pressed);
+  DasherScreen->InputButton(Pressed);
 }
 
 void UDasherWidget::InputVector(FVector2D InputVector)
 {
-	DasherScreen->InputVector(InputVector);
+  DasherScreen->InputVector(InputVector);
 }
 
+void UDasherWidget::PauseInput()
+{
+    DasherScreen->PauseInput();
+}
+
+void UDasherWidget::UnpauseInput()
+{
+    DasherScreen->UnpauseInput();
+}
+
+
 #if WITH_EDITOR
 
 //const FSlateBrush* UDasherWidget::GetEditorIcon()
@@ -101,7 +117,7 @@ void UDasherWidget::InputVector(FVector2D InputVector)
 
 const FText UDasherWidget::GetPaletteCategory()
 {
-	return LOCTEXT("Common", "Common");
+  return LOCTEXT("Common", "Common");
 }
 
 #endif
diff --git a/Source/DasherVR/Public/Dasher3DWidget.h b/Source/DasherVR/Public/Dasher3DWidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..cb45f47c259b676f124604cccdd8c17b0e7d95b9
--- /dev/null
+++ b/Source/DasherVR/Public/Dasher3DWidget.h
@@ -0,0 +1,96 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "Engine/Font.h"
+#include "GameFramework/Actor.h"
+#include "DasherCoreWrapper.h"
+#include "DasherInterface.h"
+#include "Fonts/FontMeasure.h"
+#include "Components/InstancedStaticMeshComponent.h"
+#include "Dasher3DWidget.generated.h"
+
+class DasherParents : public Dasher::CDasherScreen, public Dasher::CScreenCoordInput
+{
+public:
+	DasherParents() : CDasherScreen(0,0), CScreenCoordInput(0, _("Mouse Input")){};
+};
+
+
+UCLASS()
+class DASHERVR_API ADasher3DWidget : public AActor, public DasherParents
+{
+	GENERATED_BODY()
+	
+public:	
+	// Sets default values for this actor's properties
+	ADasher3DWidget();
+
+protected:
+	// Called when the game starts or when spawned
+	virtual void BeginPlay() override;
+	void InitializeDasher();
+	void InitializeTextureArray();
+	auto GetLetterTransformData(int letterindex, int iFontSize, int x, int y, int extrusionLevel, int position);
+
+public:	
+	// Called every frame
+	virtual void Tick(float DeltaTime) override;
+
+	virtual std::pair<Dasher::screenint, Dasher::screenint> TextSize(Label* label, unsigned iFontSize) override;
+	virtual void DrawString(Label* label, Dasher::screenint x, Dasher::screenint y, unsigned iFontSize, int iColour) override;
+	virtual void DrawRectangle(Dasher::screenint x1, Dasher::screenint y1, Dasher::screenint x2, Dasher::screenint y2, int Colour, int iOutlineColour, int iThickness);
+	virtual void DrawCube(Dasher::screenint posX, Dasher::screenint posY, Dasher::screenint sizeX, Dasher::screenint sizeY, Dasher::myint extrusionLevel, int Colour, int iOutlineColour, int iThickness) override;
+	virtual void Draw3DLabel(Label* label, Dasher::screenint x, Dasher::screenint y, Dasher::myint extrusionLevel, unsigned int iFontSize, int iColour) override;
+	virtual void DrawCircle(Dasher::screenint iCX, Dasher::screenint iCY, Dasher::screenint iR, int iFillColour, int iLineColour, int iLineWidth) override;
+	virtual void Polyline(point* Points, int Number, int iWidth, int Colour) override;
+	virtual void Polygon(point* Points, int Number, int fillColour, int outlineColour, int lineWidth) override;
+	virtual void Display() override;
+	virtual void SetColourScheme(const Dasher::CColourIO::ColourInfo* pColourScheme) override;
+	virtual bool IsPointVisible(Dasher::screenint x, Dasher::screenint y) override;
+	virtual bool GetScreenCoords(Dasher::screenint& iX, Dasher::screenint& iY, Dasher::CDasherView* pView) override;
+  virtual bool MultiSizeFonts() override { return true; }
+	virtual void SendMarker(int Marker){};
+
+
+
+	FVector2D GetCursorPosition(){return CursorPosition;};
+
+	UPROPERTY(VisibleAnywhere, Category = "Components")	UStaticMeshComponent* ActorRootComponent = nullptr;
+	UPROPERTY(VisibleAnywhere, Category = "Components")	UInstancedStaticMeshComponent* CubeInstances = nullptr;
+	UPROPERTY(VisibleAnywhere, Category = "Components")	UInstancedStaticMeshComponent* LetterInstances = nullptr;
+	UPROPERTY(EditAnywhere) UFont* DisplayFont;
+	UPROPERTY(EditAnywhere) UMaterial* FontMaterial;
+
+	UFUNCTION(BlueprintCallable) void SetMouseLocation(FVector2D InputVector);
+
+
+private:
+
+	
+
+	// stores color information 
+	const Dasher::CColourIO::ColourInfo* ColorPalette = nullptr;
+	FVector2D CursorPosition;
+	FVector2D SlateSize;
+	FVector DrawingSize = {1000,1000, 100}; // Multiplied with the Scaling of the plane, so actually pixels per meter
+	TSharedPtr<Dasher::DasherInterface> DasherMainInterface;
+	UPROPERTY() UMaterialInstanceDynamic* MaterialInstance;
+	UPROPERTY() UTexture2DArray* TextureArray;
+	int MaxVSize;
+	int MaxUSize;
+
+	FVector DefaultTranslation;
+	std::pair<TArray<FTransform>, TArray<float>> GeometryBufferA;
+	std::pair<TArray<FTransform>, TArray<float>> GeometryBufferB;
+	std::pair<TArray<FTransform>, TArray<float>>* BackBuffer = &GeometryBufferA;
+	std::pair<TArray<FTransform>, TArray<float>>* FrontBuffer = &GeometryBufferB;
+
+
+	std::pair<TArray<FTransform>, TArray<TArray<float>>> LabelGeometryBufferA;
+	std::pair<TArray<FTransform>, TArray<TArray<float>>> LabelGeometryBufferB;
+	std::pair<TArray<FTransform>, TArray<TArray<float>>>* LabelBackBuffer = &LabelGeometryBufferA;
+	std::pair<TArray<FTransform>, TArray<TArray<float>>>* LabelFrontBuffer = &LabelGeometryBufferB;
+
+};
diff --git a/Source/DasherVR/Public/DasherInterface.h b/Source/DasherVR/Public/DasherInterface.h
index b7427f2e4032b97ff8fecff814108aab6a60592b..bc2de9c7651949b6664df88755feda0884b8d0a9 100644
--- a/Source/DasherVR/Public/DasherInterface.h
+++ b/Source/DasherVR/Public/DasherInterface.h
@@ -75,7 +75,7 @@ namespace Dasher
 		void Tick(unsigned long time);
 		
 		// set the screen, needed for maximum spaghetti, to make changeScreen accessible to the outside aka SDasherWidget
-		virtual void SetScreen(SDasherWidget* screen);
+		virtual void SetScreen(CDasherScreen* screen);
 		//Sets the Training Filename
 		virtual void ImportTrainingFile(std::string filename);
 
diff --git a/Source/DasherVR/Public/DasherVR.h b/Source/DasherVR/Public/DasherVR.h
index 5aa2e2597631e06f77ab8e30ca5af57361e6da16..8a2bcca67e14c89f4d9b16b6196193fb26aa6964 100644
--- a/Source/DasherVR/Public/DasherVR.h
+++ b/Source/DasherVR/Public/DasherVR.h
@@ -3,6 +3,7 @@
 
 #include "CoreMinimal.h"
 #include "DasherCoreWrapper.h"
+#include "Modules/ModuleInterface.h"
 
 class FDasherVRModule : public IModuleInterface
 {
diff --git a/Source/DasherVR/Public/SDasherWidget.h b/Source/DasherVR/Public/SDasherWidget.h
index 31c993f819e6d1ddbdea130627718ba11dd8855c..74eac990ba6ce8de6bd73557d60c4b3990ea9ee7 100644
--- a/Source/DasherVR/Public/SDasherWidget.h
+++ b/Source/DasherVR/Public/SDasherWidget.h
@@ -7,6 +7,7 @@
 #include "DasherInterface.h"
 #include "Math/Vector2D.h"
 #include "Fonts/FontMeasure.h"
+#include "Widgets/DeclarativeSyntaxSupport.h"
 
 //using namespace Dasher;
 
@@ -77,9 +78,9 @@ public:
 
 	// Constructs this widget with InArgs. Needed for every widget. Builds this widget and any of its children
 	void Construct(const FArguments& InArgs);
-	void SetBoolParamter(FString ParameterName, bool Value);
-	void SetLongParamter(FString ParameterName, int64 Value);
-	void SetStringParamter(FString ParameterName, FString Value);
+	void SetParameter(FString ParameterName, bool Value);
+	void SetParameter(FString ParameterName, int64 Value);
+	void SetParameter(FString ParameterName, FString Value);
 
 	virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override;
 
@@ -132,11 +133,16 @@ public:
 	void InputVector(FVector2D InputVector);
 	void InputButton(bool Pressed);
 	FVector2D GetCursorPosition();
+
+	//Allows to Pause Input
+	void PauseInput();
+	void UnpauseInput();
 	
 	FDasherMouseUpDelegate MouseUpListeners;
 	FDasherMouseUpDelegate MouseDownListeners;
 	FBufferManiputlationDelegate CharacterEntered;
 	FBufferManiputlationDelegate CharacterDeleted;
+	FBufferManiputlationDelegate CharacterSwitched;
 
 private:
 	
@@ -151,9 +157,14 @@ private:
 	bool HasBeenPainted = false;
 	bool CurrentlyUsingVectorInput = false;
 	FVector2D CursorPosition;
+	bool CharacterEnteredFlag = false;
+	bool CharacterDeletedFlag = false;
+	FString AlteredChar = "";
 
 	//are we in the Editor?
 	bool IsEditor = true;
+	//is the input paused
+	bool InputPaused = false;
 
 	//set up the font measure service to ... measure fonts.
 	TSharedPtr<FSlateFontMeasure> FontMeasureService;
diff --git a/Source/DasherVR/Public/UDasherWidget.h b/Source/DasherVR/Public/UDasherWidget.h
index ae0cb7aecbcd3251e6438442002f72955648f02d..849b3f18dd56781b6d47fd2534552aae1ac997cb 100644
--- a/Source/DasherVR/Public/UDasherWidget.h
+++ b/Source/DasherVR/Public/UDasherWidget.h
@@ -40,8 +40,12 @@ public:
 	UFUNCTION(BlueprintCallable) void InputButton(bool Pressed);
 	UFUNCTION(BlueprintCallable) void InputVector(FVector2D InputVector);
 
+	UFUNCTION(BlueprintCallable) void PauseInput();
+	UFUNCTION(BlueprintCallable) void UnpauseInput();
+
 	UPROPERTY(BlueprintAssignable) FCharManipulatedEvent CharacterEntered;
 	UPROPERTY(BlueprintAssignable) FCharManipulatedEvent CharacterDeleted;
+	UPROPERTY(BlueprintAssignable) FCharManipulatedEvent CharacterSwitched;
 	UPROPERTY(BlueprintAssignable) FBufferManipulatedEvent BufferAltered;
 	UPROPERTY(BlueprintAssignable) FMouseEvent MouseEvent;
 
diff --git a/Source/DasherVR/Public/pch_plugin.h b/Source/DasherVR/Public/pch_plugin.h
new file mode 100644
index 0000000000000000000000000000000000000000..6f70f09beec2219624baeca92e2cd7deaa104fb4
--- /dev/null
+++ b/Source/DasherVR/Public/pch_plugin.h
@@ -0,0 +1 @@
+#pragma once