Jump to content
  • entries
    53
  • comments
    536
  • views
    68,404

My 1K Game Attempt


Guest

1,302 views

BreakthroughGame design by Dan Troyka (playable demo with dumb AI)Breakthrough is a fast paced board game with easy-to-learn rules. The winner is the first to get one of 14 pieces across to the last row. Pieces move forward one square vertically or diagonally, and they can capture diagonally. Because pieces always move forward, games end quickly. There are no draws.Your side is Silver. To move a piece, place the cursor there, hold the fire button, and push left or right to move diagonally or up to move vertically.Whether I succeed in making this a 1K game depends on how compact I can make the game logic and AI. I chose Breakthrough because the rules are so simple. I admit it's a long shot, but since I submitted a game last year, I feel comfortable taking more of a risk.The kernel alone is 580 bytes right now, but there is a lot of room for optimization. I could have re-used the Four-Play kernel, but it was fun to come up with something new. Does anyone care to guess how I managed 7 sprites with color changes (without using z26 tricks)? EDIT: Solved by supercat.For more information about Breakthrough, try Wikipedia.Here is the code for drawing and coloring the 7 shields:
;Values loaded by PLA serve three purposes. The high nybble;is used for shifting missiles, and the low nybble provides;shield color shading and also serves as an index for;looking up shield graphics.PLA_these       .byte $0e,$0e,$0e,$0c,$0c,$0c,$0a,$0a,$0a,$08,$08,$08       .byte $F6,$06,$06,$F5,$05,$F4,$00DynamicCode                  sta HMOVE; Covers left stripe and moves missiles      jmp StaticCode; Next few lines do not need to be in RAM. StaticCode  ; These lines are separated in the actual code         ora #$10; loaded by PLA. ORA forces color to gold      tay    ; number also serves as an index             lda shield-16,y; obtain shield graphics.      sta GRP0               sta GRP1+64-CURSORCOLOR,X; same as STA GRP1, but 1 cycle longer         tya    ;              and #$0F; Forces color to silver              jmp BackToRAMBackToRAM      sta COLUP1; 1st piece. STA draws a silver shield      sax COLUP1; 2nd piece. SAX draws a blank      sty COLUP0; 4th piece. STY draws a gold shield      stx COLUP1; 3rd piece. STX draws the cursor.      ldx M0size-16,y          stx NUSIZ0      ldx #CURSORCOLOR;The low nybble of X must be 0.      sta COLUP0             sta COLUP1; M1: left side of 7th sprite      sty COLUP0       sta COLUP0; M0: right side of 7th sprite      pla      sta HMM0      and #$1F  ; Changes right shift to left               sta HMM1                 bne DynamicCode      jmp ReturnFromDynamicCode; Will be changed to BRK during optimization

P.S. Manuel, you were actually right when you guessed I was doing a racing game! I only denied it before because I was thinking of something like Pole Position.

13 Comments


Recommended Comments

Looks like an interesting game. I think it will be quite a challenge to fit the AI into 1K, but I'm sure you will have fun trying!

 

Does anyone care to guess how I managed 7 sprites with color changes (without using z26 tricks)?

 

Could the sprites simply be masks over the background colours?

 

Chris

Link to comment

Hi there!

 

P.S. Manuel, you were actually right when you guessed I was doing a racing game! I only denied it before because I was thinking of something like Pole Position.

 

Admittedly that's what I was thinking, I really thought it being a night scene from "Monaco GP", where you just see the lights of your car ;)

 

Of course, i should've known that it'll be another board game :)

 

Greetings,

Manuel

Link to comment
Looks like an interesting game.  I think it will be quite a challenge to fit the AI into 1K, but I'm sure you will have fun trying!

 

Does anyone care to guess how I managed 7 sprites with color changes (without using z26 tricks)?

 

Could the sprites simply be masks over the background colours?

 

Chris

 

Another way to possibly do it (it wasn't done in this case however) would be to widen the sprites and display two pieces with one sprite.

Link to comment
Another way to possibly do it (it wasn't done in this case however) would be to widen the sprites and display two pieces with one sprite.

 

Except that you can't have wide sprites and multiple copies at the same time...

 

Chris

Link to comment

Hi there!

 

Except that you can't have wide sprites and multiple copies at the same time...

 

Uhm... but you can :)

 

I don't remember the trick in detail, but there's a demo in the [stella] archives that does it, showing two big dragons. I think the "meltdown" prototype also does that.

 

Greetings,

Manuel

Link to comment
Could the sprites simply be masks over the background colours?

 

Good guess. That's close to how the Four-Play demo works, but as far as I can see, to form the shields you would still need more than six sprites+color changes.

Link to comment
Hi there!

 

Except that you can't have wide sprites and multiple copies at the same time...

 

Uhm... but you can :)

 

I don't remember the trick in detail, but there's a demo in the [stella] archives that does it, showing two big dragons. I think the "meltdown" prototype also does that.

 

Greetings,

Manuel

I've heard of that trick used in Meltdown, but as I recall z26 does not support that trick. The kernel posted here does work in z26.

Link to comment

Based on the screen shots, I would guess that P0 and P1 are set for three copies wide, with P0 placed at position 28 and P1 placed at 44. This gives P0 copies at 60 and 92; P1 copies at 76 and 108. M0 starts at position 60 at size=3 (8 pixels) and M1 at position 63 with size=2 (4 pixels). On later scan lines, M0 is repositioned and resized; M1 can start enabled, but will only visible when M0 is at position 61 and size=2. Below that, it should be disabled.

 

COLUP0 and COLUP1 can be set up for the first two sprites before the beam reaches the first one. After the beam leaves the first sprite, there will be 88 pixels (about 28-29 cycles) before the beam reaches the left edge of the exposed M0, and another 4 pixels (29-30 cycles total) before it reaches the exposed part of M1.

 

So in 30 cycles it's necessary to do five color-register loads, then do an extra store to one of them. So 27 cycles to do five loads. Really not a problem at all if the accumulator is preloaded with the first value and if direct-mode accesses will suffice for the rest. Since there are a few blank scan lines between rows, direct-mode accesses shouldn't be a problem.

 

note: I'm the guy who did Strat-O-Gems. :) Only six gems in a row, not 7, but they're close-spaced.

 

note2: Shading could be accomplished by storing "delta" values in RAM rather than constants.

Link to comment
Based on the screen shots, I would guess...

Looks good, supercat. The details are a little different, but you got the gist of it. The 7th sprite is indeed drawn with missiles. M0 is shifted and changes size, and M1 is constant at 2 pixels and shifted to the left rather than disabled. Your way looks like it might have some advantages in terms of saving code space. :)

Link to comment
Looks good, supercat. The details are a little different, but you got the gist of it. The 7th sprite is indeed drawn with missiles. M0 is shifted and changes size, and M1 is constant at 2 pixels and shifted to the left rather than disabled. Your way looks like it might have some advantages in terms of saving code space. :)

 

My way as I'd envisioned it actually wouldn't work because of the need to support black squares. On the other hand, I'd offer you a nice alternative: using X to hold a scan line count, make use of the wonderful SAX instruction. Starting with the electron beam about 9-10 pixels to the left edge of the first player...

 lda Column1
 sax COLUP0
 lda Column2
 sax COLUP1
 lda Column3
 sax COLUP0
 lda Column4
 sax COLUP1
 lda Column5
 sax COLUP0
 lda Column6
 sax COLUP1
 lda Column7
 sax COLUP0
 sax COLUP1

Use color values of $8F for blue, $1F for yellow, and $00 for black. No self-modifying code needed.

Link to comment
I'd offer you a nice alternative: using X to hold a scan line count, make use of the wonderful SAX instruction...

Thanks John, unfortunately I am having trouble finding time to update GRP0, GRP1, HMM0, NUSIZ0, and ENAM1, plus doing a STA HMOVE and a branch. It would have been nice to forgo self-modifying code.
Link to comment
Thanks John, unfortunately I am having trouble finding time to update GRP0, GRP1, HMM0, NUSIZ0, and ENAM1, plus doing a STA HMOVE and a branch. It would have been nice to forgo self-modifying code.

 

If you're trying to do a 1K game and have any sort of AI, I'd suggest simply storing 255 in GRP0, GRP1, and ENAM1 and not bother updating them while drawing the pieces. Sure the pieces would just be squares, but given a choice between spending 50 bytes on improved piece graphics or 50 bytes on the AI, I'd favor the AI.

 

If you do want to go for the piece graphics, let's see what you'd need:

--Seven color loads and eight color stores (all ZP mode) 45 cycles

--Indexed load, and direct stores to HMM0 and ENAM1. 10 cycles

--Indexed load, and direct stores to HMOVE and NUSIZ0. 10 cycles

--Indexed load, and direct stores to GRP0 and GRP1. 10 cycles

 

75 cycles, without the DEX or BPL. If the loop were unrolled slightly you'd have plenty of time, but that woud probably use too much code for a 1K game.

 

Actually, self-modifying code might be good if the code to generate it in RAM is sufficiently compact. And it may be possible to do some interesting things with register usage.

 

For example, if A goes from $1F to $12, X goes from $8F to $82, and Y stays at $00, you could show a blank square (STY), a yellow piece (STA), a blue piece (STX), or a white piece (SAX). The latter might be handy for use as a cursor.

Link to comment

First I'll get the game working, then I'll see if anything needs to be compromised. But yeah, if it's a choice between graphics or AI, AI should prevail. However, compromises would only be for the minigame compo. If I have to use rectangular pieces for 1K, I'll still make a version with full graphics. Perhaps I'll publish it as a bonus game with Four-Play.

 

Anyway, I've attached a new version, fully playable with dumb AI. To move a piece, place the cursor there, hold the fire button, and push left or right to move diagonally or up to move vertically.

Link to comment
Guest
Add a comment...

×   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...