removed an unnessessary genreate button

This commit is contained in:
grimsace
2026-03-06 09:40:22 -06:00
parent 8a417870b2
commit 83695f5d1d
5 changed files with 65 additions and 29 deletions
+5 -2
View File
@@ -1,6 +1,6 @@
# Desktop Dungeon Generator
A Rust + `egui` desktop app for generating simple tabletop dungeon layouts on a scalable grid.
A Rust desktop app for generating simple tabletop dungeon layouts.
## Current Features
@@ -19,13 +19,16 @@ A Rust + `egui` desktop app for generating simple tabletop dungeon layouts on a
- `Corridor Randomness (%)` from `0` to `100`
- `Dead-End Rooms (%)` from `0` to `50`
- Generate control:
- `Generate New Layout` button increments seed and creates a new layout
- Master seed input (`u64`)
- `Random` seed button
- `Generate New Layout` button generates using the current seed
## Generation Behavior
- Rooms are stored as rectangles (`x`, `y`, `width`, `height`) and placed without overlap.
- Corridors are stored separately as vector line segments between grid cells.
- Every generated room is connected into one navigable network when possible.
- A master seed drives deterministic generation, and internal subsystems derive their own sub-seeds from it.
### Corridor Randomness
+19 -8
View File
@@ -1,3 +1,4 @@
use crate::seed;
use std::collections::{HashSet, VecDeque};
#[derive(Debug, Clone)]
@@ -37,7 +38,17 @@ pub fn generate_layout(
corridor_randomness_percent: usize,
dead_end_room_percent: usize,
) -> DungeonLayout {
let mut rng = SimpleRng::new(seed ^ ((cols as u64) << 32) ^ rows as u64);
let layout_salt = ((cols as u64) << 48)
^ ((rows as u64) << 32)
^ ((target_room_count as u64) << 16)
^ (min_room_size as u64)
^ ((max_room_size as u64) << 8)
^ ((corridor_randomness_percent as u64) << 56)
^ ((dead_end_room_percent as u64) << 40);
let base_seed = seed::derive_seed(seed, layout_salt);
let mut room_rng = SimpleRng::new(seed::derive_seed(base_seed, 1));
let mut graph_rng = SimpleRng::new(seed::derive_seed(base_seed, 2));
let mut path_rng = SimpleRng::new(seed::derive_seed(base_seed, 3));
let mut rooms = Vec::new();
let mut corridors = Vec::new();
@@ -69,7 +80,7 @@ pub fn generate_layout(
}
let (width, height) = if square_rooms_only {
let side = rng.range_inclusive(min_size, max_size.min(cols.min(rows)));
let side = room_rng.range_inclusive(min_size, max_size.min(cols.min(rows)));
(side, side)
} else {
let width_max = max_size.min(cols);
@@ -78,8 +89,8 @@ pub fn generate_layout(
continue;
}
(
rng.range_inclusive(min_size, width_max),
rng.range_inclusive(min_size, height_max),
room_rng.range_inclusive(min_size, width_max),
room_rng.range_inclusive(min_size, height_max),
)
};
@@ -87,8 +98,8 @@ pub fn generate_layout(
continue;
}
let x = rng.range_inclusive(0, cols - width);
let y = rng.range_inclusive(0, rows - height);
let x = room_rng.range_inclusive(0, cols - width);
let y = room_rng.range_inclusive(0, rows - height);
let candidate = Room {
x,
y,
@@ -112,7 +123,7 @@ pub fn generate_layout(
let centers: Vec<(usize, usize)> = rooms.iter().map(Room::center_cell).collect();
let target_dead_end_rooms = ((rooms.len() * dead_end_room_percent.min(50)) + 50) / 100;
let room_edges =
build_room_connection_edges(&centers, randomness, target_dead_end_rooms, &mut rng);
build_room_connection_edges(&centers, randomness, target_dead_end_rooms, &mut graph_rng);
let mut occupied_corridor_cells = HashSet::new();
for (a_idx, b_idx) in room_edges {
@@ -122,7 +133,7 @@ pub fn generate_layout(
let preferred = if randomness <= 0.001 {
shortest_path(a, b, cols, rows).unwrap_or_else(|| vec![a, b])
} else {
noisy_path(a, b, cols, rows, randomness, &mut rng)
noisy_path(a, b, cols, rows, randomness, &mut path_rng)
};
if !try_place_cell_path(
+4 -14
View File
@@ -1,4 +1,5 @@
mod layout;
mod seed;
mod ui;
use std::collections::HashSet;
@@ -20,19 +21,17 @@ fn main() -> eframe::Result<()> {
struct DungeonApp {
settings: UiSettings,
seed: u64,
layout: DungeonLayout,
}
impl Default for DungeonApp {
fn default() -> Self {
let settings = UiSettings::default();
let seed = 1;
let layout = generate_layout(
settings.cols,
settings.rows,
settings.room_count,
seed,
settings.seed,
settings.min_room_size,
settings.max_room_size,
settings.square_rooms_only,
@@ -40,11 +39,7 @@ impl Default for DungeonApp {
settings.dead_end_rooms_percent,
);
Self {
settings,
seed,
layout,
}
Self { settings, layout }
}
}
@@ -56,11 +51,6 @@ impl eframe::App for DungeonApp {
self.settings.max_room_size = self.settings.min_room_size;
}
if panel_result.generate_clicked {
self.seed = self.seed.wrapping_add(1);
self.regenerate_layout();
}
if panel_result.settings_changed {
self.regenerate_layout();
}
@@ -81,7 +71,7 @@ impl DungeonApp {
self.settings.cols,
self.settings.rows,
self.settings.room_count,
self.seed,
self.settings.seed,
self.settings.min_room_size,
self.settings.max_room_size,
self.settings.square_rooms_only,
+21
View File
@@ -0,0 +1,21 @@
use std::time::{SystemTime, UNIX_EPOCH};
pub fn random_seed() -> u64 {
let nanos = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_nanos() as u64)
.unwrap_or(0);
let pid = std::process::id() as u64;
mix64(nanos ^ pid.rotate_left(17))
}
pub fn derive_seed(master_seed: u64, stream_id: u64) -> u64 {
mix64(master_seed ^ stream_id.wrapping_mul(0x9E37_79B9_7F4A_7C15))
}
fn mix64(mut x: u64) -> u64 {
x = x.wrapping_add(0x9E37_79B9_7F4A_7C15);
x = (x ^ (x >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9);
x = (x ^ (x >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB);
x ^ (x >> 31)
}
+15 -4
View File
@@ -1,3 +1,4 @@
use crate::seed;
use eframe::egui;
use egui::RichText;
@@ -9,6 +10,7 @@ enum Tab {
#[derive(Debug, Clone)]
pub struct UiSettings {
pub seed: u64,
pub cols: usize,
pub rows: usize,
pub room_count: usize,
@@ -23,6 +25,7 @@ pub struct UiSettings {
impl Default for UiSettings {
fn default() -> Self {
Self {
seed: 1,
cols: 24,
rows: 18,
room_count: 8,
@@ -39,7 +42,6 @@ impl Default for UiSettings {
#[derive(Debug, Clone, Copy, Default)]
pub struct SidePanelResult {
pub settings_changed: bool,
pub generate_clicked: bool,
}
pub fn draw_side_panel(ctx: &egui::Context, settings: &mut UiSettings) -> SidePanelResult {
@@ -107,12 +109,21 @@ fn draw_generate_tab(ui: &mut egui::Ui, settings: &mut UiSettings, result: &mut
});
ui.add_space(12.0);
ui.label(RichText::new("Generation").strong());
ui.separator();
ui.add_space(8.0);
ui.label(RichText::new("Seed Settings").strong());
ui.add_space(8.0);
if ui.button("Generate New Layout").clicked() {
result.generate_clicked = true;
ui.label("Master Seed");
ui.horizontal(|ui| {
result.settings_changed |= ui
.add(egui::DragValue::new(&mut settings.seed).speed(1.0))
.changed();
if ui.button("Random").clicked() {
settings.seed = seed::random_seed();
result.settings_changed = true;
}
});
}
fn draw_layout_tab(ui: &mut egui::Ui, settings: &mut UiSettings, result: &mut SidePanelResult) {