Jump to content
Captain Spazer

Open world generator musings

Recommended Posts

I'm having a hard time thinking this setup out. My idea is this: There is a world where each screen is a place on a grid, and there is a variable that randomly picks a playfield for each of those screens in order to build the world.

 

At the moment, the best I can think up in terms of a setup is having a variable for each possible room on the grid, and a variable that picks out a playfield for that room, so when the player goes to that room on that grid the roompicker variable picks a playfield, then I would need another variable I am guessing that keeps track of whether the room has been visited before so the screen remains what was picked the first time the player enters the room, but it is very variable heavy, and I have yet to figure out how the game will remember if the rooms have been visited or not.

 dim has_room_been_visited.s
 dim roompicker.c
 dim grid_room1.d
 dim grid_room2.e
 dim grid_room3.f
 dim grid_room4.g
 dim grid_room5.h
 dim grid_room6.i
 dim grid_room7.j
 dim grid_room8.k
 dim grid_room9.l
 dim grid_room10.m
 dim grid_room11.n
 dim grid_room12.o
 dim grid_room13.p
 dim grid_room14.q
 dim grid_room15.r

I have another idea too that is a little less heavy on variables: Each time the player leaves the current room, the roompicker picks a playfield, and adds 1 to the add_new_room variable and subtracts 1 to the rooms_left_to_place variable. When the rooms_left_to_place variable reaches 0, no new rooms are placed. Still, need a way to remember if room has been visited or not so it remains static and does not randomize again.

 dim roompicker.a
 dim add_new_room.b
 dim rooms_left_to_place.c

 

Any thoughts, insights or ideas?

  • Like 1

Share this post


Link to post
Share on other sites
Posted (edited)

Here is a functional tech demo code, when moving to the right, the game chooses between 4 different rooms, and the rooms remain static throughout the whole game. And it has a pretty good collision detection too. There are 3 rooms total you can move in by going to the right, head back to a previous room by going left.

 

I am sure it can be optimized to save memory, as it's currently setup, it will require a lot of memory for a sizable map.

 

Is there a way to have the screens share the playfield data so the game can pick from a pool of rooms without duplicating the playfields for each screen?
 

 rem Generated 06/06/2021 18:41:05 by Visual bB Version 1.0.0.554
 rem **********************************
 rem *<filename>                      *
 rem *<description>                   *
 rem *<author>                        *
 rem *<contact info>                  *
 rem *<license>                       *
 rem **********************************

 set kernel_option no_blank_lines

 dim rand16 = z
 dim current_room_number = c
   dim p0_x = d
   dim p0_y = e

 dim room11_generator = f
 dim room12_generator = g
 dim room13_generator = h
game_setup

 ballx = 80 : bally = 50
 current_room_number = 10
 room11_generator = (rand&3) + 1
 room12_generator = (rand&3) + 1
 room13_generator = (rand&3) + 1
setup_map

main

 if current_room_number = 10 then playfield:
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
 X...............................
 X...............................
 X...............................
 X...............................
 X...............................
 X...............................
 X...............................
 X...............................
 X...............................
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
end

 rem ROOM11 OPTIONS
 if current_room_number = 11 && room11_generator = 1 then playfield:
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
 ................................
 ................................
 ................................
 ........XXX...........XXX.......
 .........X.............X........
 .........X.............X........
 ........XXX...........XXX.......
 ................................
 ................................
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
end

 if current_room_number = 11 && room11_generator = 2 then playfield:
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
 ................................
 ................................
 ................................
 ................................
 ................................
 ................................
 ................................
 ................................
 ................................
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
end

 if current_room_number = 11 && room11_generator = 3 then playfield:
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
 ................................
 ................................
 .........XX..........XX.........
 .......XXXXXX......XXXXXX.......
 ......XXXXXXXX....XXXXXXXX......
 .......XXXXXX......XXXXXX.......
 .........XX..........XX.........
 ................................
 ................................
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
end

 if current_room_number = 11 && room11_generator = 4 then playfield:
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
 ....XXXXXXXXX...................
 ....XXXXXXXXX...................
 ....XXXXXXXXX...................
 ...................XXXXXXXXX....
 ...................XXXXXXXXX....
 ...................XXXXXXXXX....
 ....XXXXXXXXX...................
 ....XXXXXXXXX...................
 ....XXXXXXXXX...................
 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
end

 rem ROOM12 OPTIONS
 if current_room_number = 12 && room12_generator = 1 then playfield:
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
 ................................
 ................................
 ................................
 ........XXX...........XXX.......
 .........X.............X........
 .........X.............X........
 ........XXX...........XXX.......
 ................................
 ................................
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
end

 if current_room_number = 12 && room12_generator = 2 then playfield:
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
 ................................
 ................................
 ................................
 ................................
 ................................
 ................................
 ................................
 ................................
 ................................
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
end

 if current_room_number = 12 && room12_generator = 3 then playfield:
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
 ................................
 ................................
 .........XX..........XX.........
 .......XXXXXX......XXXXXX.......
 ......XXXXXXXX....XXXXXXXX......
 .......XXXXXX......XXXXXX.......
 .........XX..........XX.........
 ................................
 ................................
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
end

 if current_room_number = 12 && room12_generator = 4 then playfield:
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
 ....XXXXXXXXX...................
 ....XXXXXXXXX...................
 ....XXXXXXXXX...................
 ...................XXXXXXXXX....
 ...................XXXXXXXXX....
 ...................XXXXXXXXX....
 ....XXXXXXXXX...................
 ....XXXXXXXXX...................
 ....XXXXXXXXX...................
 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
end

 rem ROOM13 OPTIONS
 if current_room_number = 13 && room13_generator = 1 then playfield:
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
 ................................
 ................................
 ................................
 ........XXX...........XXX.......
 .........X.............X........
 .........X.............X........
 ........XXX...........XXX.......
 ................................
 ................................
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
end

 if current_room_number = 13 && room13_generator = 2 then playfield:
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
 ................................
 ................................
 ................................
 ................................
 ................................
 ................................
 ................................
 ................................
 ................................
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
end

 if current_room_number = 13 && room13_generator = 3 then playfield:
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
 ................................
 ................................
 .........XX..........XX.........
 .......XXXXXX......XXXXXX.......
 ......XXXXXXXX....XXXXXXXX......
 .......XXXXXX......XXXXXX.......
 .........XX..........XX.........
 ................................
 ................................
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
end

 if current_room_number = 13 && room13_generator = 4 then playfield:
 XXXXXXXXXXXXX......XXXXXXXXXXXXX
 ....XXXXXXXXX...................
 ....XXXXXXXXX...................
 ....XXXXXXXXX...................
 ...................XXXXXXXXX....
 ...................XXXXXXXXX....
 ...................XXXXXXXXX....
 ....XXXXXXXXX...................
 ....XXXXXXXXX...................
 ....XXXXXXXXX...................
 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
end

 CTRLPF = $31
 ballheight = 8
 COLUPF=$0E
 COLUBK=$00
 scorecolor = $0E
 rem PLAYER CONTROLS

   p0_x = 0
   if joy0left then p0_x = 255
   if joy0right then p0_x = 1
   ballx = ballx + p0_x

   p0_y = 0
   if joy0up then p0_y = 255
   if joy0down then p0_y = 1
   bally = bally + p0_y


 if ballx > 130 then ballx = 10 : current_room_number = current_room_number + 1 : score = score + 1
 if ballx < 10 then ballx = 130 : current_room_number = current_room_number - 1 : score = score - 1

 if bally > 80 then bally = 10 : current_room_number = current_room_number + 10
 if bally < 10 then bally = 80 : current_room_number = current_room_number - 10

 drawscreen

   if collision(ball,playfield) then gosub knock_player_back
   goto main

knock_player_back
   ballx = ballx - p0_x
   bally = bally - p0_y
   return

 goto main

 

Edited by Captain Spazer

Share this post


Link to post
Share on other sites

This is similar to a problem I've tried to figure out for myself. To get a simple repeating pattern, one can use the rand function, and you can even use an "unrand" function to get the previous number. The sequence of numbers would be the same within the same game, so you would get the same numbers going forward and backwards every time for a consistent world. This could be used e.g. to generate screens for a game like Pitfall where you can move right or left to get to new screens, but not up or down. Using rand and the reverse rand function depending on which direction you are going would get you consistent screens as you traverse the linear world without having to store the screen types in variables.

 

Now, in the case of a grid, it becomes slightly more complicated. Going to new screens on the left and right are covered as described above, but for going up or down, you would run the rand or reverse rand function multiple times, depending on the number of columns. For example, if the world were an 8x8 grid, and the player moved down one screen, the rand function would be run 8 times, or the reverse rand in the case of the player going up one screen. This would be a lot of cycles used, but it might be okay since it would only need to happen for screen changes.

 

If I get a chance, I may try to whip up a proof-of-concept demo to demonstrate this.

Share this post


Link to post
Share on other sites

Here's an example that uses rand and unrand as described previously to generate an 8x8 world of 64 screens without having to use variables to track what type of screen is in what position.

 

I also track whether each screen has been visited, and an eye icon shows at the bottom of the screen if the current screen has been previously visited (using the 6lives minikernel to display the icon).

 

Bad graphics aside, I think this is more or less what you were going for?

 

A couple of issues with this version:

  • The screen type at each coordinate will vary from game to game, although it will remain the same throughout the same game. This may or may not be what you want. To make it consistent for every game, you can seed the random number generator with a specific number.
  • If you use the rand function for anything else, it throws off the pattern with the rooms. This can be avoided by using a separate rand function, and a different rand variable that does not conflict with the built-in bB one. I'll update this demo to show how this can be done, as I imagine most games will want to make use of the rand function for more than just generating screens.

Note: Not a WIP game for tracking purposes; just a code demo.

 

openworld.bas

openworld.bas.bin

  • Like 5

Share this post


Link to post
Share on other sites

Here's the version with a separate rand function and variable for cases where you would want to use rand for more than just generating screens.

 

If you want the generated screens to be the same between game sessions, then you will want to change this line:

 

    bbrand = rand

Set bbrand to any nonzero number at the beginning of the game to act as a number seed, and have the screen types be consistent from game to game.

 

(No compiled version, since it is functionally the same as the previous demo)

 

openworld-separate-rand.bas

  • Like 2

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...