We’re at the end of the first official month of development of the current version of EverEnding. That’s a lot of qualifiers, but it’s still a milestone of sorts. Did it go well, you may ask? Did it go poorly? Kind of in-between!
Most of this month was focused on creating the intro sequence, but before I even started in on that I first wrapped up what I was working on at the end of last month, the crouching animation, even though it really doesn’t need to be done until I start on the first chapter of the game.
Once I have my teeth in a problem, I really don’t like to abandon it until I’ve solved it – a tendency which kind of backfired later on. However, having accomplished that, I started developing the different graphical elements of the intro area, making a dynamic and playable version of the first test screen which was previously just a placed static image. Here’s a comparison of what it looked like before and what it looks like now:
I started with the tree, which I’ve always liked the look of but which was cut off at the edges on this screen since I’d originally drawn it on a paper pad and ran out of space. I extended the top of the tree and added layered systems of branches, then drew several different leaf clumps which I spawn in-game using a particle system. It turns out most of these leaves aren’t actually visible from the main intro area, but I think I’ll probably pan the camera down to this area at the beginning, which will show off the leaves and branches nicely. There’s some aspects I still like better in the old version, such as the overall level of saturation and contrast on the tree and the gradient in the sky background, which I’ll probably try to bring back in as I develop these assets further.
I quickly drew the night sky background, which was mostly scribbling, and somewhat less quickly I constructed fill and edge textures for the dirt, and then built the terrain using Unity’s Spriteshape tool. I had been concerned about the quality of effect this tool would provide, but I honestly couldn’t be happier with how the ground segments turned out. A point of interest is that SpriteShape used carelessly can make the edges of the collision area misleading, so I tried to make it clear via shading what the actual collision edge of the ground surface was.
Previously the main ground area had been grassy, but I figured with the special grass particle effect I developed a short while back I might be better served by leaving it as dirt and then having the grass effect handle all the grass rendering. I may reconsider this at a later date – and the grass effect itself is surely still subject to change – but the dirt ground asset will be useful later regardless. I haven’t created any rocks to replace those in the initial version – they’re not vitally important, but I probably should, especially since I’m certain to need rock elements to place later anyway.
Probably the most time this month was spent wrestling with the rendering system. While the initial simple sprite look was appealing, I couldn’t and can’t stop thinking about how incredible it could look with some extra post-processing and shadowing effects. By copying a shader I didn’t understand well I could get these effects but only at the cost of clipping away the transparency at the edge of the sprites in a fairly hideous way, and one which will cause much more severe problems as I add more assets with transparency effects later on. I still haven’t figured out a perfect solution to this, and it’s a rabbit hole I could get in deep – after all, people build entire careers specializing in this sort of graphics programming – but I’ll probably keep pursuing it both because I think the results could be worth it and because I find this kind of work inherently interesting.
The crux of the issue is that in order to properly post-process an image with certain effects, you need to draw to the ‘depth texture’. In order to make objects draw one in front of another, you need to draw to the ‘depth/z buffer’, which it turns out is a completely different thing… And, in order to draw transparent objects, one would normally avoid drawing to either the depth texture or the z buffer, because it would overwrite information about objects behind the transparent object which you still want to draw because your object is transparent! In layman’s terms: In order to know what something should look like, the game needs to know how far away it is, but it can only know the distance of one thing at a time, so: If we’re holding a piece of semitransparent glass in front of an apple, how far away is the thing it should be drawing? Is it the distance from the glass to the camera, or is it the distance from the apple to the camera?
The only solution that seems viable to me is to set a transparency threshold: If it’s barely transparent at all, like a piece of stretched rubber, then it counts for depth, and if it’s very transparent indeed, like glass, then it doesn’t. However, just knowing this as an algorithm isn’t enough, because you still need to know how to explain to the graphics hardware what behavior you want – and that’s what I’ve been struggling with, because it has very particular ideas about what information you can feed it and how.
I’m not sure how well this problem is coming across in text, so hopefully next month I can just show you a picture of the working version to illustrate what I mean.
I also started getting sound and music implemented. Now, the intro’s sound and music needs are pretty minimal, basically just requiring one music track and one long sound effect to be played, but I started seriously considering what the music system would need to look like to handle future problems. Even in the very first playable area there’s some degree of adaptive music, and later areas have other types of dynamic music planned, from transitional segments to cross-fading alternate tracks and more as I think of them. Altogether, these represent a not-insignificant programming task – and, in Unity, requires some rather awkward queuing and loading of audio tracks. I decided that it was foolish to try to create a music system like this when there’s already incredibly powerful tools made for this specific purpose out there, so, after a quick assessment of its licensing options, I began integrating FMOD, an adaptive music system for games, into the project. This system is free for small-scale projects like this, and in addition to adaptive music provides great tools for mixing sound effects together and slight dynamic tweaking of sound parameters based on arbitrary values – so, for instance, one can not merely adapt music by creating alternate tracks, but also by bumping equalizer and filter parameters based on in-game actions. FMOD also provides an actual tool for visualizing these mixes and setting up musical transitions, which is great because manually plugging values into an XML script on my first attempt at this was a real drag.
Finally, I started considering how text was going to work. This seems like it should be a freebie – there’s some pretty standardized ways of handling text in games at this point – but, for this project, I want a sort of living storybook feel, with text appearing on the page as you encounter it. First, I needed to figure out how to just get text on the screen, which ended up being fairly easy since Unity includes TextMeshPro, a great solution for solving exactly this problem in 2d and 3d spaces. However, when text is on a background that could be any color, just black print doesn’t really cut it, so I spent quite a while looking through different fonts and rendering styles until I found a couple that worked for the two main ‘voices’ I need to have at the start of the game – though I’m still undecided whether these parts will also have voice acting.
After this I created a simple class to fade in the text over time – and then worried it should have been even simpler, since for some unfathomable reason I made it so text faded in over a set total amount of time instead of at a predictable rate, meaning it would be nearly impossible to sync up between fields of different length. As soon as I started thinking about all this, though, I started thinking about the way it should be, about what the optimal interface and feature set ought to be for a tool like this. This is a trap! This exact behavior is why I was talking in the last devblog about trying to treat this project as a series of game-jam-esque sprints, and why I said my tendency to fixate on problems once I approach them causes issues: Because this is the sort of thing you don’t do in a game jam. Not only is this a far more refined solution than is immediately needed, but trying to create it pushed me into writing code for Unity’s internal UI system again which is an invariably soul-crushing practice since getting anything done in there is such a finicky and arbitrary mess. I realized all this after a couple of days, and left this text fading in a state where it’s not quite as perfect as I would want it to be if I were selling it as a product – but is still quite sufficient for my immediate needs.
One could reasonably ask: Why focus on creating an introduction before completing any playable areas? I will preface the explanation by saying that I don’t believe this is the correct approach, and might in fact argue that it’s a very incorrect approach. Generally speaking, I would prefer to start with the core gameplay, build up playable areas, and expand out from there. However, right now I’ve already essentially created a gameplay prototype with the initial AIR version of the game: I don’t know if the gameplay is going to work on the macro level, IE will engagements with enemies be interesting and will the overall flow of play be interesting, but the prototype gameplay has been enough to convince me that the simple act of moving around the world will be satisfying. In addition to these basic gameplay systems, though, there are narrative systems – which are usually considered as an afterthought, but which also need to be developed and tested. Developing the intro will a) create a distinct chunk of the game, albeit a relatively unimportant one, b) force me to create the structure of the narrative systems, and c) create a free-standing piece that should hopefully build enthusiasm for the project – both for myself and for potential audiences.
Because I got so focused on trying to get specific tasks completed correctly, instead of merely functionally, I didn’t reach my original goal of completing the intro by the beginning of this month – but I don’t think I’m actually that far off. I had originally conceived of this beginning bit as being largely just text, but with a bit of reflection I’ve realized that would be an incredibly boring and tedious start to the game, so I now have a sequence planned where the camera slowly pans down to the intro screen, across text displays, and with cuts to certain illustrations I have yet to make. This is conceptually still pretty simple – and honestly probably doesn’t sound very exciting, described in this bare-bones manner – but should be more exciting and intriguing than just a few lines of suggestive dialogue, and I think with a deft touch could be really cool. The current intro music is almost 2 minutes long, which I’m starting to suspect may be too long to actually fit this sequence without messing up the timing – so I may also need to rewrite it to accommodate this.
Thus, to complete the intro, I need to make 3 illustrations and a couple more minor pieces of art, possibly tweak some assets, animate the camera transitions and text fade ins, add some sound effects, and then edit the music track to fit. I think all this is achievable within one week. Once this is complete I’ll start in on the first area – which, at first, will mostly be animation work while I complete and implement all of the standard character animations.
In all honesty, my mood has been all over the place recently – for obvious reasons. It’s nice to have something concrete to work on, like a ship in a bottle, while being otherwise locked in place.
If you’d like to help support this project or my writing, please consider supporting me on Patreon. Support at any level lets you read new posts one week early and adds your name to the list of supporters on the sidebar.