DEVLOG #42 – Irritating Implementation of Platforming Predicament, Part V: The End, or Not

My goodness, there you are! You see, I’ve been buried in this pile of codes ever since the last devlog post, and I just barely have the chance to write this one!

Umm, where do I start? Oh well, I’m Chalcedony, and here is the 42nd entry for this devlog series. It might as well be my last chance to write, and hence the title. This will be the story of preparations towards the ending of this project.

Let’s start… Or not. Heheheh.

There is an interesting trivia about the number 42 to be the answer of life, universe, and everything. Others view it as death – the end. It’s up to you to interpret it your own way, but hopefully this entry, the 42nd, will provide you with some answers… Or not. Oh right, back to topic! Ending, from a coder’s perspective.

It is the time where every other members from the team flood you with their not-so-final creation. Yeah, nothing can ever be treated as final, as revisions pop out every day, hour, second, even millisecond.

Picted below is one in-game footage, after and before some lovely revisions… Or not.

airChange
The right one transforms into the left. Some rooms and corridors are generally widened for easier navigation.

Little changes are more often than not, jeopardize your code structure, if they are numerous and are done near the end of the development process. The addition of many if-elses is killing you. We have a couple of instances where some objects only appear at a specific time and place (and aren’t used in any other occasions). We have a dedicated folder containing local script object for those things, just to avoid massive lines of ifs.

localObjects.PNG
This cutesy folder of LocalObjects is home to nearly 100 scripts

Events that are tightly tied to time also serve as a genuine hassle when changes occurred. Mistimed jumps, stuck in closing door, you name it.

Ending sequence is constantly changing and therefore is a total time waster :(. The team made me swear not to post any spoilers here, so sorry, no more asking, and no, no screenshot nor gifs for you… Or not.

ending.gif
Watch it on your own risk.

Now you would think that, after applying all changes, we would just hit the build button, and everything should be okay… or not? Well, we still have to do the testing, assuring this game can run on most computers, et cetera. We have seen cases where people complained about this game crashing after the first screen. Weird, as it runs perfectly on our machines. This is one of the harder case of bugs, and sometimes we decide that sometimes, you just have to use a better computer for games.

typicalTestingScene.PNG
A typical testing scene.

Done checking (internally)! The next step is to distribute the executable to some secretly picked testers, for the final input for the game. We just need upload the game, and… Hey, look at the size! At the moment, our build is 2.56 GB, waaay above our expectations of how big this game should be. Zipping could reduce it to 357 MB though.

It is possible to check on what is bloating the size of your project in Unity. The editor log gives you a pointer in it. And in our case, guess what, the textures are totally dominating the build, by a whopping 97.0%!

Not all hope is lost, though. Unity also has the option to compress texture size – crunched texture the name. The upside is, crunching effectively drop the texture size to about 25% of its original size, with almost no noticeable loss of quality! The downside is, crunching takes a huuuge amount of time, and only textures with specific size could be crunched (must be 2^n or 100 * n, to be exact). And the worst part is, it is not even documented! It is recommended to write a script that selectively crunch your assets (you can do it manually, in exchange for your sanity), and let unity do its work while you party on… Or not.

crunching
Hold on, crunching may take up to a day or so.

Great! It’s finished and ready to be served! Or not. In reality, we are still struggling with constant changes, and haven’t reached this state yet. Hopefully this madness will soon reach its end! Yeah, that’s it, that’s all, guys! Tune in this channel weekly for more updates! See you around!

 

 

 

 
Still here? Okay… here’s some statistics as of 18th June.
– Build size: 2.56 GB.
– Project size: 13.8 GB
– script files in project: 400 items
– texture files in project: 5804 items
– audio files in project: 134 items
– script size in build : 1.0 MB (0.0%)
– texture size in build : 2521.6 MB (97.0%)
– audio size in build : 55.1 MB (2.1%)
Note that this will definitely change in the released version… Or not. Heheheh.

ProjectSize
The size of the project.

I’m outta here – Chalcedony

DEVLOG#30 – Irritating Implementation of Platforming Predicament, Part IV: Shader

Oh hello there, guys! Here already? Come on in! There are pictures to feast on and stories to savor, so pick a comfortable place to sit and eat well.

Haven’t I introduced myself yet? Well, if you follow this blog from the beginning, you surely must know that I am Chalcedony, one of the programmers of Ascender. Well you know what – now I’m not an intern anymore in devlogging – I am a full-fledged one!

Here we go, the appetizer: sneak peeks! The never-ever-seen-before scenes are ready for your eyes only! [*Plays awesome sound effect*]

Firstly, we have the tendrils. Sky can jump on and off it. Note how they react accordingly to sky’s movement.

sulur
Do the villagers climb on them too?

This kind of trampoline is also fun for some boing-boing. Hold the jump button for more air time.

trampoline
Trampoline image just for placeholder.

How defying gravity sounds? You can climb wall and even fall into the horizon.

skyWalk
The house is still in repair, no worries.

For today’s special, we serve shaders. What is a shader, you ask? Wikipedia says “a program that tells a computer how to draw something in a specific and unique way”. Shader is used for special (and not-so-special) effects, like these.

Remember this big robot? His laser effect was my first shader creation (not counting failures, of course)!

bro
The rune stays intact, so why sky does not?

The layer where sky is standing is affected by the light from the lamp, whereas the background and the foreground are not. Just shader.

light
Villagers have nothing to do, so they spend the whole day standing there.

Even simple menus need shader to clip the items so they are not rendered off-window.

menu
Why so many tasks for so little robot?

Look closely, the water distorts the scenery behind it. How to do it? Shader.

water
It distorts my sanity too.

Contrast to C# in terms of language, one should use Cg/HLSL language when creating shader in Unity. The scripts below both are for B.RO, the left one is written in C# for controlling the movement, and the right one is in Cg for you know, shading.

scriptCompare
These are among the first scripts for this game! Bad, bad scripts.

 Those two look alike, but in truth are quite huge in difference! Debugging is especially a hell in shading. You will often end up with this kind of result…

badWater1
Error in shader equals magenta for you. My favorite color!

Of course without you knowing what’s wrong. For some cases, Unity will be a good guy and tell you (approximately) which line caused the shader into haywire. Granted, I am by no means a master in shading, but still, when you went to fix the line, then it goes boom…

badWater2
Very menacing water.

Gah! Dealing with these stuffs always drives me to my boiling point!

Anyway, that’s all for today’s meal! Did you enjoyed it? What now, you need dessert too? If you are still craving for more, be sure to play our public preview now, and let us know what’s on your mind!

Wow, it’s been ages since my last post, but now we must apart once more. Fret not, we will prepare more special dishes for you to relish, so stay tuned, and eat well. Bye!

 

DEVLOG#10 – Irritating Implementation of Platforming Predicament, Part II: Rune System

Good day, Ascenderians.

Today, I, Chalcedony, the programmer of Ascender, also an intern in devlogging, am going to tell you an important element of Ascender – the rune system. But before we start, let me give you a sneak peek at what feature is being cooked in our kitchen. It’s your turn, Sky!

pullhook
Yes, drag it along, Sky.

Yes, we plan to extend the usage of hook, so you soon will be able to see Sky happily yanking boxes around Dolopo. Oh, about Dolopo, here’s an animated GIF showing sketches of that city.

dolopo
Dolopo. Oh, please ignore those odd sprites at the beginning of this GIF. That’s solely for testing.

Enough peeking! Without further ado, let’s get into the rune system! What is rune, you say? Hey, don’t make that what’s-wrong-by-not-knowing-it face! Check this blog post by Amethyst, you will get an explanation why it’s so awesome that it brought us the title “Leading Engineers of Game Mechanics” from Compfest, a prestigious information technology event in Indonesia. Or better yet, play the prototype now!

Alternatively, I’ll just be nice and once again copy-paste his explanation for you.

“So what is Rune? Rune is type of stone that can be found by the player. Each rune can equip Sky with new skill in order to explore the world of Ascender. The trick is that each rune can be only equipped in a limited slot. Player need to figure out how to equip rune effectively and efficiently”.

runeSystem
Rune system

You might have known from the image (or by playing the prototype) that the rune system is placed on a triangular grid. I found that triangular grid suits well with what we need – a simple grid type so anyone would have no trouble fitting the rune in, but not too simple to maintain the ‘puzzleness’ and to preserve some rooms to make it more interesting.

This rune system is appealing, but we want to make it fascinating. We have considered some ideas, such as combining runes to produce new skills, e.g. Fire + Run = able to walk on fire, Strong + Hook = able to pull heavier blocks, etc. We also thought about more rune placement rules, such as which rune must be put close to each other, and which should not, and its consequences.

Along with those thoughts, we also want the rune system to develop as the game progresses. Runes (and slots for runes) will be awarded upon quest completion, and maybe at some other rare occasions.

Now you know the charm of rune system in Ascender, let’s talk a bit about the implementation, a.k.a. the annoying math and programming stuffs. First thing first: How can we construct a coordinate system for this grid? Actually, there has already some solutions on the net, with this being on top of the search result:

triangleGrid
Example of a coordinate system for triangular grid

The implementation was straightforward. Here, we choose (0, 0, L) as the origin, and assign the triplet (x, y, z) to each triangle slot, with x and y being integers and z being L or R. Note that for each increment of x by 1, we move right exactly 1 triangle length, and for each increment of y by 1, we move up exactly 1 triangle height, and right by 0.5 triangle length. If z is L, the triangle is upright, but if it is R, it is upside down and shifted right by 0.5 unit of triangle length.

Then another problem jumped out when we needed the rune so it can be rotated. Now how do you map some point to another when it is rotated around the origin by 60 degrees? Try it – you will know that it’s not a trivial process (except maybe you are some geometry whiz, that’s it).

runeRotate
Rotating the rune. Note that each rotation is exactly 60 degrees.

After some hours thinking, I decided to play with some other coordinate system, like this one below.

integerGrid
Some weird coordinate system for the triangular grid

Now, the coordinate only needs x and y, but it omit some points as it is not valid to put a triangle in, such as point (0, 0). All valid points have odd y coordinate. Moreover, we need to derive a formula to know whether the triangles should be upright or upside-down. On top of that, the distance in y-axis is shorter than x-axis (it’s approximately 0.87 times, = 0.5 tan 60)). It looks totally uglier than what we had before. But, by some magic process, I then found a way to map it!

Imagine we are to rotate point (x, y) by 60 degrees. By using rotation matrix, we have the new point (x’, y’) to be (x cos 60 – y sin 60, x sin 60 + y cos 60). But remember that the y-axis is ‘shorter’ by half of tan 60 times than the x-axis! All in all, it turns out to be easier after we done those trigonometry calculations. Aw, yeah! Simply put, convert from integer coordinate to Cartesian, do rotation, then convert back to our integer coordinate system.

Well, that’s one problem about Ascender’s rune system solved. But we still have plenty things to experiment with, and we need your help for that! Remember about making it fascinating? How about some suggestions in these things.

  1. What other platforming skills would you like to see?
  2. Is combining runes compelling? What rune combination do you suggest?
  3. What rune placement rule do you think is intriguing? Are there any game which you must put puzzle piece in interesting ways?
  4. Do you have any ideas to make the rune system (or even the whole game) more engaging?

If you have any thoughts, fill the comment section below and we will be very glad to hear it.

Now, for a closing, check out Ascender’s Starter Bundle: You’ll get the release version of Ascender (when it is released, of course), together with some exclusive rare items, such as digital wallpaper, soundtrack, mouse pad, and a 4GB flash disk! As a bonus, we also included 3 of our games inside! Alas, it’s for sale in Indonesia only, though.

poster-starter-bundle
Ascender starter bundle

Whew, this is the longest blog entry so far, but now is the time for us to part. Always keep this blog in sight, though, as future updates might pop up anytime soon! Thanks for reading!

 
 

Chalcedony

DEVLOG#05 – Irritating Implementation of Platforming Predicament, Part I: Basic Character Control

Hello Ascenderians!

I’m Chalcedony, the programmer of Ascender, also a part-timer in devlog writing. Programming Ascender has been a great challenge for me as none of my previous projects are of this level of difficulty. Having said that, I would like to share how complex to code Ascender is, a task that might look simple, but really it isn’t.

As you might have known by now, Ascender is a 2D explorative metroidvania-like game, with a dash of RPG elements. Well, there is actually so much to code. Besides the usual main menu, pause function, etc., which are found in almost all games, some of them are (in no particular order):

  • Character movement (how he moves, including his skills such as double jump, wall jump, etc.)
  • Environment (moving platforms, floor switches)
  • Inventory
  • Dialogues (managing who talks what given current condition, e.g. possess an item, undergone a quest, different talk between night and day)
  • Quest and event system (trigger cutscene or unlock quests when certain condition occurred)
  • Camera movement
  • AI for monsters (mainly bosses)
  • Input management (interfacing different input methods: keyboards, joysticks)
  • Rune system

FYI, rune system is an element unique to Ascender. Think of it as a crossover between jigsaw and skillset manager… You gain the abilities by placing the jigsaw pieces! This feature is so *IMPORTANT* that it deserves its own page… Keep your eyes peeled for information on future updates!

runeSystemIn-game rune system

Ascender is a platformer game, and I’ll be nice to copy-paste Wikipedia about the definition of platformer games (after all, that’s what all programmers are master at – copy-pasting).

A platform game (or platformer) is a video game which involves guiding an avatar to jump between suspended platforms, over obstacles, or both to advance the game. (taken from https://en.wikipedia.org/wiki/Platform_game)

Now, there is this guy named Rodrigo who wrote about platformer types. The original article can be found in http://higherorderfun.com/blog/2012/05/20/the-guide-to-implementing-2d-platformers/ . Summarised, depending on the implementation, there are four ways to create platformer games.

  1. Tile-based (e.g. Lode Runner)
  2. Smooth tile-based (e.g. Megaman, Super Mario, Metroid, Contra)
  3. Bitmask (e.g. Worms)
  4. Vector (e.g. Braid, Limbo)

platformerThe four means of implementing platformer games

Pop quiz. Which approach did we take?

Answer: Look at those masterpiece created by our artists! Of course they won’t go easy on us programmers – we have to implement their wildest dreams! By far only option 4 satisfy them.

Having chosen option 4, there is one critical question before we proceed any further. Will you use an existing physics engine, or will you write your own physics engine? For those who are feeling bold, option 2 may yield better result, but for time-constrained project like we have right here, we took the first approach and use Unity as the game engine.

Now I shall introduce you the very first element we have to implement: How the character moves. Moving left and right on a flat surface is as simple as it gets, you just have to apply acceleration until you hit some maximum velocity so your character won’t run too fast.

The problem begins with slope. Let me give you pointers by showing some cases that you *MIGHT* want to consider if you’re going with physics.

case1

case2

Slopes, expectation vs. reality

Running on those slopes launches your character into the air? Hey, snap out of it, physics! Now how do we cope with this problem? Use raycast! That way you can prevent jumping off the slope problem.

raycastGround

raycastNothing

Raycasting helps on ground detection

In fact, raycast might be a good solution for many problems you might encounter in developing a platformer game. Detecting switch? Shooting a projectile? Pushing blocks? If none other works you should look into raycasting. Take a look at this example showing how you *must not* push a block.

kotak

Hey, I’d like to tell much more, but look at the time! I’ve written too much for today, so let’s talk about the other game elements later! Now it’s your turn to write your thoughts on the comment box below, and hit subscribe! That’s all, folks, thanks for reading!

Chalcedony