Jump to content
Gemintronic

Destiny WIP

Recommended Posts

Well, I decided I should finish this project before starting another one. Right now I've got the maze done and a placeholder "ring" object in, er, place.

 

No title screen so one must press FIRE before starting the game. Right now the score is set to display the current floor of the dungeon. How big is the dungeon? Here's a quote from my blog:

 

16 basic room types (not including rare rooms)

8 room structure styles

16 x 8 = 128 Unique Rooms

256 level dungeon consisting of 256 x 256 screens per level.

All in all, my Adventure/Roguelike should have 1,677,7216 screens per gaming session. Each time the game is powered on a game seed is used so really 256 1,677,7216 screen dungeons are possible. You do the math: I'm tired

 

Like I said this is very much WIP and not a complete game yet. Check it out anyway :) If you get stuck in a dead end don't worry: there's a random chance each time you enter a room it'll change into its rare form with new exits.

 

Initially all the room combinations were taking up too much space so I developed a technique to divide one screen into 3 slices that get "printed" and then scrolled to allow the next section to be placed on-screen. I haven't seen this done yet so I hope it'll interest fellow Batari game developers.

 

Placement of the rings stays basically static no matter how far in the dungeon you go. However, if one picks up an item ALL other items get a new random location.

post-13304-129020861448_thumb.jpg

destiny0001.bas

destiny0001.bin

post-13304-129020882883_thumb.jpg

Edited by theloon

Share this post


Link to post
Share on other sites

Well, I decided I should finish this project before starting another one. Right now I've got the maze done and a placeholder "ring" object in, er, place.

 

No title screen so one must press FIRE before starting the game. Right now the score is set to display the current floor of the dungeon. How big is the dungeon? Here's a quote from my blog:

 

16 basic room types (not including rare rooms)

8 room structure styles

16 x 8 = 128 Unique Rooms

256 level dungeon consisting of 256 x 256 screens per level.

All in all, my Adventure/Roguelike should have 1,677,7216 screens per gaming session. Each time the game is powered on a game seed is used so really 256 1,677,7216 screen dungeons are possible. You do the math: I'm tired

 

Like I said this is very much WIP and not a complete game yet. Check it out anyway :) If you get stuck in a dead end don't worry: there's a random chance each time you enter a room it'll change into its rare form with new exits.

 

Initially all the room combinations were taking up too much space so I developed a technique to divide one screen into 3 slices that get "printed" and then scrolled to allow the next section to be placed on screen. I haven't seen this done yet so I hope it'll interest fellow Batari game developers.

 

Placement of the rings stays basically static no matter how far in the dungeon you go. However, if one picks up an items ALL other items get a new random location.

 

 

Liking it so far. It feels very expansive. Not exactly sure what the objective is or how points are scored, however. I noticed I get a point for colliding with one of the white, stair-like objects, lose a point for going down the black staircase, and get no points for the rings. I know it's unfinished, but was just curious how you plan on setting up the game play.

 

Can't wait to see more!

 

-B

Share this post


Link to post
Share on other sites

Liking it so far. It feels very expansive. Not exactly sure what the objective is or how points are scored, however. I noticed I get a point for colliding with one of the white, stair-like objects, lose a point for going down the black staircase, and get no points for the rings. I know it's unfinished, but was just curious how you plan on setting up the game play.

 

Can't wait to see more!

 

-B

 

@Brian: I believe theloon is currently using the score to track what dungeon you are in, so, naturally, the number will go up if you climb the stairs and down if you go downstairs. :)

 

@theloon: I agree, nice work! Very clever dividing the screen into 3 sections. 8)

 

Only potential problem I see at this point, is not much frame of reference from where you were and where you end up. Unless you will be including more "rare" screens such as the castle screen? This will help keep a fixed point in mind as the player explores the dungeon to find other "rare" locations.

 

If the game is based on earning the most points, then I suppose you can put items anywhere and keep finding them until you earn a certain number of them to win ( or get killed by a monster ). If you are looking for a specific object however (such as Adventure does with the Chalice), will the player be able to find his way back to the starting castle?

  • Like 1

Share this post


Link to post
Share on other sites

This started out with Rogue-like aspirations so the ring was gonna be your classic variety of magical rings. I've since decided on "collect the rare carts and bring them back to your castle" style gameplay. The goal and ending parts of the game haven't been implemented yet.

 

I was wondering if the dungeon was still too generic. Maybe it will help if the normal difficulty is a static dungeon? The other thing I'm going to try is further customizing each room. Will show a new build soon.

 

Thanks Gateway and Brian O!

Share this post


Link to post
Share on other sites

I thought my Nethack habit was bad enough. Soon there will be this.

 

I love your use of pfscroll to build the rooms. I dub thee "The ROM Saver."

 

What do you have planned next? Will there be enemies to battle?

Share this post


Link to post
Share on other sites

This started out with Rogue-like aspirations so the ring was gonna be your classic variety of magical rings. I've since decided on "collect the rare carts and bring them back to your castle" style gameplay. The goal and ending parts of the game haven't been implemented yet.

 

I was wondering if the dungeon was still too generic. Maybe it will help if the normal difficulty is a static dungeon? The other thing I'm going to try is further customizing each room. Will show a new build soon.

 

Thanks Gateway and Brian O!

 

Anytime! :)

 

I think you have a really good idea to build on. The only thing that is missing is some tension. Having monsters in certain rooms, or having a Pitfall-style timer counting down, would definitely help to create a sense of urgency. Since the rooms are randomized, there's no real way create a map to help you see which rooms you've been in, right? In terms of room customization, it would definitely help from an aesthetic perspective, but may not serve a true practical purpose unless players could use the rooms as landmarks, IMO.

 

Can't wait to see the next iteration.

 

-B

Share this post


Link to post
Share on other sites
Initially all the room combinations were taking up too much space so I developed a technique to divide one screen into 3 slices that get "printed" and then scrolled to allow the next section to be placed on-screen. I haven't seen this done yet so I hope it'll interest fellow Batari game developers.

I didn't look at your code yet, so I don't know what you mean by printed and scrolled, but the part about dividing the screen into sections kind of reminds me of these threads:

 

http://www.atariage.com/forums/topic/124384-we-have-on-and-off-with-the-playfield-but-what-about-no-action/

 

http://www.atariage.com/forums/topic/133068-check-out-this-random-maze-demo/

Share this post


Link to post
Share on other sites

Definitely a solid start! I agree that more distinct room features could help. I'd also like to see matching up-stairs and down-stairs.

 

I don't know if you noticed, but your room drawing routine is using too many cycles.

 

Since you're after rings, why not call it "rings of the lord", and add some shadow riders. :P

Share this post


Link to post
Share on other sites

Well, I couldn't get the castle to stop appearing on floors other than the first. I made a "castle ruins" that appears if the dungeon floor isn't 1.

 

Right now I'm trying to see if I can hack in matching staircases. As the code is the resulting staircase would only be temporary and would disappear when returning to the room.

 

@RevEng: Going over the CPU cycles seems to be a serious no-no but I don't understand why. Can it blitzkrieg the entire game or just make funny noise on the screen when it happens? Bataris kernel isn't going over the CPU cycles right? Just my amateur game logic code (I think, dunno).

 

I want enemies. I want further detail put into the rooms. We'll see how far I get! The minimum gameplay should be collect the items and dash back to the castle on the first floor.

 

I'm having trouble coming up with a cartridge sprite to replace the ring. Nothing I draw comes out convincing. Maybe I'll bug PAC-MAN RED :)

Edited by theloon

Share this post


Link to post
Share on other sites

@RevEng: Going over the CPU cycles seems to be a serious no-no but I don't understand why. Can it blitzkrieg the entire game or just make funny noise on the screen when it happens? Bataris kernel isn't going over the CPU cycles right? Just my amateur game logic code (I think, dunno).

Right, it's not the kernel, it's the bB code. The reason using too many cycles is undesirable is because it causes the overscan part of the TV frame to have too many lines, which is quite likely to cause screen jittering or rolling.

 

The "ideal" TV frame generated from a 2600 game is made up of these parts and these line counts:


  • [VSYNC.............3 lines]
    [VBLANK...........37 lines]
    [VISIBLE SCREEN..192 lines]
    [OVERSCAN.........30 lines]

The main part of your basic program runs in the overscan part of the TV frame until it hits a drawscreen command, at which point the rest of the frame parts are drawn. When overscan time beings again, control is returned to your basic code, just after the drawscreen command.

 

One way to avoid using too many cycles is to have multiple drawscreens strategically placed in CPU-heavy parts of your code. This approach won't work in the main loop of the game, as each drawscreen in your main loop will reduce the overall framerate, but it works well enough for screen setup code.

 

If you take this approach, you may want to set the colors of all screen elements to black until the screen is completely drawn, to avoid showing the screen as it's being built-up.

 

It's also worth mentioning that your basic program can also run partially in vblank with the vblank keyword, and similarly you don't want to use too many cycles there either, or else there will be too many vblank lines, which will cause jittering or rolling.

Share this post


Link to post
Share on other sites

Are you still working on this? I found this thread again while searching for bB adventure games. I wonder if the mix of 'collision prevention' and collision detection in this example program would be helpful:

 

http://www.randomterrain.com/atari-2600-memories-batari-basic-commands.html#sprite_ball_miss_coll_example

Share this post


Link to post
Share on other sites

Are you still working on this? I found this thread again while searching for bB adventure games. I wonder if the mix of 'collision prevention' and collision detection in this example program would be helpful:

 

http://www.randomterrain.com/atari-2600-memories-batari-basic-commands.html#sprite_ball_miss_coll_example

 

I appreciate the mention RT. I don't think I had a problem with collision. RevEng may have said I'm going over the cycle count but my last build plays okay on a real 2600. I've been itching to flog my source code to the fellas in the Atari Roguelikes topic but, nah :)

 

The point I got "stuck" on was adding more items and monsters. Either I ran into a bug or just lost steam at that point. Saying I quit would imply a deadline. This is just on hold until the urge takes me again.

 

Right now I'm working on a Sega Genesis title but NOTHING compares to bB and AtariAge (this includes YOU, whoever is reading this!). Hopefully by the time I'm done bB will be non-beta with DPC+ support. Can't wait!

Edited by theloon

Share this post


Link to post
Share on other sites

I'm having trouble coming up with a cartridge sprite to replace the ring. Nothing I draw comes out convincing. Maybe I'll bug PAC-MAN RED :)

 

You mean like 2600 Carts? The top 3 are just color variations of the same sprite(sorry, sometimes I state the obvious :)):

 

post-26314-0-06963700-1313725076_thumb.png

2600 Cartridges.zip

 

 

And yes, we can hear you from the Atari Roguelikes thread. :D

 

Illya

Share this post


Link to post
Share on other sites
I appreciate the mention RT. I don't think I had a problem with collision.

I mentioned it because I noticed how your little guy was sticking on the walls and I thought you might be able to use part of the code from the example program to make it seem like the walls are coated in butter.

 

 

 

Hopefully by the time I'm done bB will be non-beta with DPC+ support. Can't wait!

When that day comes, I'll get a DPC+ tattoo on my forehead. :lust:

 

I can't wait to start using those 10 multicolored Imagic/Activision quality sprites.

Share this post


Link to post
Share on other sites
RevEng may have said I'm going over the cycle count but my last build plays okay on a real 2600.

...on your TV. Scanline issues are highly variable depending on what TV is used to view.

 

When you leave a room the scanline count goes from a regular 262 to 396. You may not notice glitching because it's a room transition and it's dark the next frame, but I'd expect to some TVs will roll and take another frame or two to stabilize.

Share this post


Link to post
Share on other sites

I can't wait to start using those 10 multicolored Imagic/Activision quality sprites.

Why wait? The dev kit is pretty much fully functional right now with a few quirks, but none of those are show stoppers :)

I'm finding the DPC+ support to be well implemented right now. Most of the issues can be accounted for and worked around.

Share this post


Link to post
Share on other sites
Why wait? The dev kit is pretty much fully functional right now with a few quirks, but none of those are show stoppers :)

 

I'm finding the DPC+ support to be well implemented right now. Most of the issues can be accounted for and worked around.

There is a style of teaching where the class has to try to solve a problem without knowing what they are doing, then when they are shown the correct way, the kids are supposed to remember it better. That doesn't work on me. I'll remember the wrong way to do it because it was first.

 

If I learn a bunch of workarounds, my brain will be cluttered with useless crap that won't work anymore after the DPC+ stuff is working perfectly. I'd rather stay a DPC+ virgin until everything is working the way it's supposed to.

Edited by Random Terrain

Share this post


Link to post
Share on other sites

@PAC-MAN-RED: Thanks! Was having major trouble visualizing an atari cart with so few pixels and colors. This gives me much more to go on!

 

@RevEng: Crud. I might have to rewrite the whole darn thing. That's OKAY since the code is so old it's pretty alien to me now :P

 

@Random Terrain: Thanks for the feedback. I didn't personally consider the collision style to be an issue. I'll try to be truer to the Adventure style.

 

@ScumSoft: Ya, workarounds suck. I've been spoiled working with bB 1.0 and its stability. Working with other compilers has given me a much greater appreciation of Freds dedication to bB.

Share this post


Link to post
Share on other sites

@RevEng: Crud. I might have to rewrite the whole darn thing. That's OKAY since the code is so old it's pretty alien to me now :P

I think you could probably solve the issue with a well placed extra drawscreen or two in your room loading routine.

 

But I understand if it's time for a do-over. After a prototype you generally understand the problem-space a lot better, and can make better coding choices the second time around.

Share this post


Link to post
Share on other sites

There is a style of teaching where the class has to try to solve a problem without knowing what they are doing, then when they are shown the correct way, the kids are supposed to remember it better. That doesn't work on me. I'll remember the wrong way to do it because it was first.

 

If I learn a bunch of workarounds, my brain will be cluttered with useless crap that won't work anymore after the DPC+ stuff is working perfectly. I'd rather stay a DPC+ virgin until everything is working the way it's supposed to.

Fair enough I suppose, however there are only I think 2 major workarounds that you need for things to work proper.

 

1)Add temp1 = temp1 right after a bank declaration to fix the stack bug. This can remain forever and not impair your game or future compilers.

2)Set kernel_options collision(playfield,player1) is required or else the code won't compile and adds the new collision detection routines.

 

Current other issue/bugs that I can recall offhand are:

* Colliding with virtual objects 2-9 from the top or bottom have a 5 pixel leeway in them and will only trigger a P0/P1 collision upon impact. Check with Y position to know which Virtual Px you hit.

* Taking a virtual player to Y = 0 will cause all other virtual players on the screen to temporarily adopt the X position of the Y = 0 player object.

* A few bB commands are missing and will cause you to deal with things differently for now (This is major for you I know)

* Stella and Harmony work completely different with ARM code, so things that look perfect on Stella during design may in fact not work at all on the Harmony.

 

I think that's almost all of the current bugs and inefficiencies of it. The other workarounds are subject to the game being designed at hand. You could try porting over your maze collision demo and see how it works out, and that might reveal some more issues yet undiscovered.

 

The following should be all you need for a DPC+ template.

 

 

 
; *****************************************************
; * BANK 1
; *****************************************************
bank 1
temp1 = temp1

set tv ntsc
set kernel DPC+
set smartbranching on
set optimization inlinerand
set kernel_options collision(playfield,player1) 

rem DEFINE VARS HERE

goto MAIN bank2

; *****************************************************
; * BANK 2
; ***************************************************** 
bank 2
temp1 = temp1

MAIN
 rem INSERT GAMEPLAY LOGIC
 goto MAIN

; *****************************************************
; * BANK 3
; ***************************************************** 
bank 3
temp1 = temp1

; *****************************************************
; * BANK 4
; ***************************************************** 
bank 4
temp1 = temp1

; *****************************************************
; * BANK 5
; ***************************************************** 
bank 5
temp1 = temp1

; *****************************************************
; * BANK 6
; ***************************************************** 
bank 6
rem temp1 = temp1 not required here as this bank is for graphics only
rem However I have placed my TitleScreen here with no apparent consequences 

 

Edited by ScumSoft

Share this post


Link to post
Share on other sites
Fair enough I suppose, however there are only I think 2 major workarounds that you need for things to work proper.

Thanks for the list and code.

Share this post


Link to post
Share on other sites

I've still got one other project to finish before I start focusing on this again. Nevertheless, recent topics mentioning Rogue have stirred me to do a little more concept work. It turns out people from the most popular Rogue forum don't remember a Rogue or Rogue-like being ported to the Atari 2600. Since the game was already starting to look like a Rogue-like I've decided to stick with it.

 

Talking about Rogue-likes has led me to believe these are what it boils down to (please correct me if I'm off):

* You must kill a boss and then come back up to the first level of the dungeon.

* Potions, rings, weapons and armor. Spell scrolls too, I think.

* Stupid, annoying (in my opinion) perma death and starvation.

* Monsters to wear you down.

 

These seem to be the best compromise on controls (again, I'd love suggestions):

Potions -> Short FIRE button press

Scrolls -> Long FIRE button press

Attack -> Contact with enemy

Feed -> Automatic use of equipped food when starvation reached

Armor -> Auto erasure of old armor and equip of new piece.

Weapon -> Auto erasure of old weapon and equip of new piece.

Ring -> Auto erasure of old ring and equip of new piece.

Use Stairwell -> Go upstairs/downstairs on contact.

 

I could just fix the level rendering code (uses too much CPU time) but I think I'll end up just using what I learned from the current codebase and rewriting the engine.

 

The real features that I learned from the source in the first post is:

* How to make a screen by stacking layers of horizontal playfield data.

* How to better randomize the pseudo random number generator by mixing in game variables.

* How to use instances of the pseudo random number to determine placement of in-game objects.

Edited by theloon

Share this post


Link to post
Share on other sites

I've been playing with theloon's code.

 

This is the result: http://pastebin.com/Wq8zKc08

 

My purpose was not primarily to rewrite or

streamline his code (although I ended up

doing a bit of that) but to put it in a

form that would make it easier to write the

play field bytewise from bB.

(if I were going to stream line it I think the

first thing I might try is replacing long strings

of if-thens with on-gotos)

 

The code draws the playfield in three pieces,

(which I called) top, mid, bot

Top and bot are three lines each and mid

is five lines.

 

There are 6 three line pieces and 8 five line

pieces to select from. Which gets drawn,

is selected by strings of if-thens (in the original

code) by the variable rclass and bits in tempvar.

rclass ranges from 0-14 and for each rclass (three)

bits of tempvar are used to select from one of two

possibilities each for top, mid and bot.

 

If you tabulate the possible selections (that are

actually in the code) there are four possible tops,

eight mids and four bots. (there are 4 bits of rclass

and 3 bits of tempvar giving a max 128 possibilities

however those 128 could be selected from a number

limited only by how much ROM you've got, but that's

not what's done)

 

I put all the 3 and 5 line pieces in a data statement.

Each rclass gets a pattern in pat_tbl.

The pattern is melded with tempvar to get three pointers

in to top_tbl, mid_tbl and bot_tbl which then points to

one of the 4, 8 or 4 (respectively) possibilities.

The contents of top_tbl, mid_tbl and bot_tbl are the

beginning location in the room_dat data statement for

their (respective) pieces which are to be written to the

playfield.

 

bit 0 of tempvar corresponds to the bottom piece

bit 1 to the middle piece and bit 2 to the top piece.

 

To get the pointers that point in to the top, mid and

bot tables:

First tempvar is overlaid with the pattern using eor.

 mid = pat_tbl[rclass]
bot = ((tempvar ^ mid) & %00000101) ^ mid

Bits two and three of the result are the top_tbl pointer

and are shifted into place with a division by four and

selected with an and mask

 top = bot / 4 & %00000011

The lower two bits of the result are the bot_tbl pointer

and are selected with an and mask

 bot = bot & %00000011

Then pattern is shifted with a divide by 16 (divding by

4 twice) and overlaid on the tempvar and the bottom three

bits masked to get the mid_tbl pointer.

 mid = mid / 4 / 4
mid = (((tempvar ^ mid) & %00000010) ^ mid) & %00000111

The results of those table lookups

 mid = mid_tbl[mid]
bot = bot_tbl[bot]
top = top_tbl[top]

which are the positions

in the data statement of the piece to be written are then

passed to the WRI_PF subroutine (one at a time) in dat_ptr

along with the location of the last byte to write in dat_last

and the location in the playfield of the first byte to be

written to in pf_ptr

 pf_ptr = 0 : dat_ptr = top : dat_last = top + 11
gosub WRI_PF
pf_ptr = 12 : dat_ptr = mid : dat_last = mid + 19
gosub WRI_PF
pf_ptr = 32 : dat_ptr = bot : dat_last = bot + 11
gosub WRI_PF

WRI_PF is just a for-next loop that reads

the data statement and writes to the playfield.

WRI_PF
for dat_ptr = dat_ptr to dat_last
pfbase[pf_ptr] = room_dat[dat_ptr]
pf_ptr = pf_ptr + 1
next
return thisbank

 

There are also four routines that create openings in the rooms.

I rewrote them to write bytes to the playfield instead of calling

pfpixel. They just do a series of read-mask-writes of the

appropriate bytes to the appropriate spots in the playfield. eg:

print_open_left
pfbase[16]=pfbase[16] & %00000011
pfbase[20]=pfbase[20] & %00000011
pfbase[24]=pfbase[24] & %00000011
return otherbank

  • Like 2

Share this post


Link to post
Share on other sites

I didn't count cycles exactly.

the for-next loop takes something more than twice as

long per byte, 34 cycles v 14 cycles than a playfield

statement but there's less overhead calling other banks

and no scrolling things into place. I figured they're

roughly equal but the for next loop probably does take

longer.

34 cycles x 44 bytes + a couple hundred overhead

is only a couple thousand cycles or so.

I don't think it's taking too long

 

But I'm not through. I expected to throw a few bytes

of asm in there to do the actual moving of bytes.

I just hadn't decided what would be the best way to

structure it. I want something somewhat general.

About as general as the for-next routine but perhaps

with the possibility of passing various data statements.

as a parameter.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...