Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags
A jam submission

Visions of EtherealView game page

Game about see hidden fairys
Submitted by Lukan Peixe (@lukanpeixe), RobertScheibe — 5 minutes, 7 seconds before the deadline
Add to collection

Play game

Visions of Ethereal's itch.io page

Results

CriteriaRankScore*Raw Score
Graphics#333.5243.524
Audio#333.1903.190
Overall#373.3523.352
Fun & Game Design#393.3333.333
Originality & Innovation#513.3333.333
Theme#573.3813.381

Ranked from 21 ratings. Score is adjusted from raw score by the median number of ratings per game in the jam.

Leave a comment

Log in with itch.io to leave a comment.

Comments

Viewing comments 22 to 3 of 22 · Next page · Last page
Submitted(+1)

Quite nice platformer with ingenious on/off mechanics.
Do continue on this game, it has much potential <3

Submitted

fun game with  amazing ideas i  left it a rating 

pleas check out and rate my game  before the deadline 

Submitted

amazing man 

made sure to give a rating!

can you check out my game to?

Submitted(+1)

Sweet metal soundtrack, nice! The movement and combat feels really sharp and good, I liked controlling the character. And her ability to see into another dimension is a unique take on the theme, beautiful! I also love her sound when jumping, haha! Thanks for sharing your work.

And if you haven't had a chance to check out my game Foxy Boom Boxy, I would appreciate any feedback, thanks!

Submitted (1 edit) (+1)

I like so much about this. The music is AWESOME!!! The movement / combat has some depth to it. I appreciate that it's not possible to go ethereal while standing in ethereal spikes.

It did perform quite poorly. I tried playing this on several browsers (firefox, chrome, edge) and it didn't seem to make a difference on performance. One thing I noticed is that the vertical shaft level with the floating skull didn't lag at all, and that had no spikes in it. Are you checking for collisions with every spike, every frame?

However, the big problem isn't the performance, it's that a large number of things seem to be arbitrarily tied to performance. It seems like I jump lower when the framerate dips. Flames sometimes wouldn't light lanterns when the framerate was low. When the framerate is good, my flames have very little range, and when it's bad, they have an extreme range. It's like TimeDelta() is being for certain things but not for others. Performance was so bad, I couldn't get past this level:


It's a real shame; this is a very competent and polished game otherwise. Great work! I hope you can sort that out!

Developer(+1)

Thank you so much for taking the time to write this wonderful feedback!

Music is my specialty, so I'm glad that in this part I was able to surprise so positively. This is the first game I program, before that just a more complex prototype that still doesn't have stage 1 complete haha

Commenting on the project in a livestream, people in the chat who know a little more about programming than I do, commented about timeDelta. In this project, NOTHING is being checked by timeDelta (although I am using some timers), for me it was just another way to solve things, but after studying a little, I realized that implementing things by timeDelta is fundamental in many cases .

The collision is being checked every frame, but only with the closest enemy for contact with the player, and only the group of nearby enemies for contact with the blade (while it exists). My gut says skimping on collision per frame is wrong, but maybe my instinct is wrong.

Even with these points, this almost supernatural variation in performance is something very strange. One day, the game was normal at 10 am, already at 4 pm it started to slow down to the point where I couldn't even get past stage 1 (note: same hardware, same session), and after that, it never returned to performance from before. There's something very strange going on. I even created a topic here on JAM, and on the Gdevelop forums, about this subject.

As much as I correct everything with deltaTime, I still find this abrupt variation in performance on the same hardware very bizarre, and that, in a way, made me insecure eith Gdev.

I will continue to update the project, my intention is to make it a salable game! Thanks again.

Submitted (2 edits) (+1)
  • "In this project, NOTHING is being checked by timeDelta (although I am using some timers)"

Oh! I didn't even think of timers! I don't use them in my projects. Those use TimeDelta().

Here, I made a quick test project to demonstrate. It's simple: there's an object with a timer, a scene variable that goes up by one every frame, and some text. The text displays:

  • The amount of frames.
  • The theoretical time if we derived it using Frames/60.
  • The value of the object's timer.

The first time I run this program, I run it using the property "Max FPS: 60." The second time, I run it using the property "Max FPS: 30."

(The values have been rounded down to 2 places to avoid flashing lights)

60 FPS30 FPS

While our theoretical Frame-based time is slowing down in the 30 fps version, the Object Timer is keeping up. QED: Timers are Time-based and not Frame-based.

One thing GDevelop is bad at (which, TBF, I've NEVER seen an engine do this well) is clearly distinguishing what is a Time-based system and what is a Frame-based system. For example, I had to figure out through trial-and-error that the animation system is Time-based and not Frame-based (though, this can be remediated by manipulating TimeScale, which essentially is just an artificial modification of TimeDelta()).

  • "The collision is being checked every frame, but only with the closest enemy for contact with the player, and only the group of nearby enemies for contact with the blade (while it exists). My gut says skimping on collision per frame is wrong, but maybe my instinct is wrong."

Sorry!! I didn't mean to imply that you had to cut frames!! I said "every spike, every frame" as an emphasis. Every frame is good!

It's hard for me to give advice in this area, since optimization is extremely personal to each individual project, and I don't know how the code is structured. I'm not sure if you've run the debugger's profiler yet, but that's a very useful tool for determining where the biggest loads are (as long as the code is organized using event groups).

My gut instinct is that the enemies shouldn't be causing problems, since there aren't that many of them; the spikes caught my interest because there's many of them, and the levels I had the most trouble with had a lot of them.

Whenever I'm working with something like this, I usually decide what the largest distance the player could be from a colliding object, add a bit to that, then compare the position of the object within that margin. For example, if I decide that the player will never be farther than 32 pixels and in collision with a spike (my projects are very low-res) my conditions will look like this:

[EDIT: The image is not loading, here's a text transcription:]

  • The X position of Spike >= Player.X() – 32
  • The X position of Spike <= Player.X() + 32
  • The Y position of Spike >= Player.Y() – 32
  • The Y position of Spike <= Player.Y() + 32
  • Player is in collision with Spike

Essentially, I'm seeing if "Spike" falls within a 64x64 box around the player before checking for collisions. This box might need to be smaller or larger depending on the specifics. It might initially look complicated and heavy, but the operation to compare these values is very quick, much quicker than an object collision, and as it goes down these conditions, it's comparing less and less spikes as they're removed from the object picking list.

Apologies for this monster of a reply! Thank you for your time!

Developer(+1)

Your answers are great, I'm grateful for them no matter how long they are.

Your test on the timers clarified the situation, I'm actually using them for things like jumping (doing interpolations between different gravities) and as an optimization feature (checking a condition every 0.2 seconds, for example).

This already alerts me to another project where musical synchronization is important, I need to create my own timers fed by the framerate to correct possible desynchronizations. I was entrusting this function to the standard timers.

About Debug mode, I still need to take a better look at it, for now, I use them only to read logs (to correct the flow of actions). It was a good reminder.

My strategy for the spikes was to select the closest one (this one I had to deactivate the prices, because it was generating bugs) and turn them into tiles (they were animated sprites).

Does the function of selecting objects by the condition "the distance between objects is less than" does it have a big impact on performance compared to your selection box? Anyway, your strategy looks good and I'll try to apply it. I'm wondering, better optimization than this, maybe just sectorize objects on the screen one step before checking the imaginary box. For example, creating 4 variations of the spike object, each being added to a specific corner of the screen. So once in a while check if "The X position of Spike >= Player.X() – 32" of all the spikes, check only those that are in a specific corner (quarter of screen), according to the position of the player. But maybe it's too much work for little performance gain.

We're having a great conversation here, but it's okay if you can't continue it :)

(I wish I could contribute some useful knowledge for you too, but I don't have the knowledge for that, sorry haha)

Submitted(+1)

I'd like to clarify that, although my programming is very frame-based, I do use TimeDelta() to mitigate the effects of lag (I don't have time to explain how I do that right now) and I think that it can be a very effective way to program games. I do not have a personal vendetta against the Timer system, though I do wish it's Frame-independent nature was more clearly explained.

Your use of timers sounds consistent with how features behaved at lower framerates: the gravity felt faster than the jump.

  • "This already alerts me to another project where musical synchronization is important, I need to create my own timers fed by the framerate to correct possible desynchronizations. I was entrusting this function to the standard timers."

This isn't hard advice, as I've never done music synchronization, and, from what I hear, it is very difficult! But I probably would use TimeDelta() instead of framerate for synchronizing something to music, which plays according to Time and not Frames. I'm not sure if I would use the in-built Timer system (which I am very unfamiliar with), but I would use TimeDelta() in conjunction with variables for timing.

  • "My strategy for the spikes was to select the closest one (this one I had to deactivate the prices, because it was generating bugs) and turn them into tiles (they were animated sprites)."

Could you clarify what "deactivate the prices" refers to?

Otherwise, that sounds reasonable. While "closest" isn't the most performant (as I'll talk about later), it shouldn't be particularly heavy. It also seems like tiles have better performance.

The sectorization is an interesting hypothesis. I don't think it would be necessary for a project like this, and it might create some weird edge cases (what if player is in quadrant Top-Left and needs to collide with a Spike on the edge of quadrant Top-Right?). Additionally, trying to program for four different kinds of spikes sounds a bit stressful. However, keeping in mind the use of unique objects to reduce load is important.

  • "Does the function of selecting objects by the condition "the distance between objects is less than" does it have a big impact on performance compared to your selection box?"

Yes.

I want to preface that I don't have intimate knowledge of how these conditions work; I mostly just do testing within the engine to come to my conclusions.

"[Object A] distance to [Object B] is below X pixels" is a very good condition. It uses a distance calculation (which probably involves square roots) between the Origin of the first and second objects. Basically, it's an "imaginary circle". It's especially useful for "area of effect" type processes. However, while this calculation is very useful for logic reasons, it is not performant.

Since I wasn't entirely sure about this, I decided to make a test project.

There's one player and some spikes. The player can be moved with WASD. Inside the frame, I have 67 spikes organized semi-randomly, with a grid of Spikes close to where the player starts. Then, at the beginning of the scene, I make 50,000 spikes at -128;-128, to increase the load.


There are four different methods for picking and checking for collisions between Player and Spike. (-1): No Cull. (0): Box Method. (1): Nearest To. (2): Distance Below. I can switch between them by modifying "Mode" by pressing the 0-3 keys. Here's what the code looks like (minus a couple of group headers for readability):


(Note: The profiler is not an exact sort of thing, especially since it's measured in time it takes for my computer to process it, which is different across every machine. There's also a lot of fluctuation in the time it takes to do stuff. I've mitigated this a bit by creating 50,000 spikes to exaggerate the differences in the methods.)

So, using the four methods and 50,067 spikes, I measured using the profiler for 600 frames each.


No Cull
10.96 ms
Box Method
1.83 ms
Nearest To
5.45 ms
Distance Below
10.35 ms

(Note: I only included the time it took to process these specific events. I didn't include the massive amounts of time it took the game to process and render the objects. The actual full process time came out to about 50-70 ms to run one frame. 50,000 objects is a tad too many!)

I was very surprised that "Distance Below" is almost identical to not culling at all. I speculate that the collision algorithm already uses a similar distance calculation to "Distance Below". Again, "Distance Below" is a good logical check, but it does not improve performance.

"Nearest To" is a very useful condition. and it seems to perform quite nicely. For example, I used "Nearest To" when deciding which Lightbulb in "Logic Bulb Adventure" should be interactable, since there should be only one of those at any time. It's a distance calculation, so it's essentially "imaginary lines", where the object picked has the shortest line.

But, it can be problematic for collisions with multiple objects in close proximity. Also, if the positions being compared aren't in the "correct" place, it can produce edge cases. In the test project, the origin of the Spike and Player are both at 0;0 (Top-left), which produces situations where the player is clearly overlapping with a spike, but the "Nearest" spike is not that one.

Of course, this could all be irrelevant to the performance in Visions of Ethereal; it might be something completely unrelated! You'll have to run your own tests to find out where the heaviest loads in the code are.

Developer (1 edit) (+1)

Lots of light being brought to the conversation with these tests.

I understand that timer, DeltaTime() and frame count must have their moments to shine. Depends on the context.

Talking about the game with music sync, I'll still try, it won't be a very high rhythmic precision game. At the moment the thing is well connected to the timers (with BPM calculation and other details), so either with frame count or TimeDelta(), in order not to have to do a big rework, I'm going to use them as a second layer of confirmation of the events. It's something I'll think about later.

"Could you clarify what "deactivate the prices" refers to?"

Haha I'm sorry! Small mistake I missed after my review with the translation tool. The correct sentence will be

"My strategy for the spikes was to select the closest one (this one I had to deactivate in a hurry [near the end of the jam], because it was generating bugs) and turn them into tiles (they were animated sprites)."

And now, about: "I was very surprised that "Distance Below" is almost identical to not culling at all. I speculate that the collision algorithm already uses a similar distance calculation to "Distance Below""

I was as surprised as you are, and I believe in the same hypothesis you raised. Anyway, this test project was awesome, and now I'll be a follower of box method supremacy! haha

In the end, each strategy works well in specific cases.

Now, after doing some testing on the project...

First, I decided to do the jump smoothing using frame count instead of timers. The result started to look nice, but I still had problems with timing, when reviewing I remembered that the jump sustain time is measured in seconds (i.e., in fact, the platformer behavior has at least one timer running with it, solve turn it off and do a manual air control by frames).

However, I was a bit apprehensive, I started to print the frame count on the screen with the jump button pressed and to reach 60, it was taking more than a second.

I improved some events using the debugger tool (very nice tool!) but nothing particularly heavy, rendering and pre-events were still the biggest performance drains, but again, nothing serious.

  So I decided to print other information, including FPS (using the extension), FPS which is constantly at 37 frames, and that's when things start to get even weirder...

Not understanding what could be draining so much performance, I did something extreme, turned off all events and deleted almost all objects from the scene, leaving only the character and the ground, the result:


As if everything wasn't confusing enough, I changed the FPS cap from 60 to 0 (unlimited) and at that point, my game went to 69~76 FPS in a regular scene.



I went back to 60fps, went to a blank scene, just copied the value printing events, and the result?

* "Scene Real Time" is the scene time counter.

** "Scene Frame Time" is a count of every frame/60.

I'm going to take a break from testing now and I'll come back to it later, but I don't know if there's anything else to be done. As soon as I had the first case of slowness a few days ago, I cleaned all Windows background processes leaving only the OS excencials and it didn't solve it. Detail, other games run here normally, even some 3D ones that require more GPU.

The mystery continues...

Thanks for another great reply :)

Submitted(+1)

.....

What is your monitor's refresh rate?

For reference: Web browsers use V-Sync by default. Electron, the JavaScript interpreter that GDevelop uses to make desktop builds (and, by extension, previews), uses V-Sync by default, because it is built on the same principles as a web browser. Basically, GDevelop games have V-Sync by default and necessity. I have my own opinions on this fact, but it is was it is.

This is also why it's hard to use FPS to determine performance.

Developer(+1)

I have 3 monitors, two are 1080p 60hz and the biggest one is 1440p 75hz.

Come had a report, this performance issue for me started suddenly in the same Windows session and never came back.

I've tried changing some properties like minimum FPS, rendering type/filter for the pixels and other minor things, and nothing delivers the expected FPS.

Submitted(+1)

Just to be clear, is it running at the same speed on the 60hz monitor as on the 75hz monitor?

Developer (2 edits) (+1)

Yes, the game runs at the same resolution regardless of where I place the window or start running the application, however, I decided to go deeper with your new message, and I disabled all the videos and ran the game again. Result: both 60hz monitors ran the application at 60 frames, the 75hz monitor ran at 37.5 frames.

I forced monitor 75 to 60, and again, framerate was stable. In the same case, I let the game run at unlimited maximum frame rate, but again, stable at 60fps. In that case is it the counter that doesn't work or the game really doesn't pass 60fps?

EDIT: Additionally, with the 3 monitors active, game in 60fps max, I left monitor 1 at 50hz (1080p, not the main one, just port 1). I ran the game from monitor 2 (1440p, 60hz, main) and the game ran at 50fps. In this case another monitor influenced the total frame count.

This story becomes more intriguing though, at least my case of lag was "resolved". Perhaps a background update from Nvidia was what started the problem over here? (even at 75hz the game ran normally before)

This also doesn't solve your lag case and other people's, but I certainly already have a point to keep an eye on and question about.

I wasn't prepared to think so far out of the box, maybe the next step would be to use a multimeter to measure the alternating current of the residential electrical network? haha

Submitted(+1)

Awesome game. Nice graphics, precise controls and just overall well polished. And having played a lot of platformers recently, it's cool that thematically this one is different and you get to play as a ghost :)

(+1)

game lindo, música e arte impecáveis 10/10

(+1)

jogo muito bom, música maravilhosa lukan vc e brabo

Submitted(+1)

The music is wonderful, as is the whole game.

Submitted(+1)

Great art, great music, very funny!

Submitted(+1)

Wow, this is a really nice looking game, and the music is absoulutelly fitting… Btw I like how you can’t use your power for instant death

(+1)

Nice game,  Nice dificult , Nice textures , Nice music ,  everything is nice congratulations Lukan peixe

(+2)

Good game, hard enough, but some of the "hard" part comes from the movement, which is not fluid enough, so yeah, everything is good but the movement

Submitted(+2)

Great work, a bit difficult but beautiful.

Submitted(+2)

Man this game is hard, but I do love the aesthetics so much. I really like the Castlevania vibe, and the pixel art is really well made, though I did miss a coyote timer for the platforming. Also I couldn't get the D-pad to work with my gamepad, but keyboard controls worked just fine

Developer(+1)

Thanks for the coyote timer tip, I wanted to skip the moves more but didn't know where to start.

Can you tell me what is your game-pad? Having the D-pad not working was something I thought I wouldn't have a problem with.

Thanks for the review :)

Submitted (1 edit) (+2)

I used a Speedlink Torid wireless gamepad, but it uses the same drivers as an xbox 360 controller. I could try it out with an Xbox One controller if you would like?

Submitted(+2)

Xbox One controller works 👌

Developer(+1)

Thanks a lot for aditional test, over here I was using the Logitech F310. I think a bug of this type goes beyond what we can do, it's an internal Gdevelop thing.

Submitted(+2)

Very interesting concept! With an exception to collisions, the game is very solid!

Submitted(+2)

Great usage of theme! The concept and gameplay of the game was neat.

Submitted(+2)

I really like the concept and it was fun to play. I quit around the level with 4 skulls since it was a bit challenging. I think the controls are a bit too sensitive and the character hitbox is a bit off. With a bit more polish, it's definitely a game that I would play and enjoy

Developer(+1)

The stage with 4 chairs ended up going with an error, it wasn't supposed to have spikes in the part just below the platforms haha

Thanks for the feedback, this will be a project I'll take forward!

Submitted(+2)

I don't like the music, it sounds like the further I got in, more instances of the music plays.

The character might also need to have a separate hitbox, the floating effect of the player character makes the jump height inconsistent. 

Developer(+2)

About the music, are you referring to the question of "musical taste" or was the music really playing in superimposition? It's actually two  similar songs that change as you use Ethereal Vision, here it's no problem, but a bug in these elements would really make the song a mess.

The character's Hitbox is already separate, it's not the character's sprite that is taken into account for jumps.

Submitted

It's 100% the latter

Submitted(+2)

This is a very beautiful platformer with a great mechanic. Would love to play a full-length version of this, with slightly tighter controls and maybe a story. Again, really great graphics and sounds!

Developer(+1)

Thanks for the feedback, a full version with more levels and many more improvements are on the plan. Any other suggestions are very welcome.

Viewing comments 22 to 3 of 22 · Next page · Last page