Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Random Map Maker (Beta)

Random Map Maker
Version 0.2.2 - December 12th, 2008

Introduction
This script makes a random map given certain specifications (much like in rmvx, the difference being the type of map produced here). Please do not be expecting magic from it right now. I only started it last night and spent most of the time recording possible autotile ids (and coming up with a algorithm for passability that i scrapped because it took too long and was ineffective).

Please post suggestions or additions I can make. I hope by now everyone knows I love customization so if you have any ideas on improvement, please do share. I already have tons of plans to develop this further, but within my entire experience with RPG Maker in over 3 years, I have made maybe 20 maps, of which were horrible quality. So you mappers, help me out.

As of now, just copy and paste the script in a project. Do not put this in your project as this over-writes Map001.rxdata once the game is run. When you press new game you will be standing on a random map. The tileset is choosen at random of the 50 in the game. Floors and walls can be further modified under module Map_Maze_Maker, where you create a list of tile ids for the floor or wall.

I know some maps generated are rather horrible so just press F12. You'll get a new map in under a second.

Code:
#==============================================================================
# ** Map Maze Maker
#------------------------------------------------------------------------------
#  SephirothSpawn
#  Version 0.2.2 (BETA)
#  2008-12-13
#------------------------------------------------------------------------------
# * As of now this script is just in it's beta form. It produces random
#   "maze like" maps given map size, enterance points, etc.
#
# * Our first step is to setup our map
#   - Map_Maze_Maker.generate_map(tileset_id, width, height, enc, floor)
#
#	 tileset_id = tileset_id from database
#	 width	  = map width (defaults to 20)
#	 height	 = map height (defaults to 15)
#	 enc		= encounter list [troop_id, ...] (defaults to [])
#	 fllor	  = floor tile_id (defaults to random tile for tileset)
#
# * Our next step is to create random pathways to our target point
#   - Map_Maze_Maker.generate_passability_table(points, target)
#
#	 points = enterance points to map [[x, y]... ] (defaults to random)
#	 target = target path end point [x, y] (defaults to random)
#
# * Our next step is to setup our walls
#   - Map_Maze_Maker.generate_data(wall)
#
#	 wall = impassable autotile id (defaults to random for tileset)
#
# * Our final step is to finalize our data
#   - Map_Maze_Maker.finalize_map
#
#
# ** Optional steps (after generate_passability_table):
#
# * Creating room around target room
#   - Map_Maze_Maker.generate_target_room(width, height)
#
#	 width  = width of room (defaults to random)
#	 height = height of room (defaults to random)
#
# * Creating a specified room
#   - Map_Maze_Maker.generate_room(x, y, width, height)
#
#	 x, y   = top left location of room
#	 width  = width of room
#	 height = height of room
#------------------------------------------------------------------------------
# * Version History
#
# Version 0.1 ---------------------------------------------------- (2008-12-12)
# Version 0.1.1 -------------------------------------------------- (2008-12-12)
#  - Fix: Path going off map
# Version 0.1.2 -------------------------------------------------- (2008-12-13)
#  - Update: Configured floors and walls default tilesets
#			Changed so "walls" may be drawn on different layers
# Version 0.2 ---------------------------------------------------- (2008-12-13)
#  - Update: Updated format layout (seperated methods)
#			Added room creation
# Version 0.2.1 -------------------------------------------------- (2008-12-13)
#  - Fix: Fixed ID & Cant_Include constants
# Version 0.2.2 -------------------------------------------------- (2008-12-13)
#  - Update: Added fllor decorations
#==============================================================================

#==============================================================================
# ** Map Maze Maker - Configuration
#==============================================================================

module Map_Maze_Maker
  #--------------------------------------------------------------------------
  # * Map Floors = {tileset_id => [floor_id, ...], ...}
  #--------------------------------------------------------------------------
  Floors = {}
  Floors[3] = (384..388).to_a
  Floors[5] = [385]
  Floors[6] = [385,386]
  Floors[9] = (384..385).to_a
  Floors[18] = (384..389).to_a
  Floors[20] = (384..388).to_a
  Floors[22] = (384..389).to_a
  Floors[24] = (384..386).to_a
  Floors[26] = (384..387).to_a
  Floors[27] = (384..387).to_a
  Floors[27] = (384..385).to_a
  Floors[29] = (384..388).to_a
  Floors[30] = (384..387).to_a
  Floors[31] = (384..386).to_a
  Floors[32] = (384..385).to_a
  Floors[33] = (384..386).to_a
  Floors[36] = (384..389).to_a
  Floors[38] = (384..389).to_a
  Floors[40] = (384..388).to_a
  Floors[41] = (384..385).to_a
  Floors[42] = (384..386).to_a
  Floors[47] = (384..385).to_a
  Floors[48] = (384..387).to_a
  Floors[49] = (384..385).to_a
  Floors[50] = (384..385).to_a
  Floors.default = [384]
  #--------------------------------------------------------------------------
  # * Floor Decorations = {tileset_id => [tile_id, ...], ...}
  #--------------------------------------------------------------------------
  Floor_Decoration_Probability = 10
  Floor_Decorations = {}
  Floor_Decorations[1] = [385, 386, 387, 389, 393, 394, 395, 397, 398, 403, 
						  404]
  Floor_Decorations[2] = [385, 386, 387, 389, 393, 394, 395, 397, 398, 402, 
						  403, 404]
  Floor_Decorations.default = []
  #--------------------------------------------------------------------------
  # * Map Walls = {tileset_id => [wall_id, ...], ...}
  #--------------------------------------------------------------------------
  Walls = {}
  Walls[1] = [[48,0],[336,0]]
  Walls[5] = [[96,0]]
  Walls[7] = [[240,0]]
  Walls[11] = [[336,0]]
  for i in [2,3,4,6,8,13,15,19,21,23,34,35,37,39,43,44,45,46]
	Walls[i] = [[48,0]]
  end
  Walls.default = [[48,1]]
  #--------------------------------------------------------------------------
  # * Inspection Tools
  #
  #   Create passability table file:  Inspect_Passability
  #   Print tile to complete:		 Inspect_Time
  #--------------------------------------------------------------------------
  Inspect_Passability = false
  Inspect_Time		= true
end

#==============================================================================
# ** Map Maze Maker - Developer Methods
#==============================================================================

module Map_Maze_Maker
  #--------------------------------------------------------------------------
  # * Generate Map
  #--------------------------------------------------------------------------
  def self.generate_map(tileset_id, width = 20, height = 15, enc = [], 
	  floor = nil)
	# Save start time  
	@start_time = Time.new
	# Floor and Wall ID
	if floor == nil
	  floors = Floors[tileset_id]
	  floor = floors[rand(floors.size)]
	end
	# Error fixer
	width = 20 if width < 20; height = 15 if height < 15
	# Create RPG::Map
	@map = RPG::Map.new(width, height)
	@map.tileset_id = tileset_id
	@map.encounter_list = enc
	@map.data = Table.new(width, height, 3)
	# Set floor
	for x in 0...width
	  for y in 0...height
		@map.data[x, y, 0] = floor
	  end
	end
  end
  #--------------------------------------------------------------------------
  # * Generate Passability Table
  #--------------------------------------------------------------------------
  def self.generate_passability_table(enterance_points = [], target = nil)
	# Create passability table
	@passability_table = Table.new(@map.width, @map.height)
	# If enterance points empty
	if enterance_points.empty?
	  # Creates sides list
	  sides  = [1, 2, 3, 4]
	  # Pick number of enterance points 2-4
	  points = [2, 3, 4][rand(3)]
	  # For each enterance point
	  points.times do
		# Pick random side
		side = sides[rand(sides.size)]
		# Delete side from list
		sides.delete(side)
		# Gets width & height
		w, h = @map.width, @map.height
		# Branch by side
		case side
		when 1 # Left
		  x = 0; y = rand(h - 1)
		when 2 # Right
		  x = w - 1; y = rand(h - 1)
		when 3 # Bottom
		  x = rand(w - 1); y = h - 1
		when 4 # Top
		  x = rand(w - 1); y = 0
		end
		# Adds random enterance point
		enterance_points << [x, y]
	  end
	end
	# Modify enterance points
	@points = enterance_points
	# If random target
	if target == nil
	  # Gets half
	  w, h = @map.width / 2, @map.height / 2
	  # Gets fouth
	  hw, hh = w / 2, h / 2
	  # Gets random x & y
	  @pt_tx, @pt_ty = rand(w) + hw, rand(h) + hh
	# If set target point
	else
	  @pt_tx, @pt_ty = *target
	end
	# Set target point
	@passability_table[@pt_tx, @pt_ty] = 1
	# Until @points is empty
	until @points.empty?
	  # Pass through each point
	  @points.each do |xy|
		# Set point
		self.gpt_set_point(xy)
	  end
	end
  end
  #--------------------------------------------------------------------------
  # * Generate Room around target
  #--------------------------------------------------------------------------
  def self.generate_target_room(w = nil, h = nil)
	# Random width/height
	if w == nil
	  h = @map.width / (@map.width / 4)
	  w = h + rand(h)
	end
	if h == nil
	  h = @map.height / (@map.width / 4)
	  h = h + rand(h)
	end
	# Random offset off target center
	rx = @pt_tx - rand(w / 2)
	ry = @pt_ty - rand(h / 2)
	# Set random room
	for x in rx..(rx + w)
	  for y in ry..(ry + h)
		@passability_table[x, y] = 1
	  end
	end
  end
  #--------------------------------------------------------------------------
  # * Generate Room
  #--------------------------------------------------------------------------
  def self.generate_room(x, y, w, h)
	for i in x..(x + w)
	  for j in y..(y + h)
		@passability_table[i, j] = 1
	  end
	end
  end
  #--------------------------------------------------------------------------
  # * Generate Data
  #--------------------------------------------------------------------------
  def self.generate_data(wall = nil)
	# Random wall
	if wall == nil
	  walls = Walls[@map.tileset_id]
	  wall = walls[rand(walls.size)]
	end
	# Gets tile_id & layer
	tile_id, layer = *wall
	# Get floor decorations
	decorations = Floor_Decorations[@map.tileset_id]
	# Pass through passability table
	for x in 0...@map.width
	  for y in 0...@map.height
		# If path tile
		if @passability_table[x, y] != 0
		  # If decorations exist
		  unless decorations.empty?
			# If randomly place floor decoration
			if rand(100) < Floor_Decoration_Probability
			  # Set floor decoration
			  @map.data[x, y, 1] = decorations[rand(decorations.size)]
			end
		  end
		  next
		end
		# Start list
		list = []
		n = @passability_table[x - 1, y + 1]
		list << 1 if n != 0 #|| n == nil
		n = @passability_table[x, y + 1]
		list << 2 if n != 0 #|| n == nil
		n = @passability_table[x + 1, y + 1]
		list << 3 if n != 0 #|| n == nil
		n = @passability_table[x - 1, y]
		list << 4 if n != 0 #|| n == nil
		n = @passability_table[x + 1, y]
		list << 6 if n != 0 #|| n == nil
		n = @passability_table[x - 1, y - 1]
		list << 7 if n != 0 #|| n == nil
		n = @passability_table[x, y - 1]
		list << 8 if n != 0 #|| n == nil
		n = @passability_table[x + 1, y - 1]
		list << 9 if n != 0 #|| n == nil
		# Set Data ID
		@map.data[x, y, layer] = tile_id + Autotile_ID_Generator.get_id(list)
	  end
	end
  end
  #--------------------------------------------------------------------------
  # * Finalize Map
  #--------------------------------------------------------------------------
  def self.finalize_map(map_id = 1, name = '')
	# Saves Map Data - Beta Feature
	save_data(@map, "Data/Map001.rxdata")
	# Make Passability Table File
	self.inspect_passability_table if Inspect_Passability
	# Print Time to Make
	p 'Complete', Time.new - @start_time if Inspect_Time
  end
  #--------------------------------------------------------------------------
  # * Inspect Passability Table
  #--------------------------------------------------------------------------
  def self.inspect_passability_table
	# Open 'Maze Maker Inspection.txt' File and write table
	File.open('Maze Maker Inspection.txt',"a+") do |f|
	  for y in 0...@map.height
		for x in 0...@map.width
		  f.write("#{@passability_table[x, y]}")
		end
		f.write("\n")
	  end
	  f.write("\n")
	end
  end
end

#==============================================================================
# ** Map Maze Maker - Private Methods
#==============================================================================

module Map_Maze_Maker
  #--------------------------------------------------------------------------
  # * Generate Passability Table: Set Point
  #--------------------------------------------------------------------------
  private
  def self.gpt_set_point(xy)
	# Delete from points
	@points.delete(xy)
	# Get x, y
	x, y = *xy
	# Set point
	@passability_table[x, y] = 1
	# Return if at target
	return if x == @pt_tx && @pt_ty == y
	# Directions
	directions = []
	directions << 2 if @pt_ty > y
	directions << 4 if @pt_tx < x
	directions << 6 if @pt_tx > x
	directions << 8 if @pt_ty < y
	# Gets distances
	dx = (@pt_tx - x).abs
	dy = (@pt_ty - @pt_ty).abs
	# Random direction addon
	if dx > dy && dx > rand(5) + 5
	  directions << (@pt_ty < y ? 2 : 8)
	elsif dy > dx && dy > rand(5) + 5
	  directions << (@pt_tx > x ? 4 : 6)
	end
	# Remove movements that go off map
	directions.delete(4) if x == 0
	directions.delete(6) if x == @map.width - 1
	directions.delete(2) if y == @map.height - 1
	directions.delete(8) if y == 0
	# Pick random directions
	d = directions[rand(directions.size)]
	# Get next point
	nx = x + (d == 4 ? -1 : d == 6 ? 1 : 0)
	ny = y + (d == 8 ? -1 : d == 2 ? 1 : 0)
	# Add to points
	@points << [nx, ny]
  end
end

#==============================================================================
# ** Autotile ID Generator
#------------------------------------------------------------------------------
#  Checking for tile z at the position x, y, with that position being an
#  autotile, pass a list of the 8 surround tiles that are also autotiles.
#
#  Autotile_ID_Generator.get_id([pos, ...])
#
#  where pos = 1:lower-left, 2:down, 3:lower-right, 4:left, 6:right,
#			  7:upper-left, 8:up, 9:upper-right
#
#  Examples: O = Autotile, X = Non-Tile, S = Autotile finding ID for
#
#  00X
#  0SX	  Autotile_ID_Generator.get_id([3,4,7,8])
#  XX0
#
#  X00
#  0S0	  Autotile_ID_Generator.get_id([2,4,5,8,9])
#  X0X
#==============================================================================

class Autotile_ID_Generator
  #--------------------------------------------------------------------------
  # * Constant Setup - DO NOT MODIFY
  #--------------------------------------------------------------------------
  ID					= {}
  Cant_Include		  = {}
  ID[[7]]			   = 1
  Cant_Include[1]	   = [1,2,3,4,6,8,9]
  ID[[9]]			   = 2
  Cant_Include[2]	   = [1,2,3,4,6,7,8]
  ID[[7,9]]			 = 3
  Cant_Include[3]	   = [1,2,3,4,6,8]
  ID[[3]]			   = 4
  Cant_Include[4]	   = [1,2,4,6,7,8,9]
  ID[[3,7]]			 = 5
  Cant_Include[5]	   = [1,2,4,6,8,9]
  ID[[3,9]]			 = 6
  Cant_Include[6]	   = [1,2,4,6,7,8]
  ID[[3,7,9]]		   = 7
  Cant_Include[7]	   = [1,2,4,6,8]
  ID[[1]]			   = 8
  Cant_Include[8]	   = [2,3,4,6,7,8,9]
  ID[[1,7]]			 = 9
  Cant_Include[9]	   = [2,3,4,6,8,9]
  ID[[1,9]]			 = 10
  Cant_Include[10]	  = [2,3,4,6,7,8]
  ID[[1,7,9]]		   = 11
  Cant_Include[11]	  = [2,3,4,6,8]
  ID[[1,3]]			 = 12
  Cant_Include[12]	  = [2,4,6,7,8,9]
  ID[[1,3,7]]		   = 13
  Cant_Include[13]	  = [2,4,6,8,9]
  ID[[1,3,9]]		   = 14
  Cant_Include[14]	  = [2,4,6,7,8]
  ID[[1,3,7,9]]		 = 15
  Cant_Include[15]	  = [2,4,6,8]
  ID[[4]]			   = 16
  Cant_Include[16]	  = [2,3,6,8,9]
  ID[[4,9]]			 = 17
  Cant_Include[17]	  = [2,3,6,8]
  ID[[3,4]]			 = 18
  Cant_Include[18]	  = [2,6,8,9]
  ID[[3,4,9]]		   = 19
  Cant_Include[19]	  = [2,6,8]
  ID[[8]]			   = 20
  Cant_Include[20]	  = [1,2,3,4,6]
  ID[[3,8]]			 = 21
  Cant_Include[21]	  = [1,2,4,6]
  ID[[1,8]]			 = 22
  Cant_Include[22]	  = [2,3,4,6]
  ID[[1,3,8]]		   = 23
  Cant_Include[23]	  = [2,4,6]
  ID[[6]]			   = 24
  Cant_Include[24]	  = [1,2,4,7,8]
  ID[[1,6]]			 = 25
  Cant_Include[25]	  = [2,4,7,8]
  ID[[6,7]]			 = 26
  Cant_Include[26]	  = [1,2,4,8]
  ID[[1,3,6,7,9]]	   = 27
  Cant_Include[27]	  = [2,4,8]
  ID[[2]]			   = 28
  Cant_Include[28]	  = [4,6,7,8,9]
  ID[[2,7]]			 = 29
  Cant_Include[29]	  = [4,6,8,9]
  ID[[2,9]]			 = 30
  Cant_Include[30]	  = [4,6,7,8]
  ID[[2,7,9]]		   = 31
  Cant_Include[31]	  = [4,6,8]
  ID[[4,6]]			 = 32
  Cant_Include[32]	  = [2,8]
  ID[[2,8]]			 = 33
  Cant_Include[33]	  = [4,6]
  ID[[4,8]]			 = 34
  Cant_Include[34]	  = [2,3,6]
  ID[[3,4,8]]		   = 35
  Cant_Include[35]	  = [2,6]
  ID[[6,8]]			 = 36
  Cant_Include[36]	  = [1,2,4]
  ID[[1,6,8]]		   = 37
  Cant_Include[37]	  = [2,4]
  ID[[2,6]]			 = 38
  Cant_Include[38]	  = [4,7,8]
  ID[[2,6,7]]		   = 39
  Cant_Include[39]	  = [4,8]
  ID[[2,4]]			 = 40
  Cant_Include[40]	  = [6,8,9]
  ID[[2,4,9]]		   = 41
  Cant_Include[41]	  = [6,8]
  ID[[4,6,8]]		   = 42
  Cant_Include[42]	  = [2]
  ID[[2,4,8]]		   = 43
  Cant_Include[43]	  = [6]
  ID[[2,4,6]]		   = 44
  Cant_Include[44]	  = [8]
  ID[[2,6,8]]		   = 45
  Cant_Include[45]	  = [4]
  ID[[2,4,6,8]]		 = 46
  #--------------------------------------------------------------------------
  # * Get ID
  #--------------------------------------------------------------------------
  def self.get_id(list)
	# If empty list
	return 0 if list.empty?
	# Pass through all list
	ID.keys.each do |l|
	  # If list includes all of searching list
	  if list.includes_all?(*l)
		# If can't include certain numbers
		if Cant_Include.has_key?(ID[l])
		  # Skip if searching list includes a non-includable number
		  next if Cant_Include[ID[l]].includes_any?(*list)
		end
		return ID[l]
	  end
	end
	# Error catcher
	p 'Please report this list so that I may fix it. Thank you.', list
	return 0
  end
end

#==============================================================================
# ** Array
#==============================================================================

class Array
  #--------------------------------------------------------------------------
  # * Includes All
  #--------------------------------------------------------------------------
  def includes_all?(*args)
	args.each {|i| return false unless include?(i)}
	return true
  end
  #--------------------------------------------------------------------------
  # * Includes Any
  #--------------------------------------------------------------------------
  def includes_any?(*args)
	return true if args.empty?
	args.each {|object| return true if include?(object)}
	return false
  end
end

#==============================================================================
# ** BETA Testing Configuration
#------------------------------------------------------------------------------
# Creates Random Map - 40x40, with 8 random enterances, 2 on each side of map
#==============================================================================

enterance_points = []
enterance_points << [0, rand(20)]
enterance_points << [0, rand(20) + 20]
enterance_points << [rand(20), 0]
enterance_points << [rand(20) + 20, 0]
enterance_points << [39, rand(20)]
enterance_points << [39, rand(20) + 20]
enterance_points << [rand(20), 39]
enterance_points << [rand(20) + 20, 39]

Map_Maze_Maker.generate_map(rand(2) + 1, 40, 40)
Map_Maze_Maker.generate_passability_table(enterance_points)
Map_Maze_Maker.generate_target_room
Map_Maze_Maker.generate_data
Map_Maze_Maker.finalize_map

Let me know what you guys think.

Heres a few screens of a few maps it produced:
http://owainc.net/screenshots/rand_map_maker/screen1.PNG
http://owainc.net/screenshots/rand_map_maker/screen2.PNG
http://owainc.net/screenshots/rand_map_maker/screen3.PNG
 
Am I suppose to dissapear in darkness on certain generated maps? Or is this just a bug? Currently fiddling with it. Will post all thoughts on it later.
 
Wow...this looks really cool. So, here are the errors I get right off the top, in a brand new project. Numbers, [3,6,8], [2,3,4,6,7,8,9],[1,2,4,6,9], [1,3,4,6,8,9],[1,2,4,6,7,8,9],[1,4,8,9], then "complete" 83.234 and here is what the maze looks like...
http://i265.photobucket.com/albums/ii209/xgamexfreakx/SephsMazeErrorPic.png[/img]

I'm really excited to see this finished. This is going to be really sweet when it's done. btw- did I mention I love you seph (in a non-gay sorta way  :thumb: ) your scripts are absolutely amazing!

~xgamexfreakx
 
I noticed that as well and its not reaaly a bug, just the floors and walls were configured for that tileset.

Thanks for the list. I need to go over those ID and Cant_Include list a second time though. Getting those IDs is a pain the butt. And thanks for the praise. Glad you like it. ^^
 
This is a great script nevertheless. Well like xgamexfrekx, I do sometimes tend to get many errors. Oh and think there was one error that crashed the player, can;t remember the error, I just keep tapping enter after F12  :dead:. There are some water autotiles error when generating a Grassland map, and sometimes I get a gigantic map with just the floor tile. XD

Anyways, great script Seph. Hope to see this grow to become more awesome like all your scripts.

Edit:
http://img67.imageshack.us/img67/8876/arshessuckssu7.png[/img]

Also, I was wondering, if we like the map, how could we keep it?
 
lol...I love that pic sieg. I also like the third pic that seph posted. I have a feeling that that wont really work very well for a maze, considering what autotile it used.

IDEA!! - You said that this pulls from the 50 tilesets, well, is it possible to make it work for any tilesets over 50? I would guess that you would just go through and change all the 50's to something higher, correct?
 
I believe it does that because off the random direction add (allowing the path to go off map, leaving poor arshes stranded).

Here are some plans of this:
~ Create a cave, where you can link maps together. For instance, you create your cave in the following structure with each x being a map
Code:
 xx
xxxx
 xxxx
    xxx

Each map can be something like 40x40 tiles, and at each point where it goes off the map, it will auto-generate events to transfer from map a to map b. You the developer can make the maps generated for each new game or each time. Random map systems where they are generated and flow together.

But I am not going to worry a lot about this quite yet. My main goal now it to make it generate unique but manageable maps. Even creating random rooms of set dimensions within the map (like in the center point, a 10x10 room is cleared). What needs to be done here is make a complex but efficient passability_table method. The autotiles and walls is quite simple once that is done. Each passability_table type method is for each type of maps allowing even more complex maps vs. simple maps.

Once we get the passability and autotiles configured, we could get into decorations and events. Just sharing future ideas with you. Right now, my focus is on making the maps, later will be connecting them together in networks and using them for game play.



@xgamexfreakx: This can work for any number of tilesets, they just need configured, and this is where I wouldn't mind getting help. I could do it myself, but configuration is a long boring process I don't have time for.

For each tileset, the following settings will need to be made for:

~ Floors - grass like tile to be placed
~ Walls - impassable autotiles
~ Floor Decorations - tiles that add to the floor (on second layer).

Certain autotiles can be placed on the first layer, saving room in the @data instance like the water in the first tileset. So i will be modifing the Walls to be Walls[tileset_id] = [[autotile_id, layer], ...]

This way it picks a random autotile and it will tell what layer to place the "walls".





EDIT: I found the error that leaves arshes stranded. It was the random directions thing causing paths to go off the map but the code is fixed in the main post.
 
So what exactly would you need to do to set up all of this. I'm looking through all of the scripts and such but I'm not really understanding where and how I would set these up.
 
As of now, it really can't be used. Right now I am just working on it generating the maps. After that, the developer (you) will have options at your disposal to make these maps setup automatically in your game, saving them, or having them random every time you go to a map.


As of now, the only use you could get out of it is running it, making a Map.rxdata file, and copying the map to a new map and using the random map or further editing it.


EDIT: Updated to 0.1.2 - Configured 50 tilesets for floors and walls; changed so walls may be drawn on different layers
EDIT: Updated to 0.2 - Reformatted structure (procedural map making); added room creation methods
EDIT: Updated to 0.2.1 - Fixed all (hopefully) autotile id generation bugs
EDIT: Updated to 0.2.2 - Added floor decorations. yeah!
 
I am working on how the developer could utilize this. I see this being used for 2 types of maps, maps that are generated on a new game, and maps that are generated every time you enter that map, but the entrance points never change. So in the editor, you have to setup a few things:

Map Links to link from map to map:
Code:
  Map_Links[[map_id, x, y]] = [map_id, x, y]

You set up this constant and you are good to go as far as going from map to map (the script will be configured to set up these events). On the maps you make that transfer to a random map, a comment with "random map transfer" is all you will need. It will transfer where it needs to.

After this, you will setup your maps that will be created when you press new game. This is done just like in the beta code at the bottom, but a little more organized. There will be a special method that is called on when you press new game. So under the basic tileset configuration, you'll have something like this:
Code:
module Map_Maze_Maker
  def self.new_game_maps
    # place your maps here. suggested format: self.new_map_<id>
    # replace <id> with the id of your map
    self.new_map_5
    self.new_map_6
  end
  def self.new_map_5
    # here is where you will setup and finalize your map
  end
  def self.new_map_6
    # here is where you will setup and finalize your map
  end
end

Now as for the maps that are random every time, you do nearly the same thing, just another special method.
Code:
module Map_Maze_Maker
  def self.random_map(map_id)
    case map_id
    when x
      self.make_random_map_x
    when y
      self.make_random_map_y
    end
  end
  def self.make_random_map_x
    # same as above, the difference this is called every time you transfer to the map vs. once
  end
end


Basically, I suggest if you are going to use this system, you will have to make some sort of mind map like this:
http://owainc.net/screenshots/rand_map_ ... utline.PNG[/img]


I will also be modding my event spawner to work with this map. So in your specialized methods where you create your map, right after self.generate_data, you will be able to use something like:
Code:
Map_Maze_Maker::Event_Spawner.start_event
Map_Maze_Maker::Event_Spawner.set_page_graphic({'c_name' => '001-Fighter01'})
Map_Maze_Maker::Event_Spawner.set_command(101, ['Hi homey'])
Map_Maze_Maker::Event_Spawner.finalize_event

Something like above would create a event that has the message "Hi homey" and the filename of '001-Fighter01'.

I will be adding lots of easy to use features here to make the creation of events easier. Like:

Code:
Event_Spawner::Event_Spawner.create_battle_event('filename', troop_id)

In which an event that random moves around with the filename you specify. When you collide with it, it starts the battle with the troop id. Basically, quick codes for spawning events.

I will through in lots of random options here, so you don't have to create a bunch of events over and over again. Again, any suggestions are welcome.
 
ok, so I'm no longer getting the number errors anymore! However, about 45-50% of the time I generate a map, I end up starting on a tile that is impassible. (In the middle of the water or in utter blackness.) I'm not quite sure how to fix this. Probably something like check if the tile is impassible and if it is, don't start there, or something. I dunno.

Also, you said you need helps with maps. What exactly would you need for that? Just maps to look at?
 
That's just because you really aren't suppose to start on a randomly generated map. The Start Player Position is still set for that map, however, the map could have been generated not taking the start player position into consideration, therefore, leaving you stranded in an impassable tile. I can make a fix that reads the start player position and if you start on a random map, it starts in the target position. Simple fix.

The help I need now is just with floor decorations.

Code:
  #--------------------------------------------------------------------------
  # * Floor Decorations = {tileset_id => [tile_id, ...], ...}
  #--------------------------------------------------------------------------
  Floor_Decoration_Probability = 10
  Floor_Decorations = {}
  Floor_Decorations[1] = [385, 386, 387, 389, 393, 394, 395, 397, 398, 403, 
						  404]
  Floor_Decorations[2] = [385, 386, 387, 389, 393, 394, 395, 397, 398, 402, 
						  403, 404]
  Floor_Decorations.default = []

For each default tileset, I just need to list tile_ids for tiles that are passable, that can be placed on the floor.

If you would like to help (which I would appreciate a lot), here's how I suggest doing it.

Open notepad, open the database and go to the tileset tab. Check your list and check the next tileset (as of now, I only have the first 2 tilesets. So you would add this under the code I gave you above

Code:
  Floor_Decorations[3] = []

Now it's simply a matter of filling in the [] with tile_ids (seperated by commas of course). Export the tileset graphic somewhere and open it with paint or some image software. Now open the image below, copy and paste it over the tileset image (make sure you can see the tiles). For each floor decoration that is passable, you can add it to the [] list. Here is the tile_id chart.
http://owainc.net/screenshots/rand_map_ ... mplate.PNG[/img]
 
so, this would be 4-10

Code:
 Floor_Decorations[3] = [385, 386, 387, 388, 389, 390, 391, 402, 405, 413, 414, 415]
 Floor_Decorations[4] = [385, 386, 387, 388, 393, 394, 395, 396, 403, 404, 405, 406]
 Floor_Decorations[5] = [385, 386, 387, 394, 395, 404, 405]
 Floor_Decorations[6] = [385, 386, 387, 388, 389, 390, 391, 393, 394, 395, 396, 397, 398, 399, 404, 405, 406, 407, 408]
 Floor_Decorations[7] = [389, 390, 391, 404, 405, 408, 409, 410, 414]
 Floor_Decorations[8] = [387, 388, 389, 395, 396, 397, 411, 412]
 Floor_Decorations[9] = [386, 387, 394]
 Floor_Decorations[10] = []

The 10th one is kinda interesting because it doesn't really have floor decorations. It has different types of floors, but that's about it. My guess it that you don't want the floors alternating so I left those out.

Edit, the next 10 in the set...

Code:
 Floor_Decorations[11] = [386, 387]
 Floor_Decorations[12] = []
 Floor_Decorations[13] = [400, 408]
 Floor_Decorations[14] = []
 Floor_Decorations[15] = [400, 408, 424, 425, 440, 448]
 Floor_Decorations[16] = []
 Floor_Decorations[17] = [424]
 Floor_Decorations[18] = []
 Floor_Decorations[19] = [386]
 Floor_Decorations[20] = []

Just like before, the house maps really don't have floor decorations so I really can't do much there. Also, on map 15, I went to 448 which was off of your tileset chart. I hope that it still does continue that far, right? if not, just remove 448 from the end of the list.
 
I like what you have done, but have something to comment on. I suppose with an ABS that this script wouldn't work well, because there doesn't seem to be enough open space like rooms. I also have a question, does this randomly generate a map in-game when entering an area? I believe this would be a nice feature for say areas like dungeons because you can redo the game if you ended up liking it, and wanting to replay it. Also, how customizable will this be toward the end, because I love just the idea of this, and if it as, as customizable as building a map specifically like in the map editor (of course with all of the generated having the same tile styles, and certain events) this will turn out excellent. Just take your time through the Beta, and do the best you can.
 
I have noticed 2 errors by testing this script:

1. The spawnpoint sometimes comes out in the water, due to the fact that you must specify it in the editor for the script to run, so you should make the script generate one upon map creation that way this will prevent spawning on an impassable tile.
2. Sometimes when I hit F12 to regenerate the map the water tile turned out a black box.

Other than that if those errors get fixed I'll probably use this even if you still have it in Beta when I am done my game (not that you will, just complimenting, basically I would use it right now if I had a game to).
 
I plan on adding something that will space out the paths to be wider by option.

It can generate rooms on the fly with a simple call script when making a map.

When it is complete, it will make maps at the start of the game, or certain maps you can have randomly generated every time. Your choice. I am going to try to add as many options as I can so you have plenty of options to make maps as dynamic as possible but keep it so you don't have to set everything.

1
That's just because you really aren't suppose to start on a randomly generated map. The Start Player Position is still set for that map, however, the map could have been generated not taking the start player position into consideration, therefore, leaving you stranded in an impassable tile. I can make a fix that reads the start player position and if you start on a random map, it starts in the target position. Simple fix.

2 - I have noticed that as well. Sometimes paths aren't generated and I am looking into this error.
 
Honestly, I PM you to figure out how I can combine tables and get them to work with your tilemap class as maps (And tell you why), and you go ahead and do what I was working on. Anyway, good job. I'd work on the pathmaking algorithm a little more, to see if you can make it almost like a maze. I know it's difficult, but it's been done before. In fact, this could easily become a part of that project you've got down at the bottom of the forums. (That seems to be being ignored at the moment) Anyway, I guess I'll have to fall back on my second reason for asking this question. (I'm just saying it's a mining system, and I'll leave it at that. Don't look at me like that, it's completely different from any other mining system you've ever seen on RMXP, and if I finish it every n00b will post a help thread on why it won't work for them. OK, maybe you should look at me like that)
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top