Hi folks, I just found my tumblr password, so I'm here to give some extra updates on CloudCanards! Good note, it's not dead!! Even better note, it's been going strong without rest!!
Truth be told, we are at a point of development where it's hard to show what we've been up to. You'll definitely see some more public presence once we're ready to show off more content. But for now, the best place to check out our preview content is in our Discord (discord.cloudcanards.com).
Remember when we said we’d have biweekly updates? We actually meant we’ll post once every half a year.
Jokes aside, we were actually working on lots of editor stuff or story. We didn’t really wanna spoil certain parts about the game, but now, I think we have just enough content to end the year with a blog post.
Concept Art
We were lucky to have Thaazius join the team temporarily to help us with concept art. Here is a rough sketch of an environment that we might share soon.
You can check out more of his work here.
Depths
If you haven’t noticed yet, CloudCanards features a fully 3D environment in a 2D artwork. You can travel to anywhere that you see, whether that’s in the foreground or the background.
Not to spoil much yet, but hopefully, you'll enjoy our seamless integration between 2D and 3D.
Micro Depths
Within 1 depth layer, we have multiple tiles that might either be in front of the player or behind the player. We spent a lot of time facilitating the creation of these tiles. Here is a quick screenshot of a tool that is part of this workflow.
Extending Unity Even Further
With Unity being our game engine, we noticed a lot of missing features that were bugging us daily. We fixed one of them and decided to share it with the public.
You can download the tool here.
Canards and Dialogue
This took the longest time in development. We now have a custom language and compiler suite that is dedicated to creating interactive dialogue as fast as possible. We also have a basic dialogue bubble that hooks into this feature.
We’re excited to further play with this tool and create the best narrative experience.
Website
We now have a temporary webpage that details what CloudCanards is for curious cats and internet browsers. Check it out:
cloudcanards.com
Etc
We’ve had a lot more going on this past 5 months, including a surprise showcase of our game to Google. But this post is getting pretty long, so I guess we’ll share these stories later (maybe).
CloudCanards - Devlog 7 - Multithreaded Pathfinding or the Job System
Hello! Gahwon here.
While we did work on the story, mechanics planning, and project management, we didn’t have fun stuff that we can share. Instead, I’ll just share some quick technical aspects of the game I finished.
CloudCanards features a living world with living characters who make their own decisions as to where to walk to. However, it is extremely expensive to constantly run the pathfinding algorithm. Therefore, I needed a way to separate the pathfinding code to a different thread from the main logic thread.
Before I move on, let me quickly define these terms. Pathfinding is to look through the world and find a way to get to a certain place before actually carrying out the motion to get to that place. Threads are programming instructions that can run concurrently.
Here were the caveats: Unity components are not thread-safe. This means that they can only be accessed from the main thread. Our physics engine loads data from the nearest Unity Tilemap. This means that I couldn’t get physics data from the pathfinding thread. Without the physics data, I couldn’t pathfind, so I needed a way to preload the physics data.
That’s how the cache was born. A cache stores temporary data in a more accessible place in memory, so that it can be read faster. It boosts performance especially when the data is accessed multiple times in an instance. Consider the data “There is a solid wall on the coordinate (2, 3, 4).” This is constantly getting read by all entities nearby. Instead of reading this data from the slow Tilemap, I stored this data in the cache and read it from there. This brought obvious performance boosts.
That wasn’t all. Since I wrote the cache myself, I could access the cache from a different thread. So when pathfinding, I would load all necessary data to the cache before starting another thread. Then, I would do the heavy calculations in the new thread. Ultimately, I would return the calculated data back to the main thread where an Entity could carry out the instructions.
Of course, some issues popped up from using a cache. By preloading data suddenly, I stalled the CPU, resulting in a framerate spike. Although barely noticeable when only loading around 64 tiles, it dropped the framerate from 100 to 60 when I loaded 4096 tiles at once. To fix this issue, I added a queue to the cache loading system. At any frame, only 2048 tiles could be loaded at once. Any more would have to wait for the next frame.
For the actual threading part, I considered using the new Unity Job System. However, there were a few limits that prevented me from doing so.
1. No way of canceling. If I were to signal an entity to try to pathfind from point A to B, I would want it to stop trying after x seconds. It would be pointless to keep searching if it’s taking that long since the path might be too convoluted or nonexistent. C# has a built-in system to cancel threads (I used CancellationTokens), but the job system does not.
2. Limitation of data. Unity restricted their job system, so it doesn’t cause common threading problems like concurrent modification (editing the same thing from different threads). To do so, the system would just copy all data before running the job. For cases like mine where each operation needs a lot of data to run, this would be harmful. Jobs do have a way to share data (using NativeArrays, NativeLists, etc), but these can only accept blittable types. Basically, if I had the data “NPC’s collision bounds size”, it would be harder for me to put in that data because it’s not a default type like ints, doubles, etc.
Granted, I could patch these issues with hacky ways, but I just decided I would manage my own threading solution (I used ThreadPools) instead.
Thanks for reading through all this! I don’t have any pictures to show, but I can say it’s working really well. It’s a joy to see characters just walk around on their own.
DreamHack was a blast! So many people checked out our work, and we were really excited to see everyone having fun.
Luckily, we did finish the demo in time :D
In the clutch moment, I added in complex collisions for sword trails and entities. The math was not fun, but they all worked out at the end.
Whenever swords collide, they are knocked backward from the clash. When a sword clashes, it cannot deal damage. Therefore, it allows you to defend by attacking. No need for another button to lift up your shield or roll around or something >:) Another neat aspect is that the slower sword recovers slower than the opposing sword. This way, you can attack ruthlessly without waiting for your opponent to stop shielding. We noticed that you barely recognized when the sword was still recovering, so we gave it a gentle yellow glow when knocked back.
I also added so that when swinging your sword, you fall down slower. This might be overly generous, but it basically allows you to recover from mistakes.
Kimchee worked on the prototype scene to better fit our world design themes. The atmosphere feels a lot better now. He also discovered his love for the bloom shader, which works nicely in conjunction with the sword trails.
During the showcase, many people had a lot to say about our game, mostly about the combat system. Nobody was used to having full control over crafting your attacks, but the intuitive controls allowed them to grasp the concept pretty easily.
One competitive Smash player told me that he wasn’t used to retracting his sword backward before being able to swing again. To fix this issue, we’ll make it so that partially retracting the joystick allows you to jab with the sword. Most other players, however, simply swung around the sword, happily hacking and slashing through the enemies. To fix this issue, we’ll zoom in with the camera to make incoming enemy attacks more visible, thereby encouraging tactical combat. Someone said that the knockback was too annoying. To fix this issue, we’ll allow Yanna to grapple towards the enemy, easily chasing them.
Speaking of grappling, everyone told us that the grappling is fun! Maybe a bit too fun. I realized that compared to regular running, grappling was way faster. Therefore, I’ll increase the running speed. At the same time, though, I’ll put in much more grappling aspects throughout the game. It’s gonna be fun slashing midair while attempting to keep altitude. Very fast and chaotic, but that’s how we roll.
Back after yet another two weeks! This one is also going to be pretty short and sweet, so let’s get into it.
First and foremost, we were invited to DreamHack Austin to showcase our work, so Gahwon and I jumped on the opportunity to get some nice experience. If you’ll be in Austin next week, please come check us out at the student section!
Due to our inexperience with relatively big events, this will be very humbling yet educative. I, for one, am excited as well as extremely anxious. But then again, nerves were made to be sweated out.
Our plan:
We don’t particularly have one. We’ll have a little demo and a poster of our game, and you’ll get to have fun with it this time! So... yeah. All we have under our belts is a small computer, a wired controller, and an LED monitor--but that’s all anyone needs, amirite?
(._).
Anyways, I wanted to also talk about our improvements in combat. We made the swords look a bit better. They’ve got trails and stuff. And the health? Well, we had some better ideas, but that’s all they are at the moment. Basically, health will be comprised of five red hearts as well as a bar of armor. While armor is subject to variable amounts of damage taken (some attacks will hit harder than others), every hit--once all your armor is depleted--will knock down one heart. And while your hearts will never regenerate naturally, relying on potions and so forth, your shield is capable of naturally regenerating over time, given you are out of combat long enough. Once you lose all your hearts, you get a game over and have to restart back to your last save slot.
Hello, this is Gahwon, and we’re back to share more.
I had to worry about finals this past week, so I’ll show some of our previous progress, mainly how we changed Unity to our liking. This post might be a bit boring for non-tech people but bear with me.
Around a year ago, we switched from LibGDX to Unity. Ever since then, I’ve been making some changes to the engine to make our lives easier.
After three posts, I finally figured out how to post gifs properly! To celebrate this occasion, I shared our shortcuts system above. It allows us to load and store camera locations on the editor. Now, we barely waste time scrolling until we find what we want in the level. In our giant Metroidvania world, something like this turned out to be a lifesaver.
Here’s a rather small improvement. You can now easily group objects in the hierarchy.
CloudCanards levels are built in limited 3D. Therefore, we created a quick system to snap objects to the correct position. We’ll share more about depth later, but it basically allows you to explore the background as well as the foreground.
Our tile palette brush extension broke after we updated to Unity 2018, but it will be making a return soon. This allows us to paint on the desired layer without constantly selecting where we want to paint. For example, this paints roofs in front of beams and fences in front of walls.
Come back soon to hear more about our grand plans and progress! Unlike this week, we’ll share more about the frontend of CloudCanards.
CloudCanards - Devlog 3 - We made the prototype too difficult
Hey y’all, it’s me, kimchee, again.
The prototype we made is frustratingly difficult, the enemies are way too overtuned, and the platforms are pretty unforgiving if you get knocked off. That being said, it’s given us a lot of valuable information as to what we wanted to address, fix, and how to implement it.
Today I wanted to talk about the many things that we intended for this game. Things that made the cut, things that we decided against later on, and others that we nipped in the bud.
Did you know that we had a run button? Yeah. It was on the ctrl button on the keyboard. But anyways, the run button is pretty overrated. In our game, every button needs to feel pretty useful, but not to the point in which you hold it down the whole game, using up a free finger or whatever you could’ve used to do more complex maneuvers. In the end, we’re planning on scrapping that.
We did, however, plan on perhaps adding a crouch maneuver that would slow you down. The long-term goal here was to make a way for one to both drop down a one-way platform but also be able to walk around enemies without them being alerted to your presence. Relate this to those old Pokemon games in which the NPC's would just do their own thing, look left and right and forward, and you could sneak by them if you didn’t run past them. But the second you press that run button, their heads would swivel and always try to point right at you at the point that when you walk into their line of sight, it’s go-time. Similarly, we wanted to have it such that this sneak maneuver would allow you to walk right at or around unsuspecting enemies. Get ready for stealth kills or pacifist runs, lads.
This takes me to my next topic: combat. We touched on this topic last time, but we have lots more to elaborate on it. We plan to have three different attack behaviors: swing, jab, flurry (we’re still working on these names) in which one will be the regular circular movement done by the cursor, the other is a charged linear move button, and the last is a 3-dimensional swing emulated by the cursor. The goal is to make every movement easy to execute and remember, but hard to master. Onto the mechanics of combat, we wanted enemies to have 3 or so lives, and we ultimately wanted some kind of indicator for a critical strike that would benefit the player if they were to execute it correctly.
Meanwhile, as for the player’s own health, we had quite a few ideas, but we’ve culled many of them and have come to the conclusion that we have no idea what we want to do with it. At the very least, we envision having a bar of health at the top, and some hits will hit you harder than others.
Now, onto news of our game in general: we recently finished a very small prototype of our game in which very rudimentary combat and grappling mechanics are present. Our grapple physics still requires some tweaks, but we’re getting there 😁.
Hi guys! My name’s Gahwon, and I'm the other developer of CloudCanards. Today, I’ll share our unique gameplay elements.
Your Combat
The main strength in CloudCanards is its combat system, but there is no attack button. Does this sound crazy? Well, hear me out until the end.
Yanna swings her weapon when you swing your joystick (or your mouse for non-controller people). If you swing the joystick 90 degrees clockwise, for example, your weapon will follow suit. If you quickly point the joystick left, Yanna will jab left with the weapon. And so on. If you’ve ever played Legend of Zelda Skyward Sword, it would be similar to that, but much more intuitive.
Maybe some enemy only gets damaged when falling from high heights. Well, you would slash from the bottom to knock him up and slam him to the ground. Maybe some enemy has a hole in its armor. Well, you would plunge your sword into that Achilles heel. Maybe some enemy will not die when his crotch is intact. Well, you know what to do.
By letting you have complete control over your weapon, we created a system that is intuitive to pick up but challenging to master.
Although not implemented yet, a weapon can interact and collide with the world. What if an arrow was shot at you? Imagine swinging your sword just fast enough to deflect the projectile. Or how about when you block an upcoming sword strike from an enemy? You can block that off and cut off his sword grip. Basically, your weapon can double as a shield. You think that’s it? Imagine fighting in a tight corridor, where the walls prevent you from making wide swings.
CloudCanards will never prevent you from precisely moving your weapon.
Your Adventure
CloudCanards allows players to explore its large world to its fullest. By fullest, I mean that you can even travel to the props in the background if you wanted to. Everything drawn on the screen would be accessible, just like how it was meant to be. You see the mountains in the distance? Well, that’s where you can have a grand race. You see the tower shrouded and barely visible? Well, you can rescue your princess from there. CloudCanards will never prevent you from accessing anywhere.
Your Story
I got tired of those background NPCs staring at the ground without saying anything, so I made every character important. Even for the most ordinary people out on the streets, their importance on the story will be procedurally determined based on how much interaction you have with them. Donated to a beggar once? He’s gonna remember your name and help you on difficult times. Recovered a rich woman’s purse from a robber? She’s going to let you into a secret party. CloudCanards will never prevent you from making your own story in the world.
Our Help
Sorry guys, any related image for this is in spoiler territory.
While you stumble through your newfound freedom in your weapon-handling skills, exploration, and immersion, the most fearsome Nimbus wielders of Twilight Marauders will help fend off enemies. Fight your way through insane opponents with the help of Levi and crew. Focus on slicing through the crowd in front of you and leave your back open for your friends to defend.
Conclusion
tl;dr: We’re trying a lot of new things!
Come back next week to hear more about our grand plans and progress.
I’m really excited to be the first one to tell you of our progress that we have made thus far, on the game and the story! Welcome to CloudCanards, the Metroidvania RPG game that will take you on a wild journey you’ve never been on before.
We would like to introduce you to Yanna, a mysterious girl who wakes up in a foreign land in the skies, and her journey to find a way back home. Another important character whom Yanna will meet is Levi, an unlikely ally that Yanna finds in this strange land. Levi is a dog who also magically appeared on the island and is stuck on it, looking for a way back, and he invites Yanna to a secret group of individuals like them who also have found themselves stranded on these mysterious floating islands. They call themselves the Twilight Marauders. There are only legends that explain what this these islands are, where it all came from, and what secrets lie hidden deep within them, waiting to be uncovered, and it’s up to the Twilight Marauders to do so. Who knows what enemies they’ll encounter? We plan to introduce more and more characters, both friends and foes, in the upcoming weeks, so stay tuned!
Okay, okay. But what about the actual gaming part of this game? Well, friends, that’s what I’m here for. You’ll explore the world with your trusty nimbus gourd, a bottle of cloudy magic, able to shoot out wisps in order to grapple your way around the map, and you’ll cut your enemies down as you brandish your sword/weapon of choice around at any foe who dares to come near to you. Point your cursor somewhere and fire away before you swing it around madly.
Explore the various supernatural powers you learn and obtain as you go through the game, such as bending time to get the edge in fighting foes and turning yourself into wisp in order to get to otherwise impossible-to-reach places.Take in the vibrant and thrilling sights of Nebulia, Mt. Emerald, the Warped Falls, the Scum, the Dredd Forest, the Frozen Heights, the Lonely Caverns, and everything in between.
Just remember not to look down–it sure is a far drop.