refined Map Generation

This commit is contained in:
2ManyProjects 2025-03-04 13:22:53 -06:00
parent 8040d708e7
commit 0f74382fde
3 changed files with 61 additions and 19 deletions

View file

@ -13,8 +13,10 @@ enum RoomType {
var min_levels = 6 var min_levels = 6
var max_levels = 15 var max_levels = 15
var min_nodes_per_level = 2 var max_connections_per_node = 4
var max_nodes_per_level = 6
var min_nodes_per_level = 1
var max_nodes_per_level = 4
var positions_per_level = 6 var positions_per_level = 6
var starting_elo = 1000 var starting_elo = 1000
var final_elo = 2100 var final_elo = 2100
@ -62,7 +64,8 @@ func generate_map():
for level in range(1, num_levels - 1): for level in range(1, num_levels - 1):
var level_nodes = [] var level_nodes = []
var level_elo = starting_elo + (elo_step * level) var level_elo = starting_elo + (elo_step * level)
var num_nodes = _rng.randi_range(min_nodes_per_level, max_nodes_per_level) # Change this so that its more weighted towards the lower end with rare occurances of max_nodes_per_level rather than an even split
var num_nodes = get_weighted_node_count(min_nodes_per_level, max_nodes_per_level)
var available_positions = [] var available_positions = []
for pos in range(positions_per_level): for pos in range(positions_per_level):
available_positions.append(pos) available_positions.append(pos)
@ -114,9 +117,9 @@ func generate_map():
# Connect to 1-2 nodes in next level if not the final level # Connect to 1-2 nodes in next level if not the final level
if level < num_levels - 2: if level < num_levels - 2:
var num_next_connections = _rng.randi_range(1, 2) var num_next_connections = _rng.randi_range(1, max_connections_per_node)
num_next_connections = min(num_next_connections, next_level_nodes.size()) num_next_connections = min(num_next_connections, next_level_nodes.size())
var shouldTrim = _rng.randi_range(1, 15) > 3 || num_next_connections > 3
for i in range(num_next_connections): for i in range(num_next_connections):
if i < next_level_nodes.size(): if i < next_level_nodes.size():
connections.append({ connections.append({
@ -124,10 +127,13 @@ func generate_map():
"to": next_level_nodes[i].id "to": next_level_nodes[i].id
}) })
# Remove the selected nodes so they aren't picked again # # Remove the selected nodes so they aren't picked again
for i in range(num_next_connections): # if lots of ocnnection earlier and deeper than lvl 3
if next_level_nodes.size() > 0: # if num_next_connections >= 2 && level > 3:
next_level_nodes.pop_front() if shouldTrim:
for i in range(num_next_connections):
if next_level_nodes.size() > 0:
next_level_nodes.pop_front()
# Connect to final boss if at the level before # Connect to final boss if at the level before
elif level == num_levels - 2: elif level == num_levels - 2:
@ -192,3 +198,22 @@ func _get_next_id():
var id = _next_id var id = _next_id
_next_id += 1 _next_id += 1
return id return id
func get_weighted_node_count(min_count, max_count):
# Use exponential distribution to weight toward lower values
var range_size = max_count - min_count + 1
var rand_val = _rng.randf()
# Apply exponential weighting (higher exponent = more weight toward minimum)
var weight_exponent = 2 # Adjust this to control the curve
var weighted_val = pow(rand_val, weight_exponent)
var node_count = min_count + floor(weighted_val * range_size)
if rand_val > 0.70:
node_count = max_count
return node_count

View file

@ -24,6 +24,8 @@ const LINE_COLOR = Color(0.2, 0.2, 0.2)
const LINE_COLOR_SELECTED = Color(0.2, 0.6, 0.2) const LINE_COLOR_SELECTED = Color(0.2, 0.6, 0.2)
const LINE_COLOR_ACCESSIBLE = Color(0.6, 0.6, 0.2) const LINE_COLOR_ACCESSIBLE = Color(0.6, 0.6, 0.2)
const NODE_COLOR = Color(0.1, 0.1, 0.1, 0.5)
const NODE_LEAF = Color(0.2, 0.6, 0.2)
# Node symbols and colors # Node symbols and colors
const NODE_SYMBOLS = { const NODE_SYMBOLS = {
RoomType.STARTING: "O", # Circle RoomType.STARTING: "O", # Circle
@ -69,11 +71,7 @@ func _ready():
# Create legend # Create legend
create_legend() create_legend()
# Generate default map
generate_map() generate_map()
# Display the map
display_map() display_map()
func create_legend(): func create_legend():
@ -82,7 +80,10 @@ func create_legend():
{"type": RoomType.BOSS, "text": "Boss"}, {"type": RoomType.BOSS, "text": "Boss"},
{"type": RoomType.STARTING, "text": "Starting Room"}, {"type": RoomType.STARTING, "text": "Starting Room"},
{"type": RoomType.FINAL, "text": "Final Boss"}, {"type": RoomType.FINAL, "text": "Final Boss"},
{"type": RoomType.NORMAL, "text": "Normal Room"} {"type": RoomType.NORMAL, "text": "Normal Room"},
{"type": RoomType.SHOP, "text": "Shop"},
{"type": RoomType.EVENT, "text": "Event"},
{"type": RoomType.NORMAL, "text": "Escape Room"}
] ]
for item in legend_items: for item in legend_items:
@ -91,7 +92,10 @@ func create_legend():
var symbol = Label.new() var symbol = Label.new()
symbol.text = NODE_SYMBOLS[item.type] symbol.text = NODE_SYMBOLS[item.type]
symbol.add_theme_color_override("font_color", NODE_COLORS[item.type]) if item.text != "Escape Room":
symbol.add_theme_color_override("font_color", NODE_COLORS[item.type])
else:
symbol.add_theme_color_override("font_color", NODE_LEAF)
symbol.add_theme_font_size_override("font_size", 24) symbol.add_theme_font_size_override("font_size", 24)
var text = Label.new() var text = Label.new()
@ -106,7 +110,6 @@ func generate_map():
map_nodes.clear() map_nodes.clear()
map_connections.clear() map_connections.clear()
var mapGen = MapGenerator.new().generate_map() var mapGen = MapGenerator.new().generate_map()
print("MapGen ", mapGen)
# Create starting node # Create starting node
# var start_node = { # var start_node = {
# "id": 0, # "id": 0,
@ -228,6 +231,14 @@ func get_node_by_id(id):
return null return null
func draw_node(node_data): func draw_node(node_data):
var isLeaf = true;
for connection in map_connections:
# if theres outgoing connection we arent at a dead end
# dont change final node colour
if connection.from == node_data.id || node_data.id == 1:
isLeaf = false
break;
var button = Button.new() var button = Button.new()
button.text = NODE_SYMBOLS[node_data.type] button.text = NODE_SYMBOLS[node_data.type]
button.custom_minimum_size = NODE_SIZE button.custom_minimum_size = NODE_SIZE
@ -236,7 +247,7 @@ func draw_node(node_data):
# Add some styling # Add some styling
var font = FontFile.new() var font = FontFile.new()
var style = StyleBoxFlat.new() var style = StyleBoxFlat.new()
style.bg_color = Color(0.1, 0.1, 0.1, 0.5) style.bg_color = NODE_COLOR
style.corner_radius_top_left = 30 style.corner_radius_top_left = 30
style.corner_radius_top_right = 30 style.corner_radius_top_right = 30
style.corner_radius_bottom_left = 30 style.corner_radius_bottom_left = 30
@ -245,10 +256,17 @@ func draw_node(node_data):
style.border_width_top = 2 style.border_width_top = 2
style.border_width_right = 2 style.border_width_right = 2
style.border_width_bottom = 2 style.border_width_bottom = 2
if isLeaf:
style.bg_color = NODE_LEAF
style.border_color = NODE_COLORS[node_data.type] style.border_color = NODE_COLORS[node_data.type]
button.add_theme_font_size_override("font_size", 28) button.add_theme_font_size_override("font_size", 28)
button.add_theme_color_override("font_color", NODE_COLORS[node_data.type]) if isLeaf:
button.add_theme_color_override("font_color", NODE_LEAF)
# style.bg_color = NODE_LEAF
else:
button.add_theme_color_override("font_color", NODE_COLORS[node_data.type])
button.add_theme_stylebox_override("normal", style) button.add_theme_stylebox_override("normal", style)
# Position the node with top and left padding adjustments # Position the node with top and left padding adjustments

View file

@ -63,7 +63,6 @@ custom_minimum_size = Vector2(800, 600)
layout_mode = 2 layout_mode = 2
[node name="LegendContainer" type="VBoxContainer" parent="."] [node name="LegendContainer" type="VBoxContainer" parent="."]
visible = false
layout_mode = 1 layout_mode = 1
anchors_preset = 1 anchors_preset = 1
anchor_left = 1.0 anchor_left = 1.0