Age of the Dead V0.1

Well, I’ve been working on this dungeon crawler “Age of the Dead” now for two months, and I need some people to test it. I have no friends or relatives that would touch a tile-based turn-based rpg type game with a ten-foot pole so no one has played it.

My web host doesn’t support JNLP so I can only provide a direct link to the executable jar file…

http://mbrenaman.com/AgeOfTheDead.jar

The closest thing I have to instructions right now is the help screen, press [h] in game.

Try it out, tell me what you think. Maybe it won’t be that bad… :-/

EDIT: this is an early version with only 3 classes and a script not extending past the first floor. Also I’ve only just finished balancing everything for one class (Mercenary) so, expect anything with the other two.

What’s there is pretty cool. Was a little confused why the viewable area is soooo small but didn’t stop me wandering about.

  • Full screen didn’t work, just got a huge window with only a portion being rendered to.
  • Damn spiders!

Kev

Exactly how do you attempt to put in full-screen mode? I’m not sure what you’re talking about ???

use the torch kev! :slight_smile:

I liked the game! However I had two problems. For one, after I ate meat, and it turned into bones, the weight actually went UP! So that didn’t make sense and I’d run out of room quickly with bones that weighed more than they did with 4 uses of food on them hehe. Also, the descriptions said that I could use those in alchemy… but I’d click the Alchemy button and it wouldn’t do anything!

Also, I spent quite a while in the dungeon and got 68 vitality so I think I progressed pretty well, but man, when do you get OUT of the dungeon? I ran out of food at one point and my only hope was to kill like 6 lizards. I had to position myself so only one could attack me at a time and fight them until I could get their meat and run off and rest. It took like 5 or 6 tries of re-loading my game in order to have the random factor work in my favor and NOT kill me :slight_smile: So that was the only point when I thought it was maybe a little more difficult than intended because that was literally my ONLY option since I couldn’t like… go back to the Inn and rest or anything hehe.

So yeah, is there a way out of the dungeon ever? I’ve never played a game, even a recent game, that would keep you stuck in a dungeon for that long without even the option of bailing out to regroup and buy/sell/rest/whatever.

However it’s a cool game and I’d be happy to keep testing as it progresses! I’m having fun playing it as it is still :slight_smile:

Oh, and damn my pants for “breaking into pieces” hehehe. Good thing I kept my old ones!

Edit: Oh, and two more suggestions I just thought of:
1 - make the viewable area 5x5 instead of 3x3… or maybe sight works as a stat that can be improved over time.
2 - make enemies within view appear on the mini-map. I know you can already see them in the screen, but sometimes you have to look REALLY close to decide if you’re looking at a lizard or a lizard corpse, and you don’t actually get a message display telling you that you killed a lizard. Even if you did though, in the same turn a lizard could walk up over the spot of the old one and you wouldn’t realize he was there unless you were paying uncommonly close attention. So another dot on the mini-map to mark an enemy close by would help with that for sure.

Edit2: The fullscreen mode he means (I think) is maximizing the window. I tried it too, and on higher than 800x600 resolution, the bottom and right sides of the display will be just junk.

Ah, when I started the game it seemed to auto maximise, I’d assumed this was it failing to make it into fullscreen mode…

Kev

Well thank you both for clearing up that window question, I’ll get that taken care of and the window mazimizes at the start on purpose (on my 800x600 display that’s the only way I can see the edges of the game buffer), and thank you very much Malohkan for your input ;D. If you interested in future updates watch this forum. Anyways, let me address the problems you both stated…

First, the light is simply just at a low radius level for torches, and kevglass, sorry about not warning you about the torches. The game is designed to draw tiles as far as the dimension of the game buffer 2518, on a 800544 canvas, so I’ll increase the light radius’ for light sources.

Sencond, sorry about that weight of bones thing, purely an accident. And for alchemy, I havent programmed it in yet (well atleast the actual recipe making stuff). But thats what those bs items are for.

Third, 68 Vitality, I hope you mean hp/life and not the stat “Vitality”, which can be seen by pressing [s] or “Stats”. If hp, good it worked right, if not then I must ask how long you played :o.

Fourth, about buy/sell/trade/repair. I made it to were characters in their dialog could to take you to buy/sell/trade/repair menu, like Marcus at the begining, ask him to trade, he sells food and stuff (You said you had trouble getting food) and he also does the sell/trade/repair. And as you progress through the game you’ll meet other character’s that trade, until you reach the “Necropolis”, which is going to be a complete undead town in the dungeon. Do you think that sounds suitable (didn’t seem to bad to me) or should I let the player return to a town map?

Looks like I’ll be busy later :slight_smile: thanks again y’all.

Looking at a dead lizard only showed me empty dungeon floor, but looking at other stuff I could see it.

Maybe the interface could use being a bit more clearly demarcated- draw clear boxes for the minimap, options panel, report console and play area.

I thought the play area was a bit small, but then I found a room with torches in and it wasn’t any more…

It didn’t crash or bring up any noticeable errors though, except when I first downloaded it and it said “main class not found” and then ran anyway.

I’ve fixed all the problems sited, but to get the area outside of the game’s Canvas to redraw, I force a redraw() on the window in my rendering loop, which obviously kills the frame rate.

Any better way to get the main JFrame that contains the game’ Canvas to draw and update the area outside of the Canvas (in the JFrame)? Or should I just make the maximized size of the game the same size as the game canvas?

Sorry to double post, but go ahead and ignore the last post, all I had to do was turn of IgnoreRepaint for the JFrame and override its paint method and make it draw a black rec. behind the game canvas.

So everything has been fixed. The weight thing with meat and bones was actually a nasty bug, thank you for seeing it.

Anyways, here’s a the link again to the jar http://mbrenaman.com/AgeOfTheDead.jar

Hopefully everything works now ::slight_smile:

Great preview of your game. It reminds me alot of an RPG on the Commodore 64 - The Temple of Apshai (http://www.lemon64.com/games/details.php?ID=2614).

Things I thought of -

Constructive Criticsim -

  • Main area seems too small.
  • I die pretty quickly. I guess that may be my fault.
  • The difficulty seems too high. I feel cheated when a rat can take me out so easily.
  • No sound
  • Having the text on the left didn’t seem ‘right’. Having it below the game arena seemed like a better place. Minor gripe.
  • Ranger class seems a tad wussy. I’d add 1 more point to his strength. I think of rangers as Aragorn from Lord of the Rings.
  • My CPU was maxed, but I can’t see why. The graphics don’t animate and the movement is tile based, so what is the app thinking about all the time?
  • The text is a tad hard to read at times. Maybe make a light grey box behind the text areas with an alpha so the background will still show thru. Im thinking a water mark like look.

Likes

  • Graphics fit well. I especially like the red blood/blob when you hit things.
  • Nothing broke. :slight_smile:
  • The character classes were nice and the descriptions you have for them.
  • There are lots of menu options, which will make gameplay more fun as you develop things more.
  • Your story is well done. The writing is very nice and it shows you put some thought into why the hero is stomping around in the dungeon.

Ideas -

  • Make the male and female class stats slightly different. If the graphics are the only difference, I have no reason to play both sets. You could make the dexterity be a point higher and lower the strength for example.

  • Add diagonal movement

  • I looked at the game save and it appears you are saving out a ton of stuff. The file was ~700K which is more than the jar file. :-/ It appears you have alot of stuff in there which could be left out. For example, I saw the text describing the ranger class. I wouldn’t think that is linked to game state.

  • For sounds, you could put in only ones that aren’t going to happen all the time. IE no walking sound, as that could get annoying very quickly. Sounds such as opening a door, a dong or something when you first enter the dungeon, a sound when you die or you kill something, a chest opening sound.

HTH -
Dr. A>

PS - Great progress so far!

[quote]- Ranger class seems a tad wussy. I’d add 1 more point to his strength. I think of rangers as Aragorn from Lord of the Rings.
[/quote]
Ah, wasn’t he “Fighter/Sage/Dunadan” ? :). (from the LoTR card games; basically, they recognised that Tolkien had his characters as “heroes” - i.e. you are hard-pressed to find someone in LoTR who isn’t a polymath. For instance, Gandalf (and most of the other wizards) are the opposite of DnD wizards: they are kick-ass sword-fighters (and kick-ass staff-fighters, but e.g. Gandalf rather prefers his sword!).

So, in the card games, everyone is multi-classed. Most of the wizards have four classes (or 5?). Ditto the most powerful of the famous names. And there’s no penalty for being multi-classed…

Anyway, OT aside, is there any way MBrenaman could make a webstart version of this? I’d like to have a go, but … And I’d offer to host it, but c.f. elsewhere I’m running out of b/w already :(.

@dranonymous ok let me address all of your very nice critques. I can weaken the rats, there’re supposed to be like “giant rats” sorry. Sound and music are coming soon. I have the code and stuff just haven’t added. But I have started on the MIDI soundtrack. I will gladly fix the ranger and sex thing also thank you for pointing that out.

About cpu usage, if its standing still, it shouldnt be doing much… hmmm I’ll profile it and get to the bottom of it.

I’m not sure what water mark like look is… do you mean a translucent box behind every bit of text or just the messages at the top.

Use the number pad to move diagonally sorry but its listed in the ‘h’ help screen (sorry again)

For sounds (not real ones but ones in the dungeon) I could easily make it not display any continuous messages. So like if you hear “Something walking by” you’ll only get one message for it until you hear it from another source or you move away. Combat, doors opening, all those sounds happen but I made it to were you can’t hear what you can see. Either that you would walkaround hearing the sound of your own footsteps. I don’t know, seemed ok not to tell a player he/she hears a door opening when he/she opened it.

@blahblahblahh as mentioned before, my web host doesnt support JNLP so I can’t make it webstart. But if you want to host a future version then that would be cool. And yes, I think its strange that DnD stuff was supposidly based on Tolkien’s books which have no specialized character at all (trying to remember stuff I havent read those books in ages).

EDIT: I reprofiled my game and my own compiled code is only 6% of the problem. Here’s a snippet that I wanted yall to look at…


        Stub + native   Method
64.6%     5  + 12391    sun.java2d.loops.Blit.Blit
 2.0%     0  +   380    sun.awt.windows.WToolkit.sync
 1.9%     2  +   356    sun.awt.font.GlyphList.setupStringData
 1.2%    38  +   187    sun.awt.windows.Win32DDRenderer.doFillRectDD
 1.0%     0  +   198    sun.java2d.loops.DrawGlyphList.DrawGlyphList
 0.6%     0  +   122    sun.awt.windows.Win32BlitLoops.Blit
 0.2%     0  +    31    java.io.RandomAccessFile.setLength
 0.1%     1  +    16    java.lang.StrictMath.floor
 0.1%     2  +    11    sun.awt.font.GlyphList.discardData
 0.1%     2  +     8    sun.awt.image.BufImgSurfaceData.getSurfaceData
 0.0%     0  +     8    java.lang.StrictMath.pow
 0.0%     0  +     6    sun.awt.shell.Win32ShellFolder2.getAttributes0
71.7%    50  + 13714    Total stub

As you can see sun.java2d.loops.Blit.Blit is the bottleneck. So is there like any common mistakes or something that one can make when 2d drawing? I’m using BufferedImages… umm (details uhh) I’m using active rendering in a JFrame. I really don’t know what other info might help short of posting source code.

I’d like to host it! :slight_smile: Gamelizard most definitely has the bandwidth and the spare room to take it. You can have a separate section on the forum dedicated to it if you’d like :slight_smile:

I’d think if you’re rendering actively you could just only repaint when something changes, in which case you’d really never hear the CPU whirl as a result of your game.

If you want the game hosted on GameLizard, I’d be happy to help you code lots too if you’d want the help. At any rate, free hosting and forums I think would be a cool deal :wink: I’d just like a cool RPG on my site ;D

Thats great Malohkan, I’d be happy to use gamelizard for future versions. I’ll try and contact you in the future, hopefully gamelizard has a link to an email address I could use, if not my profile has my email address. And also, I’ll need to find the info I need to sign the jar and do whatever I need to do to the manifest to break the game up into 3 jars. Also still trying to figure out what to do with those excess dungeon sounds. Gonna try to NOT use active rendering, see how that works… :slight_smile:

Thanks again everyone, this forum rules ;D

Ok, I’m feed up trying to make this work (that is the fact that the 2d blit eats up so much).

Here’s the latest profile with the new Window that doesnt use that active rendering

Flat profile of 73.25 secs (4163 total ticks): AWT-EventQueue-0

  Interpreted + native   Method
 12.8%     0  +   403    sun.java2d.loops.Blit.Blit
  0.3%     0  +     8    sun.awt.windows.Win32BlitLoops.Blit
  0.1%     0  +     4    sun.awt.font.GlyphList.setupStringData
  0.1%     0  +     2    sun.awt.font.NativeFontWrapper.getFontMetrics
  0.1%     0  +     2    sun.awt.windows.WInputMethod.getNativeLocale
  0.0%     0  +     1    sun.awt.windows.WComponentPeer.nativeHandleEvent
  0.0%     0  +     1    sun.awt.font.NativeFontWrapper.getCharMetrics
  0.0%     1  +     0    sun.awt.windows.Win32OffScreenSurfaceData.initSurface
  0.0%     0  +     1    javax.swing.JComponent.processKeyEvent
  0.0%     1  +     0    java.awt.Container$MouseEventTargetFilter.accept
  0.0%     1  +     0    sun.java2d.SunGraphics2D.<init>
  0.0%     1  +     0    javax.swing.JComponent.paintDoubleBuffered
 13.5%     4  +   422    Total interpreted

     Compiled + native   Method
  0.0%     1  +     0    vtable chunks
  0.0%     0  +     1    javax.swing.RepaintManager.currentManager
  0.0%     1  +     0    sun.awt.font.FontDesignMetrics.stringWidth
  0.0%     1  +     0    DungeonManager.draw
  0.1%     3  +     1    Total compiled

         Stub + native   Method
 79.0%     0  +  2497    sun.java2d.loops.Blit.Blit
  0.2%     0  +     6    sun.awt.windows.Win32DDRenderer.doFillRectDD
  0.2%     0  +     5    sun.awt.windows.Win32BlitLoops.Blit
  0.1%     0  +     2    sun.java2d.loops.DrawGlyphList.DrawGlyphList
  0.0%     0  +     1    sun.awt.font.GlyphList.setupStringData
 79.5%     0  +  2511    Total stub

Still a problem so I’m going to take a chance add post the code to the GameCore which the main game extends. Its really sloppy beacuse I was working on it but here, PLZ, tell me what the hell I’m doing wrong.

public abstract class GameCore extends JFrame{

  ////////////////////////
  //       Variables      //
  ////////////////////////

  public static final float FONT_SIZE = 14.0f;
  public static final int GAME_WIDTH = 800;
  public static final int GAME_HEIGHT = 544;

  private boolean isRunning;

  protected GameCanvas gameCanvas;

  private JFileChooser fileChooser = new JFileChooser();

  ////////////////////////
  //        Methods      //
  ////////////////////////

  //Signals the game loop that it's time to quit
  public void stop() {
    isRunning = false;
  }

  //Calls init() and gameLoop()
  public void run() {
    try{
      init();
      gameLoop();
    }
    finally{
      //screen.restoreScreen();
      lazilyExit();
    }
  }


  
  //Exits the VM from a daemon thread. The daemon thread waits
  //2 seconds then calls System.exit(0). Since the VM should
  //exit when only daemon threads are running, this makes sure
  //System.exit(0) is only called if neccesary. It's neccesary
  //if the Java Sound system is running.
  public void lazilyExit() {
    Thread thread = new Thread() {
      public void run() {
        // first, wait for the VM exit on its own.
        try {
          Thread.sleep(2000);
        }
        catch (InterruptedException ex) { }
          // system is still running, so force an exit
          System.exit(0);
        }
      };
    thread.setDaemon(true);
    thread.start();
  }

  //Sets full screen mode and initiates and objects.
  public void init() {

    //create a frame to contain our game
    setTitle("Age of the Dead - by Mathew Brenaman");

    //Set main game frame
    setBackground(Color.black);
    setForeground(Color.white);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setIconImage(loadImage("Icon.gif"));

    gameCanvas = new GameCanvas();

    gameCanvas.setBackground(Color.black);
    gameCanvas.setForeground(Color.white);
    gameCanvas.setPreferredSize( new Dimension(GAME_WIDTH,GAME_HEIGHT));
    gameCanvas.setDoubleBuffered(true);
    gameCanvas.setFocusable(true);

    //Set font
    try{
      gameCanvas.setFont(Font.createFont(Font.TRUETYPE_FONT,getClass().getResourceAsStream("Calisto.TTF") ).deriveFont(FONT_SIZE)  );
    }catch(Exception e){ 
      System.out.print("\nError in loading Calisto.ttf, unable to start game...\n");
      return; 
    }

    //Set the preffered size of the content pane and add the canvas to it            
    Container c = getContentPane();
    c.setLayout(new FlowLayout());
    c.add(gameCanvas);

    gameCanvas.requestFocus();    // the JPanel now has focus, so receives key events

    pack();
    setVisible(true);
    gameCanvas.setVisible(true);
    show();
               

    setExtendedState(Frame.MAXIMIZED_BOTH);


    isRunning = true;

  }


  //Load image using ImageIO
  public BufferedImage loadImage(String fileName) {
    try{
      return ImageIO.read( getClass().getResourceAsStream(fileName) );
    }
    catch(IOException e){}
    return null;
  }

  //Method uses and displays a JFileChooser dialog box for saving/loading,
  //and returns the file choosen, do not provide a dot for the extensions
  public File showFileChooser(String dialogTitle,String approveButtonText,
                              String approveButtonToolTip, char approveButtonMnemonic,ExtensionFilter extensionFilter,boolean saveFile){

    fileChooser.setDialogTitle(dialogTitle);
    fileChooser.setApproveButtonText(approveButtonText);
    fileChooser.setApproveButtonToolTipText(approveButtonToolTip);    
    fileChooser.setApproveButtonMnemonic(approveButtonMnemonic);
    fileChooser.addChoosableFileFilter(extensionFilter);
    fileChooser.setFileFilter(extensionFilter);
    fileChooser.rescanCurrentDirectory();
    
    int result;
    if(saveFile){
      result = fileChooser.showSaveDialog(GameCore.this);
      File fileResult = (result == fileChooser.APPROVE_OPTION) ? fileChooser.getSelectedFile() : null;
      if(fileResult!=null){
        if(!fileResult.getName().toLowerCase().endsWith(extensionFilter.getExtension()))
          fileResult = new File(fileResult.getAbsolutePath() +"."+extensionFilter.getExtension());
      }
      return fileResult;
    }    
    else{
      result = fileChooser.showOpenDialog(GameCore.this);
      return (result == fileChooser.APPROVE_OPTION) ? fileChooser.getSelectedFile() : null;
    }

  }

  //Runs through the game loop until stop() is called.
  public void gameLoop() {

    long startTime = System.currentTimeMillis();
    long currTime = startTime;
    TimeSmoothie timeSmoothie = new TimeSmoothie();

    while(isRunning){
      long elapsedTime =
        System.currentTimeMillis() - currTime;
      currTime += elapsedTime;            
        
      //update
      update(timeSmoothie.getTime(elapsedTime));

      gameCanvas.repaint();

      // Sync the display on some systems.
      // (on Linux, this fixes event queue problems)
      Toolkit.getDefaultToolkit().sync();

    }
  }

  //Updates the state of the game/animation based on the
  //amount of elapsed time that has passed.
  public void update(long elapsedTime) {
      // do nothing
  }

  //Draws to the screen. Subclasses must override this
  //method.
  public abstract void draw(Graphics g);



  public void paint(Graphics g) {
    g.setColor(Color.BLACK);    
    g.fillRect(0,0,getWidth(),getHeight());    
    gameCanvas.repaint(); 
  }


  public class GameCanvas extends JPanel {

    protected void paintComponent(Graphics g) {
      draw(g);
    }
  
  }

}//End of GameCore class

Well it looks like you’re still rendering actively, and you’re also not sleeping at all, so it’s going to render as fast as it possibly can at all times. That’s good for a fast paced game with constant animation that you’re trying to get high fps on, but that’s not what you’re going for here :wink:

If you want help with signing your jar and making it all webstart working, then yes, you can find my email on my site. I’ll save you the trouble of looking at the forum member list: Malohkan (at) gamelizard d0t com :slight_smile:

So active rendering actually using a loop to update->draw repeadily, how else can it be done? What are the alternatives to it?

As for adding a delay I can add that. But I would like to know the alternatives to my gameLoop. Maybe some source code or something ???

I’m with Malohkan - you probably don’t need active rendering here.

The rough concept is - do you have ‘stuff’ going on when the user isn’t providing any input? (Do lights flicker, does sound play, do the enemies move if the player isn’t doing anything.)

It doesn’t look like anything happens until the user presses a key in your game. If you move, then the enemies move too. If you press the menu key, then a menu shows up. It appears to be event based.

Does that make sense?

As far as the menu effect I was talking about. Let me try again. Take your background rock texture. Draw a large rectangle on the left side in white. If the square is opaque (alpha = 0) Then it will completely cover your rock texture. If the alpha is at .5, then you will see a whitish square with the background showing through somewhat. My idea was to do that on the left, with say a light blue or grey. Then you put the white text on top of the square with no alpha. You will get a nice high contrast for reading the text and it will make a cool effect seeing the ‘watermarked’ background.

HTH,
Dr. A>

Ok, I see now d. That’ll be simple to try out (the translucent rectangle).

To prevent to much change to the app class itself I will make the update method from the GameCore hang until a redraw is needed. That should do, seems like the path of least resistence. I just want to keep it so later I can have animated damage effects, like the reb blood blobs splattering and fire damage exploding and stuff.

I’ll get to work. Thanks for clearing up that stuff yall, I feel like such a newb :-/ (btw this is not my first programming language or first game so I feel… well, kinda dumb)

I wouldn’t be embarassed at all. No one can know everything. I still think everyone I meet is older than I am and has more experience.

I’ll ask you a favor though. Can you try out the app I wrote? Check the post for daughterware. If not, I won’t be offended.

Regards,
Dr. A>