1. Hey! Guest! The 36th GMC Jam will take place between February 27th, 12:00 UTC - March 2nd, 12:00 UTC. Why not join in! Click here to find out more!
    Dismiss Notice

Players Creating a Room

Discussion in 'Programming' started by Dendail, Jan 14, 2020.

  1. Dendail

    Dendail Member

    Joined:
    Mar 10, 2017
    Posts:
    4
    I would like to create something where a player is able to build their own houses but with a system that recognizes a room officially.

    If a player put up walls, floors, add a window, bed and dresser the game will alert the player that room is now a "Bedroom".

    I'm not really sure how to begin constructing something like this. Can anyone point me in the right direction in what I need to do to lay out the ground work for this?

    Thanks in advance for any assistance that is provided.




    Just in case my explanation wasn't clear enough, Dragon Quest Builders have a system very similar to what I am trying to emulate.
     
  2. robproctor83

    robproctor83 Member

    Joined:
    Sep 30, 2019
    Posts:
    295
    Something like this will likely end up being rather complicated and take a lot of work to flesh out and make perfect. In my eyes, the easiest way I could see this working is to use collisions. You could have a base empty room object (just an empty square) and that would do collisions against an interior object (walls, windows, beds, all parented under the same object). At that point it would be as simple as letting the player place those objects into the room object and then counting how many are placed and see if it meets your requirements for a room. So, each time a collision happens you just check if you have already counted that object and if not add it to some list that you use to store all the ids of objects the player has placed in the room. Then, loop over that list every time the player adds a new object and see if they have finally added enough objects to make it complete.

    Something you will probably run into is, just because the player places 4 walls doesn't necessarily mean they have build a room. They may need to place the wall objects along the edge of the room object, or maybe you do special collisions for the wall objects to make sure they are colliding with some particular edge of the room, or maybe you just check the edges of the room object every step and wait until the player has placed walls along them, it's up to you.

    There are a lot of other ways you could do this though. I think maybe a better way would be to base it off of a grid system, so 16x16 or 32x32 chunks, and you let the player draw in each chunk. They can select "wall" or "floor" and then click on a cell and paint in that data type into the cell. You could also use objects here and collisions like I mentioned above, so a wall that spans 128px with 32px chunks would be 4 wall objects, if that makes sense, but it wouldn't be necessary. If you get into all this though you will need a lot more features. You will need things like layers, where the user can work on drawing out the wall layer, or the floor layer, or the objects layer. Then you need to save all this into a file or something so that you can reload it later. You will also need a way for the user to re-arrange things and undo their work, not to mention adding scripted objects that can have player interactions like doors, stairs, refrigerator, stove, microwave, etc etc. And that is just considering how things will exist, you still need to build an entire editor that allows the user to create such things. You will need palettes, brushes, gui interfaces and the list goes on.
     
  3. Yal

    Yal GMC Memer GMC Elder

    Joined:
    Jun 20, 2016
    Posts:
    4,214
    I would do something like this:
    • Whenever the player places a wall, check the four adjacent cells' types. If they're a floor cell (as opposed to "outdoors"), slate them for "roomification checks".
    • For the roomification check, floodfill in all directions (onion-skin search... also known as breadth first). If you encounter any outdoors cell, this is not a room. If you encounter a wall, stop checking its neighbours, otherwise check any neighbours you've not checked yet.
    • If you exhaust the entire search space without finding outdoors cells, this is an enclosed area. It might qualify as a room. (Keep track of additional metadata like the number of floor cells in the area, and what type of furniture you encountered during the floodfill search - that helps you qualify the room later. In particular, it's not a valid room if it's too small, so count the number of floor cells you found when floodfill-searching)
    • Any valid rooms you find maybe should be saved in a list somewhere... you could keep track of them for NPCs that move in, and adding more cells to an existing room shouldn't count as a new room.
     
  4. maxdax5

    maxdax5 Member

    Joined:
    Nov 25, 2019
    Posts:
    28
    Yeah i was thinking like Yal for the floor part. Since you allow the player to make the floor, make so that either when placing the floor, you select what room it will be or when the floor is done, select the room you want, click the floor you wish to set and for all the tiles that are same and are not separate will become that room. An easy code would be with(instance_position(mouse...)) if its neighbor around him are the same object, if room != other.room , room = other.room and so on.
     
  5. NightFrost

    NightFrost Member

    Joined:
    Jun 24, 2016
    Posts:
    2,102
    A certain game called Dwarf Fortress has two major ways to define an area for certain use(s).

    Firstly, it allows you to create an area by simply painting a square. All storage space is defined this way. Grid squares containing something solid (normally, a wall) would be excluded once you had drawn your square and OK'd it. You could build walls around the zone you pleased, or define it to an undeground cave you had dug and get walls for free. Inverse tool allowed you to chip away grid cells to better fit it to your floorplans.

    Second tool gives you a pointer tool that starts as 1x1 grid square, and lets you change its width and height. Everything that is open space traced from its center to the edges of your selection would be defined as the area. If the selection box encounters a wall or a door, it won't expand further. (In other words, it uses a breadth-first search to paint the selection area.) All living spaces use this tool to define their shapes. So, you'd build an enclosure from wall and door parts, point the tool inside it and expand the selection until it covers all open space (stopping and walls) and then OK the area definition.
     
  6. Dendail

    Dendail Member

    Joined:
    Mar 10, 2017
    Posts:
    4
    Oof looks like I'll need to learn how to do "cells" now. Thank you all for the guidance!
     
  7. Yal

    Yal GMC Memer GMC Elder

    Joined:
    Jun 20, 2016
    Posts:
    4,214
    By "cell" I just mean a terrain grid cell, there's no right or wrong way to implement them and there's definitely no standard definition for them.
     
  8. Dendail

    Dendail Member

    Joined:
    Mar 10, 2017
    Posts:
    4
    Yea I was looking into it and discovered a lot of tutorials on the ds_grid. Not 100% sure if that is what I am looking for. The tutorials are mainly for bejeweled like games but trying to see if it's possible to convert it to my purpose. I'm just wondering if I might be out of my depth though lol.

    EDIT: Oh lol literally just found something a lot closer to what I am looking to do shortly after posting this. Here's to hoping I can make use of this!
     
  9. Dendail

    Dendail Member

    Joined:
    Mar 10, 2017
    Posts:
    4
    The approach I am thinking of taking is when laying down floors the game will check if the floor tile is connected to other floor tiles and make sure it meets the minimum/maximum dimensions for a room. Then have it check to see if all the floors not completely surrounded by floor tiles is then surrounded by wall tiles. If that check goes through then I want it check to see if a "door" exists. If so then viola it is now considered a "basic room" or whatever I want it to be. Doing this approach I need to learn ds_grids that I mentioned before right?
     
  10. NightFrost

    NightFrost Member

    Joined:
    Jun 24, 2016
    Posts:
    2,102
    A grid or an array, both let you lay out data in 2D fashion. When you run the your room validity check you can consider all options in one go. There are obviously always eight neighbours to a grid cell. Each must either be a floor tile, a wall piece or a door. If even one is missing, you can early exit the check and say nope, not a valid structure. For the door(s), you just keep a running count of doors throughout the check and at the end it must be one or higher, or the structure is not valid. You might additionally require that the door is attached at right angles to a floor tile to count - that is, diagonals won't count. This is pretty much fastest as a breath-first search running through the data so the tuts you found probably work on that premise.
     
  11. Yal

    Yal GMC Memer GMC Elder

    Joined:
    Jun 20, 2016
    Posts:
    4,214
    Debatable, most people would say there's four neighbors (up, down, left, right). Counting the diagonal neighbors as neighbors as well adds a bunch of problems depending on game genre, like movement cost between two cells not being uniquely defined (a diagonal step achieves more motion per step than a cardinal step) which can lead to balance issues in motion planning.
     
  12. NightFrost

    NightFrost Member

    Joined:
    Jun 24, 2016
    Posts:
    2,102
    Well, I was talking about walls there. If a mason laid the bricks of my house in a manner that let me see my yard through the corners, I wouldn't call it a house. Perhaps an approximation of one. But diagonals do add some additional complexity. One for example needs to decide whether to allow diagonal movement when either adjoining cardinal direction is blocked, or both of them are. (My personal opinion is a grid movement based game should support diagonals.)
     

Share This Page