official devlog for
carrotcake
written by Louis Durrant
Thursday Report: Splash Into Shaders
Making progress with deciding how the garden would be pieced together felt difficult without knowing exactly how a key feature would play: water.
No garden would be complete without water features, and a natural world wouldnāt feel right without ponds, rivers, lakes existing in and in between it.
Water has been the bane of all developers probably since it became a necessity. Solid ground requires, at a minimum, a texture that reflects the ground itself. Maybe some nice lighting. Water presents challenges that a static texture of water canāt solveāāāperhaps most importantly because itās not static. Itās translucent, it reflects light, and it reacts dynamically based on itās surroundings. I would say these are the key to presenting convincing water.
āDonāt Starveā takes a stylized approach, using 2D images of waves tiled in front of one another, moving in an almost puppet-show way. Itās a striking solution for a 2D-styled world, and fits in perfectly with the gameās kooky, macabre tone.
I imitated this in āKingdom Kaā during the head-swapping scene for the small-scale water needed for the figure to pull heads from. Itās a quirky solution that suits the absurd nature of the scene well. Itās immediately recognizable, despite sharing very little in common with actual water.
The salesman delivers.
And while this approach suits these two cases, I had my hesitations when thinking if this would be the way forward for Walled Gardens.
Although still a heavily stylized game, itās objectives are different. I want visiting a pond or a river to evoke those feelings we get when sitting next to water in a quiet corner of a forest. It brings a certain calm, and invites you to stop for thought. Donāt Starveās waves say āDanger!ā in a world where youāre constantly on your toes. You canāt watch 2D cut-outs of water for any longer than a moment before wanting to move on.
I knew then that I would need to dive into the world of shaders to achieve something that would feel both in-line with the style of the world, but also something that felt like real, calming water.
As it turns out, scripting shaders is a whole other kettle of fish to work Iāve done previously. Since water would like be the main shader (and possibly the only shader) in the game, I didnāt think it would be worth learning an entirely new languageāāāthereās people who dedicate their working lives to this sort of thing. So, I dipped into some shorter tutorials, found a few pieces of open source code, and kind of stitched and all together, slightly changing values and inserting multiplications randomly where it seemed right to see what it all might result in.
And hey, it kind of worked. Making changes and seeing how code reacts triggers a sort of boyish excitement in me, so it was a good way to spend some late afternoons.
The first breakthrough was having a reflection set up. A simple flipped portion of an image goes a long way in looking like water. The gist is that the game captures the pixels from the screen directly above the shader and inverts them horizontally, all in realtime.
Thereās definitely something magical about seeing the characters reflection suddenly appear in the water. The trouble with this solution is, as it relies on the actual pixels on the screen, it flips and breaks when things arenāt exactly what it is expecting.
For instance, if the camera moves so that the āwaterā is too far up the screen, the shader doesnāt have the information on what to reflect, as it would be out of shot. The result is the shader stretches the few pixels that are available, resulting in visual glitches that wouldnāt be passable in a final game.
Oops!
This makes sense. The source I based the code on was for a side scrolling game, where the water level remains constant. The shader also stretches things in exaggerated ways when the camera is zoomed in and out, likely because so much new information is introduced or taken away.
So maybe reflections can wait for another day. Iām sure the solution is for the game to reflect the scene rather than the pixels on the screen, which Iāll need to look into.
So I looked to focusing on the surface of the water itself. As water flows, it skews and shapes the light around it. āDisplacement mappingā in shader-talk is where a texture is used to instruct how the shader should manipulate the pixels beneath it. You can say, for instance, that the texture should react the reds and greens in a texture . Then, you pass that texture to move slowly across, the sprite below.
Think of it almost like those funhouse mirrors at carnivals where you stretch and distort your face or body in different ways by moving yourself up and down. Only here, itās the mirror that is the one thatās moving.
Example of a displacement texture.
So I quickly drew out a sort of pond-like sprite with the stones sitting at the bottom, and mapped out a polygon to match its shape that the shader would occupy.
The texture separated from the game.
After some value tweaking, it looked good! Satisfying like water. It even masks my hideous stone texture underneath somewhat. Trouble is that itās also unsatisfying like treacle. The gloopiness of the texture gives it this glossy, old-school 3D look that feels entirely out of place for the rest of the game.
Treacle pond.
With some further tuning, I was able to get something that looked much more crispy, and more fitting.
The water as it looks now.
I think the sharper look suits the gameās 2D style much better, although I donāt see this as the final product. Iām sure Iāll be going back for some further tinkering to get something that works better.
For now though, Iām happy to finally have something functional and adaptable. I can draw out rivers and ponds, throw a shader on top and very quickly have some effective water.
Ready, no doubt, for some self-reflection, and countless fishing hours.
Follow me on Twitter.
>> Link to post.Thursday Report: Find a Way!
The playable character got a slight make-over, including smaller, more manageable ears and blinking eyes. Itās a nice touch that certainly makes the character feel more alive. The plan is that these features will easily be swapped out based on future customization options.
Iām somewhat averted to the idea of a character creator. I have a habit of spending far too long in them, when at my core I would love to dive into the game itself. That said, I donāt see it as something I could completely do away withāāāsomething static like skin colour might have be selected before entering the game. In theory, the character should both be potentially male or female, or anywhere in between depending on the playerās wishes. Hairstyles will help give the player the option for the character to appear more or less feminine, for instance, without the player feeling locked out by a creation screen.
The existing face is still very boyish, so Iāll need to decide if this is something the player can change, or something to homogenize.
New backpack layer is a fun additionāāālots of possibilities for this slot that the player could customize and wear.
A rustling sound effect gives the backpack a sense of weight and place.
A bug I had trouble with, but didnāt share (because it looks terrible), is that characters would pick a point to walk to, and then do so regardless of whatever obstacle might be in their way. This meant characters would often get stuck against trees, or other impassable objects.
I toyed with the idea of having a zone around each impassable object that once the NPC enters, would stop, think, and redirect themselves.
Instead, I currently use a āRay Castā node. This creates an invisible line between where the NPC is, and where they want to go. Should this line pass through any object that might potentially block the character, the character will then decide on a new location.
I think this works well because the effect is virtually instantaneous. It means that, instead of having the character walk up to a tree and realize thereās a tree in the way, they simply wonāt choose a path they canāt get to. I think this seems more natural.
The NPCs do still walk into the player character like itās nothing, continually plowing through like no tomorrow. The solution isnāt so simple here, as the Ray Cast can cover a very long distance. Ideally, the character would stop (not change direction) if the player gets too close within a certain radius, and is actively blocking their path.
A bug that had plagued me for some time was that if the player filled a small hole, all holes would be filled across the map. The hole is essentially a sprite that looks like a hole with an area surrounding it telling the gameāāāāthis is a hole!ā. The command to remove a node in Godot is āqueue_free()ā: queue the node to be removed from the game once itās ready (not affecting any other part of the game).
Once the player emits the signal that he wishes to fill the hole he is in front of, all holes would fill. Signals are global, so this makes sense.
All holes across the map were receiving the same signal. āself.queue_free()ā produced the same result, and finding the exact name of the specific hole (Godot keeps unique names of all nodes) and calling that to remove did not work either (still unsure why).
The solution was obvious, to check the distance from the player and the hole. The the hole is in rangeāāāremove this hole. If not, leave it be.
The animation is still absent, but this puts me back on track for working on the action system throughout the game.
Amusingly, I still have similar a bug where engaging with one character in conversation will lead to all characters in a certain radius joining in on the conversation.
Hey, at least theyāre keen.
If you like the look of my work, a great way to support me right now is to check out my adventure games, currently both 75% off on itch.io.
Follow me on Twitter.
>> Link to post.Thursday Report: Chitter Chatter
Mostly polishing things up this week with some animations and tweening.
One issue I had run into with the dialogue box is that, although the box spawns in the correct locations according to the NPCās head, if the player were to move the camera, the box might obscure the NPC or simply look strange.
The fix was surprisingly simple. I set up a signal that gets emitted by the camera whenever the camera is zoomed in or out. It says to the rest of the game ācamera changed!ā and certain parts of the game can act accordingly. The dialogue box listens for this signal, and it knows that once the camera changes to find the spawn location again (now that itās moved by the camera moving), and change position.
This worked fine, but looked a bit choppyāāāthe dialogue box would suddenly appear in its new location. A simple tween takes the two points, where the box is and where the box will be, and makes a nice little animation between them.
Godot comes with a number of different mathematical animation options to change the feel of this animationāāāI went for āCIRCā, which once arriving at its destination floats a little bit back of forth. I think this gives the box a better sense of place by making it seem less rigid. Speech bubbles would float around in real life, right?
Donāt we all?
Oh, and boxes now automatically find the name of the NPC and place itās name atop the box.
Hubert is a fresh addition to the crew, and marks the first āvillagerā archetype added in the game. I figured, as a round and well proportioned apple, Hubert would be perfect for the ādefaultā villager on which all other villagers are based. In theory, all the work done on Hubert (states, scripts, animations etc) can simply be hot-swapped with new sprites and information and a new villager is ready to go.
Since there will be vastly more villagers than travelers, this makes sense in the face of father time. If at any point this feels homogeneous, Iāll be sure to make adjustments. In theory, however, personality types will be as easy to assign as, well, assigning them. Then the game will know how the villager might act, and what they might say.
Ready to hit the town.
But for now, Iām focusing on getting Hubert right.
Facial animation was another focus this week. It occurred to me that āAnimatedSpritesā would be an ideal solution to the problem I had. Previously, as seen in the video footage of Tellstone the Toad, I had the mouth animate open and closed on a tween. It looked repetitive and too bouncy for normal speech. An āAnimatedSpriteā node allows me to load in many different sprites and either pick between them or cycle through them. So, with many mouths loaded in, I can select the closed mouth when the character isnāt talking, and spin through all the mouths when they are.
By just pasting in each mouth at a fairly random order, you can quite easily create the illusion of speech.
The fun part is spamming these in a random order.
It looks smoother than my GIF capture lets on.
I think the jitter of the blinking eyes and moving mouth is a nice contrast against the smoothness of the tweens. I think itās a nice reminder of the story-book like aesthetic the game has.
Nodding in agreement.
And above is a simple example of how some small gestures can really give life to the conversation. Iām hoping that Iāll be able to change character expressions depending on their dialogue, and their actions as well. Perhaps for more casual conversations (not when a character is āshockedā, for instance), a series of different animations can play out randomly to make things look more natural.
Nothing too extreme, of course. No one wants two wild hand gestures after another. That would just be silly.
Follow me on Twitter.
>> Link to post.Thursday Report: The Groundwork
Thursday Report: The Groundwork
On Thursdays I write up a short report on my developments and thoughts if to do nothing more than keep myself accountable. Enjoy!
Last week I was up transferring my websites over to new hosting and briefly lost access to my email addresses, which wouldnāt be a problem if it werenāt for Mediumās unusual passwordless log-in system. So, oops! Plenty to dive into this week.
My priority over the last couple weeks was to improve on to the dialogue system. Itās still bare-bones, but Iām figuring out ways to make it more complex.
Previously, upon approaching an NPC and pressing the action button, the NPC will spout a single line, and the the dialogue would end.
My solution for adding multiple lines of dialogue was to convert the dialogue data into an array. An array is simply a series of strings (text) separated by a comma, where each string can be summoned by pointing to its number in the order it appears.
Then, all we do is +1 to the original number so the game knows to look to the next dialogue entry, in order. This would go on forever, though, so we need to find when the dialogue would end. For this, I conclude a line of dialogue with āENDā, the game then checks if the word āENDā is in the current line. If it is, the word is hidden, and instead of continuing onto another line of dialogue, a signal is emitted to let both characters they are free to go on their merry way.
I like this system because itās based on human language, and itās simple.
Sounds scary!
In the future, for dialogue options, Iāll likely introduce a similar system, where if a line ends in āOPTā, or something similar, the game knows to pass the dialogue onto the player.
But this is all very static for now. NPCās will always say the same line of dialogue. Eventually some selective database will need to be put in place to deliver a range of different lines to the player, and provide the player with dialogue options contextually.
That being said, this isnāt a conversation game. Listening, however, will play a large part. Iām hoping that a large part of my time working on this game will eventually be in the writingāāāwhat the characters say and express. Most dialogue options will be agree, disagree or say nothing. Options are important to keep the player engaged, and also feel as though the world is reacting to them. A little goes a very long way.
Concept for dialogue selection.
The above is just a concept at this stage. I like the idea of most UI elements feeling as though theyāre floating within the world, and not on some abstracted plane on the userās screen. Thought-bubbles play into this nicely. Perhaps using icons instead of text would give it a different feel. Thatās something Iāll need to decide.
You may have also noticed in the GIF aboveāāāsnow! In efforts to move the world building forward, I devised a new way of tiling the ground. A while ago I started building a tile-sheet of spritesāāāessentially a sheet small squares with slight differences that get drawn from and form the world. The two major issues with this is, first, blockinessāāāwhen you build a world from squares our minds can really sense the mathematics order of it, and things seem rigid. Secondly, is repetitive textures. Our brains are designed to see patterns, and itās remarkable how puzzle-piece even the most random of textures can look when stepping back.
Instead, Iāve made a single large block of plain white thatās just larger than the average screen. On top of that sits a speckled texture that gives the ground that flowering, grassy feel. The texture overhangs, so that it merges with the blocks surrounding it. The result, even when zoomed out, is a ground thatās impressively seamless. But the best part is something I hadnāt consideredāāācolour modulating!
Hereās the overlay atop the block.
Any texture thatās pure-white can be changed to any other colour through the engine. This means that, on the fly, both the colour of the ground and the overlay can be faded into a different tone dynamically.
With this we can have the grass reflect the seasons, snow cover, or anything else. Iām hoping to see if I can introduce this to tree foliage, to perhaps randomize the colours of each tree for variety, and have them gradually fade between seasonal colours.
This is ugly, but it demonstrates the point.
And just to finish us off, a new WIP animation for the old traveling gardener. He doesnāt have a name yet, despite much inner-deliberation. Turns out when a character has a cane you canāt animate them as you normally would.
This old man represents a time before the player arrives in the garden, and welcomes all fresh and exciting things to come.
Follow me on Twitter.
>> Link to post.Thursday Report: The Conventional and the Non
I thought Iād use this report to look back at some of the design work Iāve done, particularly regarding characters.
Animals are always a fun way to capture certain characteristics that bring out a role. We all anticipate a way a monkey would act against, for example, how an owl would actāāāthen we can take that further into the real world, how would a monkey lawyer conduct themselves compared to an owl lawyer?
Itās surprising how easy our minds allow the personification of animals. A monkey in a pinstripe suit doesnāt require much justification to be immediately believable, and thereās already a huge weight of traits we assume about him.
The task I had, then, was finding that balance. Riding on those assumptions too much and we have a cliche, steering away too far and things begin to feel ridiculous.
Letās say weāre designing a scuba diving character. We might immediately start considering a penguin, maybe a seal, or perhaps even a dolphin that walks on its flippers. What if it was a blackbird? Why would a blackbird be going under water? Wouldnāt its feathers get wet? Suddenly we feel that sense of doubt, it could happen, but itās a bit goofyāāāitās trying to steer away from expectation. Why couldnāt it just be a penguin?
There are still roles Iām having a hard time deciding on, and maybe Iāll concede and choose the obvious. However, there are some characters Iāve settled on that I think were the perfect choices.
Constellations will play an important role in āWalled Gardensā. Players will need to discover which stars to connect with which to unlock certain bonuses. I needed a character that would provide that knowledge, and more, to the player. Soāāāwhat animal would be looking to the stars?
Our aforementioned owl is the obvious choice. Maybe a bat could have been another. I settled on a heron. A bird known for standing very still by the riverside, itās head often turned upward. And while nothing specifically is carried over from a heron to a night, or even astrological theme, here we have an animal known for its patience, observation and staunch neckāāāhaving a heron with a telescope in hand suddenly doesnāt seem so outlandish.
And what about a character known for digging, making tunnels? Our minds probably immediately go to a mole. While a pig might not be known for itās digging undergroundāāāshowing a pig character covered in mud and dirt is just what weāve come to expect, so it doesnāt take such a leap of faith to give it a mining hat and a certain ācan-doā attitude.
Again, I still have a fair few more to consider, but hopefully this gives an insight into my designs.
Shying away from the conventional choice just gives everything that slight edge, it feels new and carries with it that bit of magic.
But, at the same time, not so unusual that it doesnāt feel familiar, and doesnāt feel at home.
āHomeā is ultimately what I want to capture.
Follow me on Twitter.
>> Link to post.Thursday Report: Digging Yourself a Hole
This week I was able to make a quick start on the landscaping that the player will do throughout the garden.
Although itās only small, itās great to see the systems for how the player might affect the garden after its generation. I decided to start with the trowelāāāitās the only tool Iām absolutely sure on including, so it was a safe choice. It has a small form factor, and a many handy uses that the player might find themselves taking advantage of.
Maybe the traditional gaming shovel will make an appearance for those larger, deeper holesāāāalthough in a game where most gardening is planting seeds, would such a hole be necessary? Maybe a shovel would be used to remove a tree stump from the ground, but in the real world this would be arduous work. I like the idea of a tree having a real presence and sense of place, planting a tree shouldnāt be done frivolously, and neither should taking one down.
I havenāt yet figured out the best way to obscure the tip of the trowel to give the illusion itās digging into the ground. Iām happy with the animation for the most part, it has rhythm and a good sense of weight and snappiness.
An easy way to establish a rhythm is to simply make sure each part of the animation plays out for the same time intervalāāāor a division thereof. Watch the animation above, and you can count a consistent beat: 1, 2, 3!, as each motion lasts for exactly 0.2 seconds.
I would prefer if the player got on the kneesāāāfor the promotion of good posture!āāā, but thatās something I might have to figure out down the road, as it might involve swapping out sprites.
I still need to add the hands, and Iām still torn whether arms are a necessary inclusionāāāit would certainly make life a lot easier without having to flail those meat sticks around in animation.
While I originally had in mind to animate the dirt being dug up myself, it occurred to me that setting up a particle would be easier and offer many benefits. Some acceleration is added to the sprites and then a large amount of gravity is applied so they fall toward the ground. I randomized the size, the rotation, and the position of each piece. Now, every time the player will dig up the ground, the effect will look different with each dig.
The game creates a node with the image of the hole just below the player, and plays the particles as it appears. Just how many nodes can the player create before the engine collapses in on itself? Who knows! Iāll likely have to start removing holes when theyāre off camera to keep things from spiraling out of control.
Next on the list to continue this will be for the player to fill in the hole after pressing the same button, orāāāof courseāāāplanting a seed.
Follow me on Twitter.
>> Link to post.Thursday Report: RNG Trees
Every Thursday I write up a report on my latest developments and thoughts if to do nothing more than keep myself accountable. Enjoy!
I always knew I wanted some kind of random generation when it came to the gameās environment. To what exact extent, Iām still undecided. Currently Iām fond of the idea that there will be a number of large āparcelsā have predetermined featuresāāācertain elevation, certain water features etc. When a new game would be made, these parcels would be pieced together randomly, like a jigsaw with hundreds of different outcomes. I think this would give a good balance of random and predictable outcomes, which would make things more manageable but also fresh.
Iām still new at all this, so Iāve decided to start by building a āSpawn Sheetā. This is a sheet of many points, wherein each point rolls a digital dice. Depending on the number that lands, depends on what will be generatedāāāa bush, a flower and so on. Then, once thatās been decided, another dice is rolled to determine whether this prop will spawn at all. Iāve called this ālikelihoodā and I simply rank it from 1ā100: 100 means itās guaranteed to spawn, 1 and it will never spawn.
I can see this system getting out of hand very quickly since itās so simple. Currently this spawns 1 of 4 outcomes, but once hundreds of different props are added to the game, Iāll need to figure out something more modular.
Having each point running itās own code is probably a messy solution too. There will be thousands of points in a single game, so Iāll likely need to think of a way to generate each point through code, instead of plonking it down myself.
Still, Iām proud of delivering something that works at all. Itās exciting seeing the game do so much work for me already, and my main game scene is no longer filled with a hundred flower nodes that Iāve been having to sift through to find the player.
A small bit of code randomly shifts each point so thereās no obvious gridāāāthings look more organic this way.
Eventually stricter rules will need to be in place. Certain zones might spawn more fir trees, for instance. Three bushes should never spawn directly on top of one another, for instance. That should come eventually.
āTellstoneā now has both placeholder walking animations. I originally envisioned his foot sprite swapping out for a version that shows the base of his foot, in front of his body. Godot doesnāt offer a super-easy way of swapping out sprites, or even showing and hiding certain sprites in its built in animation system, not without attaching code that triggers when a specific keyframe is played.
Iām actually very happy with the current animation without the foot coming up over his body. Itās surprising how much just shifting a still-sprite gives the illusion of weight and depth. Iām keen to return to the animation to give his backpack more of a clumsy heaviness, because it looks too rigid at the moment. Heās a comedic character, so I want that to come through in his animation.
Characterās now face the player when they talk to one another. This was far more simple than I anticipatedāāāI simply deducted the characterās position from the playerās position. If the number is below 0, the character knows to turn to the left, and visa versa.
I decided that characters would always face forward when speaking. This not only simplifies the checks on where the player is standing, but also means all the fun expressions the characters will show wonāt be lost to the player. It also doesnāt look as outlandish as I had worried.
Next week Iām hoping to make a solid start with the tools the player will use throughout the game, starting with the trowel, so that the player may dig small holes with which to place seeds in to cultivate their garden.
Follow me on Twitter.
>> Link to post.