New TGC product: AGK Studio(=AGK3?) + discounts for early adopters..

Started by Rick Nasher, February 04, 2019, 23:10:49

Previous topic - Next topic

Qube

Quote from: Pingus on February 07, 2019, 22:45:53
Ok, this answer my question:

Quote* Exe's will be the same as they are in AppGameKit Classic

https://forum.thegamecreators.com/thread/223741?page=2

So back to GameMaker for me (too bad I really prefer the AGK language).
Is there something you're trying to achieve in code which is just too slow for AGK?. The only speed issues I've come across is when doing my path finding routine on dozens of enemies I had to break up the path finding over time rather than brute force in one cycle. I know a compiled language would handle that side much better but I've not come across any show stopping issues yet.
Mac Studio M1 Max ( 10 core CPU - 24 core GPU ), 32GB LPDDR5, 512GB SSD,
Beelink SER7 Mini Gaming PC, Ryzen 7 7840HS 8-Core 16-Thread 5.1GHz Processor, 32G DDR5 RAM 1T PCIe 4.0 SSD
MSI MEG 342C 34" QD-OLED Monitor

Until the next time.

Pingus

@Qube

My "business" is Match3 game made of pretty big boards. This means several hundred of objects that interact between themselves with different behaviors. There are a lot of loops thru the board array and it takes a negligeable amount of CPU in bmax.
I found a piece of Match3 code in AGK which does a very simplified job compare to what my code do. And when I increase the board size of that sample, it just run like shit on my I7-6700K so I do not dare to go further with an interpreted language when I see that the same job is done effortless by a compiled exe. Of course everything can alway be optimized and rewriten but there is enough work to do when converting a game, no need to add extra work at reinventing the wheel. Of course I'll do a similar test in GameMaker, maybe I'm just used to bmax efficiency.
AGK seems perfectly fine for platform or action game, but for parsing arrays and recursive stuff (including pathfinding), it is not the best bet imo. I had a bit of hope seeing a new AGK product but it makes sense that they keep their interpreter, it is probably a huge work to handle a compiler for all targets while it is not their primary target as long as people are mostly fine with the interpreter.

(edit : if you are interrested, I can PM you the AGK code if you want to have a look at it)

Qube

QuoteI found a piece of Match3 code in AGK which does a very simplified job compare to what my code do. And when I increase the board size of that sample, it just run like shit on my I7-6700K
Crikey, that doesn't sound right :o - A match-3 shouldn't be a hard issue for AGK. I was working on a match-3 game in Oct 2017 ( abandoned ) and didn't come across any speed issues. Granted it's quite simple at this stage but the boards could have been much bigger without issue too.

QuoteAGK seems perfectly fine for platform or action game, but for parsing arrays and recursive stuff (including pathfinding), it is not the best bet imo
I did find that performance is a lot better in arrays when dealing with integers alone and performance suffers a lot when doing logic heavy stuff that compares strings. I know in general that integer vs strings is quicker on the integer side but in an interpreted language it can drain performance a lot if you're dealing with loads of strings per loop.

Quote(edit : if you are interrested, I can PM you the AGK code if you want to have a look at it)
Sure, if you could send me a full working project I'd happily take a look :)
Mac Studio M1 Max ( 10 core CPU - 24 core GPU ), 32GB LPDDR5, 512GB SSD,
Beelink SER7 Mini Gaming PC, Ryzen 7 7840HS 8-Core 16-Thread 5.1GHz Processor, 32G DDR5 RAM 1T PCIe 4.0 SSD
MSI MEG 342C 34" QD-OLED Monitor

Until the next time.

GaborD

Quote from: Pingus on February 08, 2019, 00:25:03
@Qube

My "business" is Match3 game made of pretty big boards. This means several hundred of objects that interact between themselves with different behaviors. There are a lot of loops thru the board array and it takes a negligeable amount of CPU in bmax.
I found a piece of Match3 code in AGK which does a very simplified job compare to what my code do. And when I increase the board size of that sample, it just run like shit on my I7-6700K so I do not dare to go further with an interpreted language when I see that the same job is done effortless by a compiled exe. Of course everything can alway be optimized and rewriten but there is enough work to do when converting a game, no need to add extra work at reinventing the wheel. Of course I'll do a similar test in GameMaker, maybe I'm just used to bmax efficiency.
AGK seems perfectly fine for platform or action game, but for parsing arrays and recursive stuff (including pathfinding), it is not the best bet imo. I had a bit of hope seeing a new AGK product but it makes sense that they keep their interpreter, it is probably a huge work to handle a compiler for all targets while it is not their primary target as long as people are mostly fine with the interpreter.

(edit : if you are interrested, I can PM you the AGK code if you want to have a look at it)

Is the constant array looping a must? I admit I am not an expert in match3 style games, mostly focus on 3D, but I have yet to see the code execution have any impact on speed. It must be some really complex high iteration stuff.

If the heavy loopage can't be avoided, what if you run the most impactful things on the GPU?
That's usually my choice for the potentially heavy impact "run in the background" things (particle movement, pathfinding, etc)
Looping through all the board positions sounds like a somewhat parallelized thing, doing similar simpler things for many locations, kinda exactly what a GPU is about.

But you are ofcourse right that compiled code would be faster and preferrable.
It's just not really an issue for most game scenarios (the bottleneck is almost always the rendering), my guess is that is why it hasn't been adressed yet.
There is a request thread for the upcoming version on the official forums, maybe this should be added. (my guess is it already is, I haven't checked)

Derron

You should consider switching from a "permanent grid check" to an "action/event based grid check".

Means: instead of constantly checking all tiles/elements of wheather they "match 3" or so, you only check if you recently collapsed (aka an element on the grid changed). This alone will cut CPU costs by a big big bit.

Also you never need to check the whole grid if a cell changed. you know it needs three connected cells to match 3+... so you never need to look further if the first neighbour failed already. Special tiles need special checks of course.

bye
Ron

Xerra

Quote from: GaborD on February 08, 2019, 05:50:09
Is the constant array looping a must? I admit I am not an expert in match3 style games, mostly focus on 3D, but I have yet to see the code execution have any impact on speed. It must be some really complex high iteration stuff.

Match 3 games have evolved over the last few years. nowdays they are more dynamic - as in they update constantly when shapes are being moved and also will let you make a move while the update of the other objects is taking place. That's probably a case for newer games needing three times the welly compared to the old games that made you move then processed all the permutations before letting you have another turn.

I'm pretty sure that something like AGK should be able to handle it all still, however. I've never written a match 3 game but always thought that I'd one day have a go at doing a prototype for one - just for the challenge.
M2 Pro Mac mini - 16GB 512 SSD
ACER Nitro 5 15.6" Gaming Laptop - Intel® Core™ i7, RTX 3050, 1 TB SSD
Vic 20 - 3.5k 1mhz 6502

Latest game - https://xerra.itch.io/Gridrunner
Blog: http://xerra.co.uk
Itch.IO: https://xerra.itch.io/

Derron

Games having this "move tiles while others collapse" still do not need to check all elements versus others.
Each changed/updated/moved tile marks cells as changed. Now you only handle the neighbours of changed elements. Afterwards you mark the cell as clean. Also you could have a counter describing the amount of changed/dirty cells.

Is this cellcount 0 then you do not have to check for new matches.


Another idea is: while a tile still seems to animate/move into its new position the cells have a "state". It is either occupied or not. Blocks do similar stuff.

Animation is decoupled from game logic..or should at least be only loosely coupled (eg by triggers). You could define an animation and know its duration. You start a logic timer thing with this duration...and regardless of whether you render or not, the effect happens after "duration".


Even with totally dynamic blocks there is no need to handle all the other blocks each "loop".


Bye
Ron

Qube

@Pingus - I quickly looked over the code you sent me and there's nothing glaringly wrong with it. To test if there was a bottle neck I changed the code to capture min and max FPS while making various matches. The highest FPS was 683 and the lowest was 472 which shows there's loads of cycles free for other things.

This is on a 3.8 GHz Intel Core i5 CPU so slower than your i7 so it's a mystery as to why it's slow on your faster CPU? :o
Mac Studio M1 Max ( 10 core CPU - 24 core GPU ), 32GB LPDDR5, 512GB SSD,
Beelink SER7 Mini Gaming PC, Ryzen 7 7840HS 8-Core 16-Thread 5.1GHz Processor, 32G DDR5 RAM 1T PCIe 4.0 SSD
MSI MEG 342C 34" QD-OLED Monitor

Until the next time.

Pingus

@Derrron

Things are a bit more complicated than just marking a cell as busy or complete. Some pieces are moving at different speed, and when a piece can not fall due to an obstacle, it does check if diagonal moves are possible which may interact with other pieces falling in the new column. Some pieces also moves in different directions so you'd better check everything every frame. And of course special pieces or spells can be applied anywhere at any time. In fact it is closer to a real time strategy game than a puzzle game, even if visually everything only occur in squared tiles.



@Qube,

I'm not sure the calculated fps is usefull. On my PC it shows a constant 60, even if obviously the code stuck regulary when a lot of matches are done when you restart a new random board (watch the small gems moving). If on your PC the gem is always moving smoothly at constant speed then yes there is something odd with my rig (which run most VR games without issue ;))
Please send me your code update with the fps min/max.

Derron

Quote from: Pingus on February 08, 2019, 20:11:48
Things are a bit more complicated than just marking a cell as busy or complete. Some pieces are moving at different speed, and when a piece can not fall due to an obstacle, it does check if diagonal moves are possible which may interact with other pieces falling in the new column. Some pieces also moves in different directions so you'd better check everything every frame. [...]

What you describe is still doable in a way as I described above. Just think of the whole game not being rendered but just simulated. Simulation means you can always "predict" when eg. a falling block would reach a certain cell. You know when an element reaches something. You also know when it will reach a new cell which might eg. be the first next possibility for a match (depends on the blocks - see below).
Ok, let's assume you have a "special flying block". When can this block "match with others" ? To match it always needs to get assigned to a cell. If this is not possible (eg you have a flying toaster doing a chaos flight and destroying everything it hits) then this is a block which can get added to a "special list" which is handled every loop.
But ... if this object is only able to match with other blocks once it assigned to a cell ("reaches col2,row4") then you are back at the "mark cell dirty" approach which only checks dirty cells + neighbours until "no match" was found for all possible directions.

Next to "flying objects" you might have blocks which create "cluster bombs" on destroying. Of course these clusters do not need to get checked by all tiles on a board - the clusters know their grid position and can act accordingly (cluster stuff -> hit board cell,x,y -> inform block at x,y).


@ pieces move in different directions
So why? Piece 1 moves from x,y leftwards - ok, so you mark all changed cells dirty during the movement. After all "moving pieces" moved you have a list of dirty cells - you need to check them for "matches". After you checked all, clean the dirty state and move on to the next "step"/"turn"/loop.

If during such a "turn" no object was changing position enough (eg moves still on the same cell) and has no special effect ("pulsating wave of energy blowing away surroundings") then no cells will get marked dirty. Static blocks do not move at all, so their update routines are done blazing fast. After you handled all objects on the board you again check the dirty-list and if there is nothing dirty, then you do not need to do the "costly" collision/matching-check of the board.

So the most of the time you only update the dynamic objects (flying stuff, special blocks drilling holes to other rows, ...) and you handle all the "animations" (blocks wobbling, ...). Animation handling is of course the same as with other games, so the "board logic" is not coupled to it. In other words: performance problems with animations would then happen with other games too.


But ... regardless of above: if checking a simple 50x50 board for matches is already too slow, then it might either be the way you do the checks - or the language (scripted, compiled...). As said above you can easily get rid of many of these 2500 cell checks if you only check changed cells (and right at the begin you mark all "dirty" so the whole board gets checked). Qube might say something more on how the whole thing is coded - I mean if it is frame-rate-independend/render-decoupled and so on. FPS does not mean anything if it does not maintain a guaranteed logic rate ("updates per second"). Rendering a stuttering simulation will look "stuttering" even with 600fps.

The whole approach is similar to caching information. Eg. in BlitzMax you cannot simply access a "Count()" of a TMap. You need to iterate over all keys/values and sum them up - or you have a "count" variable which gets increased/decreased on adds/removes of items (its up to you to check if inserts are skipped because of duplicates). If someone decides to add items with a different then the "add()" function the whole "count cache" fails. In your board game this means that you needed to make sure to properly mark cells "dirty" and "clean".



bye
Ron

Steve Elliott

I'm with Derron and Qube on this, it's more an algorithm problem, rather than a language problem because of the reasons they've spelt out.

Maybe a match 3 game should be the next competition theme?
Win11 64Gb 12th Gen Intel i9 12900K 3.2Ghz Nvidia RTX 3070Ti 8Gb
Win11 16Gb 12th Gen Intel i5 12450H 2Ghz Nvidia RTX 2050 8Gb
Win11  Pro 8Gb Celeron Intel UHD Graphics 600
Win10/Linux Mint 16Gb 4th Gen Intel i5 4570 3.2GHz, Nvidia GeForce GTX 1050 2Gb
macOS 32Gb Apple M2Max
pi5 8Gb
Spectrum Next 2Mb

Derron

@ Pingus
BTW: why did you move from BlitzMax to AGK for the game? Platforms?
Did it run "trouble free" when it was done with BlitzMax?


@ match 3
"Match 3" could still allow creating a Leisure Suit Larry clone ;-)


Nice to see how we achieve derailing a thread :p. Maybe Janitor Qube cleans up later on (new thread for match 3 discussion). Would be interested in how others did it (assume some of you did Match 3 in the past - albeit Grey Alien does not write here).


bye
Ron

Xerra

Actually, a match 3 type game competition isn't a bad idea. It would give me the motivation to finally have a crack at it.
M2 Pro Mac mini - 16GB 512 SSD
ACER Nitro 5 15.6" Gaming Laptop - Intel® Core™ i7, RTX 3050, 1 TB SSD
Vic 20 - 3.5k 1mhz 6502

Latest game - https://xerra.itch.io/Gridrunner
Blog: http://xerra.co.uk
Itch.IO: https://xerra.itch.io/

Pingus

The thread did not derailed so much as we speak about AGK and its (possible) limits for some kind of apps.

@Derron, I did not move from blitzmax to AGK, I envisaged it, did the test I sent to Qube and concluded that it would not worth to go further if something so simple can not run fluently on a I7.
I did other tests which showed that with AGK there is a kind of treshold (depending on the CPU) where a given amount of loops quite suddenly drop a constant fps into a choppy fps.
With AGK the purpose was to reach new targets (mainly IOS and Android).  I'm aware that there are many frameworks and game engines that can achieve what I want, but I'm looking for the simpliest and/or closiest to bmax. If Monkey2 was reliable I would have go that route.
I don't know what you mean by 'trouble free'. There are of course a lot of trouble while develloping anything, but with blitzmax I do not have to care about parsing several hundred objects. From that point of view, yes, it is trouble free and with a huge margin for more stuff inside the loop. At a time the bottleneck is more about rendering the bitmaps than handling the code.

Derron

A bit barebone but BlitzMax NG tries to support iOS/android so ... if there is some will to test out these platforms Brucey (surely more or less) happily accepts issues/bug reports and suggestions to improve support there ;-)


@ trouble free
Yes, was talking about potential performance issues and so on - assuming your "board logic" was done the same in BMX and AGK (to be "comparable". You might even think of using Godot - pretty powerful for 2D and there are some basic tutorials for match3 games there (albeit they use this kind of "Flash games" approach which is not what we BMXers are used to).


bye
Ron