Jump to content
IGNORED

WIP: Air Taxi


Kylearan

Recommended Posts

Inspired by the recent Space Taxi thread, I've started to work on a game with the working title "Air Taxi". It won't be a faithful port of Space Taxi but heavily borrows from it, meaning the gameplay will feel very similar, but level design and several details will be different.

 

There will be two different kernels: One for asymmetric levels, unable to display hi-res objects apart from the taxi and the passenger, and one for symmetric levels with an intelligent object multiplexer allowing for more hi-res objects like bullets, snowflakes etc. with minimal flicker. Both are designed to have no empty scanlines and to be able to display dynamically changing playfield graphics, i.e. levels with moving walls or doors opening and closing.

 

I've finished a proof of concept of the asymmetric kernel. Note that the graphics and level design are only a placeholder. :)

 

post-35905-0-15376500-1486123250_thumb.png

 

For those who don't want to run it in Stella, the opening in the vertical wall is moving, and the top of the ring where the passenger is in alternates between open and closed. You cannot yet move the taxi around; it's only my first experiment if the kernel works as intended.

 

Features of the kernel:

  • The interior of a level has a resolution of 32x40. Blocks can be switched on/off at a resolution of 32x20 during the game, and the level exit can be anywhere on the top.
  • The taxi will be drawn every scanline, the passenger (or the target pad if he's already on board the taxi) every second scanline.
  • The background and the playfield colors can be set every 4 scanlines.
  • Also every 4 scanlines, the missiles can be enabled or disabled. Right now they are used to mark the fuel pad in the lower right corner.
I've already created some python scripts that convert PNG images into level data and color data. That allows me to use GIMP (with the VCS palette loaded) to design levels, although changing the level during gameplay (like opening doors etc.) will require custom code for each level. Basically I hold a buffer of AND mask values in RAM that the kernel applies on the fly before writing to PF1/2.

 

The kernel has some downsides however. As already stated, it doesn't allow for additional hi-res objects. In addition, taxi and passengers only have a single color, and I'm not very happy with how the fuel pad gets displayed. But my main design goals were to be able to draw the taxi each scanline and to have an asymmetric level design which is not static, which together is pretty limiting with regards to instruction cycles left for other stuff. Hence the second kernel for symmetric levels which I will do later, but first I'll add the ability to actually fly around with the taxi. :)

taxi_170203.bin

Edited by Kylearan
  • Like 8
Link to comment
Share on other sites

The mask operation during the kernel looks quite expensive - it appears you are doing something like this:

lda    (LEFTPTR),Y  ; 5
and    LEFTMASK,X   ; 4
sta    PF2        ; 3 = 12

I wonder if you could precompute the mask operations and store them in RAM. With a vertical resolution of 40, you would need 160 bytes, i.e. too much. But if you could find 16 patterns that covered all the needed PF values you could encode two positons in 1 byte, which would only need 80 bytes, i.e:

ldx    LEFT,Y        ; 4
lda    Left0,X       ; 4
sta    PF2           ; 3
lda    Left1,X       ; 4
sta    PF1           ; 3 = 18

LEFT would contain the PF2 pattern in bits 0-3 and the PF1 pattern in bits 4-7. It would waste a bit of ROM as you would need to fill two pages of possible values for Left0 and Left1 but it would save a lot of cycles.

 

What are your constraints? With an extra 128-bytes of Superchip (SARA) memory, the RAM wouldn't be an issue. And with DPC+ you could simply read the data out of a fast fetcher?

 

Chris

Edited by cd-w
Link to comment
Share on other sites

The mask operation during the kernel looks quite expensive - it appears you are doing something like this:

lda    (LEFTPTR),Y  ; 5
and    LEFTMASK,X   ; 4
sta    PF2        ; 3 = 12

 

Yep, that's more or less how I do it. However, I have to do that only once every four scanlines (it's a four line kernel and I store the result also in RAM for re-use in the other three lines, where I then only need to do a "lda tmp_pf1; sta PF1").

 

I have to admit I don't understand your suggestion. I can have 256 possible values for PF1 and 256 possible values for the AND mask; how can I precompute something in that situation?

 

But in any case, even if it worked I would "only" save a couple of cycles every four lines while I'd need more cycles at least every two lines to add something useful.

 

What are your constraints? With an extra 128-bytes of Superchip (SARA) memory, the RAM wouldn't be an issue. And with DPC+ you could simply read the data out of a fast fetcher?

 

No extra RAM, no extra computing chip, only some more ROM (16K probably). See my stance on this issue here.

 

To sum it up, if I'd use extra RAM and DPC+, I could simply use a C64 instead and play Space Taxi on that machine. :)

Link to comment
Share on other sites

I have to admit I don't understand your suggestion. I can have 256 possible values for PF1 and 256 possible values for the AND mask; how can I precompute something in that situation?

 

Although the PF and MASK have 256 possible values each, it seems unlikely that you will need all possible combinations. If you could reduce the number of "building blocks" for your levels to 16 (e.g. by halving the horizontal resolution) then you could do the AND operation before the kernel (i.e precompute it) and pack 2 results into a byte as shown above. However, given that you are only performing this operation every 4 lines it does seem that you will not save all that many cycles.

 

 

No extra RAM, no extra computing chip, only some more ROM (16K probably). See my stance on this issue here.

To sum it up, if I'd use extra RAM and DPC+, I could simply use a C64 instead and play Space Taxi on that machine. icon_smile.gif

 

An extra 128bytes is still a long way from 64KB icon_smile.gif

 

Chris

Edited by cd-w
Link to comment
Share on other sites

  • 2 weeks later...

I've made some progress, yay! \o/

 

A considerable amount of time went into cleaning up and refactoring the existing code, turning the proof of concept into a structured project that will last me all the way - or at least I hope so. :) Things like splitting up the source into smaller files, replacing magic numbers with #defines, abstracting the way I parse level data etc.

 

The most satisfying thing for me is that I now have a fully automated build process that I can trigger out of my editor of choice (atom) that will convert all kinds of graphics and level data into source code before compiling. For example, this is what the test level looks like in my graphics program:

 

post-35905-0-70822400-1487013617_thumb.png

 

The starting point of the taxi is marked with a red dot, the fuel pad by a green line and the landing pads by blue lines. The left wall defines the color gradient to use for the playfield. During the build process, a python script reads in the PNG file, parses it and converts it to "dc.b" data, including level structure, positions and sizes of all pads etc. Another script converts a sprite sheet PNG file into the graphics data for the taxi, and yet another scripts creates color gradients (for the background, for example). This allows for very short turn-around times: I can quickly change something in the level design, hit "build" and can try it out in Stella almost immediately without any manual steps inbetween. It's fun to battle oldschool hardware with modern tools! :)

 

 

I also implemented my first ever attempt at physics. You can fly around with the taxi now, including visual and audio clues while thrusting, and even move out or in the landing supports (and lose the ability to accelerate horizontally while they are out)! You cannot land yet, but why would you want to do that anyway, seeing that the silly passenger is still floating in mid-air... :-D I've attached the current binary if you'd like to try it out.

 

The parameters (gravity and thrust values) are a first test and still need fine-tuning. I have to play the original Space Taxi some more to get a better feel for its controls.

 

I probably should implement placing the passenger on a random pad and the ability to land next, but I think I'd rather go for the fuel/lives/money display at the bottom first. That will help getting a better impression of how the game will look in the end, which should be very satisfying. (That will also bring me closer to the PAL vs. NTSC question, but I refuse to go there just yet...)

 

air_taxi_20170213.bin

  • Like 5
Link to comment
Share on other sites

BTW: Are you going to share your code?

 

Yes, I... think so. I guess. I usually publish source code. But:

 

The thing is, if the game turns out to be fun, I'd love to sell real carts through AtariAge. Not because I want to earn a lot of money, but because I'd like to call myself a "commercial game developer". :-D

 

But I have no idea what that entails. What are the technical requirements? And can I still share source code? The full .bin, or only a short demo? After a quick glance at the AA website, I couldn't really find anything on what steps are necessary to publish a game through AA, or what requirements have to be met.

 

It's way too early in the project to seriously think about it, but at one point I'd appreciate input on that from people who have successfully published a game like that.

  • Like 1
Link to comment
Share on other sites

You can share as much as you like, no one will object. Besides Boulder Dash (due to legal restrictions) I have shared all my ROMs and if anyone is interested, my code too. That's the old habit of the good, old Stella mailing list.

 

Some people think this may reduce their sales. Maybe, but I want my games in the hands of as many people playing them as possible. And since collectors seem to be the main group buying games from AtariAge, they don't care for ROMs. They want the full package anyway. So the loss of sales (if any) is irrelevant to me.

Edited by Thomas Jentzsch
  • Like 5
Link to comment
Share on other sites

All right, thanks Thomas. I don't care about reduced sales either, but didn't know how the AtariAge store would think about that - I guess they have an interest in more carts sold (and rightfully so). But if other people shared their sources without any complaints, I will do so too. I'll probably set up some bitbucket repositories for my VCS stuff (demos and Air Taxi).

  • Like 3
Link to comment
Share on other sites

All right, thanks Thomas. I don't care about reduced sales either, but didn't know how the AtariAge store would think about that - I guess they have an interest in more carts sold (and rightfully so). But if other people shared their sources without any complaints, I will do so too. I'll probably set up some bitbucket repositories for my VCS stuff (demos and Air Taxi).

 

Just send a message to Albert and he will give you the details on getting the game into the Store. He is busy with a lot of projects but he will respond.

Edited by neotokeo2001
Link to comment
Share on other sites

Everything Thomas said. All of it. Releasing ROMS, in my opinion, is a great way to drive before you buy, but at the end of the day, I want a cart. I honestly don't consider a game fully released unless there is a physical copy of it. Playing games on Stella is great, and while I'm not savvy enough for things like Harmony Carts and whatnot there are plenty who game that way, but nothing beats an awesome cartridge I can plug into my VCS and maybe even an instruction manual I can read. That is Atari for me. Releasing ROMS only helps sales from where I sit.

 

Can't wait to give this a go! Thanks

 

:spidey:

  • Like 2
Link to comment
Share on other sites

Adding a status bar turned out to be more complicated than I thought. Several things need to be displayed: The score (i.e. the total sum of money already earned), the fare for the current passenger, the number of lives and a fuel meter. Unfortunately three of those things (score, fare and lives) need player objects to look good, so I ended up with three rows that take up a lot of screen space. :( I guess I could have used a decreasing bar similar to the fuel meter and crammed it into the score row instead of showing the amount of dollars, but I like how in the original game you see the dollars dwindling away while you bring the passenger to his destination; it relates to your score better than just a bar. So I went with three rows instead.

 

post-35905-0-12216700-1487781418_thumb.png

 

There's also a small icon next to the fare that displays the current state: A waving figure if a passenger waits for you to pick him up; a sitting figure if he's on board; an up arrow if he wants to leave the level, and nothing if you just delivered a passenger and are waiting for the next one to appear. The graphics is there already, but in the test rom only the waving passenger animation is shown.

 

The three kernels posed a greater challenge than I had anticipated. I wanted to have a dot between the dollars and the cents without having to define two different fonts (one with dots, one without). In addition, I wanted the score to be able to go over $1000.00. After a couple of false starts, now the dollar sign disappears as soon as you have four digits of dollars, and the dot is added on the fly during the 48 pixel sprite display.

 

The fuel row was tricky as well. Per scanline, I need to update GRP0 and GRP1 for the number of lives, use a missile for the "F" next to the fuel meter, and show the fuel meter in a different color with hi-res precision (not just with 4 pixel playfield granularity). The display uses a mirrored playfield, updating PF2 at eactly cycle 45, and uses COLUBK for the bar color, resetting it to black again before the background shows again on the right side. Note that the status bar is a bit narrower than the full screen to hide the ugly HMOVE bars.

 

The last row with the fare was straight forward to do after I got the score row right. :)

 

In the attached demo, the taxi uses up fuel but you cannot refuel yet; also, the fare doesn't cound down yet, only test numbers are displayed. Next thing on my list is to convert the game to NTSC, as I think I have to cut down on real estate to fit it in the smaller display (current version is PAL). In addition, I have to optimized for RAM, as my naive implemetation already uses up all of it. :-D

 

For the curious, I've set up a Bitbucket repository for Air Taxi here. Note that this is heavy work-in-progress, i.e. unoptimized and ugly in places.

taxi_20170222.bin

Edited by Kylearan
  • Like 7
Link to comment
Share on other sites

The status display looks nice :thumbsup:, but it may take away too much space from the game's play field area.

 

How about displaying the current score and the fare alternatively? E.g. the score is only displayed for a few seconds when it is updated.

 

 

  • Like 2
Link to comment
Share on other sites

This looks like it's coming along nicely. I can foresee people wanting to make levels for this. Maybe there can be contests like AA had for Miniature Golf and Indy 500? Though the custom code for moving things would be a deterrent for non-programmers.

 

---

 

About roms.. I won't BS you, I get more GAMEZ to play on emulaterzz! At the same time releasing roms gets your name & game good exposure. It builds goodwill. It is educational for other developers.

 

Collectors will always want box, dox, and cart. And I think that's where the majority of sales will come from. Retrogaming is actually becoming more popular these days, and that means more collectors and novelty buyers.

 

Buying a newly developed game in 2017 for a 40-year old system made in 1977 is just plain cool.

Edited by Keatah
  • Like 2
Link to comment
Share on other sites

How about displaying the current score and the fare alternatively? E.g. the score is only displayed for a few seconds when it is updated.

That's actually a very nice idea! I could show the fare only when the passenger is on board and the total score at all other times. That might work!

 

Let's see how much scanlines I have to cut out to be able to fit it into an NTSC screen, maybe I can make it work with all three rows. I couldn't make the playing area bigger anyway (not enough RAM for the AND mask for the dynamic changes). Unfortunately I need several scanlines between the individual rows to construct the pointers for the digits etc.; I cannot do this in overscan or vblank as I don't have enough RAM. There's some room for optimization left though, and if it doesn't work out, I'll use your idea.

 

Speaking of NTSC screen space, how many scanlines can I use for the visible area? Tutorials say 192 lines, but can I use, say, 200 if I keep the total at 262, or will this be problematic for some TV sets?

Link to comment
Share on other sites

I can foresee people wanting to make levels for this.

Oooh nice, I can totally see people contributing ideas! :) They could design levels with GIMP or Photoshop using my template, and I could implement the custom code. Of course we would have to discuss if the custom code will be possible beforehand, but that wouldn't be a big problem.

 

First things first, but I'll definitely keep that idea in mind!

Link to comment
Share on other sites

Speaking of NTSC screen space, how many scanlines can I use for the visible area? Tutorials say 192 lines, but can I use, say, 200 if I keep the total at 262, or will this be problematic for some TV sets?

Actually I very recently wrote a test program and collected data in a thread to answer this question.

 

200 is completely safe, even 210 should work. But this will cut into your CPU time budget. Maybe you want to increase the total number of scannlines then (up to ~280 seems safe).

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...

This is awesome, I would definitely buy this game! I implore you to have support for AtariVox+ so we can hear "Hey AirTaxi!" and "Pad 3 Please", that would be amazing!

 

I'm glad you like it so far! :)

 

Actually my current plan is to include speech even without the need for AtariVox+. Since I'm going for 32k, I will have the ROM space to add "Hey taxi!", "Thanks!", "Up please!" and similar samples directly. While such a sample is played, visuals will be reduced to a minimum however, probably only showing the border of the playing area, the taxi, and the passenger.

 

Air Taxi is a bit on the back burner at the moment because I'll have to finish my 4k demo for the Revision Easter demo party first, but I will start development in earnest after that. I am slowly refactoring the code for NTSC right now however, and will probably ask some stupid questions about PAL, NTSC and PAL60 for cartridges on this forum soon. :D

Edited by Kylearan
  • Like 3
Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

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