Jump to content
IGNORED

Very Large PlayField Prototype (WIP)


Recommended Posts

Several times this winter I watched my youngest playing the latest of the Legend of Zelda games on the Nintendo Switch.  I was impressed with the huge open world that the game provided.  Room for many different environments and terrains and all accessible (more or less) at once.  Seeing a game like that always makes me wonder about implementing it on the Atari. 

How would I create the largest possible scrolling playfield on a standard Atari?

The largest playfield I’ve been able to create so far has been the one in Imp – which is 48 chars high by 128 wide (it could be 256 wide without the fog of war).  So the max size (with enough memory left over for everything else) would be around 12,288 (Antic mode 4) characters.  Each level takes about 5K of disk space.  I could cram 6 to 8 levels on a disk.  Not bad.  Except I wanted more.

So, using tiles was the obvious answer – I could define tiles of 8 x 8 characters and build the playfield from that.  I could create a map and represent the placement of each tile with a single byte.  However, there was still a limit to what I could store in memory.  Definitions for 128 tiles would take 8K, 256 tiles would consume 16K.  And then they would have to be stored in memory for display.  Still not providing the extra-large playfield I really wanted.

Then I hit upon the idea of a dynamic scrolling system – the screen would scroll a bit then load new tiles from disk and then continue scrolling.  For better performance, I would keep the entire map in RAM and load each tile as needed.  The scrolling algorithm would be kind of fun – I’d have to detect that the player had reached the boundary, load in new data and then change the display (basically scroll back) to reuse the same memory that had already been traveled.  And make it smooth and seamless.  In all 8 directions!

At that point I decided to shelve the project.

 

Recently however, I decided to have a go at writing this – something keep me sane during a series of excruciatingly boring Zoom meetings.  (SAP implementation)

 

ExploreDiskWIP.atr

So here is my first stab at a solution.  Besides the executable, there are two important files on the disk – the first called 0Tiles.txt is the tile definitions (I currently only have about 20).  Although each tile only consumes 64 bytes, I have stored one per sector.  This simplifies the lookup code and also allows the rest of the space to be used as metadata to describe the tile.  The other file 1Map.txt describes how to map those tiles into the playfield.   The program loads the entire map into RAM (currently 4K).  Multiple maps could exist on the disk providing a number of discrete levels as well.  Or (memory permitting) an even larger map could be created!

So, with these parameters, I get a playfield that is 64 tiles wide by 64 tiles high.  Each tile is 8 x 8 characters.  A total of 512 x 512 or 262,144 total characters!  All smooth scrolling in 8 directions.  That’s more like it!

You’re probably wondering about performance.  A very good question.  Within Altirra, with the disk acceleration turned on, the tiles load quickly enough that there is no noticeable delay.  On a real Atari loading from a disk drive, each load involves a noticeable pause – bad but not lethal.  I also tried a MaxFlash cart and was disappointed that it was not perfectly smooth – however it was better than the diskette.  I’d be interested to learn how the program performs on other hardware.

The playfield does have some flicker – I won’t get rid of that until I move my redraw routine into the VBI and right now Quick is having no part of that.  I’ll need to figure out how to write a fast memory copy routine in assembler.

Of course, nothing is quite that easy.  Now that I have the ability to display a huge playfield, I’ll have to populate it.  Which will require me to create both a tile editor and a map editor.  More fun!

  • Like 6
Link to comment
Share on other sites

If you programmed for a cartridge, you could have all that instantly accessible memory for your tiles, no disk accessing.

 

Also consider that ultra large playfields may not show fully on most tv sets. So keep your important information in the main 320x192 area.

Link to comment
Share on other sites

I would say you've started in a right direction, and I wouldn't rule out disk load from time to time...

 

Games like Zelda were coded with abstractions similar to yours just applied over more levels.

 

Something like:

- "Base tiles" 2x2 chars (wood, grass, stone, bricks, roads etc).

- "Large tiles" 4x4 base tiles (8x8 chars) (Tree, part of house, edge of mountain, river etc...).
- Part of level close to screen size made from 4x4 "large tiles" (forest, clearing, rocky area, desert etc... (total of 32x32 chars size))
If you look at something like original NES rpg games there are those screen sized rooms, caves, dungeons where only difference is which wall has a door or which enemies are inside... One room like that was probably just couple bytes in mem.

So base tiles could be 256x4 = 1 Kb
large tiles = 256x16 = 4Kb
large "parts" = 256x16 = 4Kb
And finally map could be = 64x64 = 4Kb

-----------------------------------------------------

Total: 13Kb for map of 2048x2048 chars...  Thats 50x80 screens
Play with sizes a little and whole map size can explode to what ever you want :) And all this without touching something like RLE compression of  same tiles in a row...

 

On speed of draw I would say best solution is to "draw only parts that change". There are methods like nes does with same principle possible on Atari too.

Reserve 2 or 4 times size of screen and then "just" change display list pointers and draw "new stuff" that comes into screen.

 

 

Link to comment
Share on other sites

A half arsed barely explained rambling:

 

Maybe several techniques combined?

 

* Fully custom meta tile chunks (i.e. hand placed tiles as a stamp) - First quest cave entrance, Castle sections, etc..

* Procedurally generated meta tile chunks (i.e. prng placed tiles over background tiles in a stamp) - Grassy plains, Desert, Ocean

* Procedural meta tile chunks with custom accent tiles overlayed (i.e. hand placed tiles + prng placed tiles over background tiles in a stamp) - Grassy plains with dead tree, Desert with oasis, Shoreline with ocean

 

I say stamp as in instead of storing each tile in the world individually use, say, 16x16 chunks that have their own hand designed tile layouts.

 

I say use a pseudo random number generator to make sure the "randomly" placed accent tiles are always in the same place given the world x/y coordinates.

 

I'm thinking of strategies used in games like Daggerfall, Oblivion, The Faery Tale Adventure, etc..

 

 

  • Like 2
Link to comment
Share on other sites

THat could work Gemintronic, if he can have enough cpu cycles for that...

I did procedural generation in Monk and algorithm was indeed based on random number generator, so in theory could've been 256 unique worlds 128x128 tiles each...

But it was all calculated at start. Once game starts no more complex calc.

ps. I had "stamps" exactly like you talk about with cactus, trees, flowers etc... Cool ideas..,

 

 

 

s

Link to comment
Share on other sites

On 6/11/2020 at 6:01 PM, Irgendwer said:

Thanks for the link!  I played with the code a bit but and made it compatible with the TASM Assembler,   I'm a bit lost on how to pass the three parameters to it (sourcemem,destmem,length).  Can you please help?

Copy.A65

Link to comment
Share on other sites

14 hours ago, popmilo said:

I would say you've started in a right direction, and I wouldn't rule out disk load from time to time...

 

Games like Zelda were coded with abstractions similar to yours just applied over more levels.

 

Something like:

- "Base tiles" 2x2 chars (wood, grass, stone, bricks, roads etc).

- "Large tiles" 4x4 base tiles (8x8 chars) (Tree, part of house, edge of mountain, river etc...).
- Part of level close to screen size made from 4x4 "large tiles" (forest, clearing, rocky area, desert etc... (total of 32x32 chars size))
If you look at something like original NES rpg games there are those screen sized rooms, caves, dungeons where only difference is which wall has a door or which enemies are inside... One room like that was probably just couple bytes in mem.

So base tiles could be 256x4 = 1 Kb
large tiles = 256x16 = 4Kb
large "parts" = 256x16 = 4Kb
And finally map could be = 64x64 = 4Kb

-----------------------------------------------------

Total: 13Kb for map of 2048x2048 chars...  Thats 50x80 screens
Play with sizes a little and whole map size can explode to what ever you want :) And all this without touching something like RLE compression of  same tiles in a row...

 

On speed of draw I would say best solution is to "draw only parts that change". There are methods like nes does with same principle possible on Atari too.

Reserve 2 or 4 times size of screen and then "just" change display list pointers and draw "new stuff" that comes into screen.

 

 

Interesting.  However, I struggled with keeping track of identically sized tiles on my program, the idea of different sizes is rather daunting.  Certainly something to consider.

Link to comment
Share on other sites

14 hours ago, Gemintronic said:

A half arsed barely explained rambling:

 

Maybe several techniques combined?

 

* Fully custom meta tile chunks (i.e. hand placed tiles as a stamp) - First quest cave entrance, Castle sections, etc..

* Procedurally generated meta tile chunks (i.e. prng placed tiles over background tiles in a stamp) - Grassy plains, Desert, Ocean

* Procedural meta tile chunks with custom accent tiles overlayed (i.e. hand placed tiles + prng placed tiles over background tiles in a stamp) - Grassy plains with dead tree, Desert with oasis, Shoreline with ocean

 

I say stamp as in instead of storing each tile in the world individually use, say, 16x16 chunks that have their own hand designed tile layouts.

 

I say use a pseudo random number generator to make sure the "randomly" placed accent tiles are always in the same place given the world x/y coordinates.

 

I'm thinking of strategies used in games like Daggerfall, Oblivion, The Faery Tale Adventure, etc..

 

 

I think Fort Apocalypse uses a similar technique when it expands the tiles into the playfield - the landscape is always slightly different.

 

A static map has appeal as that it would not take any extra code in the game itself to draw/maintain - additionally I envisioned a game where the player could wander back and forth over the landscape without it changing.  However the idea of saving some effort in creating static maps is appealing.  I'll look at ways to create some random or pseudo random effects.

 

Of course, I don't want the landscape to be too static - the player must be able to have some impact on the environment (killing monsters, opening doors, etc).  I had considered saving each tile as it scrolled out of sight.  That would really slow things down! ?

 

 

thanks everyone for your feedback!

  • Like 1
Link to comment
Share on other sites

I'm finding your questions extremely interesting as one of the projects that I have been daydreaming about (I have a few, though these aren't actually in code, just thought) is a top down view of an extremely large landscape with:

 

a) City wide scenery

b) Multiple cities

c) Roads and buildings in the cities and roads inbetween the cities.

 

You're thinking about the things that I have been thinking about.

 

I've figured that it'll need multiple levels of procedural creation. This would need to be combined with a tiling system.

 

In order to allow something like this to fit into an Atari, the strategies considered are:

a) Use an Atarimax 8 megabit cartridge (as most of this is data for tiles). It is also quick access.

b) Some kind procedural algorithm which has a rule something like: TILE=(INT(((TILEX*TILEY)+(TILEX*6+TILEY*3)+TILEX)/TILEY+(MANY MORE MODIFIERS)/AN_AMOUNT)

There may need to be one algorithm to decide where the roads go and then use the previous algorithm for anything either side of the roads.

c) Make the tiles LARGE, i.e. 16x16 or 8x8. As a person is moving from left to right, you'd have to be getting the next tile on the right hand side and then picking out chars from the tile, i.e. [0-15] or [0-7] depending on the tile size. Obviously this would also need to be done for vertical movement too, or if going to right to left.

d) Ensure that the scenery wraps around, so that there is never an edge to your world.

 

Jason Kelk (TMR) on here has a topdown view demo on the C64 (though his is all in memory) is an inspiration for my thoughts. Jason unfortunately though isn't well at the moment and so it seems that his server with a link to that demo appears to be down.

 

Edit: MWP Scrolling would also be useful here. It's a bit difficult to get the head around, but it would be useful: https://atariwiki.org/wiki/Wiki.jsp?page=Ironman Atari#section-Ironman+Atari-MWP

Edited by snicklin
  • Like 1
Link to comment
Share on other sites

  • 4 weeks later...
On 6/11/2020 at 1:47 PM, jacobus said:

So, using tiles was the obvious answer – I could define tiles of 8 x 8 characters and build the playfield from that.  I could create a map and represent the placement of each tile with a single byte.  However, there was still a limit to what I could store in memory.  Definitions for 128 tiles would take 8K, 256 tiles would consume 16K.  And then they would have to be stored in memory for display.  Still not providing the extra-large playfield I really wanted.

Not sure how you're managing the tiles (I'm still waiting for your ATR to finish loading in Atari800, in turbo mode! :) )... but don't forget you can create larger tiles without necessarily chopping down how many different tiles are available.  Say you're using a 40x24 text mode, and want 2x2 tiles to get higher resolution shapes appearing in a 20x12 tile grid.

 

Normally, you'd end up using up to (usually) 4 characters per shape, meaning you've got 128/4 = 32 possible shapes.  But using DLIs, you can swap between two different character sets (fonts) every other line, meaning you can get 64 different shapes.  That requires another 1KB of character set data, but you can also use Load Memory Scan so that every other line shown on the screen is simply a repeat of the one before.

 

Here's a thing I did two years ago as a little test static test.

Image

 

This is GRAPHICS 12 mode, but with 64 2x2 tiles that fit in a 20x12 (really 40x12... but not 40x24!) grid.

 

Anyway, it's late, my brain is turning off and I need to get to bed. Hopefully this makes some sense.

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