Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags

[Devlog] The First Flame

A topic by discoPiranha created Jan 26, 2020 Views: 419 Replies: 10
Viewing posts 1 to 6
Submitted(+1)

Hey! I’m discoPiranha, and this is my third time in MFGJ—so not my first, but hopefully my most successful! Past entries (with a team) included very first steps of a farming game set on the Moon, and a demo of a Galaga-style shooter with random enemies and a 9-stripe pride flag laser.

For Winter 2020 and the theme of Cold, I’m finally prototyping a game that I’ve been thinking about for a few years! The First Flame (working title) will follow a person/creature with the ability to create and manipulate fire who has to venture out from their village into the nearby forest for supplies, rescues, and eventually to understand where threatening creatures from the forest are coming from, and why the summer, overdue for generations, has not come back. (Short sentences aren’t my strong suit)

The central mechanic that has been stuck in my head is a special HUD to show the player two stats—hyperthermia (or overheating) and hypothermia. Hyperthermia appears as a fiery light that emanates from the player. When they use fire, it grows, and if it covers the entire screen they will fall unconscious from overheating. Hypothermia appears as a frost that encroaches from the edges of the screen, and grows with exposure to the cold. If it reaches the player, they’ll fall unconscious as their core temperature drops too low. The two will balance each other, so that the player can make fire to stave off the cold, and the player’s hyperthermia decreases as hypothermia increases when the player is away from heat sources.

So for these two weeks, my goals are:

  • Create that HUD! Make a player stand-in with hyper- and hypothermia stats, and tie these to a red circle that increases in size and a cut-out in a blue overlay that decreases in size.
  • Make a player! Pick some open game art, and make an animated player who can move, produce a flame from their fingertips, and fall unconscious if hyperthermia or hypothermia reach 100%
  • Keep up with a devlog, and participate in the community! I’ve never really done the participation part, except with my direct team and commenting on submitted games, and I feel like that’s only doing half the jam.

If at the end of two weeks, I’ve done those three things, I’ll be happy. I’m trying to keep my expectations meager, since I’ve also got full-time research to do. From those, though, I’ll have first steps on an idea that’s been in the icebox for years, and, I hope, some feedback on the ideas I’m bringing to it now!

Submitted(+1)

So here's some initial progress on the HUD!


I got the red circle working last night, after learning about the built-in _draw() function for Nodes in Godot, and the draw_circle() function. What turned out to be more complicated than I expected was the hypothermia overlay. 

What Godot is doing here is

  1. Draw the player sprite and the heat circle
  2. Encountering a BackBufferCopy node, and caching what's been drawn to the screen so far
  3. Drawing a rectangular pale blue transparent overlay across the whole screen
  4. Drawing a white circle over that, with a shader that sets the texture of the circle to... that cached picture of the screen!


It seems bizarre to me, but after a lot of searching it seems to be the best method I can find. If anyone has a suggestion, though, I'd love to hear it! Obviously the structure of the node tree and the way the code is written is going to change, but I'm sticking the screenshot above in just in case someone else is using Godot and looks for a way to make a hole in a texture. I'd like to write this up into a more detailed example in the future, since it would've saved me a couple hours to have a detailed example of how to use the BackBufferCopy and shaders like this!

Host

hmm i'm not totally sure i'm grasping the problem in the last post so i'll have to defer (you could possibly ask someone on the discord?) but i am a little curious if there's a reason hypo + hyperthermia are two different bars. it sounds like they are directly affected by each other--have you considered merging these two bars into one overall temperature bar?

Submitted(+1)

Thanks for the reply! What follows is a kind of general reply, for anyone who reads the first two posts and has a similar thought:

So for clarity on the stats, they are definitely intertwined, and the more I think about it they probably are enough so to be one variable. Part of why I'm doing this is to see what works and what doesn't about the idea, so I'm glad you said something! Moving forward, I'll start with a single "temperature" variable, and see where that leads. I think a good next step, before I write a single additional line of code, will be diagramming the system. I have a bad habit of diving into code...

As for the overlay, the issue was that while it's easy in Godot to draw a translucent rectangular overlay across the screen, it isn't as trivial to make a transparent circular cutout within the rectangle as I thought it would be. My solution is one that I found suggested on a forum (note to self, edit a link in here next time I'm on my computer), which is to esentially screen cap the game before the overlay, draw the overlay, and then to project the screencap onto a white circle using a shader. What I want to write up is how I did that, because nobody who's used it explicitly lays out the solution steps in one place! The steps I used fall into a class of things I would call "minimally documented."

I'm a little concerned the process of shading like that will be resource intensive, since it runs a function on every pixel in the circle. For now, I don't know enough to test the resource usage, but if I run into lag problems in the future, this will be the first thing I try disabling. At the same time, it's going to be a low-res 2D game, so running in an engine that can handle 3D shading makes me think it won't be an issue.

I hope any of that was actually illuminating! (Please let me know if it wasn't--Part of why I'm doing this is to devlog for the first time, and I def need to work on my communication skills)

Host(+1)

oh interesting that explanation makes a lot of sense! i'm not familiar enough with godot to offer any perfect alternatives, but if i were to approach the problem in an engine i'm familiar with  personally i would create a mask for the overlay. you could do this with a texture for more of a unique effect, but if you just need a circle you could use a "distance from point" function to create a gradient and remap it to adjust the softness of the edges. it's probably a bit complicated to explain without me being familiar w godot's shader functions...

Host

that said though i'm glad you could find an alternative despite not finding a single one online--it's awesome that you're considering documenting it too! you never know who might need it in the future.

Submitted (1 edit)

Mid-Jam Log:

I put a build up on Itch, motivated by the mid-week playtest suggestion! https://discopiranha.itch.io/the-first-flame I went ahead and submitted this to the jam, too, to be sure I have something in no matter how the week goes. The page is finicky about whether it loads the game or not. If you get a black screen, try refreshing the page once before giving up!

Godot is weird about exporting to HTML, and I can't tell whether issues are caused by Godot or Itch. The current build works fine in Godot and in Windows, but the overlay is all screwed up in HTML! And of course there are bugs-galore in my current build! Still, it shows some progress, and it technically meets all of my minimum viable product requirements!

I laid out some goals on that page, but here's roughly what I still want to do this week:

  • Write up an explanation of the BackBufferCopy system in Godot
  • Fix the existing bugs!
  • Implement a system where the player's fire affects snow on the ground
  • Create an explorable space
  • Give the player a quest to find a shrine buried in snow
  • Implement a consequence, in the form of falling unconscious and starting at the beginning, if body temperature reaches extremes.
Submitted(+1)

Cool Demo! I have some feedback for you after some play testing.

  • The resolution was a bit too small on my 1080p monitor, could be perfect for a mobile screen though
  • The temperature text in the bottom left matched the color of the ground so I almost did not see it there
  • Same with the red circle closing around the player, I didn't notice it till later on
  • Other than that the artwork and game mechanics were awesome! It is clear where you focused your efforts for this project. I could never get a good snow tile for my project no matter how many times I tried haha.

Looking forward to see your progress after this week!

Submitted

Thank you for the feedback! I didn't reply sooner, but I did take your feedback into account as I worked. 

Sadly, though, none of the art is mine! All my time has gone into finding out I don't know much about Godot, haha. I credit the artists, whose work is openly available, on the game page, though, if you want to check out their tiles!

Submitted

Final submission up! https://itch.io/jam/my-first-game-jam-winter-2020/rate/561687

I want to write a post-mortem when I have time this week, covering a few hang-ups, resources that were essential, and things that I learned.

Submitted

Final post / Post-mortem:

Short version: This was my third MFGJ, and it continues to be a good time! My main goals for this jam were to prototype an idea that I've had bouncing around for a while, and to actually interact with the community through writing devlogs and checking the Discord actively. In those three goals, I feel it was a pretty successful two weeks! Something always comes up, of course, but I think I did a pretty good job paring down my scope and expectations. I would've liked to write more devlogs. 

Long version, a.k.a. things I wanted to devlog: 

Outline:

  1. Backbuffercopy + shaders
  2. Fixing the screen UI
  3. Animations!
  4. Tilemap funkiness
  5. YSorts

1. Backbuffercopy + shaders

This was my first big breakthrough. The first thing I figured out when making my hot-cold overlay is that it's super easy to draw a circle and a rectangle in Godot from code, and not nearly as easy to draw a rectangle with a circle cut out of it! The structure of my UI, finally, is 

UI -> A canvaslayer node, so that it isn't affected by the viewport moving
    TemperatureOverlay -> a Control node, with a script to feed info to the overlay elements
        Heat -> A Node2D
        BackBufferCopy -> a backbuffercopy node
        Cold -> A Node2D
        Not Cold -> A Node2D
            "Not Cold" has a ShaderMaterial, with the Shader code
                shader_type canvas_item;
                void fragment(){COLOR = texture(SCREEN_TEXTURE, SCREEN_UV)}

The funny thing about all this is that I'm not positive that each element is necessary for it to work. The BackBufferCopy node, by virtue of existing in the tree, saves a buffered image of the screen when it would be drawn, so it captures all the player action going on under the UI and the red circle that shows Heat. Cold draws a blue rectangle that's a bit bigger than the screen and covers everything. Then, "Not Cold" draws a circle that gets smaller than the screen as the player's body temperature drops below neutral. It's a plain, white circle, which has the buffer from the backbuffercopy reflected onto every pixel by the shader. I think! Shaders are super weird, and I'm still learning a lot. 

2. Fixing the screen UI

I spend a lot of time screwing around with that UI above to get it to follow the player correctly. In the final iteration, these three things seem to be essential: 

  1. The root node of the UI is offset to the center of the screen
  2. The TemperatureOverlay node has its anchor and margin values set following the "Center" instructions from https://docs.godotengine.org/en/3.2/tutorials/gui/size_and_anchors.html
  3. The BackBufferCopy, and this took me forever to notice!, is set so that Copy Mode is "Viewport", and the Rect is 0,0 to 480,320, the size of the game

3. Animations!

This is just a fun little note. If you play and use the fire swirl, you may notice that it appears to pass behind the player, in super fancy faux-3D fashion! What I did to accomplish this, and I'm proud of just how ridiculous it is, is that the player has two sprites, one on either side of the flame in the node tree. The first Sprite is fully animated by the AnimationPlayer and is active all the time. The second one becomes visible only during the fire swirl, and is just the top of the player animation that plays during the swirl attack but in a position to be drawn above the fire. So silly, but it works! 

4. Tilemap funkiness

There are four TileMap nodes in the game. There's one that has all the ground, one  that has all the snow, and is checked against when the player uses FireSwirl (And tiles are set to -1 to disappear), One to draw all the border trees, and one to draw just the tops of the trees, so that the player passes in front of the trunks and behind the tops. All my tilemaps come from sprite atlases, and I cannot for the life of me understand how the whole process works. Future goals are to know a single, solitary thing about how TileMaps really work. 

5. YSorts

This was a real treat to figure out at the end! Between the TreeTrunks TileMap and the Treetops TileMap, there is what's called a YSort node. Nested in the YSort are another YSort that creates and holds all the bats, the Player, a YSort holding all the trees you can walk around, and a YSort containing all the signs and shrines. While that's all a lot to take in in a single sentence, what it means in the node tree is that Z-Sorting (Figuring out what to draw in front of what) happens automatically for every child of a YSort or child of a nested YSort. This is super cool, to me, and I'm happy it's baked in to Godot 3+ 

If you've read this far, leave me a message if anything didn't make sense, and I hope you found something here useful! I may come back later and add images, which would probably be a lot more useful than descriptions.