[A]tari [G]ame [T]ools - 2D prototyping engine for STE

GFA, ASM, STOS, ...

Moderators: simonsunnyboy, Mug UK, Zorro 2, Moderator Team

Post Reply
User avatar
Anima
Atari Super Hero
Atari Super Hero
Posts: 763
Joined: Fri Mar 06, 2009 9:43 am
Contact:

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by Anima »

Nice update! Thanks! I'll try to check it out on my Raspberry Pi development machine. ;)

Do you have any details on the compression method? I suppose it's a LZ4 variant?
User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3627
Joined: Sat Jun 30, 2012 9:33 am

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by dml »

Hi,

It uses (Markus Franz Xaver Johannes Oberhumer's) NRV2E/pack2e. I bundle an extra tool called 'packwrap' which just compresses a file with p2e and sticks a size prefix etc. on the front so it can allocate the correct space etc. at load time. :-)
User avatar
Richard
Atari freak
Atari freak
Posts: 64
Joined: Sun Mar 09, 2003 3:47 pm
Location: UK
Contact:

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by Richard »

So adding $AGTROOT into my .bash_profile....

I copied the whole AGT folder to the root of my cygwin install so C:\Cygwin\AGT

Then added the following line to the .bash_profile:

export AGTROOT="/AGT"

but my make clean; make on tutor0 returns an error on line 166 which is where the $AGTROOT var is being referenced for the Makerules and complains it cannot find it.

Clearly I have not setup this var properly. Any ideas?

Thanks in advance (and for your patience).
User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3627
Joined: Sat Jun 30, 2012 9:33 am

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by dml »

Cygwin mounts the system drives e.g. the C drive under /cygdrive/

So you'll either need to move the AGT repo inside your cygwin home dir, or set the path to /cygdrive/c/Cygwin/AGT (or whatever)

In any case the C:\Cygwin dir is probably not the place for your projects as its the system Cygwin install not really a working dir. Hope that makes sense!
User avatar
Richard
Atari freak
Atari freak
Posts: 64
Joined: Sun Mar 09, 2003 3:47 pm
Location: UK
Contact:

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by Richard »

Right success! I was trying to run the make of tutor0 from a place I copied it to rather than its location in the repo.

So yes, the repo is in the Cygwin root in a folder called AGT, when I ran make from /AGT/tutorials/tutor0 it all worked fine and compiled me tutor0.tos.

Will run through the rest of the tutorials and have a play.

Thanks for your help!
User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3627
Joined: Sat Jun 30, 2012 9:33 am

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by dml »

Great :)

There might be small inconsistencies between the tutorial wiki and the tutorial source. I tried to fix most of them today but if anything looks wrong and causes confusion just let me know.
User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3627
Joined: Sat Jun 30, 2012 9:33 am

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by dml »

[UPDATE]

The next useful thingy recently added to the engine is configurable guard band. This allows sprites to be drawn safely without physical clipping, outside the screen edges.

AGT has always used a 32-pixel guardband for scrolling purposes but recent changes allow the guard size to be configured for the playfield according to the largest sprite to be drawn.

This has mainly been added to accommodate the recent addition of huge sprite support mentioned in the last update.

Not all features are fully working with the configurable guardband (e.g. debug console is a bit broken) but I'm working on fixes for the remaining cases.
User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3627
Joined: Sat Jun 30, 2012 9:33 am

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by dml »

[UPDATE]

I recently fixed a stupid issue that prevented projects from being built outwith the AGT root directory. i.e. you had to keep your projects in the engine folder alongside the demos and examples (duh!)

It should now be possible to build projects from more sensible locations.
User avatar
Richard
Atari freak
Atari freak
Posts: 64
Joined: Sun Mar 09, 2003 3:47 pm
Location: UK
Contact:

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by Richard »

dml wrote: Fri Jul 24, 2020 5:46 pm [UPDATE]

I recently fixed a stupid issue that prevented projects from being built outwith the AGT root directory. i.e. you had to keep your projects in the engine folder alongside the demos and examples (duh!)

It should now be possible to build projects from more sensible locations.
Great work! Thanks.
User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3627
Joined: Sat Jun 30, 2012 9:33 am

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by dml »

[UPDATE]

This one is still a couple of days out - but it will soon be possible to configure the display to different size/resolutions.

320x200
320x240
320x256
320x272

The shifter interface init() function can take an argument to specify the display mode. It defaults to 320x240. It can be called as many times as required with different modes.

The list of modes above is not complete - a few more are on the way. Will cover those separately.
User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3627
Joined: Sat Jun 30, 2012 9:33 am

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by dml »

The previous update is now in GIT.

When calling shifter::init() you can pass one of these displaymodes:

STLow320x200
STLow320x240
STLow320x256
STLow320x272

e.g.

shift.init(STEDisplayMode::STLow320x200);

Passing no argument defaults to the original 320x240 expected by the samples.

There will be some other modes arriving but the switching mechanism is now in place.

The debug console has been updated to work consistently in all of these modes (and with the configurable guardband, which initially broke it).

Minimized console is always available in the low border even in 320x200 mode, maximized console uses the full 272 height.

When a project is built with the console system enabled, it can be temporarily maximized by holding the [TAB] key even if it is configured to be hidden.
User avatar
alexh
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 2808
Joined: Wed Oct 20, 2004 1:52 pm
Location: UK - Oxford
Contact:

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by alexh »

Very interesting and looking forward to trying it.

Unfortunately I don't have time (or experience/skill) to write a full game, but I'd like to use AGT to see how quickly I could prototype a game like menu system to access several single screens, in the style of the old ST multi-screen Demo disks.

Perhaps Xenon/Uridium/Warp where you fly around looking for the entry points, or a platform game like TwinWorlds/MagicPockets/Enchanted Land etc with doors to access the screens.
User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3627
Joined: Sat Jun 30, 2012 9:33 am

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by dml »

I think there is enough here to do what you suggest - I actually did something like this a few years ago with a more limited version of AGT (without the scrolling - just controlling a craft and shooting menu options to select music tracks).

Font support is currently quite weak though - for that case I used normal sprite calls wrapped in a very simplistic 68k printf stub. While this is just fine for menus, It could use something more dedicated & performant for score overlays etc. It is on my list.

While I am still working on demos/tutorials/examples in the background, I will make a note to create an example close to this description :-)
User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3627
Joined: Sat Jun 30, 2012 9:33 am

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by dml »

[UPDATE]

Until now, cutting sprites from (e.g. PNG) spritesheet images involved passing command switches for position, size etc. (tedious), or writing a small script to guide cutting - which is certainly a lot less hassle but still causes some inertia. Especially if you happen to move the sprites around on the spritesheet, then you have to update the script with all the new cutting positions.

Now it's possible to autocut sprites using a crosshair drawn 'behind' the sprite in a designated key colour.

cross.png

An example of this will be added to the repo soon.


The crosshair provides some benefits:

- in autocut mode, only sprites touching a crosshair get cut, and in approximate left-right, top-bottom order. doesn't have to be pixel accurate alignment. loose positioning is good enough.
- sprites without crosshairs are ignored.
- the sprite frame origin is automatically marked at the crosshair point, so frames animate relative to this point regardless of change in size etc.
- it's smart, so it won't accidentally cut a piece of a nearby sprite that doesn't belong to the crosshair, but overlaps the rectangle. it only cuts pixels in contact with the crosshair.
- you can add frames and move things around without necessarily redoing everything or breaking the game (although you still need to take care over frame animation order).


some other notes:

- you can specify the special key colour used for the crosshair, separately from the normal transparent key colour, per cutting job
- the 'cross' point in the crosshair doesn't have to be visible. it is assumed this will often be covered by the sprite and its position is implied from the visible parts of the crosshair. at least 2 contiguous pixels should be visible in the crosshairs on both axes, either side of the cross.
- this will likely be integrated with the sprite cutting script so you can mix methods in one job
- an update will follow which supports autocutting of sprites with pieces floating/not contacting the main part of the sprite
You do not have the required permissions to view the files attached to this post.
User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3627
Joined: Sat Jun 30, 2012 9:33 am

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by dml »

[UPDATE]

One of the areas where I received much needed feedback (this one from 'masteries', who has provided design input on some new/upcoming features), is the use of collision detection in games where the collision hitbox might need to be completely different from the sprite graphic.

An example is beat-em-ups, where the collision box is typically a short, wide rectangle near the feet, which only overlap if the z-depth (y position) of the sprites is close enough. The rectangle may need to move to a different position during animation/actions and there may even be multiple hitboxes required in specific cases.

AGT has so far produced collision hitboxes which fit the sprite graphic, requiring additional effort to re-define the hitbox in the code at runtime, if any other shape is needed.

The latest version provides something called a 'hidden asset' which may be attached to entities alongside a real (sprite) asset. This allows the engine to draw one sprite while using a different one for the hitbox.

Original:
ha1.png
With hitbox:
ha2.png
Hidden asset for cutting:
ha3.png

Hidden sprites don't actually store any pixel data, just frame metadata. A switch is provided on the sprite cutting tool to control this. Hidden sprites will 'animate' alongside the main sprite and can share a hotspot/origin or use their own.

When no hidden asset is attached to an entity, the visible asset cutting rectangle is used as the hitbox (in both cases, further classification can still be done inside the collision callback function).


An important update will follow which allows the second image ('with hitbox') to be used directly, without deleting any graphics - so hitboxes can be positioned with even less effort. Just draw a coloured box on the sprite frame where you need it. However the basic system is already working, providing you delete visible sprite pixels from the hidden asset spritesheet, leaving only the hitboxes.

Note the hitbox used in the example sprite is not a good one - this is 5-minute mockup to explain how it works ;)
You do not have the required permissions to view the files attached to this post.
User avatar
DarkLord
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 4470
Joined: Mon Aug 16, 2004 12:06 pm
Location: Prestonsburg, KY - USA
Contact:

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by DarkLord »

"DML" with time on his hands is a dangerous (but good!) thing. :)
Welcome To DarkForce! http://www.darkforce.org "The Fuji Lives.!"
Atari SW/HW based BBS - Telnet:darkforce-bbs.dyndns.org 520
User avatar
unseenmenace
Atari God
Atari God
Posts: 1965
Joined: Tue Sep 21, 2004 9:33 pm
Location: Margate, Kent, UK
Contact:

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by unseenmenace »

I only recently stumbled on this thread I'm ashamed to say and I'm very intrigued. Fantastic work and I look forward to seeing a bit more of what it can do.
UNSEEN MENACE
Several STFM's, 4MB STE, 2MB TT with 1.2GB Hard Drive and 14MB Falcon with 540MB Hard Drive,
Lynx 2 and Jaguar with JagCD
Member of GamebaseST and AtariLegend team
Check out my website at http://unseenmenace.110mb.com
User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3627
Joined: Sat Jun 30, 2012 9:33 am

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by dml »

Hi thanks for the comments. I'm travelling for a few days but there are more updates waiting - will follow up when i get back.
User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3627
Joined: Sat Jun 30, 2012 9:33 am

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by dml »

[UPDATE]

With some help from LaceySnr (Matt), it is now possible to build AGT & projects under WSL (e.g. Ubuntu under Win10).

I have only tested projects built within the Linux filesystem e.g. agtools/ cloned under the user home dir - NOT from a shared windows native path. (It might be possible but I didn't try). I think the only reason to even consider that is sharing folders for emulation purposes (e.g. STEEM ?).

Using AGT under WSL does require Vincent's Linux version of the m68k-mint gcc package. There are instructions for obtaining/installing on his site.

It is necessary to set AGTROOT to point at the agtools root dir. AGTBIN should point at the agtools/bin dir.

You'll also need GIT but it is likely to be part of the distro anyway.

As with Cygwin, the WSL approach still uses Windows-native versions of AGTCUT, PCS, RMAC etc. with slightly modified glue. However I'll gradually get these built for Linux & MacOS as well. Probably PCS first then AGTCUT.

(A few 3rd party tools might continue to need special sauce if Posix versions aren't available - will cross that bridge later).

More stuff to follow.
User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3627
Joined: Sat Jun 30, 2012 9:33 am

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by dml »

[TIP]

Here's a neat way (one of many) to wake up enemies when a player sprite crosses/touches a specific part of the game map.

The idea is to create an entity called TRIGGER in its own collision group, with no draw method (making it invisible). These are placed at key points in the map. The TRIGGER is assigned a state meaning 'dormant'. Here we set health=1.

Some enemy (NME) entities are spawned asleep on the map. These can be specified in the map editor and 'tied' to the trigger with some sort of grouping ID (for the game to link up to the TRIGGERs at load time), or the TRIGGER itself can spawn these entities at some offset position, on its first tick. (It then swaps its own tick function to NONE for subsequent ticks, making it inert).

In both cases, the NME entities should point at the TRIGGER as their parent entity.

When the PLAYER sprite crosses the TRIGGER hitbox, the TRIGGER collision callback is called, allowing the TRIGGER health to be changed to 0.

The NME entities watch the health of their parent and when they see it reach 0, they change their own state - either swap their tick function or change a general purpose state variable (such as 'counter') so they can start chasing the PLAYER.

Triggers.png

One cool extra trick is to have the TRIGGER/PLAYER collision event change the NME's parent to the entity that caused the collision (here, the PLAYER). This allows the triggered sprites to chase an arbitrary entity, not just the PLAYER. So certain enemies could trigger them just as the PLAYER does, and start a fight - providing the PLAYER with some extra strategies for play. e.g. if the triggered enemies are particularly tough, it could be useful to have less troublesome enemies wake them up to save you some grief.


An easier way to trigger entities is to simply have a TRIGGER entity spawn some enemies when the player collides with it. However that implies the enemies are not visible before the collision (since they don't spawn before that time). The method described here actually spawns the enemies much earlier and puts them to sleep, changing their state to wake them up. In some situations this is more 'fair' since the player may be able to see where the sprites are hiding and get them first!

There are also more hacky ways to do this - such as keeping a predefined table of entities to wake up on each map, for each trigger - but a more general method (like this one) works better with a map editor, where you are more likely to be placing entities, setting their variables and testing the map in some sort of cycle, without having to maintain tables all the time.


Note: The BOSSCORE demo uses parent-monitoring AI to change the BOSS state as pieces of it are shot away. Shooting the shields away opens the eye and makes the boss mad. (Although it is not quite complete so you can't actually kill the boss yet!). I will make a more specific example for plain triggers soon, matching this writeup.

There are many other things you can do with invisible entities - I'll try to cover some of these in separate tips. :-P
You do not have the required permissions to view the files attached to this post.
User avatar
LaceySnr
Captain Atari
Captain Atari
Posts: 188
Joined: Wed Jun 26, 2013 5:00 am
Contact:

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by LaceySnr »

That's a great setup - pretty sure I could leverage those ideas to great effect in Dave :)

I really should come up with a better name...
User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3627
Joined: Sat Jun 30, 2012 9:33 am

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by dml »

LaceySnr wrote: Fri Aug 07, 2020 12:17 pm That's a great setup - pretty sure I could leverage those ideas to great effect in Dave :)
I really should come up with a better name...
:-)

The full name is fine, but the short version 'Dave' maybe doesn't do it justice!
User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3627
Joined: Sat Jun 30, 2012 9:33 am

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by dml »

[TIP]

When programming entity tick functions, it's useful to know that entities are never really deleted. They never become 'invalid memory' but rather recycled with a new identity and revision.

So it is program-safe to tolerate hanging pointers between entities. e.g...

* entity M points at entity P (lets assume M is a missile and P it its prey)
* P dies in some unfortunate incident unrelated to M
* M still points at the dead entity - no longer being processed or drawn - and still trying to chase it....

To remedy this situation, all you need to do is have M track the state of P, using a reserved field in P (entity_t::rev_self). This is the revision of the entity assigned by the engine when it was spawned.

When the entity is removed, it is put in a KILL pending state by the engine but remains intact until the end of the tick pass.

Following the tick pass, all entities in this KILL state are removed/recycled together. The entity_t::rev_self field is then modified to indicate to any observers (other entities interested in it) that this entity no longer exists and should drop interest.

In the case of our missile M, it will stop chasing the killed entity P and either self-destruct, or continue on its last trajectory until it goes out of the viewport.

---

Tracking.png

In order to be able to do this, each entity provides the following fields:

entity_t::pparent + entity_t::rev_parent
entity_t::ptrack + entity_t::rev_track
entity_t::rev_user

entity_t::rev_parent is used with entity_t::pparent to track the revision of the parent which spawned it, so parent disconnections can be managed (when the parent entity dies). pparent can be assigned manually but it can also assigned automatically when spawning entities relative to other entities using the spawn interface (e.g. in their tick or collide functions).

entity_t::rev_track can be used with entity_t::ptrack to implement chasing or tracking behaviour, separately from the parent link. This can be useful if parent links are already being used to build object hierarchies or composite entities made from several parts, but still need to track some other entities. ptrack/rev_track are user fields and can only be assigned manually!

entity_t::rev_user is a spare revision variable for any user purpose. In the interests of keeping entity_t structure small, it doesn't have a dedicated entity pointer but one can be obtained by overloading another unused entity field.


There are other ways to do this - observer chains are arguably more efficient, removing the need to monitor links (e.g. each entity has a list of interested entities to notify when it dies) - but is more complex and requires more storage and/or initialization. This increases the cost floor for small abundant entities such as bullets which do not need the mechanism. Tracking/chasing and composite structures will not be the majority of game objects so the revision tracking approach should work well for most situations and is cheap to represent.
You do not have the required permissions to view the files attached to this post.
User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3627
Joined: Sat Jun 30, 2012 9:33 am

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by dml »

[UPDATE]

Have committed a new sample under 'examples/giantsprites' showing how to cut & use the giant sprite format shown previously as a W.I.P.

There's a bit more to this sample though - another update will follow.
User avatar
dml
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3627
Joined: Sat Jun 30, 2012 9:33 am

Re: [A]tari [G]ame [T]ools - 2D prototyping engine for STE

Post by dml »

[UPDATE]

The next new thing is something called occlusion maps. This is the product of suggestions & ideas I received (thanks masteries!) to improve performance for very big sprites e.g. end-of-level bosses.

partial refresh 1.png
When cutting giant sprites (which must be done with the -emc switch), you can also embed precalculated occlusion maps with '-ocm'. This generates a kind of pixel coverage map indicating what areas need refreshed under the sprite when it moves. The maps represent 1 bit per covered background tile.

To use occlusion maps, the PFA_OcclusionMaps attribute must also be set in the playfield config, (otherwise the sprites will draw but the background behind them won't be refreshed).


DETAILS:

Two maps are generated per sprite frame - one (the 'T' map for transparency) indicates tiles with 'any pixels covered' and the other ('O' map for opacity) indicates tiles with 'all pixels covered'.

When sprites overlap using this mechanism, BG area behind them is only refreshed once. (With the standard mechanism, some areas may be refreshed multiple times, depending on the overlap depth). This provides a saving when large sprites overlap or are made of multiple composite parts.

When the sprite moves, the opaque areas at the NEW position are subtracted from the transparent areas at the OLD position. This means the sprite is only updated at the edges which trail behind it. The bigger the sprite and the slower it moves, the fewer tiles need refreshed in proportion to the whole - and more time is saved.

When animation occurs, opaque parts of the new frame are also subtracted from transparent parts of the previous frame.

The opaque parts of overlapping sprites combine, which can provide further savings.

When an entity is destroyed, no opacity is emitted so the entire contour is refreshed next frame.

(One further optimization remains to be done - when a sprite does not move, refreshing can be bypassed completely for that frame - this will be a separate update at some point in future)


While this mechanism is fairly general, it is not worth using for small or medium sized sprites because the standard BG refresh mechanism is more efficient at tightly-fitting the sprite shape. The occlusion maps are preshifted on a 4x4 pixel grid but still the standard method is faster for most cases. It will only yield savings when the sprites really big - increasing when they overlap and even more so when the objects move very slowly.

However it is possible to mix different sprite refresh mechanisms on one playfield - it can be reserved for sprites that most need it.

SAMPLE:

The examples/giantsprites sample uses two sprites with occlusion maps and four without. It can be used as a reference for integrating this into a game project.


Occlusion maps only work on 'giant (cut with '-emc')' sprites in EMX/EMS format, using 16x16 playfield tiles and with single-layer playfields.
You do not have the required permissions to view the files attached to this post.
Post Reply

Return to “Coding”