Author Topic: 4DRL Success: UNSTOPPABLE  (Read 5148 times)

Darren Grey

  • Rogueliker
  • ***
  • Posts: 2004
  • Karma: +0/-0
  • It is pitch black. You are likely to eat someone.
    • View Profile
    • Games of Grey
4DRL Success: UNSTOPPABLE
« on: October 26, 2010, 10:43:20 PM »
So I made a new roguelike, this time in 4 days. You can get it here:

http://www.gruesomegames.com/unstoppable4drl.zip
(contains Windows and Linux execs and FPC source - I'm trying to get an OSX compile at the mo)

Alternatively you can ssh unstoppable@squidnet.ath.cx (many thanks to Whales for this)

UNSTOPPABLE is a sci-fi themed roguelike(esque) game where you play a robot with invincible armour and wield an unstoppable weapon. The enemies in the game can't directly harm you, but with looping map edges all those shots you keep firing suddenly start getting dangerous. The object of the game is to defeat the Rogue AI on level 10, who also wields an unstoppable weapon, but is thankfully lacking the invincible armour.

Gameplay is tense and hard, but generally fair. Just watch the map edges - those bloody Flashers creep up outta nowhere...

Ugly screenshot:

« Last Edit: October 27, 2010, 12:27:13 AM by Darren Grey »

Z

  • Rogueliker
  • ***
  • Posts: 905
  • Karma: +0/-0
    • View Profile
    • Z's Roguelike Stuff
Re: 4DRL Success: UNSTOPPABLE
« Reply #1 on: November 10, 2010, 06:56:55 PM »
Nice idea! And one error = game over, as usual. ;)

I think autoscroll would be very useful, it is difficult to see where the map wraps around.

Maybe also a clearer display of missiles (denote e.g. with >,<,^,v,L,J,7,F so that we can exactly see where the missile is going, and * when there are several missiles in the same location).

Darren Grey

  • Rogueliker
  • ***
  • Posts: 2004
  • Karma: +0/-0
  • It is pitch black. You are likely to eat someone.
    • View Profile
    • Games of Grey
Re: 4DRL Success: UNSTOPPABLE
« Reply #2 on: November 10, 2010, 10:49:51 PM »
I have no idea how to attempt map scrolling, so I'm not even going to attempt that.

The shaped missiles would be nice, but the diagonals would just look silly.  Someone else has suggested highlighting targeted squares, which is trivial to add, so I think I'll do that when I get a chance.  I also plan on nerfing missiles a bit, and maybe giving the option of firing "fast" shots (which are perhaps more dangerous than they are useful).

Z

  • Rogueliker
  • ***
  • Posts: 905
  • Karma: +0/-0
    • View Profile
    • Z's Roguelike Stuff
Re: 4DRL Success: UNSTOPPABLE
« Reply #3 on: November 10, 2010, 11:17:17 PM »
That's easy, you do not have to change the model, only the procedure DrawMap (which should be then called after each move*): at the position pos on the screen, display not the contents of pos, but the contents of pos + center - player (obviously adjusting for the torus), where center is the position of the center of screen, and player is the position of the player. This means that whenever the player moves, he is displayed in the center. (I think that type of view is quite popular for roguelikes with big maps.)

Yeah, highlighting targeted squares seems to be a better idea. A pity we have no good diagonal arrows in ASCII... (Another would be color coding upward and downward missiles differently, but still, highlighting targets is better.

* it might depend on the system and how good is Free Pascal's terminal support, but IME on modern computers there is no problem to just redraw the whole screen after each move (actually Curses is smart enough to only change what has been changed, don't know about Free Pascal).

Z

  • Rogueliker
  • ***
  • Posts: 905
  • Karma: +0/-0
    • View Profile
    • Z's Roguelike Stuff
Re: 4DRL Success: UNSTOPPABLE
« Reply #4 on: November 10, 2010, 11:45:33 PM »
Also, another programming advice. Many, many times, you do something for all 8 directions (repeating almost the same thing 8 or 9 times), or for one of 8 directions (having a big "case" which inside has almost the same thing 8 times). This bad, because if you want to change something in the copied routine, you have to change it 8 times. This can be solved by

const dx: Array[1..9] of Integer = (-1,0,1,-1,0,1,-1,0,1);
const dy: Array[1..9] of Integer = (1,1,1,0,0,0,-1,-1,-1);

and then replacing case routine by just x := realx(xpos+dx[r]); y := realy(ypos+dy[r]);, and similarly replacing a similar thing 8 times by a FOR loop. (I have not read carefully, but I suppose there is also no reason to pretend that a 9 is a 5. Just go on with an array of size 9 and ignore the 5th element.)

Darren Grey

  • Rogueliker
  • ***
  • Posts: 2004
  • Karma: +0/-0
  • It is pitch black. You are likely to eat someone.
    • View Profile
    • Games of Grey
Re: 4DRL Success: UNSTOPPABLE
« Reply #5 on: November 11, 2010, 09:17:22 AM »
Thanks for the advice - using those const arrays would definitely be a lot easier.

I did the 5 is 9 thing in a couple of situations where I was choosing a direction randomly and didn't want a the rest option to exist.  So I'd generate a number from 1 to 8 and pretend the 5 was the 9 move for simplicity's sake.  During my four days of frantically copy-pasting code it ended up sticking in some redundant places.

As for the map redraw, Pascal can actually be a bit slow with its default display unit.  I'm not sure if redrawing the whole screen every turn is wise.  At the moment squares only redraw when actually changed.  Still, I might give it a go.
« Last Edit: November 11, 2010, 09:23:24 AM by Darren Grey »

Z

  • Rogueliker
  • ***
  • Posts: 905
  • Karma: +0/-0
    • View Profile
    • Z's Roguelike Stuff
Re: 4DRL Success: UNSTOPPABLE
« Reply #6 on: November 11, 2010, 01:49:43 PM »
Copy-pasting is very bad, and generally should be avoided (by using FOR loops, functions, or procedures), unless for some reason it is hard in the particular case to factor something out as a separate routine. Avoiding improves both readability (because I don't have to look whether similar pieces are really the same) and coding speed (especially because you do not have to change something in several places if you update the copied piece) and eliminates bugs (caused by forgetting to update all places), so I think that applies a to 4DRL, too.

I have given dx and dy arrays in the order you are using, but I usually give them in a counterclockwise order, so I can e.g. rotate by 90 degrees by adding 2 -- and you could denote no-move by 9, and picking numbers from 1 to 8 is no-move is impossible in given case.

I see you are using e.g. trunc(random(5)), AFAIK random(5) already gives an integer and there is no reason to use trunc. Also, instead of trunc(x*0.5) or trunc(x/2), you can write x div 2.

Darren Grey

  • Rogueliker
  • ***
  • Posts: 2004
  • Karma: +0/-0
  • It is pitch black. You are likely to eat someone.
    • View Profile
    • Games of Grey
Re: 4DRL Success: UNSTOPPABLE
« Reply #7 on: November 11, 2010, 06:41:41 PM »
Random in FreePascal gives a real number, so trunc is quite vital there  :)

As much as I like elegant code, I still found copy-pasting quite essential in my 4DRL, especially in the last few hours.  I was copying a fair bit of monster behaviour code from my 7DRL Trapper, but modifying it for completely different movement styles.  Thankfully it wasn't that hard to copy over and add some tweaks, exception, and change a few conditions.  Extremely ugly, but it worked without much effort.

If I was coding Unstoppable in a less restricted timeframe I'd go about coding it in a very different way!  But then I probably wouldn't have made it without the competition to push me...

Z

  • Rogueliker
  • ***
  • Posts: 905
  • Karma: +0/-0
    • View Profile
    • Z's Roguelike Stuff
Re: 4DRL Success: UNSTOPPABLE
« Reply #8 on: November 11, 2010, 07:08:00 PM »
For me, random(n) gives an integer, and random (without parameters) gives a real number.

Darren Grey

  • Rogueliker
  • ***
  • Posts: 2004
  • Karma: +0/-0
  • It is pitch black. You are likely to eat someone.
    • View Profile
    • Games of Grey
Re: 4DRL Success: UNSTOPPABLE
« Reply #9 on: November 12, 2010, 12:44:14 PM »
Hmm, odd - I'm sure I always get compilation errors for mismatched types when I forget to use trunc on random numbers...