New to Fuse4-want a Faery Tale Adventure like game
-
Looking good, Tim!
-
Yeah, it totally is!
-
Good luck! This was one of the first games I played on my own computer, so it has a special place in my heart. Don't forget to include the secret of mysterious Pixle Grove! (Going by the ingame spelling)
You should probably spend some time on removing code duplication, though. I haven't looked too closely, only had a quick scroll through (the version from two days ago or so), but are you handling each item in the world in its own bit of code? If you continue that, you'll go mad. The code editor is slowing down already, that's only going to get worse as the file grows. Code cleanup isn't sexy and it's tempting to put it off for later, but in my experience (outside of FUZE), it's best do do it as early as possible.
-
@Z-Mann thank you for the insight. I’m not a programmer so I tend to do things as I think of them. It has definitely been driving me crazy but I’m drawn to it.
I was figuring out how to deal with all of the landscaping (plants, etc) hoping I could make them into sprites and randomly lay down a few million of them but that caused memory array issues. But the worst was the more I add, it seams like the NOTE FREQ music seems to slow down. I then thought of making plants into Images but all that happens is that they float on the main 1920x1080 window as the character walks. So it looks like I’m going to have to use the map editor and just click all over the grass. I did that and got the character and enemies to slow down at random speed differences so that worked. But the larger this program gets it makes me wonder about the effort in the landscaping and being worth it. Yes grass and villages and mountains and castles are ok but it’s already over 10k of code lines to scroll through. The enemies don’t really fight yet but they do swarm around and get near the main character. I can kill them by running back and forth into each one 5 times when they drop a random item for me to pick up.
I also had problems getting arrays to transfer with functions too so I went back to how it is now.I just shared the latest copy:
FTA
ID: Z7573MND51 -
I haven't used images myself yet and the documentation is not super clear, but could it be that the coordinates you give to drawImage are just screen coordinates? With sprites and maps, any coordinates you give them are modified by the sprite camera postion. So when you want to draw images in specific world positions, you may need to place them at {x - centerPoint.x, y-centerPoint.y}. That's what I would try, anyway. But: stick to sprites and maps. The huge advantage of sprites is that Fuze takes care of not wasting time on offscreen sprites for you. Slowdown only crops in between 5000 and 10000 sprites. I'd be surprised if the map system would perform worse.
To make the map less tedious to fill, you could define your own huge grass image (like four screens big) and use that as background over and over. That would only need repeating... 4250 times. Err. You'll need to either shrink the map or divide the world between several maps, it seems.Speaking of the sprite camera postion: You should do drawMap() after setSpriteCamera(). The way you do it now, the old sprite camera position is still used for the map, so the map scrolling is one frame behind the sprite scolling. The visible effect is that as you change walking direction, the sprites seem to wobble back and forth on the ground.
A little push in the right direction against code duplication: Around line 1730, you're distributing the items randomly. You can simplify that:
function RandomizePositions(ref sprites) positions = [] for i = 0 to len(sprites) loop rx = rnd(range1)-range2 ry = rnd(range1)-range2 positions[i] = {rx, ry} setSpriteLocation(sprites[i], rx, ry) setSpriteVisibility(sprites[i], true) repeat return positions
Key caveats are that while you can modify array elements of an array you pass in via 'ref', you can't currently extend the array. So the options to fill the positions array are to either pre-allocate it to its correct length before passing it into the randomize function by reference, or just having the randomize function return it. Returning it is easier.
Then you can position your white keys withp2white = RandomizePositions(keywhite)
and the other items accordingly. Extra randomization, like the bag contents, still need extra care, obviously.
-
@Z-Mann and others,
I was able to clean up alot of my code in sprite duplicate areas for 10k lines down to 7k without even looking at the enemy coding yet so that’s a huge improvement!
However I’m still seeing the Game and music playing slower for some time now. When Map1 is loaded the FPS drops from 60 to less than 30.
Since the original Faery Tale Adventure game had 17k screens that were 256x256 which equates to 1.1 billion screens. (It’s hard to believe over a billion screens were created by hand with 16x16 tiles)
Map1 which only covers a small portion of the original game (Tambry, graveyard, marheim, teleportation, walking, etc) is ~ 86,000 x 44,000 which is 1,824 (1920 x 1080) screens. If the original games 1.1 billion (256x256) screens were divided into (1920x1080) screens that would be 57,456 screen so currently my too large 1824 (1920x1080) screens would need to be 31.5 times more maps.
As it appears my configuration would need much smaller and higher quantities of maps to keep the frames per second up towards 60, I believe will need to scrap my Map1 and try to figure out what screen size would keep my FPS high.
If I load a blank map (map graphics are gone but game operates normally with sprites present running normal. It’s showing with Map-Blank loaded 1686 MB at 60 FPS. However with Map1 (map graphics are all there, ie houses, grass, teleported) but has 30 FPS and 1431 MB size playing slowly.
Thoughts on this?
Thank you - Tim
-
To make the music play at constant speed no matter the FPS, you need to incorporate the measured frame rate into account somehow. The length in second of the previous frame is returned by deltaTime(). Care needs to be taken: it will not be exactly 1/60 if you hit 60 fps and 1/30 if you drop to 30 fps. Even in the best case, it is going to fluctuate a little around 1/60. The playback code should cope with that.
What I tried, and it worked, is to modify the playMelody function near the bottom. Before it, I declare a global variable:
melodyRemainder = 0.0
And in the body, I replace
melodyTimer += melodyTempo
with this:
melodyRemainder += deltaTime() * 60 // take into account actually passed time melodySteps = floor(melodyRemainder) // take only integer part if melodySteps < 1 then melodySteps = 1 endIf // advance at least one step melodyRemainder -= melodySteps // keep balance for next frame melodyTimer += melodyTempo * melodySteps
If you hit 60 FPS, even if deltaTime fluctuates, melodySteps will be 1 almost all of the time, so no change. And if you hit 30 FSP, deltaTime() will be about 2, so will melodySteps.
Or, if you prefer it to be simpler, you can omit the melodyRemainder variable and just do
melodyTimer += melodyTempo * deltaTime() * 60
This might even be better, depending on how sound and video output interact timing wise. Go with the simpler version first and switch to the more complicated one only if the simple version doesn't work for you.
Regarding the map: Make sure it is really the map rendering. Just because you jump from 30 to 60 FPS if you disable it says nothing; maybe the map rendering takes 1 ms and the rest of your main loop takes 16 ms, just fast enough to allow 60 FPS, and the map rendering just pushes you over the edge. You can test that by not removing the map rendering, but replacing it with
sleep(0.008) // 8 ms of sleep
If you still get 60 FPS with that, you know the map rendering takes more than about 8 ms and yeah, you'll need to do something about that.
But if you drop to 30 FPS, you know the rest of your main loop takes more than about 8 ms and that's where you're more likely to find improvement opportunities.
You can play with the 0.008 parameter to get a better feel for where the problems lie.If it is indeed the map rendering, there would be one way to deal with it without splitting the map. Instead of rendering the map to the screen, you render a section of the map, say of size 3x3 screens, into an image. That image is then what you render to the screen. Since it is larger than the screen, you can scroll around in it quite a bit before you hit the edge; until you do so, you do not have to refresh it from the map. Of course, every time you do have to refresh the image, there will be a short, but noticeable, pause. And any chance to maybe put sprites behind map objects is lost. I'd just split the map up, I think.
(Well, no. I would try to implement the metatile system, fail miserably and give up.) -
@Z-Mann thank you for your analysis!
I tried the simple fix (1 line approach) and the note freq music played normally at 60 FPS so that fixed that issue.
I inserted the sleep (0.008) statement and removed load / draw map statements and the FPS did stay at 60 FPS so that tells me it’s a draw map issue. Perhaps with the music sounding right again, the game appears to be ok at 30 FPS. Is it ok to have it at 30 FPS or should it always be close to 60 FPS?
I’m heading on vacation in the morning to Ohio for a few days so I won’t be able to work on this until Friday.
Thank you again!
-
If you do manage to hold 30 FPS to the end, it should be fine. It's a slow paced game. The original ran at 20 FPS at most, going by memory and feeling, and that was not an issue. Focus your attention to things that matter more.
-
Hi All! I haven’t left the site but experienced a job loss which turned into a transfer and promotion within my company. I have moved with my wife to Utah from Illinois and have been tied up with my new role and purchasing a house. I will continue with my FUZE4 FTA like game in February or March once we close on the house. (Tim)
-
Sounds busy! Good look with everything you're doing, and happy coding (once you got time for it again, that is)
-
Glad you haven’t left, Tim. Congrats on the promotion!