Last but not least came the time to publish Forgecore. I planned to release it on Gamejolt, Kongregate and Newgrounds but unfortunately Kongregate closed new game submissions just in the nick of time.
I had a surprisingly positive experience on Newgrounds, and not only because Forgecore was featured. I found out that it's one of the few websites that still actively promotes new submissions instead of just showcasing the most successful games. Overall the community is also very welcoming, I feel it still retains some sort of indie idealism that is very rare to find nowadays.
During the time that Forgecore was featured on Newgrounds, I've received lots of feedback. There are many aspects of the game that could have been done better, but the most important subjects are about the difficulty of the game.
Forgecore has a simple narrative aspect, but some people may find it entertaining and engaging nonetheless. Some of these people may not like the gameplay enough to enjoy tackling a demanding challenge, or they may just want to have a more relaxed experience in general. It happened to me too a few times, in some games I played there were moments in which the gameplay difficulty felt like an annoying obstacle to keep the story going.
For some reason, I completely overlooked this aspect and when I released Forgecore there was no difficulty level selection. When some reviews pointed out that the level of challenge wasn't enjoyable for everyone, I've slapped together an easy mode and updated the game. It's not the most elegant solution, but it was the only one doable in a short time.
From the reviews it emerged that the biggest issue was the mountain level. I never thought it would be so hard.
The problem was that the most intuitive strategy to beat the level wasn't the one that I had in mind, because I was biased by my knowledge of the game mechanics. As a result, the margin to make it through the level using the strategy that most people attempted was extremely tight and it wasn't meant to be so. Sometimes it's hard to put myself in the shoes of a new player.
Adding an easy mode solved also this problem in a way, I didn't want to make the mountain easier because it would be unfair towards who already got through it at the original difficulty level.
All in all it was a wild, emotional and satisfying learning experience. I'm grateful to Newgrounds and to all the players that shared their thoughts, if my next games will be better it will be because of them.
My initial plan was that Forgecore would feature randomized level layouts. I gave up on that idea eventually because I realized that memorizing the level layout was a big part of what made a run successful. In facts Forgecore levels are procedurally generated using a fixed seed, so that they are the same for every game.
Also all of the graphical elements are procedurally generated, in some cases with a degree of randomness.
While developing Forgecore, I've found that it's better to ask myself a couple of questions before of shamelessly jamming some randomness into the mix.
The first question is: "Is that really random or it actually has an underlying scheme?"
I've spent some time trying to figure out how to distribute trees on a mountain for a certain ending sequence. I've tried randomizing it in various and implausible ways, but it was looking good just one time out of ten. I was overlooking a fact: trees don't grow randomly.
Trees need light and space to grow. I've ended up placing the trees in a perfect brick layout and applying some randomness just to create some noise and don't let it look too perfect.
Which brings me to the second question: "Even if there's no underlying scheme, is that really random or it's better if it's equally distributed?"
Let's continue with trees, but considering a single one. Let's leave aside the look and let's focus on the structure of branches. The algorithm I used is pretty simple: the tree has an amount of "age" or "energy" and every time it branches the amount is split between the branches. It goes on recursively until it eventually gets a branch with just 1 energy.
I wanted to have both branches that split into 2 other branches and branches that split into 3 other branches. On my first approach I've tried to randomize it, but many times I would get too many consecutive split into 2 or consecutive split into 3 and it was looking fairly bad. So I realized that in that case I didn't want to have it really random but distributed equally. I completely gave up randomness and I've opted for a fixed 3 - 2 - 2 sequence. It works quite well because it is applied breadth first and the repeating pattern doesn't stand out.
I can say that my idea on the use of randomness in game development has changed a lot. I'm a long-time fan of classic turn-based roguelikes and I used to think that procedural generation was all about randomness, but now I feel that it has be used with a great deal of care and with a clear purpose. Nobody likes a bunch of pointless noise.
At a certain point I had a lot of free time on my hands and I decided to develop my own toolkit. I wanted my games to be exactly the way I wanted. I also have to admit that I have an interest in understanding the technical aspects of making video games and that I mostly learn by doing. I know, it's not a very designer-like attitude, but with time I've learned that sometimes it's better to just let me be me.
The whole thing begun with "The Clock & The Chaos": I simply wrote a piece of code to draw images and spritesheets using HTML5 canvas. Then came "The Cursed Mirror": I went deeper and I implemented skeletal animation, so that I could procedurally animate the characters. At that point my geeky side was too hooked to stop: I was creating something aesthetically pleasing solely by writing code.
But editing images like that was messy and extremely time-consuming, so I wrote an editor to draw images by writing code, assemble them into skeletons and create animations: SkeleTool.
But then I wanted something with better performances that could leverage WebGL. I also wanted to add more features, so I rewrote it using AngularJS for the editing interface and PixiJS to handle rendering.
But then I realized that wasn't easy to persuade game engines to import that stuff. I was never happy with particle effects implementations after all, better write my own engine based on PixiJS for the rendering and p2.js for the physics simulation.
But then... well, you got the picture. I went in full frenzied developer mode and I wrote an awful lot of code.
I ended up reinventing the wheel, the brakes, the engine and the whole truck. Plus my free time drastically decreased at a certain point, so it started to feel really daunting.
No need to be said that it's not the ideal approach if your plan is to be a game developer. The amount of time spent on strictly technical work overweights the amount of time spent on developing the actual game. In retrospect, I can say that it was an interesting trip. If I had known that at a certain point I couldn't spend all that time on game development, probably I wouldn't do it. I feel that in some way I've been hiding again in my problem-solving comfort zone.
But, yeah, it has been interesting and I've learned a lot. It's bitter-sweet, but let's focus on the sweet. There have been some unespected outcomes too. For example, I've implemented a function in SkeleTool and in my game engine to quickly generate animated gifs, which sparked an interest for creating looping animated gifs. Also, working on audio context was pivotal to understand how it can be leveraged to create visuals synchronized with music.
So, maybe Mr. Romero was right.
You might not think that programmers are artists, but programming is an extremely creative profession. It's logic-based creativity.
John Romero
I've read it a thousand times, but maybe only now I can understand what it really means. I've been working as a programmer for 15 years, for most of the time I've been writing code just to solve a problem that someone wanted me to solve. I've used to think that there was no trace of the mysterious charm of the artist in a programmer.
But everything changes if you remove customers, requirements and money.
That's another of the reasons why I don't want to depend on game development as my main source of income.
Scrolling down my Twitter timeline, then scrolling it down again and again, I've found out that the first tweet featuring ideas about the game that now is published and is known as "Forgecore" was posted on June 19 2016. At the time I was referring to it as "the game I won't finish", but some of the core ideas (no pun intended!) were already there.
After a couple of months I stopped working at that idea, I wanted to try to do something I could actually finish.
Since then I've worked on "Forgecore" in my spare time. There have been pauses, even long ones. In the end the game took probably around 6 months of full-time work to be developed, diluted over the course of 2 years. I did only develop games for game jams before, which is the opposite approach. Working at a slow pace like that had some notable effects, positive and negative.
The good thing is that I had a lot of time to think about what I was making. I ended up having a clear idea and I aimed to do something simple and essential, trimming all the unfocused stuff that could drain my scarce development time.
The bad thing is that I really had a constant dread feeling that I'll never actually finish.
The weird thing is that I've managed to actually finish it. It makes me feel wise and patient, almost adult.
I had the inspiration for the story during a visit to Pompei. I've been living near Naples since 2009 and I've been learning a lot of local folklore and traditions since then. One thing that I find particularly striking is the consideration of Mount Vesuvius: most of the people living here aren't scared or worried at all, they see Mount Vesuvius as a symbol of being home, as a guardian even. Also, I feel that the real threat for humanity is its own darkest side, not nature.
The idea of having a construct as the protagonist was borrowed from another game I've made, "The Clock & The Chaos". I usually try to develop simple and focused games, where the protagonist has a single goal or a straightforward task, I see that as more suited for a machine that for a person. Also people seems to like unconventional, weird and somewhat cute protagonists. Someone empathize with them, even if they are machines. At a certain point I've let some friends of mine toy with an early prototype, when I've told them that I wasn't actively developing the game anymore, one of them told me "Poor thing. I'm imagining the glowing core slowly getting dim and ultimately going off!"
The flame propulsion was inspired by the extensive use of jetpacks in "Tribes: Ascend", a game I've enjoyed quite a lot back then. In the early versions of "Forgecore" you could also control the rolling direction of the protagonist with the keyboard, but in the end I was holding the "roll right" button all the time. So I came up with the idea of giving to the protagonist the stubborn and single-minded behaviour of always rolling right on its own.
I was also thinking to have the temperature as a limit to the use of the propulsion and some sort of classic health bar, but I liked the idea that you could sometimes benefit from what would normally kill you and the risk-reward gameplay that could spring from it, hence I came up with the idea of having the temperature as the only resource to manage and an environment that wants to freeze you.
It's needless to say that most of the design happened very early in the developement process. There was just that little detail missing, the implementation. I also may have overcomplicated it a bit, by the way. Let's say I wouldn't do it how I did it if I could go back, but in a way I had to give it a try, at least to understand how it really worked. It deserves its own dedicated post anyway.
The first technical aspect of game development I've been fascinated about is particle effects. Generating aesthetically pleasing things with simple elements and simple rules is the kind of stuff that really tickles my inner geek.
I've spent quite a lot of time trying to figure out how to make flames, puffs of smoke, jets of water. What they have in common, and I was missing, was some kind of cohesive look. After some research, I found out good news and bad news. Bad news was that the answer was a pixel shader. Good news was that it's a very simple one.
So let's get stared: as a particle we will be using a regular radial gradient, which goes from fully opaque to fully transparent. The color doesn't matter as we will be applying it with the pixel shader. Something like this:
Now let's put this gradient into a particle effect that just spits out some particles with some degree of randomness in a general direction, let's make them affected by gravity and colliding with solid elements on the scene. The outcome doesn't really look impressive, but bear with me.
What we need to do is to "meld" these particles together. What we want to achieve is an effect reminiscing of a fluid: nearby particles should stick together, they should completely separate only when they reach a certain distance. It can be summarized with this image: when two "drops" are close we want to see the part inside the blue line filled with color, while the outside parts becomes transparent:
So we want to cut out the parts that are less overlapping and we want to fill the parts that are more overlapping. To obtain that effect, we are going to use a threshold pixel shader, which does exactly that: if the original pixel doesn't reach a certain opacity threshold it will be made fully transparent, if it does it will be made fully colored.
To avoid pixelated borders, we are going to customize the shader a little bit: instead of going from fully transparent to fully colored when crossing the threshold, we will make the pixel gradually less transparent until we hit a second threshold.
Finally we are going to apply the color we want for the effect, in this case I'll use a watery and 50% transparent light blue, hence vec4(0.43, 0.46, 0.5, 0.5)
Without further ado, this is the code for the shader:
precision mediump float;
varying vec2 vTextureCoord;
uniform sampler2D uSampler;
void main() {
vec4 col = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));
if(col.a > 0.75) {
// the pixel is above the threshold: apply the color
col = vec4(0.43, 0.46, 0.5, 0.5);
}
else if(col.a > 0.65) {
// optional: apply the color gradually to avoid pixelated borders
float colVal = (col.a - 0.65) / 0.1;
col = vec4(0.43 * colVal, 0.46 * colVal, 0.5 * colVal, 0.5 * colVal);
}
else {
// the pixel is below the threshold: make it transparent
col = vec4(0.0, 0.0, 0.0, 0.0);
}
gl_FragColor = col;
}
It's very simple, but applying it to our unimpressive particle effect makes some kind of sorcery and turns it into something that makes more sense:
By tinkering with the shader and the particles, you can obtain different effects.
For the next example I've used a particle that goes from 0.25 opacity to fully transparent. The reason is that I want a more cohesive look and a more gradual color application, so I want to be able to check with the shader how much particles are overlapping on a finer scale. The particle effect has a negative value for gravity and shoots in random directions on 360 degrees. Finally I've modified the shader to add multiple thresholds, so I can make color progress gradually from transparent to red and from red to light yellow:
precision mediump float;
varying vec2 vTextureCoord;
varying vec4 vColor;
uniform sampler2D uSampler;
void main() {
vec4 col = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));
if(col.a > 0.95) {
// the pixel is above the yellow threshold: make it yellow
col = vec4(1.0, 0.9, 0.6, 1.0);
}
else if(col.a > 0.5) {
// the pixel is below the yellow threshold and above red threshold: apply a mix of the colors
float colVal = (col.a - 0.5) / 0.45;
col = vec4(
1.0 * colVal + 0.75 * (1.0 - colVal),
0.9 * colVal + 0.2 * (1.0 - colVal),
0.6 * colVal + 0.0 * (1.0 - colVal),
1.0 * colVal + 0.75 * (1.0 - colVal));
}
else if(col.a > 0.35) {
// the pixel is below the red threshold and above the visibile threshold: fade in red
float colVal = (col.a - 0.35) / 0.15;
col = vec4(
0.75 * colVal,
0.2 * colVal,
0.0 * colVal,
0.75 * colVal);
}
else {
// the pixel is below the visibile threshold: make it transparent
col = vec4(0.0, 0.0, 0.0, 0.0);
}
gl_FragColor = col;
}
And this is the result:
Considering how simple the code is, I find it wonderfully useful.
Obviously it's not the only way to achieve such effects, but arguably it's one of the simpler and lighter approaches. For example, I've read about a technique using fully opaque circles as particles, with a blur shader and then a threshold shader. The result would be probably better, but the blur effect adds a bit of load and complexity. This goes all the way up to realistic fluid simulation, which for many developers is high out of their scope.
Again, it's something logic, undeniable and inevitable. Despite this, my mind seems to avoid taking it into account, maybe to preserve its own sanity. Every time reality reaffirms this concept, it hits me hard.
The last time it happened, I started feeling like I had to take a firm grip on my life and make it turn in the direction I wanted, right in that moment.
So, after more than a year of inconclusiveness, I decided to make a game.
Procedural generation is a topic that I have always found interesting: I'm fascinated by the intricacies of harnessing randomness into something meaningful and beautiful. PROCJAM was around the corner, so I decided to participate.
Soon enough, it became clear that the game jam was just an excuse to give myself a deadline and a general direction. Then I realized that I didn't even care about the players and how the game would be received. I just needed to shout and I did it in a digital, game-like form.
That's how "Hanging by a Thread" took form. It taught me two things: I was still able to make something I liked and I still wanted to make games.
After <5 Minutes of Play Jam, I was very excited and I jumped right into another game jam: JS13K, make a game in Javascript with a zipped size less than 13 Kb.
My inner geek couldn't resist to the call of something that felt so technical. Moreover, the technique I used in "The Clock & The Chaos" was a great starting point because generated images and animations are very lightweight. I was very eager to experiment more with that approach and elaborate it deeper.
To be fully honest: I also thought that JS13K was a good way to show off my programming skills and my effort has been focused on technical details all the time. I've tried to cram all I could inside that 13 Kb zip, but I forgot to put in something fundamental.
Fun and engagement.
"The Cursed Mirror" is not that bad, but it's a good example of how not to invest time and effort when making a game.
The whole point of making a game is to create an experience for the player, even in a game jam like JS13K.
In the end, the game felt dull and soulless. I felt that I did fail.
A video game interacts with two human senses: sight and hearing.
Sight is more precise and analytical, it's our primary way to perceive the world. Hearing has to give us an idea of what is going on in our surroundings, even outside of our field of vision. Also, while visual stimuli are usually continuous, sounds are often discontinuous: hearing has to trigger swift and instinctive responses to stimuli, even before we can further analyze what is going with our sight.
Hearing is primordial, linked to instincts and subconscious.
Sounds effects and music are powerful means to whisper directly to the deepest parts of a player's mind. They can convey moods and feelings in a subtle but efficient way.
A game without sound lacks what makes the player believe to be in the game and not in front of a screen.
<5 Minutes of Play Jam instantly got my attention. I was fascinated by the idea of creating a gaming experience in a concise and elegant way. I also liked the idea to have a very narrow scope and, hopefully, time to polish.
There wasn't a proper theme, so I used the limit imposed by the game jam as a theme. The limited time, a clock ticking, a protagonist struggling against time but ultimately failing: a small robot fixing a clock that is falling apart.
I was still undecided on which kind of technique to use for graphic and animations. The idea I had involved gears of different size and colors, perfectly fitting together. I discarded the idea of drawing them and I wrote a piece of code that generated gears, given size and color. Then I needed an image for the clock face... and again, it was easier for me to write code to generate it instead of drawing it.
All of a sudden I realized that this was the technique I was looking for. The thing I do best is telling computers how to work for me. I ended up generating procedurally all images and animations of the game.
I've also made quite an effort for sound and music. I've spent hours on freesound.org searching for samples to use for the sound effects and I've listened to lots of Creative Commons music, until I found this gem: "suddenly i feel alone". I could feel the clock ticking, mechanisms falling apart and the loneliness of the protagonist fighting for a lost cause. The crescendo was perfect for the gameplay I had in mind, I ended up adapting the game pace to match the pace of the music.
I felt deeply inspired and it paid off. "The Clock & The Chaos" is still the best game I've made so far.
From my perspective, it was very, successful. There was a clear measure for its success: it has been played for far more time than what I've spent developing it.
The ancient Zen question addresses this directly: "If a tree falls in the forest, and no one is there to hear it, does it make a sound?" [...] As designers, we don't really care about the tree and how it falls — we care only about the experience of hearing it. The tree is just a means to an end.
Jesse Schell, "The Art of Game Design"
The whole point of making a game is to create an experience for the player. A game without the player is just a fancily-arranged-but-pointless bunch of bytes; it's like it doesn't exist.
Playing a game is bringing it into existence.
Watching someone playing your game is being witness of the moment in which your game stops being just a bunch of bytes. It's very meaningful for anyone making games.
I've tried many times to develop a video game with other people, but it didn't work for a number of reasons. To be honest: probably I'm not a good team worker. To be fully honest: probably I wasn't interested enough in making a game with other people, what I really wanted is to make my game.
I wanted to feel free to express myself, try weird approaches, fail miserably.
At some point, I've discovered game jams and Ludum Dare. In particular Mini LD #58 draw my interest because of the theme: PONG.
The main issue with making a video game as a solo developer is that you have to take care of every aspect of the game. Which, at the same time, it's also the most exciting thing. Anyway: my artistic training is equal to zero and at the time I felt it was a big problem. The fact that the game had to be inspired by PONG had a very clear implication: I could make a game out of rectangles.
And so, in about three days, I put together "A Ball's Life".