diff --git a/Source/DasherVR/DasherVR.Build.cs b/Source/DasherVR/DasherVR.Build.cs
index d7f74ec1345122dd45a9b6295a765488486a4eb4..b1cd040debb4fc13a1c73e8acbbf980e8b524e4f 100644
--- a/Source/DasherVR/DasherVR.Build.cs
+++ b/Source/DasherVR/DasherVR.Build.cs
@@ -6,7 +6,9 @@ public class DasherVR : ModuleRules
 {
 	public DasherVR(ReadOnlyTargetRules Target) : base(Target)
 	{
-		PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
+		PCHUsage = PCHUsageMode.NoSharedPCHs;
+		CppStandard = CppStandardVersion.Cpp17;
+		PrivatePCHHeaderFile = "Private/DasherVRPrivatePCH.h";
 		PrivateDefinitions.Add("HAVE_OWN_FILEUTILS");
 
 		PublicIncludePaths.AddRange(
diff --git a/Source/DasherVR/Private/Dasher3DWidget.cpp b/Source/DasherVR/Private/Dasher3DWidget.cpp
index 74980edc57a08939c5efe6dd4ef822208be4a773..f5d673a20e03e3b762227f32cf764da7c5d4055f 100644
--- a/Source/DasherVR/Private/Dasher3DWidget.cpp
+++ b/Source/DasherVR/Private/Dasher3DWidget.cpp
@@ -3,6 +3,9 @@
 #include "Dasher3DWidget.h"
 #include "Math/Rotator.h"
 #include "Engine/Texture2DArray.h"
+#include "Engine/World.h"
+#include "GameFramework/WorldSettings.h"
+#include "Materials/MaterialInstanceDynamic.h"
 // Sets default values
 ADasher3DWidget::ADasher3DWidget() : DasherParents()
 {
@@ -15,19 +18,27 @@ ADasher3DWidget::ADasher3DWidget() : DasherParents()
 	CubeInstances = CreateDefaultSubobject<UInstancedStaticMeshComponent>("Cubes");
 	CubeInstances->SetupAttachment(GetRootComponent());
 	CubeInstances->SetFlags(RF_Transactional);
-	CubeInstances->NumCustomDataFloats = 6; //Full Linear Color
+	CubeInstances->NumCustomDataFloats = 7; //Color(3), Scale(3), LineWidth(1)
 	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->NumCustomDataFloats = 5; //UV(2), Size(2), TexturePage(1)
 	LetterInstances->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);
 	this->AddInstanceComponent(LetterInstances);
 
 }
 
+void ADasher3DWidget::PostInitializeComponents()
+{
+	Super::PostInitializeComponents();
+
+	CubeMaterialInstanceDynamic = UMaterialInstanceDynamic::Create(CubeInstances->GetMaterial(0), CubeInstances);
+	CubeInstances->SetMaterial(0, CubeMaterialInstanceDynamic);
+}
+
 // Called when the game starts or when spawned
 void ADasher3DWidget::BeginPlay()
 {
@@ -35,149 +46,117 @@ void ADasher3DWidget::BeginPlay()
 	//Setting up Dasher
 	InitializeDasher();
 	//Setting up the Texture array for the font
-	InitializeTextureArray();	
+	InitializeTextureArray();
+
+	WorldToMeters = GetWorld()->GetWorldSettings()->WorldToMeters;
+
+	CubeMaterialInstanceDynamic->SetVectorParameterValue("DrawingSizeBorderWidth", FVector(DrawingSize, 0));
 }
 
 // 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);
+	DasherMainInterface->Tick(static_cast<unsigned long>(GetGameTimeSinceCreation() * 1000.0)); //we need to provide ticks in milliseconds
 }
 
 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) };
-	
+	char CurrentChar = label->m_strText[0];
+	if (CurrentChar < 32) CurrentChar = 32; // replace non-printable characters with spaces.
+
+	const float FontScale = iFontSize / DisplayFont->ImportOptions.Height;
+	const float CharacterSizeU = DisplayFont->Characters[CurrentChar].USize; // Pixel Sizes for actual character without blank space
+	const float CharacterSizeV = DisplayFont->Characters[CurrentChar].VSize; // Pixel Sizes for actual character without blank space
+	const float CharacterVerticalOffset = DisplayFont->Characters[CurrentChar].VerticalOffset;
+	const FVector2D CharScale = FVector2D(
+					(CharacterSizeU / CharacterSizeV) * CharacterSizeV, // (Width/Height * Height)
+					CharacterSizeV + CharacterVerticalOffset // Height + Vertical Offset, as the vertical offset also counts towards the height for line-height calculations
+					) * FontScale;
+
+	return {CharScale.X, CharScale.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) {
+void ADasher3DWidget::DrawCube(Dasher::screenint posX, Dasher::screenint posY, Dasher::screenint sizeX, Dasher::screenint sizeY, Dasher::myint extrusionLevel, Dasher::myint groupRecursionDepth, Dasher::myint levelUnderCrosshair, 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);
+	const FVector Scale = FVector(FVector2D(sizeX, sizeY) / DrawingSize, 
+						FMath::Max(ExtrusionLevelToHeight(extrusionLevel), 0.001) + groupRecursionDepth*0.001) // Min Depth 1mm
+							+ FVector(extrusionLevel,extrusionLevel,0)*FLT_EPSILON;
+	const FVector2D Translation = FVector2D(posX, posY) / DrawingSize - FVector2D(0.5f, 0.5f);
 	
 	FLinearColor RectColor;
 
 	if (ColorPalette) {
-			RectColor = FLinearColor(ColorPalette->Colors[Colour].Red / 255.0, ColorPalette->Colors[Colour].Green / 255.0, ColorPalette->Colors[Colour].Blue / 255.0);
+		RectColor = FLinearColor(ColorPalette->Colors[Colour].Red / 255.0, ColorPalette->Colors[Colour].Green / 255.0, ColorPalette->Colors[Colour].Blue / 255.0);
 	}
 	else {
-			RectColor = FLinearColor::Blue;
+		RectColor = FLinearColor::Blue;
 	}
 
-	BackBuffer->first.Add(FTransform(FQuat::Identity, Translation / DrawingSize * 100.0f, Scale));
+	BackBuffer->first.Add(FTransform(FQuat::Identity, FVector(Translation, -ExtrusionLevelToHeight(levelUnderCrosshair)) * WorldToMeters, 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);
+	BackBuffer->second.Add(0.5f * iThickness); //Allows for individual adjustment
 }
 
-
-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;
+// x & y are given as upper left corner of the character
+void ADasher3DWidget::Draw3DLabel(Label* label, Dasher::screenint x, Dasher::screenint y, Dasher::myint extrusionLevel, Dasher::myint groupRecursionDepth, Dasher::myint levelUnderCrosshair, unsigned int iFontSize, int iColour) {
+		float CharacterOffset = 0; // in Meters
 		
-		for (int i = 0; i < labeltext.size(); i++)
+		for (int i = 0; i < label->m_strText.size(); i++)
 		{
-				int letterindex = labeltext[i];
-				auto [Transform, FontData] = GetLetterTransformData(letterindex, iFontSize, x, y, extrusionLevel, i);
-				LabelBackBuffer->first.Add(Transform);
-				LabelBackBuffer->second.Add(FontData);
+			char CurrentChar = label->m_strText[i];
+			if (CurrentChar < 32) CurrentChar = 32; // replace non-printable characters with spaces.
+
+			const int TextureIndex = DisplayFont->Characters[CurrentChar].TextureIndex;
+			const float FontScale = iFontSize / DisplayFont->ImportOptions.Height;
+			const float TextureSizeU = TextureArray->SourceTextures[TextureIndex]->GetSizeX(); // Pixel Sizes
+			const float TextureSizeV = TextureArray->SourceTextures[TextureIndex]->GetSizeY(); // Pixel Sizes
+			const float CharacterOffsetU = DisplayFont->Characters[CurrentChar].StartU; //Upper left corner
+			const float CharacterOffsetV = DisplayFont->Characters[CurrentChar].StartV; //Upper left corner
+			const float CharacterSizeU = DisplayFont->Characters[CurrentChar].USize; // Pixel Sizes for actual character without blank space
+			const float CharacterSizeV = DisplayFont->Characters[CurrentChar].VSize; // Pixel Sizes for actual character without blank space
+			const float CharacterVerticalOffset = DisplayFont->Characters[CurrentChar].VerticalOffset * FontScale; //vertical offset in pixels
+
+			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
+			};
+			
+			const FVector2D CharScale = FVector2D(
+					(CharacterSizeU / CharacterSizeV) * CharacterSizeV, // (Width/Height * Height)
+					CharacterSizeV // Height
+					) * FontScale / DrawingSize; // From Pixel to "Meter" (afterwards scaled by parent)
+
+
+			const FVector CharTranslation = FVector(
+					(x / DrawingSize.X + CharScale.X * 0.5f) * WorldToMeters + CharacterOffset, 
+					((y + CharacterVerticalOffset) / DrawingSize.Y) * WorldToMeters,
+					(FMath::Max(ExtrusionLevelToHeight(extrusionLevel), 0.001) - ExtrusionLevelToHeight(levelUnderCrosshair) + groupRecursionDepth*FLT_EPSILON) * WorldToMeters + 0.01f
+				)
+				- FVector(0.5f, 0.5f, 0) * WorldToMeters; // Move to upper left corner of parent
+
+			LabelBackBuffer->first.Add(FTransform(FQuat::Identity, CharTranslation, FVector(CharScale, 1.0f)));
+			LabelBackBuffer->second.Add(FontData);
+
+			CharacterOffset += CharScale.X * WorldToMeters; // characterOffset is accumulated for multiple character strings
 		}
 }
 
-
-
-
-
-
 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
+	DrawCube((x2 - x1)/2 + x1, (y2-y1)/2 + y1, x2-x1, y2-y1, 1, 0, 0, Colour, iOutlineColour, iThickness);
 }
 
 void ADasher3DWidget::DrawCircle(Dasher::screenint iCX, Dasher::screenint iCY, Dasher::screenint iR, int iFillColour, int iLineColour, int iLineWidth)
@@ -187,7 +166,33 @@ void ADasher3DWidget::DrawCircle(Dasher::screenint iCX, Dasher::screenint iCY, D
 
 void ADasher3DWidget::Polyline(point* Points, int Number, int iWidth, int Colour)
 {
-	//Todo
+	for(int i = 1; i < Number; i++)
+	{
+		const point& p1 = Points[i-1];
+		const point& p2 = Points[i];
+
+		const FVector Scale = FVector(FVector2D(sqrt(powf(p1.x - p2.x, 2)+powf(p1.y - p2.y, 2)), iWidth) / DrawingSize, ExtrusionLevelToHeight(2));
+		const FVector2D Translation = FVector2D((p2.x - p1.x)/2.0f + p1.x, (p2.y - p1.y)/2.0f + p1.y) / DrawingSize - FVector2D(0.5f, 0.5f);
+		const FQuat Rotation = FQuat().MakeFromEuler({0,0,FMath::RadiansToDegrees(FMath::Atan2(static_cast<float>(p2.y - p1.y), static_cast<float>(p2.x - p1.x)))});
+		
+		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::Black;
+		}
+
+		BackBuffer->first.Add(FTransform(Rotation, FVector(Translation, 0) * WorldToMeters, 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);
+		BackBuffer->second.Add(0);
+	}
 }
 
 void ADasher3DWidget::Polygon(point* Points, int Number, int fillColour, int outlineColour, int lineWidth)
@@ -212,7 +217,8 @@ void ADasher3DWidget::Display()
 			FrontBuffer->second[i*CubeInstances->NumCustomDataFloats+2],
 			FrontBuffer->second[i*CubeInstances->NumCustomDataFloats+3],
 			FrontBuffer->second[i*CubeInstances->NumCustomDataFloats+4],
-			FrontBuffer->second[i*CubeInstances->NumCustomDataFloats+5]
+			FrontBuffer->second[i*CubeInstances->NumCustomDataFloats+5],
+			FrontBuffer->second[i*CubeInstances->NumCustomDataFloats+6]
 		};
 		CubeInstances->SetCustomData(i, ColorScale);
 	}
@@ -252,51 +258,51 @@ bool ADasher3DWidget::GetScreenCoords(Dasher::screenint& iX, Dasher::screenint&
 	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::SetMouseLocation(FVector WorldLocation)
+{
+	FVector2D inp = FVector2D(ActorRootComponent->GetComponentToWorld().InverseTransformPosition(WorldLocation)) / WorldToMeters + FVector2D(0.5f,0.5f);
+	CursorPosition = inp * DrawingSize; //convert to pixels
+}
+
+void ADasher3DWidget::SimulateClick(FKey Key, bool pressed)
+{
+	if(Key == EKeys::LeftMouseButton || Key == EKeys::RightMouseButton)
+	if(pressed)
+	{
+		DasherMainInterface->KeyDown(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), (Key == EKeys::LeftMouseButton)?100:101);
+	} else
+	{
+		DasherMainInterface->KeyUp(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), (Key == EKeys::LeftMouseButton)?100:101);
+	}
 }
 
 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;
-		}
+	TextureArray = NewObject<UTexture2DArray>();
+	for (int i = 0; i < DisplayFont->Textures.Num(); i++)
+	{
+			TextureArray->SourceTextures.Add(DisplayFont->Textures[i]);
+	}
+	TextureArray->UpdateSourceFromSourceTextures(true);
+}
+
+float ADasher3DWidget::ExtrusionLevelToHeight(float level)
+{
+	return level*DepthScale;
 }
 
 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
+	resize(DrawingSize.X, 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->SetLongParameter(Dasher::LP_SHAPE_TYPE, Dasher::Options::CUBE);
+
+	DasherMainInterface->SetScreen(this);
+	DasherMainInterface->SetBuffer(0);
+}
diff --git a/Source/DasherVR/Public/Dasher3DWidget.h b/Source/DasherVR/Public/Dasher3DWidget.h
index cb45f47c259b676f124604cccdd8c17b0e7d95b9..2444822a4f33ce3c9476a95560f87b864e4d2de4 100644
--- a/Source/DasherVR/Public/Dasher3DWidget.h
+++ b/Source/DasherVR/Public/Dasher3DWidget.h
@@ -9,6 +9,8 @@
 #include "DasherInterface.h"
 #include "Fonts/FontMeasure.h"
 #include "Components/InstancedStaticMeshComponent.h"
+#include "Engine/Texture2DArray.h"
+#include "Materials/Material.h"
 #include "Dasher3DWidget.generated.h"
 
 class DasherParents : public Dasher::CDasherScreen, public Dasher::CScreenCoordInput
@@ -32,7 +34,7 @@ protected:
 	virtual void BeginPlay() override;
 	void InitializeDasher();
 	void InitializeTextureArray();
-	auto GetLetterTransformData(int letterindex, int iFontSize, int x, int y, int extrusionLevel, int position);
+	virtual float ExtrusionLevelToHeight(float level);
 
 public:	
 	// Called every frame
@@ -40,9 +42,9 @@ public:
 
 	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 DrawRectangle(Dasher::screenint x1, Dasher::screenint y1, Dasher::screenint x2, Dasher::screenint y2, int Colour, int iOutlineColour, int iThickness) override;
+	virtual void DrawCube(Dasher::screenint posX, Dasher::screenint posY, Dasher::screenint sizeX, Dasher::screenint sizeY, Dasher::myint extrusionLevel, Dasher::myint groupRecursionDepth, Dasher::myint levelUnderCrosshair, int Colour, int iOutlineColour, int iThickness) override;
+	virtual void Draw3DLabel(Label* label, Dasher::screenint x, Dasher::screenint y, Dasher::myint extrusionLevel, Dasher::myint groupRecursionDepth, Dasher::myint levelUnderCrosshair, 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;
@@ -50,10 +52,8 @@ public:
 	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){};
-
-
+	virtual bool MultiSizeFonts() override { return true; }
+	virtual void SendMarker(int Marker) override {};
 
 	FVector2D GetCursorPosition(){return CursorPosition;};
 
@@ -62,24 +62,21 @@ public:
 	UPROPERTY(VisibleAnywhere, Category = "Components")	UInstancedStaticMeshComponent* LetterInstances = nullptr;
 	UPROPERTY(EditAnywhere) UFont* DisplayFont;
 	UPROPERTY(EditAnywhere) UMaterial* FontMaterial;
+	UPROPERTY(EditAnywhere) float DepthScale = 0.1;
 
-	UFUNCTION(BlueprintCallable) void SetMouseLocation(FVector2D InputVector);
-
+	UFUNCTION(BlueprintCallable) void SetMouseLocation(FVector WorldLocation);
+	UFUNCTION(BlueprintCallable) void SimulateClick(FKey Key, bool pressed);
+	virtual void PostInitializeComponents() override;
 
 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
+	float WorldToMeters; // normally 100
+	FVector2D DrawingSize = {1000,1000}; // Rendering Resolution
 	TSharedPtr<Dasher::DasherInterface> DasherMainInterface;
-	UPROPERTY() UMaterialInstanceDynamic* MaterialInstance;
+	UPROPERTY() UMaterialInstanceDynamic* CubeMaterialInstanceDynamic;
 	UPROPERTY() UTexture2DArray* TextureArray;
-	int MaxVSize;
-	int MaxUSize;
 
 	FVector DefaultTranslation;
 	std::pair<TArray<FTransform>, TArray<float>> GeometryBufferA;
diff --git a/Source/Thirdparty/Dasher/DasherCore b/Source/Thirdparty/Dasher/DasherCore
index a94a47badf40d9b7f7e8c80c08b015c41d1ecc90..e72cbf1cb4e9ab4e7a8b90a670cd3d97423ad6de 160000
--- a/Source/Thirdparty/Dasher/DasherCore
+++ b/Source/Thirdparty/Dasher/DasherCore
@@ -1 +1 @@
-Subproject commit a94a47badf40d9b7f7e8c80c08b015c41d1ecc90
+Subproject commit e72cbf1cb4e9ab4e7a8b90a670cd3d97423ad6de