diff --git a/cube.json b/cube.json
new file mode 100644
index 0000000..09aa455
--- /dev/null
+++ b/cube.json
@@ -0,0 +1,75 @@
+{
+  "collections": {
+  "name":"Main",
+    "subCollections":
+    [
+      {
+        "name":"collection1",
+        "objects":[
+          {
+            "name":"Cube",
+            "position":
+            [0,0,0],
+            "rotation":
+            [0,0,0],
+            "points":
+            [[-30.0, -10.0, -10.0],
+            [-30.0, -10.0, 10.0],
+            [-30.0, 10.0, -10.0],
+            [-30.0, 10.0, 10.0],
+            [-10.0, -10.0, -10.0],
+            [-10.0, -10.0, 10.0],
+            [-10.0, 10.0, -10.0],
+            [-10.0, 10.0, 10.0]
+            ]
+            ,"faceList":[
+            [0, 2, 3, 1],
+            [4, 5, 7, 6],
+            [0, 1, 5, 4],
+            [1, 3, 7, 5],
+            [3, 2, 6, 7],
+            [2, 0, 4, 6]],
+            "textureList":
+            ["red", "green", "blue", "cyan", "magenta", "yellow"],
+            "uvPointsList":
+            [
+            [[0, 0], [100, 0], [100, 100], [0, 100]],
+            [[0, 0], [100, 0], [100, 100], [0, 100]],
+            [[0, 0], [100, 0], [100, 100], [0, 100]],
+            [[0, 0], [100, 0], [100, 100], [0, 100]],
+            [[0, 0], [100, 0], [100, 100], [0, 100]],
+            [[0, 0], [100, 0], [100, 100], [0, 100]]
+            ]
+            }
+          ]
+        }
+    ]
+  },
+  "textures":[
+    {
+      "name":"red",
+      "type":"solid",
+      "color":"FF0000"
+    },{
+      "name":"green",
+      "type":"solid",
+      "color":"00FF00"
+    },{
+      "name":"blue",
+      "type":"solid",
+      "color":"0000FF"
+    },{
+      "name":"cyan",
+      "type":"solid",
+      "color":"00FFFF"
+    },{
+      "name":"magenta",
+      "type":"solid",
+      "color":"FF00FF"
+    },{
+      "name":"yellow",
+      "type":"solid",
+      "color":"FFFF00"
+    }
+]
+}
diff --git a/src/main/java/uk/org/floop/epq3d/App.java b/src/main/java/uk/org/floop/epq3d/App.java
index b358050..0ba19ab 100644
--- a/src/main/java/uk/org/floop/epq3d/App.java
+++ b/src/main/java/uk/org/floop/epq3d/App.java
@@ -1,7 +1,6 @@
 package uk.org.floop.epq3d;
 
 import javax.swing.*;
-import java.awt.*;
 
 class App {
     static ObjectCollection mainCollection;
@@ -33,88 +32,92 @@
     public static void main(String[] args) {
         // invokeLater() is used here to prevent our graphics processing from
         // blocking the GUI. https://stackoverflow.com/a/22534931/4655368
-        // this is a lot of boilerplate code that you shouldn't be too concerned about.
-        // just know that when main runs it will call initWindow() once.
+        // will call initWindow() once.
         SwingUtilities.invokeLater(App::initWindow);
     }
 
     public static void initObjects(){
-        mainCollection = new ObjectCollection();
+        JsonReader Jason = new JsonReader("cube.json");
+        Jason.getObjects();
+        mainCollection = Jason.mainCollection;
+        mainCollection.initialiseAll();
+        //textures = Jason.textures;
+        //mainCollection = new ObjectCollection();
 
-        Texture testTexture;
-        /*try {
-            //testTexture = ImageIO.read(new File("/home/cory/Screenshot from 2022-06-06 18-52-12.png"));
-            testTexture = new Texture(ImageIO.read(new File("/home/cory/Screenshot from 2022-09-26 13-05-40.png")));
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }*/
-        Texture red = new Texture(Color.red);
-        Texture green = new Texture(Color.GREEN);
-        Texture blue = new Texture(Color.BLUE);
-        Texture cyan = new Texture(Color.CYAN);
-        Texture magenta = new Texture(Color.magenta);
-        Texture yellow = new Texture(Color.yellow);
-
-
-        mainCollection.addObject(new Object3d(new PointComp[]{
-                new PointComp(-30,-10,-10),
-                new PointComp(-30,-10,10),
-                new PointComp(-30,10,-10),
-                new PointComp(-30,10,10),
-                new PointComp(-10,-10,-10),
-                new PointComp(-10,-10,10),
-                new PointComp(-10,10,-10),
-                new PointComp(-10,10,10)
-
-        }, new int[][]{
-                {0,2,3,1},
-                {4,5,7,6},
-                {0,1,5,4},
-                {1,3,7,5},
-                {3,2,6,7},
-                {2,0,4,6},
-        }, new Point2D[][]{
-                {new Point2D(0, 0), new Point2D(100, 0), new Point2D(100, 100), new Point2D(0, 100)},
-                {new Point2D(0, 0), new Point2D(100, 0), new Point2D(100, 100), new Point2D(0, 100)},
-                {new Point2D(0, 0), new Point2D(100, 0), new Point2D(100, 100), new Point2D(0, 100)},
-                {new Point2D(0, 0), new Point2D(100, 0), new Point2D(100, 100), new Point2D(0, 100)},
-                {new Point2D(0, 0), new Point2D(100, 0), new Point2D(100, 100), new Point2D(0, 100)},
-                {new Point2D(0, 0), new Point2D(100, 0), new Point2D(100, 100), new Point2D(0, 100)},
-                {new Point2D(0, 0), new Point2D(100, 0), new Point2D(100, 100), new Point2D(0, 100)},
-        },
-                false,
-                new Texture[]{red, green, blue, cyan, magenta, yellow},
-                true));
+//        Texture testTexture;
+//        /*try {
+//            //testTexture = ImageIO.read(new File("/home/cory/Screenshot from 2022-06-06 18-52-12.png"));
+//            testTexture = new Texture(ImageIO.read(new File("/home/cory/Screenshot from 2022-09-26 13-05-40.png")));
+//        } catch (IOException e) {
+//            throw new RuntimeException(e);
+//        }*/
+//        Texture red = new Texture("red", Color.red);
+//        Texture green = new Texture("green", Color.GREEN);
+//        Texture blue = new Texture("blue", Color.BLUE);
+//        Texture cyan = new Texture(Color.CYAN);
+//        Texture magenta = new Texture(Color.magenta);
+//        Texture yellow = new Texture(Color.yellow);
+//
+//
 //        mainCollection.addObject(new Object3d(new PointComp[]{
-//                new PointComp(-10,10,10),
+//                new PointComp(-30,-10,-10),
+//                new PointComp(-30,-10,10),
+//                new PointComp(-30,10,-10),
+//                new PointComp(-30,10,10),
+//                new PointComp(-10,-10,-10),
 //                new PointComp(-10,-10,10),
-//                new PointComp(10,10,10),
-//                new PointComp(10,-10,10),
-//                new PointComp(0,0,24)
+//                new PointComp(-10,10,-10),
+//                new PointComp(-10,10,10)
+//
 //        }, new int[][]{
 //                {0,2,3,1},
-//                {1,0,4},
-//                {0,2,4},
-//                {2,3,4},
-//                {3,1,4}
-//        }, true));
-        mainCollection.addObject(new Object3d(new PointComp[]{
-                new PointComp(0,0,0),
-                new PointComp(20,0,0),
-                new PointComp(0,10,0),
-                new PointComp(0,0,10),
-        }, new int[][]{
-                {0,1,2},
-                {0,2,3},
-                {0,3,1},
-                {2,1,3}
-        }, new Point2D[][]{
-                {new Point2D(0,0), new Point2D(100,0), new Point2D(0,100)},
-                {new Point2D(0,0), new Point2D(100,0), new Point2D(0,100)},
-                {new Point2D(0,0), new Point2D(100,0), new Point2D(0,100)},
-        },
-                false,
-                new Texture[]{red, blue, cyan, yellow},
-                true));
+//                {4,5,7,6},
+//                {0,1,5,4},
+//                {1,3,7,5},
+//                {3,2,6,7},
+//                {2,0,4,6},
+//        }, new Point2D[][]{
+//                {new Point2D(0, 0), new Point2D(100, 0), new Point2D(100, 100), new Point2D(0, 100)},
+//                {new Point2D(0, 0), new Point2D(100, 0), new Point2D(100, 100), new Point2D(0, 100)},
+//                {new Point2D(0, 0), new Point2D(100, 0), new Point2D(100, 100), new Point2D(0, 100)},
+//                {new Point2D(0, 0), new Point2D(100, 0), new Point2D(100, 100), new Point2D(0, 100)},
+//                {new Point2D(0, 0), new Point2D(100, 0), new Point2D(100, 100), new Point2D(0, 100)},
+//                {new Point2D(0, 0), new Point2D(100, 0), new Point2D(100, 100), new Point2D(0, 100)},
+//                {new Point2D(0, 0), new Point2D(100, 0), new Point2D(100, 100), new Point2D(0, 100)},
+//        },
+//                false,
+//                new Texture[]{red, green, blue, cyan, magenta, yellow},
+//                true));
+////        mainCollection.addObject(new Object3d(new PointComp[]{
+////                new PointComp(-10,10,10),
+////                new PointComp(-10,-10,10),
+////                new PointComp(10,10,10),
+////                new PointComp(10,-10,10),
+////                new PointComp(0,0,24)
+////        }, new int[][]{
+////                {0,2,3,1},
+////                {1,0,4},
+////                {0,2,4},
+////                {2,3,4},
+////                {3,1,4}
+////        }, true));
+//        mainCollection.addObject(new Object3d(new PointComp[]{
+//                new PointComp(0,0,0),
+//                new PointComp(20,0,0),
+//                new PointComp(0,10,0),
+//                new PointComp(0,0,10),
+//        }, new int[][]{
+//                {0,1,2},
+//                {0,2,3},
+//                {0,3,1},
+//                {2,1,3}
+//        }, new Point2D[][]{
+//                {new Point2D(0,0), new Point2D(100,0), new Point2D(0,100)},
+//                {new Point2D(0,0), new Point2D(100,0), new Point2D(0,100)},
+//                {new Point2D(0,0), new Point2D(100,0), new Point2D(0,100)},
+//        },
+//                false,
+//                new Texture[]{red, blue, cyan, yellow},
+//                true));
     }
 }
diff --git a/src/main/java/uk/org/floop/epq3d/HTTPPost.java b/src/main/java/uk/org/floop/epq3d/HTTPPost.java
index c46cb8b..6701a9d 100644
--- a/src/main/java/uk/org/floop/epq3d/HTTPPost.java
+++ b/src/main/java/uk/org/floop/epq3d/HTTPPost.java
@@ -1,13 +1,7 @@
 package uk.org.floop.epq3d;
 
-import java.io.IOException;
-import java.net.URI;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
-
 public class HTTPPost {
-    public void invokePost(JsonWriter json) {
+    /*    public void invokePost(JsonWriter json) {
 
         try {
             String requestBody = json.file.toJSONString();
@@ -41,6 +35,6 @@
 //        String requestBody = objectMapper.writeValueAsString(values);
 //        return requestBody;
 //    }
-
+*/
 }
 
diff --git a/src/main/java/uk/org/floop/epq3d/JsonReader.java b/src/main/java/uk/org/floop/epq3d/JsonReader.java
new file mode 100644
index 0000000..c257612
--- /dev/null
+++ b/src/main/java/uk/org/floop/epq3d/JsonReader.java
@@ -0,0 +1,109 @@
+package uk.org.floop.epq3d;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+
+import java.awt.*;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Objects;
+
+// Program for print data in JSON format.
+public class JsonReader {
+    JSONObject file;
+    Texture[] textures;
+    ObjectCollection mainCollection;
+    public JsonReader(String filePath) {
+        JSONParser parser = new JSONParser();
+        Object obj;
+        try {
+             obj = parser.parse(new FileReader(filePath));
+        } catch (IOException | ParseException e) {
+            throw new RuntimeException(e);
+        }
+        file = (JSONObject)obj;
+    }
+    public void getObjects(){
+        textures = getTextures((JSONArray) file.get("textures"));
+        mainCollection = separateCollection((JSONObject) file.get("collections"), textures);
+        file.get("collection");
+    }
+    private ObjectCollection separateCollection(JSONObject json, Texture[] textures){
+        ObjectCollection result = new ObjectCollection();
+
+        // first, get the sub collections of the object and separate them recursively.
+        JSONArray subCollections = (JSONArray) json.get("subCollections");
+        if(subCollections != null) for (Object collection: subCollections) {
+            result.addCollection(separateCollection((JSONObject) collection, textures));
+        }
+        // next, get the name of the collection
+        result.name = json.get("name").toString();
+
+        // next, get the objects contained in this collection
+        JSONArray objects3d = (JSONArray) json.get("objects");
+        if(objects3d != null) for(Object objectJson: objects3d){
+            JSONObject object = (JSONObject)objectJson;
+            JSONArray pointsJson = (JSONArray) object.get("points");
+            // pack points
+            PointComp[] points = new PointComp[pointsJson.size()];
+            for (int i = 0; i < pointsJson.size(); i+=1){
+                JSONArray jsonPoint = (JSONArray) pointsJson.get(i);
+                points[i] = new PointComp(
+                        (double) jsonPoint.get(0),
+                        (double) jsonPoint.get(1),
+                        (double) jsonPoint.get(2)
+                );
+
+            }
+
+            // make faceList, UV list and texture lists
+            // (the indices should match up, if they don't something went wrong)
+            JSONArray faceListJson = (JSONArray) object.get("faceList");
+            JSONArray uvPointsListJson = (JSONArray) object.get("uvPointsList");
+            JSONArray texturesNamesJson = (JSONArray) object.get("textureList");
+
+            int[][] faceList = new int[faceListJson.size()][];
+            Point2D[][] uvPointsList = new Point2D[faceListJson.size()][];
+            Texture[] texturesList = new Texture[faceListJson.size()];
+
+            for (int i = 0; i < faceListJson.size(); i+=1) {
+                JSONArray jsonFace = (JSONArray) faceListJson.get(i);
+                JSONArray jsonUV = (JSONArray) uvPointsListJson.get(i);
+                String jsonTextureName = (String) texturesNamesJson.get(i);
+
+                faceList[i] = new int[jsonFace.size()];
+                uvPointsList[i] = new Point2D[jsonFace.size()];
+
+                for (int j = 0; j < jsonFace.size(); j += 1){
+                    faceList[i][j] = Integer.parseInt(String.valueOf(jsonFace.get(j)));
+                    uvPointsList[i][j] = new Point2D(
+                            Integer.parseInt(String.valueOf(((JSONArray)jsonUV.get(j)).get(0))),
+                            Integer.parseInt(String.valueOf(((JSONArray)jsonUV.get(j)).get(1)))
+                            );
+                }
+
+                // terrible linear search but idc because this code only runs once
+                for (Texture texture : textures) {
+                    if (Objects.equals(texture.name, jsonTextureName)) {
+                        texturesList[i] = texture;
+                        break;
+                    }
+                }
+            }
+            result.addObject(new Object3d(points, faceList, uvPointsList, false, texturesList, true));
+        }
+        return result;
+    }
+    public Texture[] getTextures(JSONArray textures){
+        Texture[] result = new Texture[textures.size()];
+        for(int i = 0; i < textures.size(); i += 1){
+            JSONObject JsonTexture = (JSONObject) textures.get(i);
+            if(Objects.equals(JsonTexture.get("type"), "solid")){
+                result[i] = new Texture(JsonTexture.get("name").toString(), Color.decode('#' + (String) JsonTexture.get("color")));
+            }
+        }
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/uk/org/floop/epq3d/Object3d.java b/src/main/java/uk/org/floop/epq3d/Object3d.java
index b057b7a..037a5ef 100644
--- a/src/main/java/uk/org/floop/epq3d/Object3d.java
+++ b/src/main/java/uk/org/floop/epq3d/Object3d.java
@@ -22,6 +22,8 @@
 
         if(initialise){initialise();}
     }
+
+
     public void invalidate(){
         for (Face face:
              faces) {
@@ -56,7 +58,7 @@
             }
             faces[face].hasEdges = hasEdges;
             faces[face].texture = textures[face];
-            faces[face].UVPoints = uvPoints[0];
+            faces[face].UVPoints = uvPoints[face];
             faces[face].initialise();
         }
         // init bounding sphere
diff --git a/src/main/java/uk/org/floop/epq3d/ObjectCollection.java b/src/main/java/uk/org/floop/epq3d/ObjectCollection.java
index 1513f94..7a7bdb7 100644
--- a/src/main/java/uk/org/floop/epq3d/ObjectCollection.java
+++ b/src/main/java/uk/org/floop/epq3d/ObjectCollection.java
@@ -5,15 +5,26 @@
 
 // stores both objects and other object collections
 public class ObjectCollection {
+    public String name;
     public ArrayList<PointComp> points = new ArrayList<PointComp>();
-    private Object3d collectionObject;
+
+    //private Object3d collectionObject;
     public double boundingSphereR;
     public Point3D boundingSphereC;
 
-
     public ArrayList<ObjectCollection> subCollections = new ArrayList<ObjectCollection>();
     public ArrayList<Object3d> objects = new ArrayList<Object3d>();
 
+    public ArrayList<PointComp> initialiseAll(){
+        for (ObjectCollection subCollection:
+             subCollections) {
+            ArrayList<PointComp> subPoints = subCollection.initialiseAll();
+            points.addAll(subPoints);
+        }
+        initialise();
+
+        return points;
+    }
     public void invalidate(boolean invalidatePoints){
         // the first level of object collections should contain all the points for the sublevels.
         // this means that we only need to invalidate them at the top level
@@ -64,9 +75,12 @@
             collection.draw(img, zBuf, debugImg, camMatrix, playerPos, frustumPlanes, FPDis, scrX, scrY);
         }
     }
-    public void addCollection(int[] pointList){
+    public void addCollection(){
         subCollections.add(new ObjectCollection());
     }
+    public void addCollection(ObjectCollection newCollection){
+        subCollections.add(newCollection);
+    }
     // making sure that all the point indices make sense might be a nightmare but ehh
     public void addObject(Object3d object){
         PointComp[] newpoints = object.points;
diff --git a/src/main/java/uk/org/floop/epq3d/Screen.java b/src/main/java/uk/org/floop/epq3d/Screen.java
index 4a79d08..75e4829 100644
--- a/src/main/java/uk/org/floop/epq3d/Screen.java
+++ b/src/main/java/uk/org/floop/epq3d/Screen.java
@@ -21,7 +21,7 @@
     public Object3d skyBox;
     // stores the 2d information on the HUD
     public BufferedImage debugImg;
-    public JsonWriter json;
+    public JsonReader json;
 
         // testing\
 //    private Line2d line = new Line2d(
@@ -69,6 +69,12 @@
 
         // initialize the game state
         player = new Player(scrX, scrY);
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+            System.out.println("aaaaaaaaaaa");
+            //throw new RuntimeException(e);
+        }
         // this frameTimer will call the actionPerformed() method every DELAY ms
         frameTimer = new Timer(DELAY, this);
         frameTimer.start();
diff --git a/src/main/java/uk/org/floop/epq3d/Texture.java b/src/main/java/uk/org/floop/epq3d/Texture.java
index f6f7eb5..617fb4a 100644
--- a/src/main/java/uk/org/floop/epq3d/Texture.java
+++ b/src/main/java/uk/org/floop/epq3d/Texture.java
@@ -1,24 +1,42 @@
 package uk.org.floop.epq3d;
 
+import javax.imageio.ImageIO;
 import java.awt.*;
 import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
 import java.util.Objects;
 
 public class Texture {
-    public BufferedImage img;
+    protected final String name;
+    private final String type;
+    public int[][] img;
     public Color color;
-    public String type;
 
-    public Texture(Color _color){
-        type = "solidColor";
+    public Texture(String _name, Color _color){
+        name = _name;
+        type = "solid";
         color = _color;
     }
-    public Texture(BufferedImage _img){
-        type = "textured";
-        img = _img;
+    public Texture(String _name, String _imgPath){
+        name = _name;
+        type = "image";
+
+        // grab file and pack it into a list[][] int (gives better performance than a BufferedImage by a _lot_
+        File imgFile = new File(_imgPath);
+        try {
+            BufferedImage _img = ImageIO.read(imgFile);
+            for(int x = 0; x < _img.getWidth(); x +=1) {
+                for (int y = 0; y < _img.getHeight(); y += 1) {
+                    img[x][y] = _img.getRGB(x, y);
+                }
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
     }
     public boolean isSolid(){
-        if (Objects.equals(type, "solidColor")){
+        if (Objects.equals(type, "solid")){
             return true;
         }
         else{
diff --git a/src/main/java/uk/org/floop/epq3d/testing.java b/src/main/java/uk/org/floop/epq3d/testing.java
index 05aa248..ff24384 100644
--- a/src/main/java/uk/org/floop/epq3d/testing.java
+++ b/src/main/java/uk/org/floop/epq3d/testing.java
@@ -2,24 +2,9 @@
 
 class testing {
     public static void main(String[] args) {
-//        Matrix matt = new Matrix(2, 2);
-//        matt.setItems(new double[][]{
-//                {3, 7},
-//                {4, 8},
-//        });
-//        Matrix matt = new Matrix(3, 3);
-//        matt.setItems(new double[][]{
-//                {2, -1, 3},
-//                {0, 5, 2},
-//                {1, -1, -2}
-//        });
-
-        Matrix matt = new Matrix(4, 4);
-        matt.setItems(new double[][]{
-                {3, 3, 3, 0},
-                {4, 8, 7, 2.3},
-                {5, 1, 3, 9.4},
-                {2, 1, 4, 7}
-        });
+        JsonReader Jason = new JsonReader("cube.json");
+        Jason.getObjects();
+        ObjectCollection main = Jason.mainCollection;
+        Texture[] textures = Jason.textures;
     }
 }