Jump to content

Photo

Atari 8 Bit WIP: Escape the Night Garden

WIP work in progress atari 8 bit escape the night garden

72 replies to this topic

#1 snicklin OFFLINE  

snicklin

    River Patroller

  • 2,197 posts
  • Location:Australia

Posted Sun Nov 17, 2013 2:13 PM

I've been working on a new (well, it's been going on a while) project to bring a new game to the Atari. It is currently called "Escape the Night Garden" and can be viewed here:

 

http://www.youtube.c...h?v=kYArkNuj0L8

 

I would like to thank Miker for the music, I came across this track and just loved it, so I asked him if I could use it and he was happy to allow me to use the track. Thanks Miker!

 

Please don't be too harsh, it's my first attempt at programming a full game in MADS. A lot of work still needs to be done to get it into a working game.

 

It'll basically be a game where you have to get out of the maze (night garden in this case) by flicking switches in the right order and avoiding enemies (when they're fully programmed), I just need to get past a programming problem with MADS structs.

 

I'll better the graphics later, add a title screen, DLI's for more colour, extra levels, sprite animation, possibly more music if memory allows, additional fonts for more varied graphics and add a status bar at the bottom. At the moment you can also walk through walls, obviously that needs to be sorted.

 

Levels (24 screens) are compressed down to around 450 bytes. That'll take up more when colour schemes, disappearing doors and enemies are implemented.

 



#2 GroovyBee OFFLINE  

GroovyBee

    Games Developer

  • 9,821 posts
  • Busy bee!
  • Location:England

Posted Sun Nov 17, 2013 2:22 PM

Good start! You have an engine for various "Ultimate style" games there.

#3 snicklin OFFLINE  

snicklin

    River Patroller

  • Topic Starter
  • 2,197 posts
  • Location:Australia

Posted Sun Nov 17, 2013 2:43 PM

Funny you should mention that, as I am attempting to write in a way whereby I can re-use a lot of the code again.

 

I am writing the code with re-usable libraries. However I am fighting my instinct (which is to write all the libraries first, perfectly) and I am fighting that with what you said to me at the Replay Expo in '12, which was to write code that works first and then go back and refine it later. The two are clashing at the moment, but I am trying to go with your way of doing things, as long as my code is designed in a way that it can be amended easily to fit into a library.

 

I'm definitely seeing quicker progression with your way of doing it, which keeps me somewhat more interested in the programming.



#4 GroovyBee OFFLINE  

GroovyBee

    Games Developer

  • 9,821 posts
  • Busy bee!
  • Location:England

Posted Sun Nov 17, 2013 2:48 PM

Unless your code has to be cycle accurate or super optimised then a "code it first and then sanitise it later" approach is always more fun and keeps you motivated on the project in my opinion.

#5 Tezz OFFLINE  

Tezz

    River Patroller

  • 2,406 posts
  • Location:Manchester, England

Posted Sun Nov 17, 2013 2:53 PM

Well done Steve, great start :thumbsup:

 

+1 for writing rough code to get everything initially running and together to rework it later.



#6 snicklin OFFLINE  

snicklin

    River Patroller

  • Topic Starter
  • 2,197 posts
  • Location:Australia

Posted Sun Nov 17, 2013 2:54 PM

Nah, there's no super optimisation in there so that isn't a problem at the moment. Maybe if I get clever with midline DLI's later, possibly but not for now.

 

At the moment, I'm seeing progression each day which is keeping me interested.



#7 snicklin OFFLINE  

snicklin

    River Patroller

  • Topic Starter
  • 2,197 posts
  • Location:Australia

Posted Sun Nov 17, 2013 3:00 PM

Well done Steve, great start :thumbsup:

 

+1 for writing rough code to get everything initially running and together to rework it later.

 

It does seem to be paying off, though it goes against all my instincts!! Thanks!

 

If anyone here has experience with MADS structures and can let me know how to reference one with a variable for the index, please let me know.

 

I want a big array of enemy struct data. Then each one will have a room designated to them. When entering a room, I then want to go through all the enemies until I find one that is designated for that specific room or alternatively, no enemy is found. The moving ball that you see in the first room is my placeholder code for handling enemies. Each enemy will have an initial X and Y within the room and will follow a formation of movements.



#8 Creature XL OFFLINE  

Creature XL

    Dragonstomper

  • 904 posts
  • Location:Hannover.De

Posted Mon Nov 18, 2013 4:16 PM

Well done Steve, great start :thumbsup:
 
+1 for writing rough code to get everything initially running and together to rework it later.


Honestly I do not favor that method. We all know he won't rework it later. There is always just one feature to be added before redesigning the code :-)

Be aware, we aren't talking optimization. On this matter I am all for make it working before optimizing. But restructuring? We will see:-)



#9 Creature XL OFFLINE  

Creature XL

    Dragonstomper

  • 904 posts
  • Location:Hannover.De

Posted Mon Nov 18, 2013 4:21 PM

 
It does seem to be paying off, though it goes against all my instincts!! Thanks!
 
If anyone here has experience with MADS structures and can let me know how to reference one with a variable for the index, please let me know.
 
I want a big array of enemy struct data. Then each one will have a room designated to them. When entering a room, I then want to go through all the enemies until I find one that is designated for that specific room or alternatively, no enemy is found. The moving ball that you see in the first room is my placeholder code for handling enemies. Each enemy will have an initial X and Y within the room and will follow a formation of movements.


I use ca65 so no help here.
However, in HeliCave I took the other way.
I have a table for every room where, besides other stuff, the enemies with their start attributes are listed. And for me it worked rather well. Scanning enemy structures each time sounds like a lot of work.


#10 snicklin OFFLINE  

snicklin

    River Patroller

  • Topic Starter
  • 2,197 posts
  • Location:Australia

Posted Mon Nov 18, 2013 4:21 PM

Honestly I do not favor that method. We all know he won't rework it later. There is always just one feature to be added before redesigning the code :-)

Be aware, we aren't talking optimization. On this matter I am all for make it working before optimizing. But restructuring? We will see:-)

 

Honest opinion.... when I am happy with the final output, I'll release the game just to get it "out of the door". Then I believe that I will rework the code, but only so that I can use the libraries that I am creating in the process of doing this for projects.

 

Complete rewrite - no, some rewrite - yes.



#11 flashjazzcat OFFLINE  

flashjazzcat

    Quadrunner

  • 14,498 posts
  • Location:United Kingdom

Posted Mon Nov 18, 2013 4:26 PM

If anyone here has experience with MADS structures and can let me know how to reference one with a variable for the index, please let me know.
 
I want a big array of enemy struct data. Then each one will have a room designated to them. When entering a room, I then want to go through all the enemies until I find one that is designated for that specific room or alternatively, no enemy is found. The moving ball that you see in the first room is my placeholder code for handling enemies. Each enemy will have an initial X and Y within the room and will follow a formation of movements.

 
I found the best way to use structs in that manner is to define a pointer to the struct array and then use the struct tags as offsets in the Y register, thus:

ldy #Enemy.Room
lda (Enemy_Pointer),y
You'd advance the pointer like this:

adc # [.len Enemy]
Or you could use a look-up table or similar for the array element addresses.
 
Anyway - that's the way I use arrays of structs. I don't define them as static: I just allocate a buffer large enough to hold n * [.len Struct] and index it as above.
 
 

Honestly I do not favor that method. We all know he won't rework it later. There is always just one feature to be added before redesigning the code :-)

Be aware, we aren't talking optimization. On this matter I am all for make it working before optimizing. But restructuring? We will see:-)

 
Heh... it can be reworked later (and it does happen) - it just takes longer (in the long-term) than getting it just so in the first place. :)

Edited by flashjazzcat, Mon Nov 18, 2013 4:27 PM.


#12 snicklin OFFLINE  

snicklin

    River Patroller

  • Topic Starter
  • 2,197 posts
  • Location:Australia

Posted Mon Nov 18, 2013 4:31 PM

I use ca65 so no help here.
However, in HeliCave I took the other way.
I have a table for every room where, besides other stuff, the enemies with their start attributes are listed. And for me it worked rather well. Scanning enemy structures each time sounds like a lot of work.

 

I used to use CC65/CA65 but then went it against it due to sizing problems.

 

Anyway, so you use a table, I assume that uses room characters/tiles as well as enemies and so forth? My implementation doesn't lend itself to that. I use CharPad 1.0 to draw the map, I then have a Perl script which compresses the level (4x6) rooms. Then within the code, I decompress the whole level to memory. But this works level by level and doesn't include any enemy data, which I am loading from hand-made binary files.

 

Does anyone know of a good cross-development product for saving enemy properties to file?

 

I currently have the following properties.....

 
    defaultX .byte
    defaultY .byte
    level .byte
    room_x .byte
    room_y .byte
    animateFrameTotal .byte
    defaultColour .byte
    defaultEnergy .byte
    defaultAwake .byte
    defaultAnimationID .byte
    harmful .byte
    graphicID .byte    
 
If you're wondering what "harmful" is, it is a value which represents how many energy points are taken away from the user on touching it. I would like to have birds flying overhead, a bit like in Cannon Fodder which are harmless, so they will have a value of '0'.
 
I've seen tools that draw graphics and levels and so forth, but nothing which handles properties. Something *must* exist....


#13 snicklin OFFLINE  

snicklin

    River Patroller

  • Topic Starter
  • 2,197 posts
  • Location:Australia

Posted Mon Nov 18, 2013 4:39 PM

 I found the best way to use structs in that manner is to define a pointer to the struct array and then use the struct tags as offsets in the Y register, thus:

ldy #Enemy.Room
lda (Enemy_Pointer),y
You'd advance the pointer like this:
adc # [.len Enemy]
Or you could use a look-up table or similar for the array element addresses.
 
Anyway - that's the way I use arrays of structs. I don't define them as static: I just allocate a buffer large enough to hold n * [.len Struct] and index it as above.

 

Perfect! Just what I was looking for! (+1 is deserved). Right, my next line of attack will be to implement some enemies.

 

I've just designed the graphics for him walking in different directions (which uses plenty of memory), but haven't written the code to animate him just yet.



#14 Creature XL OFFLINE  

Creature XL

    Dragonstomper

  • 904 posts
  • Location:Hannover.De

Posted Mon Nov 18, 2013 4:48 PM

No. Tiles go extra. I paste some code tomorrow. There is only a pointer to the room layout.
One reason to code structured from the beginning is that debugging is much easier :-)
At Charpad, used that for Har'em and it works kinda.

#15 Creature XL OFFLINE  

Creature XL

    Dragonstomper

  • 904 posts
  • Location:Hannover.De

Posted Mon Nov 18, 2013 4:51 PM

The part about sizing problems I don't get. I was talking ca65 not cc65. It is an awesome assembler and the linker is fantastic when you have to reorder your memory layout'

#16 snicklin OFFLINE  

snicklin

    River Patroller

  • Topic Starter
  • 2,197 posts
  • Location:Australia

Posted Mon Nov 18, 2013 5:00 PM

The part about sizing problems I don't get. I was talking ca65 not cc65. It is an awesome assembler and the linker is fantastic when you have to reorder your memory layout'

 

Fair enough for CA65, I mean't CC65 with CA65! Sorry!


Edited by snicklin, Mon Nov 18, 2013 5:01 PM.


#17 Tezz OFFLINE  

Tezz

    River Patroller

  • 2,406 posts
  • Location:Manchester, England

Posted Mon Nov 18, 2013 6:06 PM

+1 for writing rough code to get everything initially running and together to rework it later.

Just to clarify, what I meant by "writing rough code" was to not be too pedantic in the early stages and enjoy evolving your code :)


Edited by Tezz, Mon Nov 18, 2013 6:07 PM.


#18 snicklin OFFLINE  

snicklin

    River Patroller

  • Topic Starter
  • 2,197 posts
  • Location:Australia

Posted Tue Nov 19, 2013 1:16 AM

Just to clarify, what I meant by "writing rough code" was to not be too pedantic in the early stages and enjoy evolving your code :)

 

It's OK, I got what you meant. And yes, it seems good.



#19 TMR OFFLINE  

TMR

    River Patroller

  • 3,473 posts
  • Beeping the horn on the data bus
  • Location:Leeds, U.K.

Posted Tue Nov 19, 2013 2:27 AM

i just write any old crap and just hit it repeatedly until it works... =-)

#20 Mclaneinc OFFLINE  

Mclaneinc

    Retro Madman

  • 6,567 posts
  • Location:Northolt, UK

Posted Tue Nov 19, 2013 3:34 AM

i just write any old crap and just hit it repeatedly until it works... =-)

 

Yes, we noticed :)

 

Nah, you know I love the stuff you put out, shooters are my bread and butters...Hail to Atari Ages Andrew Braybrook clone :)



#21 Heaven/TQA ONLINE  

Heaven/TQA

    Quadrunner

  • 11,212 posts
  • Location:Baden-Württemberg, Germany

Posted Tue Nov 19, 2013 4:22 AM

Just to clarify, what I meant by "writing rough code" was to not be too pedantic in the early stages and enjoy evolving your code :)

 

isn't that called nowadays "agile" or "rapid development"? ;)



#22 Creature XL OFFLINE  

Creature XL

    Dragonstomper

  • 904 posts
  • Location:Hannover.De

Posted Tue Nov 19, 2013 4:32 AM

The posts I made yesterday were made on my tablet while lying in bed and they were in no way meant to tell anybody how to anything and what tools to use and how to develop.

 

The purpose of these posts was to tell you something I experienced in the last three years while developing A8 games (MJO, HAR'em and HitC). So you should clearly value the opinion of those which much longer experience higher :)

 

 

 

 

 

I used to use CC65/CA65 but then went it against it due to sizing problems.

 

Anyway, so you use a table, I assume that uses room characters/tiles as well as enemies and so forth? My implementation doesn't lend itself to that. I use CharPad 1.0 to draw the map, I then have a Perl script which compresses the level (4x6) rooms. Then within the code, I decompress the whole level to memory. But this works level by level and doesn't include any enemy data, which I am loading from hand-made binary files.

 

Does anyone know of a good cross-development product for saving enemy properties to file?

 

I currently have the following properties.....

 
    defaultX .byte
    defaultY .byte
    level .byte
    room_x .byte
    room_y .byte
    animateFrameTotal .byte
    defaultColour .byte
    defaultEnergy .byte
    defaultAwake .byte
    defaultAnimationID .byte
    harmful .byte
    graphicID .byte    
 
If you're wondering what "harmful" is, it is a value which represents how many energy points are taken away from the user on touching it. I would like to have birds flying overhead, a bit like in Cannon Fodder which are harmless, so they will have a value of '0'.
 
I've seen tools that draw graphics and levels and so forth, but nothing which handles properties. Something *must* exist....

 

 

 

Here is a table for one room:

room_33:
		.word	ROOM_part0_33


	; Modification tiles pointer
		.word	mtiles_33


	; Dynamic tiles
		.word	0
		.byte	DTILE_X0
		.word	tab_phases_dt0


	; Cannon pointer
		.word	cannons_none


	; NPCs
		.byte	4

		.byte	-1,19*8,22*8,250
		.byte	NPC_TYPE_TANK,20*8,2*16,(5<<5)|1

		.byte	1,18*8+4,24*8-5,90
		.byte	NPC_TYPE_TANK,24*8,8*16,(5<<5)|5

		.byte	1,4*16,7*16,0
		.byte	NPC_TYPE_UPDOWN,26*8+3,50,(6<<5)|2

		.byte	0,1,9*8+3,3*16
		.byte	NPC_TYPE_HCIRC,0,0,(7<<5)|3

The romms layout (the tiles) are referenced by a pointer "ROOM_part0_33". That way I can use the same basic layout for more then one room. The modifications tile pointer points to a list where I can define tiles which should be set at a specific lcoations. So I can modifiy the basic rooms. For example walls or exits and stuff like that. Dynamic tiles are tiles you can shoot, cannons points to a list of cannons to set in the room (not implemented in the ABBUC version) and then finally the NPCs

 

First the numbr of NPCs in the room (4 in this case).

Followed by 4 initial values for the 4 variables each NPC can use. You have to know, for each NPC type there is as routine which gets called each frame. Then the type and the start location of the sprite. The last value is the PMG to use as overlay (5-7) and the soft-sprite  to use (1-5).

When a room  is entered this table is used to prepare the room.

 

This might not be the perfect solution, but it let's me make interesting stuff. BTW, one NPC can be combined with another and so on.



#23 Heaven/TQA ONLINE  

Heaven/TQA

    Quadrunner

  • 11,212 posts
  • Location:Baden-Württemberg, Germany

Posted Tue Nov 19, 2013 4:34 AM

 

Perfect! Just what I was looking for! (+1 is deserved). Right, my next line of attack will be to implement some enemies.

 

I've just designed the graphics for him walking in different directions (which uses plenty of memory), but haven't written the code to animate him just yet.

 

Beyond Evil I am using similar approach. Maybe today I would do it more optimised but that's how I do the monster "structs". as far as I remember I have nearly 32 stats per monster...



#24 snicklin OFFLINE  

snicklin

    River Patroller

  • Topic Starter
  • 2,197 posts
  • Location:Australia

Posted Tue Nov 19, 2013 10:52 AM

 

Beyond Evil I am using similar approach. Maybe today I would do it more optimised but that's how I do the monster "structs". as far as I remember I have nearly 32 stats per monster...

 

 

And the more in-depth that I think about my enemy characters, the more stats I keep adding.

 

Apparently in the first "Theme Park" game, every person that walked around had 1kb of stats associated with them.

 

I could do some bit-packing, but the routines to extract the values may end up being more bytes than the actual current data.



#25 snicklin OFFLINE  

snicklin

    River Patroller

  • Topic Starter
  • 2,197 posts
  • Location:Australia

Posted Sun Nov 24, 2013 8:07 AM

Added: Dynamic enemies : Enemies can appear in rooms defined to contain them.

Added: Enemy speed : Different enemy speeds set up.

Added; Different coloured enemies

Improved: Transparent ball graphic for enemy changed to a solid ball shape.

Added: Broken fences

Added: Double layers of trees

Improved: Slightly cleaned up the graphics on the level.

Improved: Diagonal blocks cleaned up a bit

Improved: PMG priority, PMGs are now in the foreground.

Added: Enemy types added within a new data structure, less duplication of data required.

 

Next few planned improvements:

1) Different enemies use different graphics

2) Enemies follow paths, not just going from left to right.

3) Remove corrupted sprite on 1st screen when game started (but not when re-entered).


Edited by snicklin, Sun Nov 24, 2013 8:15 AM.






Also tagged with one or more of these keywords: WIP, work in progress, atari, 8 bit, escape, the, night, garden

0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users