{"id":10661,"date":"2025-02-15T17:49:26","date_gmt":"2025-02-15T17:49:26","guid":{"rendered":"https:\/\/www.gamelab.ch\/?p=10661"},"modified":"2025-05-29T15:13:25","modified_gmt":"2025-05-29T15:13:25","slug":"nanogames-zax256b-shootemup-in-256-bytes-on-a-c64-deluxe-variante-mit-384-bytessizecoding","status":"publish","type":"post","link":"https:\/\/www.gamelab.ch\/?p=10661","title":{"rendered":"NanoGames: ZAX254b ShootEmUp in 254 Bytes on a c64 &#8211; Deluxe version with 384 Bytes(SizeCoding) 2025"},"content":{"rendered":"\n<p>See also: SizeCoding\/Nanogames as a method of science: <a rel=\"noreferrer noopener\" href=\"https:\/\/research.swissdigitization.ch\/?p=2819\" target=\"_blank\">https:\/\/research.swissdigitization.ch\/?p=2819<\/a><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"904\" height=\"602\" src=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-17.18.36.png\" alt=\"\" class=\"wp-image-10671\" srcset=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-17.18.36.png 904w, https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-17.18.36-300x200.png 300w, https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-17.18.36-768x511.png 768w\" sizes=\"(max-width: 904px) 100vw, 904px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/02\/movie.mp4\"><\/video><\/figure>\n\n\n\n<p>What is a ShootEmUp? This question alone answers the outcome of a nanogame development. But perhaps this will only crystallize during nanogame development and the definition will have to be changed several times to make it appear feasible.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The ShootEmup &#8211; the tasks<\/h2>\n\n\n\n<p>As we all know, there are a large number of different ShootEmUps. The simplest variant remains the subgroup of Space Invaders and later Galagas. Here the management\/game mechanics are mostly based on the management of sprites independently of a background (or interactions with the background, see Xevious etc.) This means that only one type of object has to be managed (see games such as Breakout).<\/p>\n\n\n\n<p>The most important interactions\/queries are collisions. There are two different types of objects.<\/p>\n\n\n\n<p><br><strong>Own\/Avatar objects: <br><\/strong><\/p>\n\n\n\n<p>Your own objects are divided into the avatar and the shot(s).<br>Avatar controls: Left and right of the avatar. Limitation of left and right.<br>Shooting: This interaction was also replaced by autofire in the previous case (idea from a nanogame developer). Less code<br>Shoot: Moves up.<\/p>\n\n\n\n<p><br><br><strong>Enemy objects:<br><\/strong>The classic opponents react to the shot (destruction) and the shots (are not destroyed by the shots). To simplify matters, the enemy shots have been deleted in this case (additional cases: shot does not hit shot).<br>Enemy objects fall downwards. Move neutrally or tend towards the avatar.<\/p>\n\n\n\n<p><br><br><strong>Fail condition<\/strong>:<br><\/p>\n\n\n\n<p>The opponents come behind the avatar and\/or hit the avatar. In this case, however, the second implementation was deactivated again because the game was too difficult.<\/p>\n\n\n\n<p>A concept similar to the one presented here was also used for a 256-byte nanogame for PICO8 for the LoveByte competition 2024.<\/p>\n\n\n\n<p>Look also at  <a rel=\"noreferrer noopener\" href=\"https:\/\/demozoo.org\/productions\/338037\/\" target=\"_blank\">TaipDefendor_256b<\/a> (256 Bytes) and here the deluxe variant  <a rel=\"noreferrer noopener\" href=\"https:\/\/demozoo.org\/productions\/319896\/\" target=\"_blank\">ION382b<\/a> (386 Bytes in the fantasy console pico8)<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"ion_382b - nanogame by la1n | Alternative\/Oldschool Realtime Compo | MountainBytes 2023\" width=\"640\" height=\"360\" src=\"https:\/\/www.youtube.com\/embed\/7DG-wI8ghDM?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Classic implementation: separate\/encapsulated code &#8211; impossible<\/h2>\n\n\n\n<p>Even with this adaptation, a classic implementation is not possible. It simply requires far too much code.<\/p>\n\n\n\n<p>A classic implementation would be: Separation of all important parts into individual sections or functions.<\/p>\n\n\n\n<p>At least the following events:<\/p>\n\n\n\n<p>_Init game field (background)<br>_Init game objects<br>_In the loop<br>__Handling of the individual objects &#8211; Behavior<br>__Collision of objects (all collide with each other or with the avatar) &#8211; Score handling<br>__Drawing the objects<br>__Abort condition (GameOver)<br>_Score display The only option is further simplification and radical integration. This means double or triple use of existing structures.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Selection of the game medium (hardware)<\/h2>\n\n\n\n<p>Displaying in particular is a major problem in ShootEmUp, as the objects\/sprites move freely &#8211; at least by default in this genre. This is a major problem, especially on older platforms, as bytes have to be shifted, the background has to be restored after use, etc. Older systems also lack the option of simply deleting everything and redrawing it again (see Pico8).<\/p>\n\n\n\n<p>The only thing that usually helps here is to select a system that comes with the appropriate hardware (hardware sprites) and has low initial costs.<\/p>\n\n\n\n<p>The Atari ST (no hardware simplifications at all)\/Amiga (init too complicated) are additionally handicapped in that all commands consume an average of 4 bytes, leaving 64 commands for a 256 byte nanogame. The tests to try it were not very successful. Precisely because there are no default graphics (character set) that can be used. There is only one possibility left. Using the existing graphics of the start screen and working with the blitter from here. Initial experiments were promising.<\/p>\n\n\n\n<p>Nevertheless, the promising horse here was an 8-bit computer with sprites (an 8-bit console such as Intellivision would of course also be possible): C64.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Hardware &#8211; a Challenge<\/h2>\n\n\n\n<p>The C64 is an 8-bit processor and requires an average of 2 bytes per command. One byte for the command and one byte for the argument.<\/p>\n\n\n\n<p>So you have to get by with 128 commands for a game, in this case a ShootEmUp. Of course, the hardware equipment with its Petscii font\/charset also helps<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Two Games &#8211; 254 bytes und &#8222;Deluxe&#8220; 384 Bytes Versions<\/h2>\n\n\n\n<p>In this case, two versions were created: a 254-byte version and an expanded version with 384 bytes. This also allows you to compare what you can do with 130 bytes more. However, the basic mechanics and programming have remained largely the same. The deluxe version is discussed at the end.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">ZAX254 &#8211; 254 Bytes<\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"904\" height=\"602\" src=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-17.18.36-1.png\" alt=\"\" class=\"wp-image-10673\" srcset=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-17.18.36-1.png 904w, https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-17.18.36-1-300x200.png 300w, https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-17.18.36-1-768x511.png 768w\" sizes=\"(max-width: 904px) 100vw, 904px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">The game in action<\/h3>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/02\/movie.mp4\"><\/video><\/figure>\n\n\n\n<p>The game is a simple shooter. The white avatar can move left and right and fires a shot continuously. If an opponent is hit (C64 hardware collision detection), the shot moves back to the beginning of the screen. At the same time, a dot is printed in the background (a score-display is difficult to achieve in less than 256 bytes &#8211; see Deluxe version). It (enemey) continues to move downwards and with the counter to the right until it crosses a threshold and then flies towards the avatar.<br>If an opponent cannot be stopped and gets behind the avatar&#8217;s position, it is GameOver. The game than restarts and writes down many characters again. It is the gameover. And now you can score again. However, the previous game remains visible and the current score is comparable. The high score is therefore in the background. <strong>An interesting side effect is that this gives the game a background.<\/strong> The background is deliberately not graphically colorful (there are variations that are) so that the game remains playable.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"926\" height=\"600\" src=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.09.58.png\" alt=\"\" class=\"wp-image-10687\" srcset=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.09.58.png 926w, https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.09.58-300x194.png 300w, https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.09.58-768x498.png 768w\" sizes=\"(max-width: 926px) 100vw, 926px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">GameObject\/Sprite management: Sprites &#8211; the data structure<\/h3>\n\n\n\n<p>Sprites are used as the data structure. These have predefined and used memories. All management and movement is done directly here. The coordinates are changed and updated immediately. Sprites are also cpu cost-neutral, they are drawn last on the screen and leave nothing in the memory that needs to be cleaned up.<\/p>\n\n\n\n<p>The division of the sprites is static and looks like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-19.20.29.png\" alt=\"\" class=\"wp-image-10680\" width=\"244\" height=\"469\" srcset=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-19.20.29.png 482w, https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-19.20.29-156x300.png 156w\" sizes=\"(max-width: 244px) 100vw, 244px\" \/><\/figure>\n\n\n\n<p>This makes it easy to distinguish between your own and your opponents (&gt;1).<\/p>\n\n\n\n<p>The coordinates are stored in the memory one after the other from address $d000 (always first the X and then the Y coordinate.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Code &#8222;explained&#8220;<\/h3>\n\n\n\n<p>All variables are not contained in the program but are fixed addresses in free memory.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ VARS (direct in memory)\n\n.var tmpx = $3000\n\/\/tmpx: .byte 0 \/\/ x position of avatar\n.var tmpy = tmpx +1 \n\/\/tmpy: .byte 0 \/\/ x position of avatar\n\n.var tmp = tmpx +2\n\/\/ tmp: .byte 0\n\n.var col = tmpx +3\n\/\/ col: .byte 0 \n\n.var ind = tmpx +4\n\/\/ ind: .byte 0\n\n.var counter = tmpx +5 \n\/\/ counter: .byte 0<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Flow<\/h3>\n\n\n\n<p>The code follows the following sequence<\/p>\n\n\n\n<p>First, the most important things are initialized:<\/p>\n\n\n\n<p>_ The screen is cleared with a BasicRom function<br>_ The colors are set to black<\/p>\n\n\n\n<p>The code for this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>start:  \n    \/\/ --------------------------\n    \/\/ clear screen\n    \/\/ --------------------------\n    jsr $E544 \n\nrestart:\nstart_all:\n        \/\/ ----------------------\n        \/\/ back to black\n        \/\/ ----------------------\n        lda #0 \/\/ color black\n        sta $D020 \/\/ screen border register\n        sta $D021 \/\/ screen border register\n        <\/code><\/pre>\n\n\n\n<p>The code follows the following sequence<\/p>\n\n\n\n<p>In a first Loop\/ForNext, the following tasks are processed in a loop y 0 &gt; 201:<\/p>\n\n\n\n<p>_Init of the sprites (8) at the top edge (sta $d000,y)<br>_Set the address of the graphic data of the sprites (sta $07f8,y)<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.04.30.png\" alt=\"\" class=\"wp-image-10683\" width=\"519\" height=\"129\" srcset=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.04.30.png 784w, https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.04.30-300x75.png 300w, https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.04.30-768x192.png 768w\" sizes=\"(max-width: 519px) 100vw, 519px\" \/><\/figure>\n\n\n\n<p>_Write stripe pattern to the memory of the graphic data (sta $2000,y)<br>_Print the intermediate characters (jsr print)<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"54\" src=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.06.09.png\" alt=\"\" class=\"wp-image-10684\" srcset=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.06.09.png 800w, https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.06.09-300x20.png 300w, https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.06.09-768x52.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n\n\n\n<p>At the end, all sprites are activated (lda #%11111111 \/ sta $d015)<br>Avatar gets a new Y-coordinate (sta $d001)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>        ldy #0 \/\/ counter\n       \n    sprites:\n\n\n        lda #$80 \/\/ sprite data here\n        sta $07f8,y \/\/ store +1 memory block \n\n        lda #57\n        sta $2000,y \n\n        \/\/ store for\n        cpy #16\n        bcs nothere\n            sta $d000,y\n        nothere:     \n        \n        lda #44\/\/ #-34 \/\/ #44 \/\/ #47  \/\/ -58 \/\/ 44 \/\/ #45 \/\/ 252\n        jsr print\n        \n        iny        \n        cpy #201\n        bne sprites\n\n    \/\/ enable sprite 0\n    lda #%11111111\n    sta $d015 \/\/ all eight sprites on (all bits set)\n\n     \/\/ ship only        \n     lda #shipy\n     sta $d001 \/\/ use x value ...<\/code><\/pre>\n\n\n\n<p>All sprites are then activated.<\/p>\n\n\n\n<p>The ship is the only sprite to be moved downwards.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Gameloop<\/h3>\n\n\n\n<p>The large gameloop then contains the rest of the game from Loop &#8211; jmp Loop.<\/p>\n\n\n\n<p>The loop is divided into:<br>_ Vsync, wait until the cathode ray is at the beginning of the screen<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vsync:\n          lda #$FF    \/\/ load 255 into A\n        cmp $D012    \/\/look if current rasterline equals 255\n        bne vsync     \/\/ if no, goto wait\n<\/code><\/pre>\n\n\n\n<p><br>Read out the collision flags in the variable \u201ccol\u201d<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>         \/\/ ----------------\n        \/\/ collision\n        \/\/ ----------------\n        \/\/ 01 000100\n        lda $d01e \/\/ collision read and clear at the same time ...            \n        sta col<\/code><\/pre>\n\n\n\n<p>Behavior&amp;Collision of the objects (see below in detail)<\/p>\n\n\n\n<p>Counter, which always counts from 0 to 256 in steps of 7.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>        \/\/ ----------------------\n        \/\/ counter for all \n        \/\/ and border\n        \/\/ ----------------------\n        \/\/ &lt;----spread-----&gt;\n        lda counter\n        adc #7\n        cmp #255-4-40  \/\/ more than 250 ... \n        bcc ttt\n          lda #50+40\n            \/\/ &gt; 251\n        ttt:       \n        sta counter<\/code><\/pre>\n\n\n\n<p><br>Interaction part (movement of the avatar using the joystick)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\n\n        \/\/ ----------------------\n        \/\/ JOYSTICK\n        \/\/ -----------------------        \n        \/\/ LEFT&amp;RIGHT        \n        lda #JOY_RIGHT                \/\/ mask left movement (8 == bit 4 == %0000 1000)\n        bit $DC01               \/\/ bitwise \"and\" with joystick port 1\n        bne joystick_notright   \/\/ if not active (==1), go to .input_up_check\n            lda $d000\n            adc #4\n            sta $d000\njoystick_notright:\n        lda #JOY_LEFT             \/\/ mask left movement (8 == bit 4 == %0000 1000)\n        bit $DC01               \/\/ bitwise \"and\" with joystick port 1\n        bne joystick_notleft   \/\/ if not active (==1), go to .input_up_check\n            lda $d000\n            sbc #4\n            sta $d000\njoystick_notleft:<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Sprit management: Behavior&amp;Collision of the objects<\/h4>\n\n\n\n<p>The register x counts up from 0 &#8211; 14, so go through all sprite addresses times 2.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>        ldx #0\n        \n        \/\/ 010001 &lt; \n        lda #1\n        sta ind\n\nbehaviors:\n\n&#91;..]\n\n        \/\/ ----------------\n        \/\/ next\n        \/\/ ----------------\n            \/\/ x=x+2 \n            inx \n            inx \n            \/\/ 00010000 &lt; shifting\n            asl ind\n\n        cpx #spritesmax*2\n        bne behaviors\n<\/code><\/pre>\n\n\n\n<p>Collision detection is also being worked on at the bottom. This makes it possible to clarify whether the shot has collided with an opponent.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Movement<\/h4>\n\n\n\n<p>The behaviors of the objects are designed in terms of movement:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-19.40.15.png\" alt=\"\" class=\"wp-image-10682\" width=\"345\" height=\"391\" srcset=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-19.40.15.png 736w, https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-19.40.15-265x300.png 265w\" sizes=\"(max-width: 345px) 100vw, 345px\" \/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>                \/\/ -----------------\n                \/\/ shoot &amp; enemies                \n                \/\/ -----------------\n\n                cpx #2\n                bcc behavior_enemies_end\n  \n\n                    \/\/ always\n                    \/\/ +\n                    adc #1\n                    \n                    \/\/ 4+\n                    cpx #4\n                    bcs third\n                        \/\/ -\n                        sbc #shoot_speed+1\n                        \/\/ -\n                        cmp #50+60\n                        bcs third\n                            lda $d000\n                            sta tmpx\n                            lda #shoot_start\n                    third:<\/code><\/pre>\n\n\n\n<p>If the shot is below 50+60, it is returned to the avatar and flies off again.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Game Over?<\/h4>\n\n\n\n<p>If an opponent flies further than the Y-position 245, the program jumps back to the beginning and restarts.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gameover:\n                     cmp #245\n                     bcs restart\n               \n               \n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Init new enemy<br><br><\/h4>\n\n\n\n<p><\/p>\n\n\n\n<p>If the opponent is still at the top, it is moved to the right by a counter until it goes down. This is a replacement for random numbers that are difficult to generate (maybe use basic random? Does it need fewer bytes?)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>                    \/\/ enemies\n                    \/\/ flying down ... \n                    cmp #50+25 \/\/ 204\n                    bcs nnn \n                        lda counter\n                        sta tmpx                                            \n                        \/\/ inc $d020                            \n                    nnn:<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Enemy &#8222;hits&#8220; Shot &#8211; Pts<\/h4>\n\n\n\n<p>If the opponent is still at the top, it is moved to the right by a counter until it goes down. This is a replacement for random numbers that are difficult to generate (maybe use basic random? Does it need fewer bytes?) And finally, the system also checks whether an opponent has touched the shot. To do this, the collision flag saved above is used and compared with the current sprite. If the sprite collides with the shot, a dot is printed (jsr print)<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"238\" height=\"46\" src=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.06.14.png\" alt=\"\" class=\"wp-image-10685\"\/><\/figure>\n\n\n\n<p>The shot is placed in front of the avatar (lda $d000 \/ sta $d002 \/ #shoot_start \/ sta $d003). \u201cThe avatar shoots\u201d.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>                    lda ind\n                    ora #%00000010 \n                    sta tmp\n                    lda col\n                    and tmp\n                    cmp tmp \/\/ invers!\n                    bne hit\n\n \n                    \n                         \/\/ check if actual ..\n                         lda $d003\n                         cmp tmpy\n                         bcs hit\n\n                         lda #0 \/\/ take print value!\n                         sta tmpy \n\n\n                         lda #252 \/\/ 252\n                         jsr print\n\n\n                         \/\/ ----------------\n                         \/\/ reset shot\n                         \/\/ ----------------\n                         lda $d000\n                         sta $d002 \/\/ shot                         \n                         lda #shoot_start\n                         sta $d003 \/\/ shot\n\n                      \n                       hit:<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Release:<\/h3>\n\n\n\n<p>lovebyte.party Feb 2025 (unfortu. they dont have anymore a category for nanogames!)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">ZAX254 &#8211; The whole code and exe (prg) you find here, after release.<\/h3>\n\n\n\n<div class=\"wp-block-file\"><a id=\"wp-block-file--media-91fcce31-242c-4fd3-abb9-39050a7666c5\" href=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/02\/zax254-1.zip\">zax254-1<\/a><a href=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/02\/zax254-1.zip\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-91fcce31-242c-4fd3-abb9-39050a7666c5\">Herunterladen<\/a><\/div>\n\n\n\n<p>Try it out yourself? Download the zip and unzip it. .PRG is the actual program. In emulators such as VICE (attention must be configured) the PRG can simply be dropped or you can use an online emulator such as <a href=\"http:\/\/111mb.de\" target=\"_blank\" rel=\"noreferrer noopener\">111mb.de<\/a>, where you simply have to upload it. And then you can try out the whole thing and see if the game has anything to do with what is described above. .-)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">ZAX384 <\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"779\" src=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-15.33.26-1024x779.png\" alt=\"\" class=\"wp-image-10669\" srcset=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-15.33.26-1024x779.png 1024w, https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-15.33.26-300x228.png 300w, https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-15.33.26-768x584.png 768w, https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-15.33.26.png 1404w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>ZAX384 is a revised version.<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/02\/video.mp4\"><\/video><\/figure>\n\n\n\n<p>The 130 extra bytes were used for:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Title<\/h3>\n\n\n\n<p>The game has a visible title. With a Petscii-X.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Score<\/h3>\n\n\n\n<p>The game has a classic flashing score. This uses the print routine of the basic. The maximum score is 255, but it is almost impossible to score 255 points as the player will lose concentration at some point.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">&#8222;More beautiful and ambiguous sprites&#8220;<\/h3>\n\n\n\n<p>The sprites are more detailed and an if condition makes it possible to insert a different graphic at the bottom. This allows the sprites to be used three times. If they fall downwards, they look like they are landing (landing ships). If they are a shot upwards, the shape is perceived as a shot forwards. And when cut off, the front part looks like a gun.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"122\" height=\"124\" src=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.19.11.png\" alt=\"\" class=\"wp-image-10689\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.24.59.png\" alt=\"\" class=\"wp-image-10693\" width=\"133\" height=\"199\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Background<\/h3>\n\n\n\n<p>The sprites are more detailed and an if condition makes it possible to insert a different graphic at the bottom. This allows the sprites to be used three times. If they fall downwards, they look like they are landing (landing ships). If they are a shot upwards, the shape is perceived as a shot forwards. And when cut off, the front part looks like a gun.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.21.00.png\" alt=\"\" class=\"wp-image-10691\" width=\"178\" height=\"313\" srcset=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.21.00.png 410w, https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/01\/Bildschirmfoto-2025-01-09-um-20.21.00-170x300.png 170w\" sizes=\"(max-width: 178px) 100vw, 178px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Game Over<\/h3>\n\n\n\n<p>The gameover now pauses the game, you can memorize the score and you have to restart with Fire.<\/p>\n\n\n\n<p>All in all, the game now feels more like an arcade or action game. A one-screen action game. The setting also tells a (very stereotypical) story.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Release<\/h3>\n\n\n\n<p> mountainbytes.ch mid of Feb 2025<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Prg &amp; Sources<\/h3>\n\n\n\n<div class=\"wp-block-file\"><a id=\"wp-block-file--media-4bd36e47-23a9-4c2b-a3f1-7327c700a7bb\" href=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/02\/zax384.zip\">zax384<\/a><a href=\"https:\/\/www.gamelab.ch\/wp-content\/uploads\/2025\/02\/zax384.zip\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-4bd36e47-23a9-4c2b-a3f1-7327c700a7bb\">Herunterladen<\/a><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Optimization options<\/h2>\n\n\n\n<p>256b version: variant with a score could probably also be created with a lot of savings. However, the score then requires a variable that counts up and a display. It might also be possible to write this directly into the screen memory so that you don&#8217;t have to use the complex SetPos and Print.<\/p>\n\n\n\n<p>Of course, this is not the end of the story (and there is probably already something much more interesting and smaller out there .-) and other, newer concepts will also make other, hopefully better ShootEmUps possible. In any case, it was an interesting game to realize something like this here.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>See also: SizeCoding\/Nanogames as a method of science: https:\/\/research.swissdigitization.ch\/?p=2819 What is a ShootEmUp? This question alone answers the outcome of a nanogame development. But perhaps this will only crystallize during nanogame development and the definition will have to be changed &hellip; <a href=\"https:\/\/www.gamelab.ch\/?p=10661\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/www.gamelab.ch\/index.php?rest_route=\/wp\/v2\/posts\/10661"}],"collection":[{"href":"https:\/\/www.gamelab.ch\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gamelab.ch\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gamelab.ch\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gamelab.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10661"}],"version-history":[{"count":42,"href":"https:\/\/www.gamelab.ch\/index.php?rest_route=\/wp\/v2\/posts\/10661\/revisions"}],"predecessor-version":[{"id":11470,"href":"https:\/\/www.gamelab.ch\/index.php?rest_route=\/wp\/v2\/posts\/10661\/revisions\/11470"}],"wp:attachment":[{"href":"https:\/\/www.gamelab.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10661"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gamelab.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=10661"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gamelab.ch\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=10661"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}