carrotcake Blog šŸƒ


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.