diff --git a/index.html b/index.html
index 14ac46a..c32f998 100644
--- a/index.html
+++ b/index.html
@@ -143,15 +143,17 @@
 		</script>
 	</head>
 	<body>
-		<div id="container"></div>
-		<span id="message" class="loading">
-			<div id="progressCircle" style="--progress: 0deg;">0%</div>
+		<div id="loading">
+			<table id="labyTable"></table>
+			<div id="loadingMessage">Construction du labyrinthe : <span id="progress">0</span>%</div>
 			<div>
 				Se déplacer : ↑←↓→, ZQSD ou clic<br/>
 				Sauter : ESPACE<br/>
 				Regarder : Souris
 			</div>
-		</span>
+		</div>
+		<div id="container"></div>
+		<span id="message"></span>
 
 		<script type="module" src="./main.js"></script>
 	</body>
diff --git a/main.js b/main.js
index 5501bdd..c190541 100644
--- a/main.js
+++ b/main.js
@@ -7,48 +7,90 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'
 import { OctreeHelper } from 'three/addons/helpers/OctreeHelper.js'
 import Stats from 'three/addons/libs/stats.module.js'
 
-//import 'three-hex-tiling'
-
 import MazeMesh from './MazeMesh.js'
 
+//import 'three-hex-tiling'
 
-const playerHeight = 0.5;
-const mazeWidth = 23
 
-const parameters = {
-    elevation: 48,
-    azimuth  : 53,
-};
+// LOADING
 
-const waves = {
-    A: { direction:  0, steepness: 0.05, wavelength: 3 },
-    B: { direction: 30, steepness: 0.10, wavelength: 6 },
-    C: { direction: 60, steepness: 0.05, wavelength: 1.5 },
-};
+const labyWidth =23
+const labyHeight = 23
 
-const dev = window.location.search.includes("dev")
+for(let y=0; y < labyHeight; y++) {
+    let tr = document.createElement("tr")
+    labyTable.appendChild(tr)
+    for(let x=0; x < labyHeight; x++) {
+        let td = document.createElement("td")
+        tr.appendChild(td)
+    }
+}
 
-const ambiance = new Audio("snd/ambiance.mp3")
-ambiance.loop = true
-const piano = new Audio("snd/waves-and-tears.mp3")
-piano.loop = false
+let walls
 
-const loadMngr = new THREE.LoadingManager();
-const loader = new THREE.TextureLoader(loadMngr);
+function dig(x, y) {
+    walls[y][x] = false
+    window.requestAnimationFrame(() => labyTable.children[y].children[x].className = "ground")
+}
+
+const directions = [[0, 1], [0, -1], [1, 0], [-1, 0]]
+function* build(x, y) {
+    for (let direction of Array.from(directions).sort(x => .5 - Math.random())) {
+        let [dx, dy] = direction
+        let x1 = x + dx
+        let y1 = y + dy
+        let x2 = x1 + dx
+        let y2 = y1 + dy
+        if (0 <= x2 && x2 < labyWidth && 0 <= y2 && y2 < labyHeight && walls[y2][x2]) {
+            dig(x1, y1)
+            yield x1, y1
+            dig(x2, y2)
+            yield x2, y2
+            yield* build(x2, y2)
+        }
+    }
+}
+
+function* endlessLaby() {
+    while (true) {
+        for (const tr of labyTable.children) {
+            for (const td of tr.children) {
+                td.className = "wall"
+            }
+        }
+
+        walls = Array(labyHeight).fill(true).map(row => Array(labyWidth).fill(true))
+
+        //let x0 = 2 * Math.floor(labyWidth * Math.random() / 2) + 1
+        //let y0 = 2 * Math.floor(labyHeight * Math.random() / 2) + 1
+        let x0 = Math.floor(labyWidth / 2)
+        let y0 = Math.floor(labyHeight / 2)
+
+        dig(x0, y0)
+        yield* build(x0, y0)
+    }
+}
+
+let labyIterator = endlessLaby()
+
+let interval = window.setInterval(() => labyIterator.next(), 200)
+
+
+const loadMngr = new THREE.LoadingManager()
+const loader = new THREE.TextureLoader(loadMngr)
+loader.setPath("textures/")
 loadMngr.onStart = function (url, itemsLoaded, itemsTotal) {
-	progressCircle.innerText = "0%"
-	progressCircle.style.setProperty("--progress", "0deg")
+	progress.innerText = "0"
 }
 loadMngr.onProgress = function (url, itemsLoaded, itemsTotal) {
-	progressCircle.innerText = Math.floor(100 * itemsLoaded / itemsTotal) + "%"
-	progressCircle.style.setProperty("--progress", Math.floor(360 * itemsLoaded / itemsTotal)+"deg")
+	progress.innerText = Math.floor(100 * itemsLoaded / itemsTotal)
 }
 loadMngr.onError = function (url) {
-    message.innerHTML = `Erreur de chargement :<br/>${url}`
+    loadingMessage.innerHTML = `Erreur de chargement :<br/>${url}`
 }
 loadMngr.onLoad = function (url, itemsLoaded, itemsTotal) {
-    message.innerHTML = ""
-    message.className = ""
+    loading.style.display = "none"
+    window.clearInterval(interval)
 
     renderer.setAnimationLoop(animate)
 
@@ -56,26 +98,45 @@ loadMngr.onLoad = function (url, itemsLoaded, itemsTotal) {
         let x = Math.floor(8 + camera.position.x * 16 / mazeWidth)
         let y = Math.floor(8 + camera.position.z * 16 / mazeWidth)
         favicon.href = `favicon.php?x=${x}&y=${y}`
-    }, 1000);
-};
+    }, 1000)
+}
 
-//
 
-const container = document.getElementById('container');
+// GAME
+
+const playerHeight = 0.5
+const mazeWidth = 23
+
+const parameters = {
+    elevation: 48,
+    azimuth  : 53,
+}
+
+const waves = {
+    A: { direction:  0, steepness: 0.06, wavelength: 4 },
+    B: { direction: 30, steepness: 0.10, wavelength: 6 },
+    C: { direction: 60, steepness: 0.05, wavelength: 1.5 },
+}
+
+const ambiance = new Audio("snd/ambiance.mp3")
+ambiance.loop = true
+const piano = new Audio("snd/waves-and-tears.mp3")
+piano.loop = false
+
+const container = document.getElementById('container')
 
 const renderer = new THREE.WebGLRenderer({
     powerPreference: "high-performance",
-    antialias: true,
-});
-renderer.setPixelRatio(window.devicePixelRatio);
-renderer.setSize(window.innerWidth, window.innerHeight);
-renderer.toneMapping = THREE.ACESFilmicToneMapping;
-renderer.shadowMap.enabled = true;
-renderer.shadowMap.type = THREE.PCFSoftShadowMap;
+})
+renderer.setPixelRatio(window.devicePixelRatio)
+renderer.setSize(window.innerWidth, window.innerHeight)
+renderer.toneMapping = THREE.ACESFilmicToneMapping
+renderer.shadowMap.enabled = true
+renderer.shadowMap.type = THREE.PCFSoftShadowMap
 
-container.appendChild(renderer.domElement);
+container.appendChild(renderer.domElement)
 
-const scene = new THREE.Scene();
+const scene = new THREE.Scene()
 
 scene.background = new THREE.CubeTextureLoader(loadMngr)
     .setPath( 'textures/calm-sea-skybox/' )
@@ -86,48 +147,50 @@ scene.background = new THREE.CubeTextureLoader(loadMngr)
         'dn.webp',
         'rt.webp',
         'lf.webp',
-    ] );
-scene.backgroundBlurriness = 0.03;
-scene.backgroundIntensity  = 1.4;
-scene.environment = scene.background;
+    ] )
+scene.backgroundBlurriness = 0.03
+scene.backgroundIntensity  = 1.4
+scene.environment = scene.background
 
-window.scene = scene;
+window.scene = scene
 
-const camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 0.1, 1000);
-camera.rotation.order = 'YXZ';
-camera.position.set(0, 25 + playerHeight, 0);
+const camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 0.1, 1000)
+camera.rotation.order = 'YXZ'
+camera.position.set(0, 25 + playerHeight, 0)
 
-const mazeCollisionner = new THREE.Group();
+const mazeCollisionner = new THREE.Group()
 
 // Maze
 
 const wallMaterial = new THREE.MeshStandardMaterial({
-    map            : loader.load('textures/Poly-cobblestone-wall/color_map.webp'),
-    normalMap      : loader.load('textures/Poly-cobblestone-wall/normal_map_opengl.webp'),
-	aoMap          : loader.load('textures/Poly-cobblestone-wall/ao_map.webp'),
-	roughnessMap   : loader.load('textures/Poly-cobblestone-wall/roughness_map.webp'),
+    map            : loader.load('Poly-cobblestone-wall/color_map.webp'),
+    normalMap      : loader.load('Poly-cobblestone-wall/normal_map_opengl.webp'),
+	aoMap          : loader.load('Poly-cobblestone-wall/ao_map.webp'),
+	roughnessMap   : loader.load('Poly-cobblestone-wall/roughness_map.webp'),
 	roughness      : 1
 })
 
-const maze = new MazeMesh(mazeWidth, mazeWidth, 1, wallMaterial);
-maze.castShadow = true;
-maze.receiveShadow = true;
+const maze = new MazeMesh(mazeWidth, mazeWidth, 1, wallMaterial)
+maze.castShadow = true
+maze.receiveShadow = true
 maze.matrixAutoUpdate = false
 scene.add(maze)
 
 console.log(String(maze))
 
+const dev = window.location.search.includes("dev")
+
 if (!dev) {
-    const invisibleWall = new THREE.Mesh(new THREE.BoxGeometry( .9, 1.8, .9 ));
-    invisibleWall.material.visible = false;
+    const invisibleWall = new THREE.Mesh(new THREE.BoxGeometry( .9, 1.8, .9 ))
+    invisibleWall.material.visible = false
     let matrix = new THREE.Matrix4()
 
     for (let i = 0; i < maze.count; i++) {
         maze.getMatrixAt(i, matrix)
         const clone = invisibleWall.clone()
-        clone.position.setFromMatrixPosition(matrix);
-        clone.position.y = 1;
-        mazeCollisionner.add(clone);
+        clone.position.setFromMatrixPosition(matrix)
+        clone.position.y = 1
+        mazeCollisionner.add(clone)
     }
 }
 
@@ -139,11 +202,11 @@ function repeatGroundMaterial (texture) {
     texture.repeat.set(mazeWidth / 4, mazeWidth / 4)
 }
 const groundMaterial = new THREE.MeshStandardMaterial({
-    map         : loader.load('textures/angled-blocks-vegetation/albedo.webp', repeatGroundMaterial),
-    aoMap       : loader.load('textures/angled-blocks-vegetation/ao.webp', repeatGroundMaterial),
-    metalnessMap: loader.load('textures/angled-blocks-vegetation/metallic.webp', repeatGroundMaterial),
-    normalMap   : loader.load('textures/angled-blocks-vegetation/normal-dx.webp', repeatGroundMaterial),
-    roughnessMap: loader.load('textures/angled-blocks-vegetation/roughness.webp', repeatGroundMaterial),
+    map         : loader.load('angled-blocks-vegetation/albedo.webp', repeatGroundMaterial),
+    aoMap       : loader.load('angled-blocks-vegetation/ao.webp', repeatGroundMaterial),
+    metalnessMap: loader.load('angled-blocks-vegetation/metallic.webp', repeatGroundMaterial),
+    normalMap   : loader.load('angled-blocks-vegetation/normal-dx.webp', repeatGroundMaterial),
+    roughnessMap: loader.load('angled-blocks-vegetation/roughness.webp', repeatGroundMaterial),
     /*hexTiling   : {
         patchScale: 1,
         useContrastCorrectedBlending: true,
@@ -184,29 +247,29 @@ const ground = new THREE.Mesh(
         groundMaterial,
     ]
 )
-ground.rotation.x = -Math.PI / 2;
+ground.rotation.x = -Math.PI / 2
 ground.position.y = -10
-ground.receiveShadow = true;
+ground.receiveShadow = true
 ground.matrixAutoUpdate = false
-ground.updateMatrix();
+ground.updateMatrix()
 
 mazeCollisionner.add(ground)
 
-scene.add(mazeCollisionner);
+scene.add(mazeCollisionner)
 
-const mazeOctree = new Octree().fromGraphNode(mazeCollisionner);
+const mazeOctree = new Octree().fromGraphNode(mazeCollisionner)
 
 // Water
 
-const waterGeometry = new THREE.PlaneGeometry(1024, 1024, 512, 512);
+const waterGeometry = new THREE.PlaneGeometry(512, 512, 128, 128)
 
 const ocean = new Water(waterGeometry, {
-    textureWidth : 512,
-    textureHeight: 512,
+    textureWidth : 256,
+    textureHeight: 256,
     waterNormals : loader.load(
-        'textures/waternormals.webp',
+        'waternormals.webp',
         function (texture) {
-            texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
+            texture.wrapS = texture.wrapT = THREE.RepeatWrapping
         }
     ),
     sunDirection   : new THREE.Vector3(),
@@ -214,12 +277,12 @@ const ocean = new Water(waterGeometry, {
     waterColor     : 0x001e0f,
     distortionScale: 3.7,
     fog            : scene.fog !== undefined,
-    alpha          : 0.9
-});
-ocean.rotation.x = - Math.PI / 2;
-ocean.position.y = -0.2;
+    alpha          : 0.7
+})
+ocean.rotation.x = - Math.PI / 2
+ocean.position.y = -0.2
 
-ocean.material.transparent = true;
+ocean.material.transparent = true
 ocean.material.onBeforeCompile = function (shader) {
 
     shader.uniforms.size = { value: 6 }
@@ -231,7 +294,7 @@ ocean.material.onBeforeCompile = function (shader) {
             waves.A.steepness,
             waves.A.wavelength,
         ],
-    };
+    }
     shader.uniforms.waveB = {
         value: [
             Math.sin((waves.B.direction * Math.PI) / 180),
@@ -239,7 +302,7 @@ ocean.material.onBeforeCompile = function (shader) {
             waves.B.steepness,
             waves.B.wavelength,
         ],
-    };
+    }
     shader.uniforms.waveC = {
         value: [
             Math.sin((waves.C.direction * Math.PI) / 180),
@@ -247,50 +310,50 @@ ocean.material.onBeforeCompile = function (shader) {
             waves.C.steepness,
             waves.C.wavelength,
         ],
-    };
-    shader.vertexShader = document.getElementById('vertexShader').textContent;
-    shader.fragmentShader = document.getElementById('fragmentShader').textContent;
+    }
+    shader.vertexShader = document.getElementById('vertexShader').textContent
+    shader.fragmentShader = document.getElementById('fragmentShader').textContent
 
-};
+}
 
-scene.add(ocean);
-const oceanOctree  = new Octree().fromGraphNode(ocean);
+scene.add(ocean)
+const oceanOctree  = new Octree().fromGraphNode(ocean)
 
 // Lights
 
-const sun = new THREE.Vector3();
+const sun = new THREE.Vector3()
 
-const ambientLight = new THREE.AmbientLight(0x404040, 5);
-scene.add(ambientLight);
+const ambientLight = new THREE.AmbientLight(0x404040, 5)
+scene.add(ambientLight)
 
-const sunLight = new THREE.DirectionalLight(0xffffff, 1);
-sunLight.castShadow            = true;
-sunLight.shadow.camera.near    = 0.1;
-sunLight.shadow.camera.far     =  1.4 * mazeWidth;
-sunLight.shadow.camera.left    = -1.4 * mazeWidth/2;
-sunLight.shadow.camera.right   =  1.4 * mazeWidth/2;
-sunLight.shadow.camera.bottom  = -1.4 * mazeWidth/2;
-sunLight.shadow.camera.top     =  1.4 * mazeWidth/2;
-sunLight.shadow.mapSize.width  = 1024;
-sunLight.shadow.mapSize.height = 1024;
-//sunLight.shadow.radius         = 0.01;
-sunLight.shadow.bias           = 0.0001;
+const sunLight = new THREE.DirectionalLight(0xffffff, 1)
+sunLight.castShadow            = true
+sunLight.shadow.camera.near    = 0.1
+sunLight.shadow.camera.far     =  1.4 * mazeWidth
+sunLight.shadow.camera.left    = -1.4 * mazeWidth/2
+sunLight.shadow.camera.right   =  1.4 * mazeWidth/2
+sunLight.shadow.camera.bottom  = -1.4 * mazeWidth/2
+sunLight.shadow.camera.top     =  1.4 * mazeWidth/2
+sunLight.shadow.mapSize.width  = 1024
+sunLight.shadow.mapSize.height = 1024
+sunLight.shadow.radius         = 0.01
+sunLight.shadow.bias           = 0.0001
 sunLight.target                = maze
-scene.add(sunLight);
+scene.add(sunLight)
 
-updateSun();
+updateSun()
 
 function updateSun() {
 
-    const phi = THREE.MathUtils.degToRad(90 - parameters.elevation);
-    const theta = THREE.MathUtils.degToRad(parameters.azimuth);
+    const phi = THREE.MathUtils.degToRad(90 - parameters.elevation)
+    const theta = THREE.MathUtils.degToRad(parameters.azimuth)
 
-    sun.setFromSphericalCoords(1.4 * mazeWidth/2, phi, theta);
-    ocean.material.uniforms['sunDirection'].value.copy(sun).normalize();
+    sun.setFromSphericalCoords(1.4 * mazeWidth/2, phi, theta)
+    ocean.material.uniforms['sunDirection'].value.copy(sun).normalize()
     
     sunLight.position.copy(sun)
 
-    //ambientLight.intensity = 5 + 5 * Math.sin(Math.max(THREE.MathUtils.degToRad(parameters.elevation), 0));
+    //ambientLight.intensity = 5 + 5 * Math.sin(Math.max(THREE.MathUtils.degToRad(parameters.elevation), 0))
 
 }
 
@@ -302,49 +365,49 @@ function repeatRaftMaterial(texture) {
     texture.repeat.set(2, 1)
 }
 const raftMaterial = new THREE.MeshStandardMaterial({
-    map: loader.load("textures/Poly-wood/color_map.webp", repeatRaftMaterial),
-    aoMap: loader.load("textures/Poly-wood/ao_map.webp", repeatRaftMaterial),
-    normalMap: loader.load("textures/Poly-wood/normal_map_opengl.webp", repeatRaftMaterial),
+    map: loader.load("Poly-wood/color_map.webp", repeatRaftMaterial),
+    aoMap: loader.load("Poly-wood/ao_map.webp", repeatRaftMaterial),
+    normalMap: loader.load("Poly-wood/normal_map_opengl.webp", repeatRaftMaterial),
     normalScale : new THREE.Vector2(2, 2),
-    roughnessMap: loader.load("textures/Poly-wood/roughness_map.webp", repeatRaftMaterial),
+    roughnessMap: loader.load("Poly-wood/roughness_map.webp", repeatRaftMaterial),
     depthFunc: 3,
     depthTest: true,
     depthWrite: true,
-    displacementMap: loader.load("textures/Poly-wood/displacement_map.webp", repeatRaftMaterial),
+    displacementMap: loader.load("Poly-wood/displacement_map.webp", repeatRaftMaterial),
     displacementScale: -0.3,
     displacementBias: 0.15,
 })
 const raft = new THREE.Mesh(raftGeometry, raftMaterial)
 raft.position.set( .25, ocean.position.y, -mazeWidth/2 - 1.1 )
-raft.castShadow = true;
+raft.castShadow = true
 
-scene.add(raft);
-const raftOctree  = new Octree().fromGraphNode(raft);
+scene.add(raft)
+const raftOctree  = new Octree().fromGraphNode(raft)
 
 // GUI
 
-const stats = new Stats();
+const stats = new Stats()
 
 if (dev) {
     
-    container.appendChild(stats.dom);
+    container.appendChild(stats.dom)
 
-    const gui = new GUI();
+    const gui = new GUI()
 
     const lightHelper = new THREE.DirectionalLightHelper(sunLight, .5)
     lightHelper.position.copy(maze.start)
-    lightHelper.visible = false;
+    lightHelper.visible = false
 
-    const octreeHelper = new OctreeHelper(mazeOctree);
-    octreeHelper.visible = false;
-    scene.add(octreeHelper);
+    const octreeHelper = new OctreeHelper(mazeOctree)
+    octreeHelper.visible = false
+    scene.add(octreeHelper)
     const showHelper = gui.add({ helpers: false }, "helpers")
     showHelper.onChange(function (value) {
 
-        lightHelper.visible = value;
-        octreeHelper.visible = value;
+        lightHelper.visible = value
+        octreeHelper.visible = value
 
-    });
+    })
 
     const cameraFolder = gui.addFolder("camera")
     cameraFolder.add(camera, "focus",     0, 200).onChange(() => camera.updateProjectionMatrix())
@@ -360,91 +423,91 @@ if (dev) {
     raftRotationFolder.add(raft.rotation, "x")
     raftRotationFolder.add(raft.rotation, "y")
     raftRotationFolder.add(raft.rotation, "z")
-    raftFolder.close();
+    raftFolder.close()
 
-    const skyFolder = gui.addFolder('Sky');
-    skyFolder.add(parameters, 'elevation', 0, 90, 0.1).onChange(updateSun);
-    skyFolder.add(parameters, 'azimuth', - 180, 180, 0.1).onChange(updateSun);
-    skyFolder.close();
+    const skyFolder = gui.addFolder('Sky')
+    skyFolder.add(parameters, 'elevation', 0, 90, 0.1).onChange(updateSun)
+    skyFolder.add(parameters, 'azimuth', - 180, 180, 0.1).onChange(updateSun)
+    skyFolder.close()
 
-    const waterUniforms = ocean.material.uniforms;
+    const waterUniforms = ocean.material.uniforms
 
-    const waterFolder = gui.addFolder('Water');
+    const waterFolder = gui.addFolder('Water')
     waterFolder
         .add(waterUniforms.distortionScale, 'value', 0, 8, 0.1)
-        .name('distortionScale');
-    waterFolder.add(waterUniforms.size, 'value', 0.1, 10, 0.1).name('size');
-    waterFolder.add(ocean.material, 'wireframe');
-    waterFolder.close();
+        .name('distortionScale')
+    waterFolder.add(waterUniforms.size, 'value', 0.1, 10, 0.1).name('size')
+    waterFolder.add(ocean.material, 'wireframe')
+    waterFolder.close()
 
-    const waveAFolder = waterFolder.addFolder('Wave A');
+    const waveAFolder = waterFolder.addFolder('Wave A')
     waveAFolder
         .add(waves.A, 'direction', 0, 359)
         .name('Direction')
         .onChange((v) => {
-            const x = (v * Math.PI) / 180;
-            ocean.material.uniforms.waveA.value[0] = Math.sin(x);
-            ocean.material.uniforms.waveA.value[1] = Math.cos(x);
-        });
+            const x = (v * Math.PI) / 180
+            ocean.material.uniforms.waveA.value[0] = Math.sin(x)
+            ocean.material.uniforms.waveA.value[1] = Math.cos(x)
+        })
     waveAFolder
         .add(waves.A, 'steepness', 0, 1, 0.01)
         .name('Steepness')
         .onChange((v) => {
-            ocean.material.uniforms.waveA.value[2] = v;
-        });
+            ocean.material.uniforms.waveA.value[2] = v
+        })
     waveAFolder
         .add(waves.A, 'wavelength', 1, 100)
         .name('Wavelength')
         .onChange((v) => {
-            ocean.material.uniforms.waveA.value[3] = v;
-        });
-    waveAFolder.open();
+            ocean.material.uniforms.waveA.value[3] = v
+        })
+    waveAFolder.open()
 
-    const waveBFolder = waterFolder.addFolder('Wave B');
+    const waveBFolder = waterFolder.addFolder('Wave B')
     waveBFolder
         .add(waves.B, 'direction', 0, 359)
         .name('Direction')
         .onChange((v) => {
-            const x = (v * Math.PI) / 180;
-            ocean.material.uniforms.waveB.value[0] = Math.sin(x);
-            ocean.material.uniforms.waveB.value[1] = Math.cos(x);
-        });
+            const x = (v * Math.PI) / 180
+            ocean.material.uniforms.waveB.value[0] = Math.sin(x)
+            ocean.material.uniforms.waveB.value[1] = Math.cos(x)
+        })
     waveBFolder
         .add(waves.B, 'steepness', 0, 1, 0.01)
         .name('Steepness')
         .onChange((v) => {
-            ocean.material.uniforms.waveB.value[2] = v;
-        });
+            ocean.material.uniforms.waveB.value[2] = v
+        })
     waveBFolder
         .add(waves.B, 'wavelength', 1, 100)
         .name('Wavelength')
         .onChange((v) => {
-            ocean.material.uniforms.waveB.value[3] = v;
-        });
-    waveBFolder.open();
+            ocean.material.uniforms.waveB.value[3] = v
+        })
+    waveBFolder.open()
 
-    const waveCFolder = waterFolder.addFolder('Wave C');
+    const waveCFolder = waterFolder.addFolder('Wave C')
     waveCFolder
         .add(waves.C, 'direction', 0, 359)
         .name('Direction')
         .onChange((v) => {
-            const x = (v * Math.PI) / 180;
-            ocean.material.uniforms.waveC.value[0] = Math.sin(x);
-            ocean.material.uniforms.waveC.value[1] = Math.cos(x);
-        });
+            const x = (v * Math.PI) / 180
+            ocean.material.uniforms.waveC.value[0] = Math.sin(x)
+            ocean.material.uniforms.waveC.value[1] = Math.cos(x)
+        })
     waveCFolder
         .add(waves.C, 'steepness', 0, 1, 0.01)
         .name('Steepness')
         .onChange((v) => {
-            ocean.material.uniforms.waveC.value[2] = v;
-        });
+            ocean.material.uniforms.waveC.value[2] = v
+        })
     waveCFolder
         .add(waves.C, 'wavelength', 1, 100)
         .name('Wavelength')
         .onChange((v) => {
-            ocean.material.uniforms.waveC.value[3] = v;
-        });
-    waveCFolder.open();
+            ocean.material.uniforms.waveC.value[3] = v
+        })
+    waveCFolder.open()
 
     const hexTilingFolder = gui.addFolder('Hex Tiling')
     if (wallMaterial?.hexTiling?.patchScale) {
@@ -466,66 +529,66 @@ if (dev) {
 
 //
 
-const clock = new THREE.Clock();
+const clock = new THREE.Clock()
 
 // Controls
 
-const GRAVITY = 30;
+const GRAVITY = 30
 
-const STEPS_PER_FRAME = 10;
+const STEPS_PER_FRAME = 10
 
 const playerCollider = new Capsule(
     new THREE.Vector3(0, 25.0, 0),
     new THREE.Vector3(0, 25 + playerHeight, 0),
     0.3
-);
+)
 
-const playerVelocity = new THREE.Vector3();
-const playerDirection = new THREE.Vector3();
+const playerVelocity = new THREE.Vector3()
+const playerDirection = new THREE.Vector3()
 
-let playerOnFloor = false;
-let jumping = false;
-let escaped = false;
+let playerOnFloor = false
+let jumping = false
+let escaped = false
 
-const pointerLockControls = new PointerLockControls(camera, document.body);
-pointerLockControls.pointerSpeed = 0.7;
+const pointerLockControls = new PointerLockControls(camera, document.body)
+pointerLockControls.pointerSpeed = 0.7
 
-const keyStates = {};
+const keyStates = {}
 
 document.addEventListener('keydown', (event) => {
-    keyStates[event.code] = true;
-});
+    keyStates[event.code] = true
+})
 
 document.addEventListener('keyup', (event) => {
-    keyStates[event.code] = false;
+    keyStates[event.code] = false
     if (event.code == 'Space') jumping = false
-});
+})
 
-var mouseButtonsStates = [];
+let mouseButtonsStates = []
 
 function onMouseChange(event) {
-    for(var i=0; i < mouseButtonsStates.length || i <= Math.log2(event.buttons); i++) {
+    for(let i=0; i < mouseButtonsStates.length || i <= Math.log2(event.buttons); i++) {
         mouseButtonsStates[i] = (event.buttons & (1 << i)) > 0
     }
 }
 
 container.addEventListener('click', function () {
-    pointerLockControls.lock();
+    pointerLockControls.lock()
 })
 
 pointerLockControls.addEventListener('lock', function () {
-    ambiance.play();
+    ambiance.play()
     document.addEventListener('mousedown', onMouseChange)
     document.addEventListener('mouseup', onMouseChange)
 })
 
 pointerLockControls.addEventListener('unlock', function () {
-    ambiance.pause();
+    ambiance.pause()
     document.removeEventListener('mousedown', onMouseChange)
     document.removeEventListener('mouseup', onMouseChange)
 })
 
-scene.add(pointerLockControls.getObject());
+scene.add(pointerLockControls.getObject())
 
 function playerCollisions() {
 
@@ -535,23 +598,23 @@ function playerCollisions() {
 
     const result = playerOnMaze || playerOnRaft || playerOnWater
 
-    playerOnFloor = false;
+    playerOnFloor = false
 
     if ( result ) {
-        playerOnFloor = result.normal.y > 0;
+        playerOnFloor = result.normal.y > 0
 
         if (!playerOnFloor) {
-            playerVelocity.addScaledVector(result.normal, - result.normal.dot(playerVelocity));
+            playerVelocity.addScaledVector(result.normal, - result.normal.dot(playerVelocity))
         }
 
-        playerCollider.translate(result.normal.multiplyScalar(result.depth));
+        playerCollider.translate(result.normal.multiplyScalar(result.depth))
 
         if (playerOnRaft) {    
             camera.position.y = playerCollider.end.y + raft.position.y
             if (!escaped) gameEnd()
 
         } else if (playerOnWater) {
-            const t = ocean.material.uniforms['time'].value;
+            const t = ocean.material.uniforms['time'].value
             const waveInfo = getWaveInfo(playerCollider.end.x, playerCollider.end.z, t)
             camera.position.y = ocean.position.y + waveInfo.position.y + 0.2
         }
@@ -561,61 +624,61 @@ function playerCollisions() {
 
 function gameEnd() {
 
-    escaped = true;
-    message.innerHTML = '<h2>Libre !</h2><a href="">Rejouer</a>';
-    message.className = "escaped";
-    piano.play();
+    escaped = true
+    message.innerHTML = '<h2>Libre !</h2><a href="">Rejouer</a>'
+    message.className = "escaped"
+    piano.play()
 
-    document.exitPointerLock();
-    //container.style.cursor = "default";
+    document.exitPointerLock()
+    //container.style.cursor = "default"
 
 }
 
 function updatePlayer(deltaTime) {
 
-    let damping = Math.exp(- 4 * deltaTime) - 1;
+    let damping = Math.exp(- 4 * deltaTime) - 1
 
     if (!playerOnFloor) {
-        playerVelocity.y -= GRAVITY * deltaTime;
+        playerVelocity.y -= GRAVITY * deltaTime
         damping *= 0.1; // small air resistance
     }
 
-    playerVelocity.addScaledVector(playerVelocity, damping);
+    playerVelocity.addScaledVector(playerVelocity, damping)
 
-    const deltaPosition = playerVelocity.clone().multiplyScalar(deltaTime);
-    playerCollider.translate(deltaPosition);
+    const deltaPosition = playerVelocity.clone().multiplyScalar(deltaTime)
+    playerCollider.translate(deltaPosition)
 
-    camera.position.copy(playerCollider.end);
+    camera.position.copy(playerCollider.end)
 
-    playerCollisions();
+    playerCollisions()
 
 }
 
 function getForwardVector() {
 
-    camera.getWorldDirection(playerDirection);
-    playerDirection.y = 0;
-    playerDirection.normalize();
+    camera.getWorldDirection(playerDirection)
+    playerDirection.y = 0
+    playerDirection.normalize()
 
-    return playerDirection;
+    return playerDirection
 
 }
 
 function getSideVector() {
 
-    camera.getWorldDirection(playerDirection);
-    playerDirection.y = 0;
-    playerDirection.normalize();
-    playerDirection.cross(camera.up);
+    camera.getWorldDirection(playerDirection)
+    playerDirection.y = 0
+    playerDirection.normalize()
+    playerDirection.cross(camera.up)
 
-    return playerDirection;
+    return playerDirection
 
 }
 
 function controls(deltaTime) {
 
     // gives a bit of air control
-    const speedDelta = deltaTime * (playerOnFloor ? 100 : 20) / STEPS_PER_FRAME;
+    const speedDelta = deltaTime * (playerOnFloor ? 100 : 20) / STEPS_PER_FRAME
 
     if (keyStates["ArrowUp"] || keyStates['KeyW'] || mouseButtonsStates[0]) {
         playerVelocity.add(getForwardVector().multiplyScalar(speedDelta))
@@ -631,7 +694,7 @@ function controls(deltaTime) {
     }
     if (playerOnFloor && jumping == false) {
         if (keyStates['Space']) {
-            playerVelocity.y = 9;
+            playerVelocity.y = 9
             jumping = true
         }
     }
@@ -639,88 +702,88 @@ function controls(deltaTime) {
 
 function getWaveInfo(x, z, time) {
 
-    const pos = new THREE.Vector3();
-    const tangent = new THREE.Vector3(1, 0, 0);
-    const binormal = new THREE.Vector3(0, 0, 1);
+    const pos = new THREE.Vector3()
+    const tangent = new THREE.Vector3(1, 0, 0)
+    const binormal = new THREE.Vector3(0, 0, 1)
     Object.keys(waves).forEach((wave) => {
-        const w = waves[wave];
-        const k = (Math.PI * 2) / w.wavelength;
-        const c = Math.sqrt(9.8 / k);
+        const w = waves[wave]
+        const k = (Math.PI * 2) / w.wavelength
+        const c = Math.sqrt(9.8 / k)
         const d = new THREE.Vector2(
             Math.sin((w.direction * Math.PI) / 180),
             - Math.cos((w.direction * Math.PI) / 180)
-        );
-        const f = k * (d.dot(new THREE.Vector2(x, z)) - c * time);
-        const a = w.steepness / k;
+        )
+        const f = k * (d.dot(new THREE.Vector2(x, z)) - c * time)
+        const a = w.steepness / k
 
-        pos.x += d.y * (a * Math.cos(f));
-        pos.y += a * Math.sin(f);
-        pos.z += d.x * (a * Math.cos(f));
+        pos.x += d.y * (a * Math.cos(f))
+        pos.y += a * Math.sin(f)
+        pos.z += d.x * (a * Math.cos(f))
 
-        tangent.x += - d.x * d.x * (w.steepness * Math.sin(f));
-        tangent.y += d.x * (w.steepness * Math.cos(f));
-        tangent.z += - d.x * d.y * (w.steepness * Math.sin(f));
+        tangent.x += - d.x * d.x * (w.steepness * Math.sin(f))
+        tangent.y += d.x * (w.steepness * Math.cos(f))
+        tangent.z += - d.x * d.y * (w.steepness * Math.sin(f))
 
-        binormal.x += - d.x * d.y * (w.steepness * Math.sin(f));
-        binormal.y += d.y * (w.steepness * Math.cos(f));
-        binormal.z += - d.y * d.y * (w.steepness * Math.sin(f));
+        binormal.x += - d.x * d.y * (w.steepness * Math.sin(f))
+        binormal.y += d.y * (w.steepness * Math.cos(f))
+        binormal.z += - d.y * d.y * (w.steepness * Math.sin(f))
     })
 
-    const normal = binormal.cross(tangent).normalize();
+    const normal = binormal.cross(tangent).normalize()
 
-    return { position: pos, normal: normal };
+    return { position: pos, normal: normal }
 
 }
 
 function updateRaft(delta) {
 
-    const t = ocean.material.uniforms['time'].value;
+    const t = ocean.material.uniforms['time'].value
 
-    const waveInfo = getWaveInfo(raft.position.x, raft.position.z, t);
-    raft.position.y = ocean.position.y + waveInfo.position.y;
+    const waveInfo = getWaveInfo(raft.position.x, raft.position.z, t)
+    raft.position.y = ocean.position.y + waveInfo.position.y
     const quat = new THREE.Quaternion().setFromEuler(
         new THREE.Euler().setFromVector3(waveInfo.normal)
-    );
-    raft.quaternion.rotateTowards(quat, delta * 0.5);
+    )
+    raft.quaternion.rotateTowards(quat, delta * 0.5)
 
 }
 
-window.addEventListener('resize', onWindowResize);
+window.addEventListener('resize', onWindowResize)
 
 function onWindowResize() {
 
-    camera.aspect = window.innerWidth / window.innerHeight;
-    camera.updateProjectionMatrix();
+    camera.aspect = window.innerWidth / window.innerHeight
+    camera.updateProjectionMatrix()
 
-    renderer.setSize(window.innerWidth, window.innerHeight);
+    renderer.setSize(window.innerWidth, window.innerHeight)
 
 }
 
 function animate() {
 
     const delta = Math.min(0.05, clock.getDelta())
-    const deltaTime = delta / STEPS_PER_FRAME;
+    const deltaTime = delta / STEPS_PER_FRAME
 
-    ocean.material.uniforms['time'].value += delta;
+    ocean.material.uniforms['time'].value += delta
 
-    updateRaft(delta);
+    updateRaft(delta)
 
     // we look for collisions in substeps to mitigate the risk of
     // an object traversing another too quickly for detection.
 
     for (let i = 0; i < STEPS_PER_FRAME; i++) {
 
-        controls(deltaTime);
+        controls(deltaTime)
 
-        updatePlayer(deltaTime);
+        updatePlayer(deltaTime)
 
     }
 
     if (camera.position.y > 3.5)
-        camera.lookAt(raft.position.x, raft.position.y, raft.position.z);
+        camera.lookAt(raft.position.x, raft.position.y, raft.position.z)
 
-    renderer.render(scene, camera);
+    renderer.render(scene, camera)
 
-    if (dev) stats.update();
+    if (dev) stats.update()
 
 }
\ No newline at end of file
diff --git a/style.css b/style.css
index cc8f170..61d1b80 100644
--- a/style.css
+++ b/style.css
@@ -1,9 +1,45 @@
 body {
   margin: 0;
-  background-color: #000;
-  color: #fff;
-  font-family: Georgia, serif;
+  background-color: #041626;
+  font-size: 1.3em;
   overscroll-behavior: none;
+  cursor: wait;
+}
+
+#loading {
+  width: fit-content;
+  color: #2c5c88;
+  font-size: 1.3em;
+  top: 20vh;
+  margin: auto;
+}
+
+#loadingMessage {
+  margin-bottom: 0.5em;
+}
+
+#labyTable {
+    width: 230px;
+    height: 230px;
+    margin-left: auto;
+    margin-right: auto;
+    margin-top: 20vh;
+    margin-bottom: 5vh;
+    border-collapse: collapse;
+}
+
+td {
+    width: 10px;
+    height: 10px;
+    transition: background-color 1s;
+}
+
+.wall {
+    background-color: transparent;
+}
+
+.ground {
+    background-color: #214464;
 }
 
 #container {
@@ -32,48 +68,7 @@ body {
   justify-content: center;
   z-index: 1;
   color: gray;
-}
-
-#message.loading {
-  display: flex;
-  flex-direction: column;
-  top: 20vh;
-  width: 100%;
-  margin: auto;
-  align-items: center;
-  gap: 5rem;
-  text-align: center;
-  font-size: 1.7em;
-  cursor: progress;
-}
-
-#progressCircle {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  position: relative;
-  width: 200px;
-  height: 200px;
-  border: 4px solid dimgray;
-  border-radius: 50%;
-  font-size: 0;
-  font-size: 3vh;
-  font-weight: 700;
-  font-family: system-ui;
-  text-align: center;
-}
-
-#progressCircle::after {
-  content: "";
-  display: flex;
-  position: absolute;
-  width: 200px;
-  height: 200px;
-  top: -4px;
-  left: -4px;
-  border: 4px solid #1da8b7;
-  border-radius: 50%;
-  mask: conic-gradient(black var(--progress), transparent var(--progress));
+  font-family: Times, "Times New Roman", Georgia, serif;
 }
 
 #message a {