Kennels and Other Rooms

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • wobbly
    Prophet
    • May 2012
    • 2627

    Kennels and Other Rooms

    This is a dog kennel from fcpb:

    Code:
    N:Kennel
    T:ROOM:NORMAL
    W:10:*:4
    L:C:MON(HOUND, DEPTH+5)
    M:%%%%%%%%%%%%%%%%%%%%%
    M:%...................%
    M:%.#################.%
    M:%.#C#C#C#C#C#C#C#C#.%
    M:%.#+#+#+#+#+#+#+#+#.%
    M:%.+...............#.%
    M:%.#+#+#+#+#+#+#+#+#.%
    M:%.#C#C#C#C#C#C#C#C#.%
    M:%.#################.%
    M:%...................%
    M:%%%%%%%%%%%%%%%%%%%%%
    and straight away I notice this is easy enough to do with a build_kennel instead. The advantage being that it wouldn't always be 16 dogs, it could be random x dogs, random x serpents or random x basilisks.

    These are room stacks, they actually go up to 6:

    Code:
    N:Room Stack I
    T:ROOM:NORMAL
    W:20:*:2
    L:M:MON(*, DEPTH+5)
    L:$:OBJ(*)
    M:%%%%%%%%%%%%%%%%%%%%%%%%%
    M:%.......................%
    M:%.#####################.%
    M:%.#......M..#..M......#.%
    M:%.+.....M..$#$..M.....+.%
    M:%.#......M..#..M......#.%
    M:%.#####################.%
    M:%.......................%
    M:%%%%%%%%%%%%%%%%%%%%%%%%%
    
    N:Room Stack II
    T:ROOM:NORMAL
    W:20:*:4
    L:M:MON(*, DEPTH+5)
    L:$:OBJ(*)
    M:%%%%%%%%%%%%%%%%%%%%%%%%%
    M:%.......................%
    M:%.+###################+.%
    M:%.#......M..#..M......#.%
    M:%.#......M.$#$.M......#.%
    M:%.#####################.%
    M:%.#......M.$#$.M......#.%
    M:%.#......M..#..M......#.%
    M:%.+###################+.%
    M:%.......................%
    M:%%%%%%%%%%%%%%%%%%%%%%%%%
    Again these are simple symmetrical building that could be done with a builder. all 6 could be done with 1 builder. The kennel could be done with the same builder, though there it would be 1 builder with 2 parts (which seems to lose more then it gains compared to 2 separate builders).

    Anyway I'm curious if anyone has any thoughts on:
    • Which rooms are better done with builders & which with prefabs
    • How many versions to cram into 1 builder
    • anything else


    I plan to do the kennel for the reasons above, the rest I'm putting off till I decide whether it's worth it.
  • wobbly
    Prophet
    • May 2012
    • 2627

    #2
    Turns out kennels are tricky if you want different layouts & orientations. I'm not sure if this is right:

    Code:
    /**
     * Build cells on the north wall.
     * \param c the current chunk
     * \param x1 inclusive room boundaries
     * \param x2 inclusive room boundaries
     * \param y1 inclusive room boundaries
     * \param y2 inclusive room boundaries
     * \param flag the SQUARE_* flag we are marking with
     */
    static void cells_n(struct chunk *c, int x1, int x2, int y1, int y2, int flag)
    {
    	fill_xrange(c, y2, x1, x2, FEAT_GRANITE, flag, false);
    	fill_yrange(c, x1, y1, y2, FEAT_GRANITE, flag, false);
    	fill_yrange(c, x2, y1, y2, FEAT_GRANITE, flag, false);
    	int x, y;
    	for (y = y1; y <= y2 - 1; y++) {
    		for (x = x1 + 2; x <= x2 - 2; x += 2) {
    			struct loc grid = loc(x, y);
    			square_set_feat(c, grid, FEAT_GRANITE);
    			sqinfo_on(square(c, grid).info, SQUARE_WALL_INNER);
    		}
    	}
    	for (x = x1 + 1; x <= x2 - 1; x += 2) {
    		struct loc grid = loc(x, y1);
    		square_set_feat(c, grid, FEAT_CLOSED);
    	}
    }
    Will it spit the dummy about struct loc grid appearing in both loops? Do I declare it outside & set the y co-ordinate inside?

    Comment

    • backwardsEric
      Knight
      • Aug 2019
      • 526

      #3
      Originally posted by wobbly
      Will it spit the dummy about struct loc grid appearing in both loops? Do I declare it outside & set the y co-ordinate inside?
      Since those declarations are in separate blocks, they won't clash.

      Declarations within the for() statement itself,
      Code:
      for (int i = ....)
      , are a C99 feature and have always been allowed in C++. I don't know the scoping rules for those in C (whether such a declaration is also visible to the block containing the for loop or if it's only visible within the for loop). For C++, they are limited to the for loop, though I vaguely recall a period of time where some common compilers didn't handle that properly.

      Comment

      • wobbly
        Prophet
        • May 2012
        • 2627

        #4
        Thanks. A lot of this stuff is still confusing to me. I had to go through a bunch of my code & fix some randint0s because I'd messed up. Apparently Randint0(1) is 0 <= x < 1 rather then 0 - 1. Glad I found that out before getting much further. Anway it's working, at least as far as building the rooms, still need to place the occupants. Currently its handling the different layouts with a bunch of if/else & I notice elsewhere in the code its using switch instead. Is there an advantage to switch? Or is this about readability?
        Last edited by wobbly; April 4, 2020, 05:56.

        Comment

        • backwardsEric
          Knight
          • Aug 2019
          • 526

          #5
          Originally posted by wobbly
          Currently its handling the different layouts with a bunch of if/else & I notice elsewhere in the code its using switch instead. Is there an advantage to switch? Or is this about readability?
          For me, the primary concern would be readability, and I prefer a switch statement in the cases where it's most applicable: testing a single integer value for whether it falls in one of several categories that don't overlap. It does have the disadvantage that the compiler won't catch the error of leaving out the break statement between cases that are to be treated separately. With the if/else construct, the compiler readily notices the equivalent error of omitting a brace.

          Both will be awkward with enough separate cases.

          Comment

          • fph
            Veteran
            • Apr 2009
            • 1030

            #6
            Originally posted by backwardsEric
            the compiler won't catch the error of leaving out the break statement between cases that are to be treated separately. With the if/else construct, the compiler readily notices the equivalent error of omitting a brace.
            Isn't there a compiler warning that can be enabled to catch this? At least in GCC.
            --
            Dive fast, die young, leave a high-CHA corpse.

            Comment

            • wobbly
              Prophet
              • May 2012
              • 2627

              #7
              Thanks again! Yeah I suspect what ever I do it's going to end up a long list of cases just because it's got a type & an orientation.

              Code:
              	} else if (t == 3) {
              		if (o == 0 ) {
              			cells_n(c, x1 - 1, x2 + 1, y2 - 1, y2 + 1, SQUARE_WALL_SOLID);
              			cells_s(c, x1 - 1, x2 + 1, y1 - 1, y1 + 1, SQUARE_WALL_SOLID);
              			cells_e(c, x1 + 1, x1 + 3, y1 + 3, y2 - 3, SQUARE_WALL_INNER);
              			cells_w(c, x2 - 3, x2 - 1, y1 + 3, y2 - 3, SQUARE_WALL_INNER);
              			
              			cells_monsters_xrange(c, y2, x1, x2, depth, race, zoo);
              			cells_monsters_xrange(c, y1, x1, x2, depth, race, zoo);
              			cells_monsters_yrange(c, x1 + 2, y1 + 4, y2 - 4, depth, race, zoo);
              			cells_monsters_yrange(c, x2 - 2, y1 + 4, y2 - 4, depth, race, zoo);
              			
              		} else {
              			cells_w(c, x1 - 1, x1 + 1, y1 - 1, y2 + 1, SQUARE_WALL_SOLID);
              			cells_e(c, x2 - 1, x2 + 1, y1 - 1, y2 + 1, SQUARE_WALL_SOLID);
              			cells_n(c, x1 + 3, x2 - 3, y1 + 1, y1 + 3, SQUARE_WALL_INNER);
              			cells_s(c, x1 + 3, x2 - 3, y2 - 3, y2 - 1, SQUARE_WALL_INNER);
              			
              			cells_monsters_yrange(c, x1, y1, y2, depth, race, zoo);
              			cells_monsters_yrange(c, x2, y1, y2, depth, race, zoo);
              			cells_monsters_xrange(c, y1 + 2, x1 + 4, x2 - 4, depth, race, zoo);
              			cells_monsters_xrange(c, y2 - 2, x1 + 4, x2 - 4, depth, race, zoo);			
              		}
              That shouldn't be too bad though? Place 4 rows of cells, fill 4 rows of cells.

              Comment

              • Pete Mack
                Prophet
                • Apr 2007
                • 6883

                #8
                I disagree with this design. You are breaking code/configuration separation for no apparent reason.

                Comment

                • wobbly
                  Prophet
                  • May 2012
                  • 2627

                  #9
                  Well I can potentially rearrange it, but I'm not sure what you actually mean.

                  Comment

                  • Derakon
                    Prophet
                    • Dec 2009
                    • 9022

                    #10
                    Originally posted by wobbly
                    Well I can potentially rearrange it, but I'm not sure what you actually mean.
                    By baking the design of the rooms into the code, you're making it so nobody can change this bit of game content without having a full development environment set up. Much of Angband development over the long haul has been moving things out of code and into resource files, to make them more accessible and easier to modify.

                    I can see the appeal of "these rooms are all just variations on each other, we could have a generator that produces the variations", but then you want to be exposing, like, some kind of configuration for the generator so people can still modify its behavior without recompiling. And that all starts to sound like it gets complicated fast...

                    Comment

                    • wobbly
                      Prophet
                      • May 2012
                      • 2627

                      #11
                      Thanks. That makes sense. It is something I can maybe pull out with a bit of work. It's a basic square room with blocks of cells & the blocks of cells potentially only really need a length, a starting co-ordinate & an orientation from 1 to 4. I'll think about it, for the moment changing the datafiles is something I don't actually know how to do. For now it does what I want it to do & I can look at it again when I understand the code a bit better.

                      Comment

                      • fph
                        Veteran
                        • Apr 2009
                        • 1030

                        #12
                        I think that the point that they are trying to make is: what is the actual advantage of this method wrt 3-4 different kennel sizes hardcoded in the config files? That method looks simpler to understand, change, and keep bug-free.
                        --
                        Dive fast, die young, leave a high-CHA corpse.

                        Comment

                        • wobbly
                          Prophet
                          • May 2012
                          • 2627

                          #13
                          I guess the pt from my perspective is I'm always seeing the same rooms. A prefab gives you 1 room which over the space of 100+ dlvls you see again & again & they're going to be the exact same rooms next play through, & the next. Always the same. 2 or 3 versions of a prefab is only giving you a couple more & each has to be drawn & added to a datafile. 3 variables from 1-5 is already giving 125 different rooms, you can get far more variance stacking variations & probabilities.
                          Last edited by wobbly; April 6, 2020, 20:21.

                          Comment

                          • Nick
                            Vanilla maintainer
                            • Apr 2007
                            • 9633

                            #14
                            So a simpler example of the sort of thing you're trying to do is Nomad's template rooms. These have optional features which are generated or not at random. I think Nomad's approach to what you're doing would just be to introduce about 50 rooms to a file covering every possible configuration

                            Note too that vaults can specify monsters of a given type.
                            One for the Dark Lord on his dark throne
                            In the Land of Mordor where the Shadows lie.

                            Comment

                            • wobbly
                              Prophet
                              • May 2012
                              • 2627

                              #15
                              Yeah I've looked at the template rooms. It's a pretty nice idea but actually fairly awkward to work with in some ways. At the end of the day I don't think I agree. It's hard to "break code/configuration separation" if it doesn't exist in the first place.

                              Code:
                              /* name						rows	cols	builder */
                              ROOM("staircase room",		0,		0,		staircase)
                              ROOM("simple room",			0,		0,		simple)
                              ROOM("moria room",			0,		0,		moria)
                              ROOM("large room",			0,		0,		large)
                              ROOM("crossed room",		0,		0,		crossed)
                              ROOM("circular room",		0,		0,		circular)
                              ROOM("overlap room",		0,		0,		overlap)
                              ROOM("room template",		11,		33,		template)
                              ROOM("Interesting room",	40,		50,		interesting)
                              ROOM("monster pit",			0,		0,		pit)
                              ROOM("monster nest",		0,		0,		nest)
                              ROOM("huge room",			0,		0,		huge)
                              ROOM("room of chambers",	0,		0,		room_of_chambers)
                              ROOM("Lesser vault",		22,		22,		lesser_vault)
                              ROOM("Medium vault",		22,		33,		medium_vault)
                              ROOM("Greater vault",		44,		66,		greater_vault)
                              ROOM("Lesser vault (new)",	22,		22,		lesser_vault)
                              ROOM("Medium vault (new)",	22,		33,		medium_vault)
                              ROOM("Greater vault (new)",	44,		66,		greater_vault)
                              Which of these actually are editable outside the code? Very few, & generally the least common. Fact is, the vast majority of level gen is actually under the hood & needs code change & recompiling to work. There's a fair bit that you can do in the edit files, but a hell of a lot more that you can't. If you look at the pit code not only is it impossible to change outside of the code (with the exception of the monsters), it's actually pretty awkward to change inside the code, the monster placement routine is setup for a fixed 5x11 size.

                              Level gen is currently a mix of these room generators & edit file rooms with the generators doing the bulk of the level. I think it would be a mistake to ignore the part that is actually building most of the level.

                              Comment

                              Working...
                              😀
                              😂
                              🥰
                              😘
                              🤢
                              😎
                              😞
                              😡
                              👍
                              👎