diff --git a/Assets/Plugins/Native/BackroomsNoise/README.md b/Assets/Plugins/Native/BackroomsNoise/README.md
new file mode 100644
index 00000000..5383caab
--- /dev/null
+++ b/Assets/Plugins/Native/BackroomsNoise/README.md
@@ -0,0 +1,30 @@
+# BackroomsNoise C++ Plugin
+
+This native plugin provides high-performance noise generation for the Backrooms map system using **FastNoiseLite**.
+
+## Files
+- `BackroomsNoise.cpp`: C wrapper for Unity P/Invoke.
+- `FastNoiseLite.h`: The noise library (ensure you have the full version from [GitHub](https://github.com/Auburn/FastNoiseLite)).
+
+## How to Build (Windows MSVC)
+
+1. Open **Developer Command Prompt for VS**.
+2. Navigate to this directory.
+3. Run:
+ ```cmd
+ cl /LD /O2 /EHsc BackroomsNoise.cpp /Fe:BackroomsNoise.dll
+ ```
+4. Copy `BackroomsNoise.dll` to the `Assets/Plugins/` folder in Unity.
+
+## How to Build (Cross-platform with CMake)
+
+1. Create a `CMakeLists.txt`:
+ ```cmake
+ cmake_minimum_required(VERSION 3.10)
+ project(BackroomsNoise)
+ add_library(BackroomsNoise SHARED BackroomsNoise.cpp)
+ ```
+2. Build as usual.
+
+## Usage in Unity
+The `NativeNoiseProvider.cs` script will automatically attempt to load `BackroomsNoise.dll`. If it fails, it will fall back to Unity's built-in `Mathf.PerlinNoise`.
diff --git a/Assets/Plugins/Native/BackroomsNoise/README.md.meta b/Assets/Plugins/Native/BackroomsNoise/README.md.meta
new file mode 100644
index 00000000..76af727d
--- /dev/null
+++ b/Assets/Plugins/Native/BackroomsNoise/README.md.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: ebf9d2e10b290754b8cae46ebb44cbb0
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/GameSetup/Maze/MazeManager.cs b/Assets/Scripts/GameSetup/Maze/MazeManager.cs
index ef1741b4..d219925d 100644
--- a/Assets/Scripts/GameSetup/Maze/MazeManager.cs
+++ b/Assets/Scripts/GameSetup/Maze/MazeManager.cs
@@ -11,7 +11,7 @@ namespace Hallucinate.GameSetup.Maze
///
public class MazeManager : MonoBehaviour
{
- public enum AlgorithmType { Recursive, Wilsons, Prims, Crawler }
+ public enum AlgorithmType { Recursive, Wilsons, Prims, Crawler, NoiseRecursive }
[BoxGroup("Generation")]
[InfoBox("Set the array size to control how many maze floors are generated. Runtime grid data is rebuilt when Regenerate runs.")]
@@ -215,6 +215,7 @@ namespace Hallucinate.GameSetup.Maze
AlgorithmType.Wilsons => new WilsonsAlgorithm(),
AlgorithmType.Prims => new PrimsAlgorithm(),
AlgorithmType.Crawler => new CrawlerAlgorithm(),
+ AlgorithmType.NoiseRecursive => new NoiseRecursiveGenerator(),
_ => new RecursiveAlgorithm()
};
}
diff --git a/Assets/Scripts/GameSetup/Maze/NoiseRecursiveGenerator.cs b/Assets/Scripts/GameSetup/Maze/NoiseRecursiveGenerator.cs
new file mode 100644
index 00000000..3d48f3d0
--- /dev/null
+++ b/Assets/Scripts/GameSetup/Maze/NoiseRecursiveGenerator.cs
@@ -0,0 +1,152 @@
+using System.Collections;
+using System.Collections.Generic;
+using Hallucinate.GameSetup.Maze.Extensions;
+using Hallucinate.GameSetup.Maze.Native;
+using UnityEngine;
+
+namespace Hallucinate.GameSetup.Maze
+{
+ ///
+ /// Advanced generator that combines C++ Native Noise with a Recursive Backtracking algorithm.
+ /// Creates a hybrid layout of large rooms and chaotic corridors.
+ ///
+ public class NoiseRecursiveGenerator : IMazeAlgorithm
+ {
+ private readonly List _directions = MapLocation.Directions;
+ private float[] _noiseMap;
+ private int _seed = 1337;
+
+ // Thresholds
+ private const float RoomThreshold = 0.5f;
+ private const float CorridorThreshold = -0.3f;
+ private const int DeadEndNeighbourThreshold = 2;
+
+ public void Generate(MazeGrid grid)
+ {
+ InitializeNoise(grid);
+
+ // Step 1: Pre-place rooms based on noise peaks
+ for (int z = 0; z < grid.Depth; z++)
+ {
+ for (int x = 0; x < grid.Width; x++)
+ {
+ float noise = GetNoiseAt(x, z, grid.Width);
+ if (noise > RoomThreshold)
+ {
+ grid.SetCell(x, z, MazeCellType.Corridor);
+ }
+ }
+ }
+
+ // Step 2: Run recursive carving in the "connectable" zones
+ // We start from a few points to ensure coverage
+ for (int i = 0; i < 5; i++)
+ {
+ int startX = Random.Range(1, grid.Width - 1);
+ int startZ = Random.Range(1, grid.Depth - 1);
+ GenerateRecursive(grid, startX, startZ);
+ }
+ }
+
+ public IEnumerator GenerateStepByStep(MazeGrid grid, float interval)
+ {
+ InitializeNoise(grid);
+
+ // Visual feedback for noise pre-placement
+ for (int z = 0; z < grid.Depth; z++)
+ {
+ for (int x = 0; x < grid.Width; x++)
+ {
+ float noise = GetNoiseAt(x, z, grid.Width);
+ if (noise > RoomThreshold)
+ {
+ grid.SetCell(x, z, MazeCellType.Processing);
+ }
+ }
+ if (z % 5 == 0) yield return null;
+ }
+
+ for (int z = 0; z < grid.Depth; z++)
+ {
+ for (int x = 0; x < grid.Width; x++)
+ {
+ if (grid.GetCell(x, z) == MazeCellType.Processing)
+ grid.SetCell(x, z, MazeCellType.Corridor);
+ }
+ }
+
+ yield return GenerateRecursiveStepByStep(grid, 5, 5, interval);
+ }
+
+ private void InitializeNoise(MazeGrid grid)
+ {
+ _noiseMap = new float[grid.Width * grid.Depth];
+ using (var provider = new NativeNoiseProvider(_seed, 0.05f))
+ {
+ if (provider.IsInitialized)
+ {
+ provider.FillBuffer(0, 0, grid.Width, grid.Depth, _noiseMap);
+ }
+ else
+ {
+ // Fallback to Unity Perlin
+ for (int z = 0; z < grid.Depth; z++)
+ {
+ for (int x = 0; x < grid.Width; x++)
+ {
+ _noiseMap[z * grid.Width + x] = Mathf.PerlinNoise(x * 0.1f, z * 0.1f) * 2f - 1f;
+ }
+ }
+ }
+ }
+ }
+
+ private float GetNoiseAt(int x, int z, int width)
+ {
+ if (_noiseMap == null) return 0f;
+ return _noiseMap[z * width + x];
+ }
+
+ private void GenerateRecursive(MazeGrid grid, int x, int z)
+ {
+ // Boundary and Noise check
+ if (!grid.IsInBounds(x, z)) return;
+ if (GetNoiseAt(x, z, grid.Width) < CorridorThreshold) return;
+ if (grid.GetCell(x, z) == MazeCellType.Corridor) return;
+
+ if (grid.CountSquareNeighbours(x, z, MazeCellType.Corridor) >= DeadEndNeighbourThreshold) return;
+
+ grid.SetCell(x, z, MazeCellType.Corridor);
+
+ List shuffledDirs = new List(_directions);
+ shuffledDirs.Shuffle();
+
+ foreach (var dir in shuffledDirs)
+ {
+ GenerateRecursive(grid, x + dir.x, z + dir.z);
+ }
+ }
+
+ private IEnumerator GenerateRecursiveStepByStep(MazeGrid grid, int x, int z, float interval)
+ {
+ if (!grid.IsInBounds(x, z)) yield break;
+ if (GetNoiseAt(x, z, grid.Width) < CorridorThreshold) yield break;
+ if (grid.GetCell(x, z) == MazeCellType.Corridor) yield break;
+
+ if (grid.CountSquareNeighbours(x, z, MazeCellType.Corridor) >= DeadEndNeighbourThreshold) yield break;
+
+ grid.SetCell(x, z, MazeCellType.Processing);
+ if (interval > 0) yield return new WaitForSeconds(interval);
+
+ grid.SetCell(x, z, MazeCellType.Corridor);
+
+ List shuffledDirs = new List(_directions);
+ shuffledDirs.Shuffle();
+
+ foreach (var dir in shuffledDirs)
+ {
+ yield return GenerateRecursiveStepByStep(grid, x + dir.x, z + dir.z, interval);
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/GameSetup/Maze/NoiseRecursiveGenerator.cs.meta b/Assets/Scripts/GameSetup/Maze/NoiseRecursiveGenerator.cs.meta
new file mode 100644
index 00000000..8cb9a347
--- /dev/null
+++ b/Assets/Scripts/GameSetup/Maze/NoiseRecursiveGenerator.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 22e17049420e98f43a692fd3e7d7d261
\ No newline at end of file