Roguelike Dungeon Crawler Game Planning


#21

You mean the .bind method? I think it is necessary so the right id is sent up to the parent. I may be wrong.

With regards to Excel, maybe I’m thinking of a different program. When I look at the output of the dungeon builder program now, it looks fine. I don’t know what I was thinking about.


#22

@ksjazzguitar I was thinking one way instead is maybe I could make an algorithm to generate a map. I know it might be harder, but it wouldn’t be as tedious or as annoying transferring it from the map generator app into the full game. It would also help my problem-solving skills. I made a basic function outside of my component that should render a map of all blank spaces. However, when I try to implement this into my code, it doesn’t seem to work. What do you think is going astray?


#23

When I look in your browser console, I get this:

react-dom.min.js:14 Uncaught TypeError: Cannot read property 'state' of undefined
    at _export (pen.js:67)
    at Object.r (react-dom.min.js:14)
    at a (react-dom.min.js:12)
    at Object.s [as executeDispatchesInOrder] (react-dom.min.js:12)
    at f (react-dom.min.js:12)
    at m (react-dom.min.js:12)
    at Array.forEach (<anonymous>)
    at r (react-dom.min.js:15)
    at Object.processEventQueue (react-dom.min.js:12)
    at r (react-dom.min.js:14)

When I just try to send this to the console, I get back undefined. The function Board.export() doesn’t know what this is. Ahhh. You need to bind this. In your JSX you need:

<button onClick={this.export.bind(this)} className="btn btn-primary">Export Results</button>

I’m not sure how auto-randomly generating maps will be easier, but if you figure it out, please share.


#24

@ksjazzguitar

Well thank you that helped, but the problem is the map is still not rendering on the screen and I don’t know why it won’t.
The two .map functions are being called, and the data can all be console.logged but, the actual divs are not rendering in the line

    return(
      <div>
       {this.props.board.map((row) => {
          row.map((cell) => {
            return (<div id={cell.id} className={cell.status}></div>)
          });
		    })}
      </div>
    );

#25

Hey,

Sorry, but I’m not going to have the time to go step by step through this with you.

I’d say it’s a chance to work on your debugging skills. My instinct is always that I’d rather debug simple than complex. If I was having this problem, the first thing I’d do is step back and see if I could map something simple, on the component level, a string or a character. Then I’d go up to the row level and then column level and do the same thing. I always test as I go, especially if it’s in an area where I wasn’t comfortable.

But it looks like you have it going now, at least to some extent.

One suggestion I’d make is that for a cell status, instead of a string, I’d use a number. It just seems more efficient to me. I defined a bunch of constants at the top of mine for readability.

const S_CODE = 0; // code for a stone segment, dungeon wall
const F_CODE = 1; // code for a floor segment - open, empty dungeon
const P_CODE = 2; // code for player
const M_CODE = 3; // code for a monster
const H_CODE = 4; // code for health
const W_CODE = 5; // code for a weapon
const B_CODE = 6; // code for the boss

It’s just a thought.


#26

Hey dude, I’d advise you to look at the source code of some roguelikes, both modern and oldschool, and try to port it over to Javascript.

I’d recommend Brogue, as it is a simple yet well-known and well-loved roguelike with a large and commited community.

The Brogue forums, now hosted on Reddit. The sidebar provides links to the official Brogue website and other resources.

I’d also advise you to take a gander at http://www.nethack.org/ and /r/nethack on reddit, as well as the nethack usenet forums at rec.games.roguelike.nethack.

It also won’t hurt to take a look at the source code and forums of other influencial roguelikes, such as ADOM, TOME, and DC:SS.


#27

@ksjazzguitar I was just missing a return statement and now it is able to render. I just have to work on now how I’m going to be able to generate a map that is playable within the generation function.

@rainythunderstorm I’ll make sure to look at some source code of other roguelikes after class today. My only question is wouldn’t the comparison be not that valuable because React modifies HTML DOM elements while other languages can create renderable images, sprites, etc. right in the context of their code?


#28

@njanne19, dude, just do the graphics the oldschool way and jse text instead of graphics, orreasons of simplicitly. With regards to looking at th source code, I meant more as in copying things like gameplay, moster ai, and level generation. To be quite honest doing a simple text-only nethack clone, or if you’re confident in your skills porting over the graphics version of nethack or adom or whatever, or or maybe Brogue if you’d prefer a newer codebase, will be a lot easker than trying to design a new game without any previous game-design experience.

Come to think about it, have you ever actually won a game such as ADOM, DC:SS, Nethack or Brogue? Because if not, you might want to ask around somewhere like the angband.ook.cz forums, the various reddit roguelike games forums, the various roguelike usenet groups or other forums,in order to get an experienced rogue-like player’s input on you game.
Of course, if I femember correctly theexamples I losted use C-family programming languages, so unless you caread those this may not be very good advice. Thankfully, asking around on reddit.com/r/roguelikes for a decent browser-based html5 or/javascript roguelike would be a better idea or decision.


#29

@njanne19 you might want to go over to a site like newgrounds or itch.io and see how actual, experienced html5/javascript game developers do things. If I remember correctly there may be some pretty decent software libraries for you to use while developing games.


#30

@rainythunderstorm I’d rather try and go the full route as seen in the example project,

@ksjazzguitar I spent a couple of hours and worked out my map program, now I have something that generates every wall and a couple of openings. Sure I could’ve made a better map, but I think this map will do just fine. Now, I need to work on generating the player. I’m not entirely sure the best way to handle this because the player is nothing more than a CSS class (this is because you generate the map first, and then the player is just on top of the map I presume with the “player” class taking the spot of a cell). I obviously don’t want you to give me the answer because I know I can do this for myself but I’m looking for some more guidance. Maybe you’ll enjoy my map algorithm as well:


#31

Yes, the player is a css class, but it also has data associated with it, probably kept in state.

I created a function to randomly place things (since I was going to have to do it for several things.) The function generated a random number, and I checked to see that that was a empty floor. I used a do/while until I got a good number. Another thing I did (optional) was to check to make sure that all the adjacent squares were also empty floor. I didn’t want to get into a situation where a monster was blocking the only path the player could follow to get to the weapons and health he needed. But I had a fairly tight, hand generated map so that was a real possibility.


#32

Do you recommend I hold the location of the player inside the state of a potential player component?


#33

I held all that data in state. With the exception of the location, all the data was output to the screen in a player status component. Things like health, weapon, level, attack, etc. Anytime data needs to be output to the screen, then it should probably be held in state so React can do its data binding magic. I suppose the player location didn’t need to be as it was just there for calculations. The user sees where the player is on the grid, which is its own state data, those codes that are kept in the grid. But since I had an object in state called player it seemed like a convenient place to keep that data.


#34

I’ve done a lot in the past couple of days, and now I’m moving on to get my player to move. This is the current code I have, however, the key presses do not seem to be going through (or at least the function is not being called). Do you see something obvious that I’m doing wrong?

 componentDidMount() {
    document.onkeydown = this.key.bind(this);
  }
  key (event) {
    switch(event.code) {
      case 37  :
        this.setState({x: this.state.x - 1});
        console.log("Something is happening");
        break;
      case 39 :
        this.setState({x: this.state.x + 1});
        break;
      case 38    : 
        this.setState({y: this.state.y + 1});
        break;
      case 40  :
        this.setState({y: this.state.y - 1});
        break;
    }
  }

Original Project: https://s.codepen.io/njanne19/debug/WOPVZj/PNrvYLxyYBeM


#35

Adding this to your code, and looking in the console, I was able to confirm that your keys are getting logged and they are affecting the state. Again, basic debugging.

But of course that isn’t moving the character on the screen, because that is in a different state. You are keeping your player info in the Player state, but how is that going to get back to the Game state? I think you need to pass that data up to the parent so it can adjust its grid. I find it easier to keep the player position there too since your going to need it to remove the previous player CSS code.


#36

As an example for how to pass data in React (at least as I’ve learned it) I created this pen.


#37

@ksjazzguitar Well I was just trying to see if first the keys were even being logged. When I hit the left key, that console.log function never goes through for me. Additionally, my render function uses an “update” method that passes up its locations through a method passed down through its props.


#38

Sorry, I forgot to mention a problem with the key code, but first …

Again, this just goes back to basic debugging. You have a console.log statement in there. Good. But it is in the second layer of code, in the switch statement (third if you count the case as another layer). My first instinct, if it isn’t making it to the second layer of code is to check the first layer of code, at the beginning of key(). Put a statement there, console.log("key"); as the first statement in key(). When you do that we see that key() is in fact getting called. OK, so why isn’t the switch working. My next instinct is to console.log that event so I can make sure I’m getting exactly what I think I’m getting. If you do that, you will find your mistake. Examine the object that is event and see what’s in there.

I’m getting concerned that maybe I’m doing you a disservice. I’ve tried to explain how I debug these things as I help you but you don’t seem to be picking up on this. The mistake you made here is a really easy mistake to make, but is also a really easy one to debug. Just keep stepping back and see if what you think is happening is really happening. It’s concerning that your first instinct wasn’t to see if it was making it into key() at all but just assumed that if it made it into key() that it must make it into the case of that switch statement.

With regards to your update function, you’re right, that is the basic idea, though, I might have chosen a more meaningful name than “update”. My only concern is that I don’t see where that puts the data into the state. There’s another little problem, but you’ll find that easy enough.


#39

@ksjazzguitar

Sorry, I hadn’t responded yet, I went on a bit of a hiatus, I grinded out a lot of the project. All I have left to do is the darkness; I hope you enjoy seeing the progress after a couple days of hard work.