Jump to content
IGNORED

Final Assault - new game by GMG


globe

Recommended Posts

4 minutes ago, Heaven/TQA said:

are you going the standard way in terms of 1d z buffer and sorting the enemies by Z?

Yes. Though sorting is kind of a strong word considering the limit of 2 objects/enemies in player's FoV.

Basically I just check how many objects there are in front of the player (result should be 0,1 or 2) and if it's 2 then the closer one gets assigned PMG Player 0+1 and the farther Player 2+3  so they are shown correctly if they overlap.

  • Like 1
  • Thanks 2
Link to comment
Share on other sites

On 11/5/2021 at 10:29 AM, AHA said:

fabu-tastic at last a doom like game for our little 8 bits, well done to those that made it, i like this a lot!! many thanks guys!

Did you consider using color mode (like Numen) and software sprites? The lighting effects probably wouldn't work without that many shades but textures could be more diverse.

  • Like 1
Link to comment
Share on other sites

16 minutes ago, ilmenit said:

Did you consider using color mode (like Numen)

Gr.10?

Yes, but there's only 9 color registers and considerations never went beyond switching PRIOR $D01B for a bit without making proper textures for it.

Actually when player gets hit, GR.10 flashes for a frame (or two?) to show interference. I wanted to use some static noise for that but changing PRIOR $D01B was cheaper.

gr10.png.b65ff111d4363d0c577c417423aa0502.png

 

23 minutes ago, ilmenit said:

software sprites

Some downsides, some upsides but in the end the memory cost was too great.

 

Upsides:

-closer, big objects could be more detailed

-more zoom levels than 12

-no 2 per view limit on objects and enemies (this has some extra cost because of overlapping of more objects wouldn't be as easy as with PMGs)

-much easier clipping since you draw into wall columns (clipping was a nightmare with PMGs)

 

Downsides:

-farther, smaller objects and enemies would be blocky and less recognizable compared to PMGs,

-because of the mode used they'd blend into the environment more

-RAM cost: PMGs have 2x and 4x HW zoom (although you still need to handle the vertical stretching manually) so for 12 zoom levels used I only need to store data for 4 and get rest almost for free.

You could try to work around this by storing only some zoom levels and doing scaling in software but then you'll be spending much more cycles than for PMGs.

Then you need a mask and pre-shifted graphics if you want enemies to move at pixel resolution + associated cycle costs of doing bit operations.

 

1030880361_zoomlevels.png.b7fbd6e46d208d57deeed74e650e764d.png

 

 

 

 

 

 

 

 

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

2 hours ago, globe said:

Yes. Though sorting is kind of a strong word considering the limit of 2 objects/enemies in player's FoV.

Basically I just check how many objects there are in front of the player (result should be 0,1 or 2) and if it's 2 then the closer one gets assigned PMG Player 0+1 and the farther Player 2+3  so they are shown correctly if they overlap.

and clipping behind the wall?

Link to comment
Share on other sites

1 hour ago, globe said:

Gr.10?

Yes, but there's only 9 color registers and considerations never went beyond switching PRIOR $D01B for a bit without making proper textures for it.

Actually when player gets hit, GR.10 flashes for a frame (or two?) to show interference. I wanted to use some static noise for that but changing PRIOR $D01B was cheaper.

gr10.png.b65ff111d4363d0c577c417423aa0502.png

 

Some downsides, some upsides but in the end the memory cost was too great.

 

Upsides:

-closer, big objects could be more detailed

-more zoom levels than 12

-no 2 per view limit on objects and enemies (this has some extra cost because of overlapping of more objects wouldn't be as easy as with PMGs)

-much easier clipping since you draw into wall columns (clipping was a nightmare with PMGs)

 

Downsides:

-farther, smaller objects and enemies would be blocky and less recognizable compared to PMGs,

-because of the mode used they'd blend into the environment more

-RAM cost: PMGs have 2x and 4x HW zoom (although you still need to handle the vertical stretching manually) so for 12 zoom levels used I only need to store data for 4 and get rest almost for free.

You could try to work around this by storing only some zoom levels and doing scaling in software but then you'll be spending much more cycles than for PMGs.

Then you need a mask and pre-shifted graphics if you want enemies to move at pixel resolution + associated cycle costs of doing bit operations.

 

1030880361_zoomlevels.png.b7fbd6e46d208d57deeed74e650e764d.png

 

 

 

 

 

 

 

 

cool. finally one game using our "hardware zoom" :D 

  • Like 1
Link to comment
Share on other sites

1 hour ago, ilmenit said:

Did you consider using color mode (like Numen) and software sprites? The lighting effects probably wouldn't work without that many shades but textures could be more diverse.

to be honest. even ported the numen engine to different platforms... I have to admit... didn't paid attention of how Piotr handled the duke nukem sprites. need to have a look in the source again.

Link to comment
Share on other sites

1 hour ago, Heaven/TQA said:

and clipping behind the wall?

If you decide to use PMGs for enemies, I promise you're going to love the clipping part:)

 

Anyway, you probably know the basics: calculate how far away the enemy is from the player (translate into 'wall depth' if necessary).

Depending on zoom level (width) of the enemy and position on the screen, find out what wall slices he occupies and check enemy depth against wall depth, slice by slice.

 

Possible results:

1. all wall slices are behind the enemy = easy part, draw the enemy with desired zoom level because there's no wall covering it, only clipping you may need is on the sides of the screen (for 40 bytes width screen, if you went with wide screen you'd avoid even this hassle).

2. all wall slices are in front of the enemy = you won, don't need to draw the enemy at all, just clear PMG memory or set horizontal registers to 0

3. enemy is partially covered by slice/s of the wall from one side, other side, both sides or clipped by left screen border or right screen border (while also being covered by the wall from the other side:)

 

clipping.png.be01c9940aeb2600ddf2d5f1dca5adb4.png

 

Things to consider:

 

PMG zoom level:

4x zoom = one enemy pixel = 2 gr.9 pixels - you clip single bits

2x zoom = one enemy pixel = 1 gr.9 pixel - you clip bit pairs

1x zoom = two enemy pixels = 1 gr.9pixel - you clip 4 bits at once

 

Alignment - does the enemy 'stands' at the border of the wall slice or in the middle (my enemies / objects are always aligned to gr.9 pixels, at maximum zoom level to whole bytes because I can't clip half the pixels from PMG player)

 

PMG width:

If you're going for something similar to this

zoom.png.4836f808ce34c7ecdcd23f8de19d4a9e.png

you'll notice that at 4x HW zoom enemy may occupy 5 - 8 wall slices depending on zoom level

 

That should be more or less all.

It's not a long routine but it's one I spent a lot of time with before it worked properly.

 

If you go with softsprites it should be considerably easier to do this (though you'll pay the price in RAM and cycles for other things)

 

Anyway, good luck making it work.

Edited by globe
correction player/enemy in Possible results: point 3
  • Like 2
  • Thanks 1
Link to comment
Share on other sites

My only issue with this game so far is the fact that enemies are able to shoot and hit me through the walls. Those roving blue sentries are the worst about this. I will hear the alert type chirp they make and then be taking damage. Spin around and look and I do NOT see where the shots are coming from. Finally move and get around the wall and there they are! So yes it would seem that they have the ability to detect and shoot me through the walls sometimes which really isn't cool!

 

  • Like 2
Link to comment
Share on other sites

24 minutes ago, -^CrossBow^- said:

My only issue with this game so far is the fact that enemies are able to shoot and hit me through the walls. Those roving blue sentries are the worst about this. I will hear the alert type chirp they make and then be taking damage. Spin around and look and I do NOT see where the shots are coming from. Finally move and get around the wall and there they are! So yes it would seem that they have the ability to detect and shoot me through the walls sometimes which really isn't cool!

 

 

 

In a game it is probably confusing and Globe will probably explain what could go wrong during pixel rounding etc.

 

But in real life my shoulders are quite wider than my head where the eyes are placed. So I can be shot to my arm that protrudes the corner I do not see behind.

 

If we were Electronic Arts we could easily call it a real world feature and not a bug.

I suggested to include microtransactions and loot boxes during development, but Globe just kept staring at me for a while and then told me to get out. ? 

 

It looks like we are not like EA and probably will take a closer look at players look(ing)...

 

 

Edited by goldy/gmg aka lopez453
  • Haha 5
Link to comment
Share on other sites

3 hours ago, -^CrossBow^- said:

My only issue with this game so far is the fact that enemies are able to shoot and hit me through the walls. Those roving blue sentries are the worst about this. I will hear the alert type chirp they make and then be taking damage. Spin around and look and I do NOT see where the shots are coming from. Finally move and get around the wall and there they are! So yes it would seem that they have the ability to detect and shoot me through the walls sometimes which really isn't cool!

 

Line of sight checking was another tough nut to crack.

 

First I tried to do simplest, cheapest thing and only check using the resolution of a grid tile (grid tile = square tile which is either wall or floor) hoping something at least partially useful will come out of it.

Well, it didn't. 

 

1167798596_enemyagro.png.888a4ae0225451d73401bc70f7d29085.png

 

 

Next attempt was a single precise line (which is more expensive to do cycle-wise) but that didn't go so well either.

A lot of cases where player could clearly see the enemy but the enemy didn't 'see' the player and didn't start to attack at all (would be skewed too much in favor of player and we can't have that:).

 

519104752_enemyagro2.png.c50a9c9202f963d160584a5fdbec350c.png

 

Foolproof solution would be to cast a lot more precise lines but that's a lot of cycles spent because line of sight checking can't be easily simplified like the ray casting part.

 

In the end I went back the grid based LoS check, but instead of whole grid tile I divided the tile and did some adjustments according to player's and enemy's position inside the tile.

Precision isn't 100% and the check errs in favor of enemy so shooting through corners of wall can happen.

 

I don't see an easy solution to this besides making the check go in favor of the player but then cases like picture 2 in this post, especially with static enemies would happen.

 

 

3 hours ago, goldy/gmg aka lopez453 said:

 

I suggested to include microtransactions and loot boxes during development, but Globe just kept staring at me for a while and then told me to get out. ? 

Couldn't find anything in immediate vicinity to throw so what else could I do? :)

 

 

3 hours ago, goldy/gmg aka lopez453 said:

But in real life my shoulders are quite wider than my head where the eyes are placed. So I can be shot to my arm that protrudes the corner I do not see behind.

I like this excuse a lot, must memorize:)

 

  • Like 3
Link to comment
Share on other sites

If I remember correctly in Half Life 2 there was an AI exploitation technique that enemies saw you (or were able to shot at you?) only if you saw them. Maybe something similar could be used in this engine - if you are facing an enemy it may attack you only if any part of it is not covered by a wall (so some pixels of enemy are visible), but if it's not in your field of view the currently implemented line of sight can be used?

  • Thanks 1
Link to comment
Share on other sites

2 minutes ago, ilmenit said:

If I remember correctly in Half Life 2 there was an AI exploitation technique that enemies saw you (or were able to shot at you?) only if you saw them. Maybe something similar could be used in this engine - if you are facing an enemy it may attack you only if any part of it is not covered by a wall (so some pixels of enemy are visible), but if it's not in your field of view the currently implemented line of sight can be used?

that would open serious speedrunning challenge because you would be able walk/strafe by enemies while looking to walls only... so called "pacifist run".

  • Like 1
Link to comment
Share on other sites

4 hours ago, globe said:

Line of sight checking was another tough nut to crack.

Don't you have all needed info in raycasting and pmg masking already ?

 

You have wall distance for all columns, you have distance to enemy that you use to determine if pm column is visible or not.
So player can hit enemy only if PM column is visible where player is aiming.

 

For detecting if enemy can hit player you only need to "cast" that one ray between enemy and player. My guess 40+couple casted rays instead of 40 isn't that big difference ?

If you run into a wall while going from enemy toward player position, just quit, no hit possible.

Of course, this is valid if you don't want to take into account width of player shoulders etc ;)

Could even use some randomness with each shot fired. Distance * randomness factor. So if enemy is far away he can fire but less chance to hit. If you're too close, and visible to enemy, every shot probably counts.

 

  • Like 2
Link to comment
Share on other sites

5 hours ago, ilmenit said:

Maybe something similar could be used in this engine - if you are facing an enemy it may attack you only if any part of it is not covered by a wall (so some pixels of enemy are visible), but if it's not in your field of view the currently implemented line of sight can be used?

This could probably work. I like the 'out of sight out of mind' part.

 

54 minutes ago, popmilo said:

Don't you have all needed info in raycasting and pmg masking already ?

 

You have wall distance for all columns, you have distance to enemy that you use to determine if pm column is visible or not.
So player can hit enemy only if PM column is visible where player is aiming.

That's when player shoots the enemy and it works exactly as you described, if there's enemy slice in the middle of screen, under the cross hair and you pull the trigger, enemy gets hit (with first 3 weapons at least).

My post was about enemy shooting toward the player.

 

54 minutes ago, popmilo said:

For detecting if enemy can hit player you only need to "cast" that one ray between enemy and player.

See post #237 image 2 for why this isn't always ideal solution.

 

54 minutes ago, popmilo said:

My guess 40+couple casted rays instead of 40 isn't that big difference ?

It's not really comparable.

Raycasting doesn't 'draw' a full line, that would be too slow and wasteful. Only grid intersections are checked.

For line of sight check I do 'standard' bresenham line and if you check a few 'fast line drawing' threads on AA you'll see how much that costs and how many per frame can be done (somewhere around 9 or 10 per frame IIRC and that's while CPU is completely dedicated to drawing)

So '+couple casted rays' would definitely slow things down and there's 4 enemies in one map segment so multiply accordingly.

To manage the last part I already do some simple scheduling so all LoS checks don't fire at once.

57 minutes ago, popmilo said:

If you run into a wall while going from enemy toward player position, just quit, no hit possible.

Of course, this is valid if you don't want to take into account width of player shoulders etc

Yeah, that' the thing. If you go from enemy center to player center things like post #237 image 2 will happen while it would be perfectly possible in that scenario for the enemy to hit the player if it aimed a bit more to the right.

 

What I'm trying to say with all this: Perfect check is possible but unbearably costly, every other method is just a shortcut with different set of circumstances where it doesn't perform as required.

 

 

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

Globe - youve done a great job with this engine and game.  Havent seen any options that you havent already vetted to get to where its at today.  For those asking about a quick turn would it be possible to bind a key which provides a 180 turn?  Would only be used when players want to fully turn around?

  • Like 2
Link to comment
Share on other sites

3 hours ago, globe said:

This could probably work. I like the 'out of sight out of mind' part.

 

That's when player shoots the enemy and it works exactly as you described, if there's enemy slice in the middle of screen, under the cross hair and you pull the trigger, enemy gets hit (with first 3 weapons at least).

My post was about enemy shooting toward the player.

 

See post #237 image 2 for why this isn't always ideal solution.

 

It's not really comparable.

Raycasting doesn't 'draw' a full line, that would be too slow and wasteful. Only grid intersections are checked.

For line of sight check I do 'standard' bresenham line and if you check a few 'fast line drawing' threads on AA you'll see how much that costs and how many per frame can be done (somewhere around 9 or 10 per frame IIRC and that's while CPU is completely dedicated to drawing)

So '+couple casted rays' would definitely slow things down and there's 4 enemies in one map segment so multiply accordingly.

To manage the last part I already do some simple scheduling so all LoS checks don't fire at once.

Yeah, that' the thing. If you go from enemy center to player center things like post #237 image 2 will happen while it would be perfectly possible in that scenario for the enemy to hit the player if it aimed a bit more to the right.

 

What I'm trying to say with all this: Perfect check is possible but unbearably costly, every other method is just a shortcut with different set of circumstances where it doesn't perform as required.

 

 

DDA instead of bresenham might worth to consider…. but you can not compare a long line with LOS length?

  • Like 1
Link to comment
Share on other sites

5 hours ago, globe said:

Raycasting doesn't 'draw' a full line, that would be too slow and wasteful. Only grid intersections are checked.

...

So '+couple casted rays' would definitely slow things down and there's 4 enemies in one map segment so multiply accordingly.

To manage the last part I already do some simple scheduling so all LoS checks don't fire at once.

Yeah, that' the thing. If you go from enemy center to player center things like post #237 image 2 will happen while it would be perfectly possible in that scenario for the enemy to hit the player if it aimed a bit more to the right.

Well, as it looks you thought about everything that's slowly coming to my mind while thinking about this, so I'm happy :)

I was just going to write about distributing load across multiple frames :)


Guess you only need to check enemies that are firing. i hope it's not like every enemy is firing every frame ;)

With that in mind, one could go simple grid cell resolution raycast from enemy towards player until last cell with player is reached (if wall is encountered process is done anyway).

When you know ray is in last cell, do some math to check if player is hit.

 

That problem with "ray would be stopped at wall corner" is interesting... Makes you wanna code full enemy and player width check. like cast rays from one entity to both left and right edge of second entity.

I wonder if it could be that simple. Cast two standard grid rays per enemy which is firing. 5 enemies firing in a second is like 1 enemy fires per 10 frames... Maybe enough to calc two rays. As player and enemies are always narrower than grid cell, no wall could hide both edges of a target. If one is visible -> hit.

Of course, as you're doing raycast based on x,y pairs of shooter and target and not by angle of column of screen, it would need some additional math I guess...

Such a complex topic, I admire you got to a complete product :)

ps. How long did development take if you don't mind me asking ?

 

Cheers!

Vladimir

 

 

  • Like 1
Link to comment
Share on other sites

12 hours ago, Goochman said:

would it be possible to bind a key which provides a 180 turn?  Would only be used when players want to fully turn around?

In the version for larger RAM machines absolutely.

Just wondering, I get various fast turning and 90 degrees turning requests but 180 degrees seems only useful when you decide to 'go back', for traversal, since usually there shouldn't be any enemies in direction where you came from.

I mean, there are no complicated map segments where enemies would be able to sneak behind your back.

 

9 hours ago, Heaven/TQA said:

DDA instead of bresenham might worth to consider…. but you can not compare a long line with LOS length?

Thanks, I'll check it out. Not sure what the question means.

 

7 hours ago, popmilo said:

i hope it's not like every enemy is firing every frame

Some of them aren't shooting at all (floating mines) so they're excluded from LoS check.

For the rest the checks are relatively frequent because of how the whole enemy aggression works.

Don't want to write another page-long post so let's just say there's couple of phases and player gets a bit of leeway and audio warning in the beginning instead of being blasted by bots as soon as he gets spotted.

(for detailed enemy attack behavior there's [ENEMY INFO] section in the manual)

 

7 hours ago, popmilo said:

With that in mind, one could go simple grid cell resolution raycast from enemy towards player until last cell with player is reached (if wall is encountered process is done anyway).

When you know ray is in last cell, do some math to check if player is hit.

See post #237 image 1 for grid tile check trouble.

Red square = enemy, green squares = possible player positions, in both cases there's no obstacle between enemy and player at grid tile resolution while it's pretty obvious they can't see each other.

 

What does 'do some match check' means anyway? 

Unless you do some proper line from enemy towards the player how else do you detect corners protruding and blocking the shot?

 

8 hours ago, popmilo said:

That problem with "ray would be stopped at wall corner" is interesting... Makes you wanna code full enemy and player width check. like cast rays from one entity to both left and right edge of second entity.

I wonder if it could be that simple.

I really wish it would. Sure it's somewhat more expensive but it it was 100% correct it would be a good solution

Here's a rough sketch that shows what could go wrong at 'incorrect' angles and enemy/player positions. (nothing's really up to scale, just an illustration)

 

519104752_enemyagro2.png.c50a9c9202f963d160584a5fdbec350c.png.e8576c02ea5689e9d4fb12d41db483a4.png

 

Enemy CAN hit the player if it aimed a bit to the right from players center (talking from enemy POW)

 

If you want to complicate this a lot more the flying sentry (blue floating ball) has gun in the middle but the armored sentry (grey bot) has guns at both sides :) :) :)

 

The more I think about this the more I come to the conclusion that making it simple, flawed but IN FAVOR OF THE PLAYER would solve this.

People would probably feel it's less flawed when they aren't getting shot from behind the wall by enemy they can't see.

 

7 hours ago, popmilo said:

How long did development take if you don't mind me asking ?

Roughly 2,5 years of coding and testing* with a couple of weeks for research before that.

 

*that's 'hobby time' so sometimes I spent week worth of evenings coding drawing etc.. sometimes real life had priority and only small progress was made (or none), you know how that works.

 

  • Like 4
  • Thanks 2
Link to comment
Share on other sites

3 hours ago, globe said:

 

The more I think about this the more I come to the conclusion that making it simple, flawed but IN FAVOR OF THE PLAYER would solve this.

People would probably feel it's less flawed when they aren't getting shot from behind the wall by enemy they can't see.

 

@globe  Just been catching up withn the last few pages.

 

I would totally agree with your above statement. Definitely happened to me several times and what you suggest would eliviate the frustration factor.

 

Honestly can't wait to see 1.1 release as and when. :D

 

As for the development time you have put into this - 2.5years is a long time. Hats off to you for sticking at it. The A8 commmunity is better off for it that's for sure. :thumbsup:

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

re: Bresenham fast line / DDA

what I ment with my "sentence" was that I don't know how long is your actual "line of sight" so my gut feeling was that even it is just few "pixels" long bresenham might loose in terms of setup time etc? as you mentioned you had a look at the fast line drawing thread. but that was highres line drawing all over the screen while your "use case" is far less?

 

That was my question... in what resolution you are woring for the Line of Sight?

  • Like 2
Link to comment
Share on other sites

@globe guess what me and @Heaven/TQA are mentioning is dda algorithm for grid based traversal of space, something like this (similar to one on lodev.org):

https://www.researchgate.net/figure/Ray-casting-DDA-algorithm-illustrated-in-two-dimensions-Rays-are-cast-through-a_fig2_329503247

 

It's similar to Permadi tutorial as it goes from edge to edge of grid cells, but math is little different (easier).

 

 

Anyway... Your last point is probably most important. Make game feel fun to play, not too hard, not to easy. Even robots shooting only in straight lines (with simplest possible line of sight check) would probably be ok.

 

Kudos on 2.5years of dev time, that's a really great work :)

 

  • Like 3
  • Thanks 1
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...