Jump to content

Phantasia (Atari 7800 ARPG)

Recommended Posts

Some of you may have noticed on the AtariAge handbills handed out at PRGE, that on the back cover there's a list of games Coming “Soon.” One of those is Phantasia, so I guess it's time to start a forum thread, even though I don't (yet) have a playable demo.




What's Phantasia going to be?

Phantasia is a new Action Role-Playing Game (ARPG), heavily inspired by a certain popular series of 27 ARPGs from a certain game hardware & software company, in particular, the SNES entry in that series.


In point of fact, my very first “real” game I ever had written was a sort of knock-off of the NES original of that series on the Commodore 64 (my game, I believe, having been lost to time), so this is a particularly exciting project for me.


Game Play Features

  • Explore the world of Aclypt to uncover mysteries and quests and, of course, save your village
  • Support for ProLine & compatible, Genesis, and Joy2b+ controllers. One button for using your equipped item, the other for calling up an item-select screen. (Joy2b+ button III = pause.) Your shield operates passively: when you're not using another item, your shield is effective. SNES2Atari: A/B use item, X/Y item-select, Start = pause, Select = same as console Select.
  • Console switches: Pause=Pause, Select=Save (or password?), Reset=Quit/Reset
  • Support for SaveKey (or AtariVox) for saving progress. (Possibly: also a password system? if it's practical)
  • AtariVox voices for dialogue
  • Pick up and use various items of various kinds: equipment items (e.g. weapons), single-use items (e.g. potions), items that are used automatically (e.g. keys), shields, armor, and possibly some other things.
  • Converse interactively with characters in the game world
  • Defeat monsters. Solve puzzles.




Technical Notes

  • A map system that allows arbitrary palettes and action attributes for each tile as well as “decals” over them to provide more than the 128 tiles that would otherwise be available, edited using Tiled
  • Graphics are developed in Gimp as PNGs and converted to Maria's awkward formats as appropriate.
  • 320px mode for stats and text, 160px mode for the game play board
  • Music conversion from MIDI; probably for HOKEY/POKEY. Thanks to @Synthpopalooza's spreadsheets for providing the tabular basis for my converter.
  • Uses a 16k RAM addition for decompressing map data (which currently uses a cheap RLE system)
  • I'm not sure how large it will be in the end, but “big.” I've written an allocation system for the larger assets (maps, music, scripts, &c.) to be packed into 16k ROM banks as efficiently as reasonable.
  • Demo builds are being designed to work with the Concerto (as well as, of course, that it should work with emulators and Dragonfly, but Concerto is the lowest-common-denominator at the moment)


What's Coming Up?

  • First, I need to fix quite a few things that are badly broken to get a playable demo!
  • Also, we'll definitely want some collaborators, particularly as regards to testing the game as we go along, but of course any input or suggestions are appreciated.

Screenshot from 2022-10-29 15-25-32.png

Edited by Bruce-Robert Pocock
SNES controller & console switches info
  • Like 16
Link to comment
Share on other sites

On 10/30/2022 at 7:44 PM, RevEng said:

here are the autodetection and reading routines from 7800basic, if you're interested.

Thanks! I've kinda hacked that into something I can use directly (at the expense of dual-controller support, since I only need/want one) but I'll have to wait a bit before I can get my hands on a dongle to test it :)

  • Like 3
Link to comment
Share on other sites

On 10/30/2022 at 4:48 PM, Bruce-Robert Pocock said:
  • Also, we'll definitely want some collaborators, particularly as regards to testing the game as we go along, but of course any input or suggestions are appreciated.

I find the below to be a great reference example, courtesy of @Defender_2600, to aid visually in working with the pixel aspect ratio of 160 modes, balancing detail while reducing a wide-sprite appearance:


Hope the above may be useful.

  • Like 2
Link to comment
Share on other sites

Thanks @Trebor! Interestingly, I was using more like a 1.6 ratio, I'll have to re-examine my assumptions there if 1.7 is more accurate!


I mostly am doing the artwork in Gimp, which has a lovely setting to allow non-square pixels. (Set Print Size to match the desired ratio + turn off View→□ Dot for Dot)


Unfortunately there will probably remain a little bit of vertical squashing for our PAL friends :"( as I doubt I'll have the opportunity to create distinct artwork for each region, so I'm focusing on getting the NTSC version “square”-ish.


Dot for Dot mode:


with Dot for Dot disabled (and Print Size set to about the right aspect ratio):


  • Like 4
Link to comment
Share on other sites

Very cool and ambitious project indeed!


Regarding the graphics modes for the playing field, I would like to suggest that you also consider 160B mode, 12 colors + background / transparent from 2 palettes. The 160B mode is 4 bits per pixel therefore it consumes more resources than 160A 2 bits per pixel, consequently not all types of games can be made using *exclusively* the 160B mode, however it can be a tremendous ally when used in conjunction with the 160A.


But again, after having seen the extraordinary result obtained with the recent "Attack of the PETSCII robots" which for the playing field uses exclusively the 160B mode, maybe you could evaluate if "Phantasia" can also use exclusively the 160B mode for the playing field. In addition to the great aesthetic result, it would also make it easier to design the tiles, always having 12 colors available.


Usually this type of game uses a limited number of sprites on the screen and, for the Boss at the end of level, it is still possible to use the sprites as tiles and only include the floor where the sprites are not placed, so without any overlapping sprites (as does the NES with Gauntlet which only uses tiles as sprites). It is also possible to reduce the horizontal resolution of the playing field from 160 to 128 pixels, in order to save several cycles which will be useful for sprites.


Either way, feeling completely free in any direction you want to go, these are just ideas and suggestions. Thanks for your kind attention.



Edited by Defender_2600
  • Like 3
Link to comment
Share on other sites

49 minutes ago, Defender_2600 said:

Regarding the graphics modes for the playing field, I would like to suggest that you also consider 160B mode

The way it's currently working goes something like this:

  • The map is broken down into a base tile map, which uses indirection and 160A mode; each tile can have a distinct palette, with its three colors. Due to the limits of indirect mode, there are a maximum of 128 base tiles (8×16px) possible at a time. Using 4×8px tiles at 160B would also limit me to 128 tiles, but would quadruple the amount of RAM needed to store a map, reducing the maximum size of a map/region. In order to draw a full screen like this without overloading Maria, groups of tiles that share a common palette are strung together into a single display list instruction, which is precomputed when the maps are being compiled (and compressed).
  • In addition, “decals” can be affixed at any tile position, which are normally also in 160A mode, with their own palettes. Due to restrictions of memory layout, this is also limited to 128 possible decal tiles at a time. These allow more detail to appear on the map than would be possible with just the tile set; for example, in the screenshot I posted earlier, the palm tree near the top-center is a pair of decals, which you can see cross both the beach and ocean tiles; the coins in the center-right are seen on top of both grass and flower tiles.
  • Beyond that, most enemies (or unusual NPCs) are coming from their own tile set, also in 160A mode. This tile set has 128 animation frames available, which are copied into a RAM buffer to be displayed due to memory limitations.
  • The player-character and human NPCs, however, are in 160B mode. These are also composited into a RAM buffer, but in a more complex way; for the player-character, this can mean equipment items (like the shield in the screenshot I posted earlier) being composited into place; for other NPCs, there is a system being built (but not working yet) that composites them from a collection of body parts and colorizes them appropriately. These are in RAM both because of the compositing, and to get around memory limitations.

I do appreciate the 160B rendering, and you may be right that it would be more doable at 128×192. The map region of the screen is currently running at 160px width; the height, however, skips over a few lines at the top for the status area. The actual, “internal” size of the display area is a little wider and taller than the viewport, since a partial tile may be scrolled off the edge of the screen at a time. In a 128px wide system, I guess I would need to mask out some of the edges by plotting additional black boxes over each edge…


The display system is sure to evolve, but I expect the above description will remain largely the same, as Holey DMA limits which areas of memory can be safely used for various types of graphics.


I should probably point out that 128 × 8×16px × 160A (= 4px/byte) = 4kiB, which is precisely the size area that Maria can see between DMA holes at 16px height. This means that the base tileset and main set of tile decals can each occupy a DMA region in the same 16kiB ROM bank — the two such windows available, while the more sprite-like objects (enemies, player, NPCs) are copied into RAM that is visible between to Maria's DMA as well. There is, also, more than one tile/decal set, but as you can imagine, 16kiB ROM banks are relatively “expensive” in this scale of a system and I don't want to get too carried away.


You may be interested to know also that the title screen seen above is also in 160A mode, in order to fill the screen without overtaxing Maria. I haven't ruled out adding some animations to it, as well, which are just about possible with the current display list system.

  • Like 6
Link to comment
Share on other sites

8 hours ago, Bruce-Robert Pocock said:

The display system is sure to evolve, but I expect the above description will remain largely the same, as Holey DMA limits which areas of memory can be safely used for various types of graphics.

If it may prove useful or practical for this project, there is Bankset Bankswitching, leveraged by the 7800 port of PETSCII Robots:


Maria is shown a different section of ROM than the Sally CPU is, with each of these views comprising a different set of banks... the Banksets scheme allows for more overall ROM storage, enables 100% of the cart address space to be dedicated to the display of graphics, and does away with the need to interlace code and graphics within ROM.

More specifics and in-depth explanation at the respective page under the Atari 7800 Development wiki site.

  • Like 4
Link to comment
Share on other sites

2 hours ago, Trebor said:

If it may prove useful or practical for this project, there is Bankset Bankswitching, leveraged by the 7800 port of PETSCII Robots

Thanks! I had been vaguely aware of this technique/hardware, but for my purposes the “problem” comes in that Sally and Maria may see different contents, but both switch banks together. During the drawing of the screen I'm basically “stuck” with $8000 pointing to a particular bank (which varies) for a certain set of graphics/stamps for Maria for that screen; this basically prevents me from running code anywhere but the fixed bank at $c000 while the screen is being drawn. It's also limited to 128k, which might be a limiting factor.


I'm definitely not fixated on the current (Superbank) bank switching, but I don't know if Bankset will bring a direct benefit as it is today.



Link to comment
Share on other sites

Its stuck in the same way that Supergame is also stuck, for sure. But you have much more space for code in those same banks, since you don't need to interlace graphics and code in them; in a graphics heavy game you'd have twice the space available for code than you would when using Supergame.


Similarly, you can pack in more graphics when you don't need to worry about code storage - Petscii Bots turns off DMA holes and packs in 42K+ worth of tile graphics, all addressable at the same time. When sprites need holes you can just manually place empty rom above and below the sprite instead. (or if you want to stick with DMA holes, then stick rom based character strings into the Maria rom being covered by the holes)


The other benefit with banksets and cart ram is you have 16k RAM for Sally's game logic, and 16k RAM for Maria's display.


I'm not trying to sell you on it, though. One big downside to banksets is that none of the flash carts support it, though I'm hoping that changes when the Petscii Robots demo is released. Do whatever works for you, as you're clearly capable of great work!

  • Like 4
Link to comment
Share on other sites

3 hours ago, RevEng said:

But you have much more space for code in those same banks since you don't need to interlace graphics and code in them.

I'm currently packing all 16k with graphics, and just copying selected graphics (basically sprites) out of the DMA holes into RAM, but there really isn't a 1:1 relationship between what graphics are being displayed and what code I wish I had access to.


I could probably put code or something else into the gaps, but currently the “over world” and “indoors” banks are designed with different tiles, decals, and enemies, and each is currently ~12k of graphics data and planned to be 16k each. I toyed with arranging it to be hole-free, but my rationale is something like this: there are a lot of animation frames for one enemy, but relatively few distinct enemies visible at a time. If I were to directly draw from the ROM an enemy — let's say a slime (spoilers! :D), it has 4 animation frames right now, and each is 8×16px @ 160A = 32 bytes. But if I had to accommodate non-holey DMA, it would have to be effectively 96 bytes for each of those 4 frames, which is 384 bytes total rather than 128 bytes — in general, each frame balloons up 300%.


Neither helps for the player or NPCs, since they're composited from pieces. (The player gets equipment composited on to avoid proliferation of parts, and most NPCs are colorized combinations of bodies and heads.)

3 hours ago, RevEng said:

The other benefit is you have 16k RAM for Sally's game logic, and 16k RAM for Maria's display.

That part is just sheer awesomeness, actually.


$4000 is before holey DMA and ∴ I do have to pad composited or copied sprites there, which has led to some really crazy RAM layouts for other things: I have basically got the first 12k of RAM set up where a certain part of each page is reserved for striping Maria buffers, of which of course the first and last 4k's Maria portion are all zeroes, and all the actual game vars &c are split up into the gaps between the Maria data. So: each RAM page from $4000-$6fff actually has a part reserved for Maria, and a part delegated out for whatever other purposes it's needed, which limits the uncompressed map data (including the tile map and its attributes, like palette, interactivity, &c) to the remaining $7000-$7fff region, which effectively limits the maps to around 1k worth of tiles — e.g. 32×32 or any other variation that adds up the same way. (The screen can show at least part of about 21×13 tiles at a time, depending on what's going on.) Each tile takes a minimum of 2 bytes, one for tile/palette selection, and one is an indirection to its attributes block. (There are other map data as well, rounding out the 4k block there.)




I think the Dream Configuration would be to have something like: Maria sees a 16k RAM + 32k banked ROM; and Sally seeing the same sort of think as Superbank, with 16k RAM + 16k banked ROM + 16k fixed ROM, but ideally with some ridiculous amount of ROM behind it. With what little I know about hardware, I'd imagine someone could potentially go with a 1MiB EEPROM for the Sally + Maria data both, which would be driving “only” the six upper address lines to the ROM (and one address line to RAM). If you use the last bank ($ff) as the fixed bank for Sally, then you can make the programmer choose carefully between 16k banks for Sally and 32k banks for Maria made up out of the same range of physical ROM space. (The Maria banks could potentially start at any 16k multiple and just run for 32k, or could be specified in multiples of 32k, whichever was easier to implement.)

Edited by Bruce-Robert Pocock
part of a line went missing? probably my fault.
  • Like 3
Link to comment
Share on other sites

A couple of folks have reached out with some questions and I found myself writing a too-detailed message late the night before last, much of which I thought might have a little broader interest:


Lots of Stuff About Tools


With Grizzards I spent several months creating (or updating) some toolchain elements before reaching a playable demo around June 2021 — 15 months later, in October 2022 (about a week later than it should have bene), it was finally done. Phantasia is still leading up to a playable demo, and mostly crashing. However, a lot of the tool chain support is either already in place, or in the works.


I'm a firm believer in using existing tools wherever possible, so I've spent a good deal of time building up the framework for asset importers for the game already. Stamp graphics of all kinds are imported from png files, with palette indicator swatches in the lower margin; they're brought in either as tilesets from tsx files from Tiled, or using simple bundling for other graphics like fonts and decorative UI elements for the status area, e.g. one block of ROM is packed with the 8×8 font, some UI drawing elements, and the “sad face” from the crash screen:



Hopefully nobody else ever “gets” to see this screen, but it's in there…


There's also a separate “blob” (as in “bitmap large object block”) importer used for e.g. the title card that rips everything into display lists for a fixed screen; some work is still needed to make that animation-friendly, though. (The title card currently has no animation per se.)


The maps are brought in from tmx files from Tiled, and contain the base layer tiles, alternate tiles for some things (e.g. destructible objects), placed objects for decals (e.g. the signs that say “SHOP” and “INN” here, or the coins near the player), enemies, NPCs, shallow or deep water, animated base tiles, climbable surfaces, &c. — basically anything I can get away with using Tiled to do. (Please disregard the palette error on the SHOP sign, I haven't worked out what I've done wrong there, but it's on the list of bugs.) As you might imagine, that means I make pretty hearty use of “custom properties” in Tiled. (Also, everything looks a bit “squashed” in Tiled since it assumes square pixels and 160A/B mode does not have those.) Right now, maps in ROM are compressed using a super-simple run-length encoding that rewards you for repeating, adjacent horizontal spans of graphics, but I hope to work in a better quality compression algorithm.



The [non-player] characters are mostly constructed by applying colors to a figure made up of compositing heads onto bodies, although I do probably have the opportunity to also introduce a handful of unique character designs for very special characters. Their scripting will be (this does not work at all yet) using a pretty simplistic scripting “language” based upon the format teleplays/screenplays are usually written in (fountain files) with some specific rules about the stage directions and such. A test script that won't appear in the game that I'm using for testing the script parser looks like this:


You can see the branching logic for the player is buried in the parentheticals which normally would indicate something adverbial about how the actor is meant to deliver the line.


The music should be coming from MIDI files, but I haven't gotten much into the MIDI→HOKEY/POKEY converter yet; it's going to be based on an improved version of the MIDI→TIA converter from Grizzards. I'm using the spreadsheet by @Synthpopalooza as a data table to drive the conversion routine, but it needs a good amount more work yet. (It currently seems to think that zero-note polyphony is the limit, rather than four.) We do rely upon MuseScore3 for MIDI editing, but potentially any MIDI editor could be usable.



And, finally, the data tables for a lot of game attributes are straight-up coming from ods spreadsheets: these include mapping frames from a “sprite sheet” to the player, or an enemy, or an NPC; assigning enemies stats like HP and damage amounts; assigning item drops to enemies and destructible objects; assigning stats to NPCs; and assigning items to shops. Again, basically anything that would be easier to work with in LibreOffice than a text file is going in there.



The whole build system is F/OSS, and the compiler tools are designed to be moderately friendly to a non-programmer designer, so with a little initial set-up someone can pretty easily make changes to the design files (maps, graphics, scripts) and build a new a78 file to test without knowing much about the code, although I haven't tested anything to see how it would work on a non-Linux system yet. All the parts are nominally available on macOS or Windows, with varying degrees of difficulty to install them.


The current build time going directly from make clean to time make test (running unit tests in the A7800 emulator) is 3m35s, which is pretty much the same time expected for make emu to start the emulator in debug mode. A ridiculously long amount of that time is spent in the very dumb RLE compressor for the maps (just the base map seen above takes 27s to compile), although the “BLOB” importer for the title card &c is also stupidly slow (1m22s for that title card!) and probably just needs some gentle optimizations or memoizing some functions. Unfortunately, changing any of the “large” assets (maps, scripts, music) causes the asset allocator to re-run, assigning assets to ROM banks to find an optimal layout, which means rebuilding much more than should strictly be necessary, but I'm fighting to keep the total build time less than 10m for the full game if possible. Again, none of these importers are very optimized so there is room for improvement.



“Dev Journal”


By way of “dev journal” I think the following are the major tech. hurdles that are still under weigh — I've kinda intentionally “front-loaded” the heavy lifting work, so once the game reaches a playable demo it “should” (I know, dangerous word) be more straightforward coding and less “solving technology hurdles” to progress:

  • Scrolling is just misery right now. I think I'm perhaps using the wrong pointers sometimes and causing arbitrary corruption to display lists that are then modified again at the next scroll and multiplying the error until everything is wrong. Nobody said scrolling would be easy, that's why it's front-loaded.
  • There is no animation of “tiles” in the game yet, but the compiler is yanking the animation information from Tiled and embedding it — I just have to come up with a somewhat effective way to use that information.
  • NPCs require the script compiler, which means me remembering how to write a yacc grammar properly.
  • The music compiler (MIDI→HOKEY) is far from working as well. I may defer this to after getting a silent demo running.
  • The script compiler is in purgatory, because I actually have never written a lexer/parser for something as “Markdown”-like as Fountain files and I'm doing it horribly wrong. (Using CL-YACC, if by some miracle someone here is familiar with it.)
  • There are a few serious timing glitches with Display List Interrupts when certain routines take too long to complete, so I have to distribute some workloads differently to ensure that can't happen.

Heavy lifting, all, but the first one is the most troublesome as there really isn't anything to look to for references since the display list structures I'm using are kinda unique to this game engine.


In unrelated news, we finished the first draft of the outline for the entire game's script last night! I'm pretty excited about the overall story, but we're gonna keep it under pretty close wraps, so as not to spoil any surprises. I will reveal that there are five “real” endings in addition to “you died, game over” being planned ;)

  • Like 9
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.

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.

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...