MetRiko

Ludum Dare 56

We made a blob game! - Blob, To the Top!

This is definitely one of our proudest jam games. We put a lot of work and attention to detail to Blob, To The Top! and we're super proud of how it came out.

We took inspiration from World of Goo and Jump King and we ended up with something that's (hopefully) very fun to play and quite challenging ^^

Link to the game: https://ldjam.com/events/ludum-dare/56/blob-to-the-top

1.png

2.png

Blob, To the Top! is now even blobbier than before!

Hi all! We're really glad you're enjoying Blob, To the Top! After seeing people play our game and after reading all the feedback we made some small improvements to the game.

Blobs have been rewritten and the game now runs way smoother. No blobs suffered in the process.

blobs_tube.gif

Aiming is now faster, less sluggish and more precise. Blobs are happy that they will no longer hit the walls so frequently.

blobs_launch.gif

Difficulty in a few levels has been adjusted based on your feedback. Wake up! New Blob, to The Top update just dropped!

blobsemwake/emup.gif

If you haven't played Blob, To the Top! yet, check it out here: https://ldjam.com/events/ludum-dare/56/blob-to-the-top

The full changelog is also listed out on the game page.

Thank you again for all the feedback and ratings ❤️

Blobs are back with yet another patch!

Give it a try and let us know what you think!

If you missed our previous "Blob, To the Top!" post, you can read it here: https://ldjam.com/events/ludum-dare/56/blob-to-the-top/blob-to-the-top-is-now-even-blobbier-than-before

Highlights of this patch!

  • New max power indicator, which subtly shows to what extent the blob launcher can be charged. The charging mechanic should be less confusing now. You won't overshoot this time, right? Right?

blobsemnew/emindicator_4.gif

  • Blobs are now properly synchronized with the camera regardless of the frame rate. Developers were crying when it finally started working...

blobsemcamera/emopt.gif

  • Blobs will no longer get stuck in one-way platforms and will fly through them correctly from below. No blobs are left behind!

blobsemplatform/em2_opt.gif

  • Blobs now bounce off bouncy walls properly and in a more predictable manner. Check the wind, adjust the angle, and finally make stylish and mathematically correct blob shots!

blobsembounce/em2_opt.gif

  • ...and even more bugfixes, difficulty adjustments and performance boosts.

The full changelog can be found on the game's page here:

https://ldjam.com/events/ludum-dare/56/blob-to-the-top

Once again, thank you sooo much for all the feedback you left under our little blobby game :heart: Your words gave us the confidence we needed. We are now fully committed to continue working on "Blob, To the Top!", with the goal of releasing it as a full-fledged game in the future! And because you are the first to read this post... tell us what you would like to see in the full game, we will see what we can do :wink:

This is the last patch for "Blob, To the Top!". Now we would like to fully focus on playing your games! We have a very long list of games that we want to try before the voting period ends. We probably won't be able to play everything before time runs out (working on this patch and real life stuff took all of our free time).

First, we want to play all the games from people that commented on our game (just to thank for all the fantastic feedback - we appreciate every little bit of it). But for those of you who made it to the end of this post... link your game below so we will play it first right after that :grin:

And finally, a small bonus for fellow Godot developers. Our work on the blob shader synchronization (so that their position is always correct relative to the camera regardless of the frame rate) has taken our sleep away last weekend. We want to share a small tip for you so you don't have to go through the same thing we did. In short... if you want to get the camera position in the canvas_item shader, don't send it by uniform. Instead, read it directly like so:

varying vec2 v_camera_coords; void vertex() { vec2 camera_pos = vec2(CANVAS_MATRIX[3][0], CANVAS_MATRIX[3][1]); vec2 camera_zoom = vec2(CANVAS_MATRIX[0][0], CANVAS_MATRIX[1][1]); v_camera_coords = -camera_pos / camera_zoom; }

Want to learn 2D shaping with shaders?

We have good news for you!

Recently in Blob, to The Top! we added a subtle circular indicator that shows max power while charging a shoot. We mentioned it in our latest update post (check it out here; yes it has gifs :D)

This indicator was made using shaders and here is a quick step by step guide how we made it.

To start.. create a new Godot Sprite2D, put there a default icon.svg texture and create a new shader material with a code (not a shader graph!). And now it's time for code!

1. First we need a function to draw a simple circle:

c float circle(float radius, vec2 uv) { float len = length(uv); return len < radius ? 1.0 : 0.0; } We can replace ternary operator with built-in step function to simplify it, like that: c float circle(float radius, vec2 uv) { float len = length(uv); return step(len, radius); }

2. Now let's make a ring function to draw a ring.

The plan is simple.. we will draw 2 circles and remove inner circle from outer circle. To simplify some math later, instead of just subtraction operation we will use multiplication instead. c float ring(float radius, float width, vec2 uv) { float outer_circle = circle(radius, uv); float inner_circle = 1.0 - circle(radius - width, uv); return outer_circle * inner_circle; } We can optimize it a little bit by using code from the circle function directly. We can also invert result of step function just by swapping arguments inside.

c float ring(float radius, float width, vec2 uv) { float len = length(uv); float outer_circle = step(len, radius); float inner_circle = step(radius - width, len); return outer_circle * inner_circle; }

Time to test this ring function!

frament_1.png

Well.. it works! But you can see it's not very practical. We have to use normalized values and ring isn't even centered. Let's fix that by modifying UV in the vertex function.

Also for the future use, we will copy value of COLOR variable from the vertex function. It's a Godot specific feature which allows for using value of modulate property (the one from the node) directly inside a shader code within the fragment function. To "transport" value from the vertex function to fragment function we will define a special varying variable.

So in the end our vertex function will look like this: ```c varying vec4 modulate;

void vertex() { // Copy value of modulate property to new variable modulate = COLOR;

// Read a node scale from built-in matrix
vec2 node_scale = vec2(MODEL_MATRIX[0][0], MODEL_MATRIX[1][1]);

// Read texture size used in the Sprite2D node (in this case we used default 128x128 Godot icon)
vec2 tex_size = 1.0 / TEXTURE_PIXEL_SIZE; // = 128x128

// Let's change UV from range 0..1 to -64..64.
UV = (UV * 2.0 - 1.0) * tex_size * node_scale * 0.5; //0..1 -> -1..1 -> -64..64

} ```

And now we can finally use pixels as units! And also shader reacts to modulate property and circle is finally centered.

frament_2.png

3. Now it's time to make dashed ring instead of solid one.

First, to make a rotating dashed ring we will need few utility functions:

  • A. get_angle to get angle of the vector in range -PI to PI.
  • B. rotate which will return 2d transformation matrix to rotate any vector by specific angle.

3A. Let's start with get_angle function.

The proper formula would be like this: c float get_angle(vec2 vec) { vec2 base = vec2(1.0, 0.0); // Base vector from which we will calculate angle to `vec` float a = dot(vec, base); float b = determinant(mat2(vec, base)); return atan(a, b); } This might look like a dark magic but let's simplify some things. We can replace dot and determinant built-in functions with just plane formulas:

c float get_angle(vec2 vec) { vec2 base = vec2(1.0, 0.0); float a = vec.x * base.x + vec.y * base.y; float b = vec.x * base.y - vec.y * base.x; return atan(a, b); }

Isn't it more clear now? But that's not the end. We can replace base.x and base.y with numbers and in the end we will get this simple function:

c float get_angle(vec2 vec) { return atan(vec.x, -vec.y); }

Now when it's finally done..

3B. Let's write a rotate function!

This will return a basic rotation matrix. The theory works like this: if we will multiply any vector by such matrix it will be rotated by a specific angle.. simple enough, right? :D

The final rotate function will look like this: c mat2 rotate(float angle) { float s = sin(angle); float c = cos(angle); return mat2(vec2(c,-s),vec2(s,c)); } Now it's the hardest part.

4. Time to make holes in the ring to create a dashed ring.

The idea is simple: 1. Split space into N*2 squared pizza fragments. 2. Make only each odd fragment visible. 3. Let's combine our ring with pizza.

```c float pizza(float radius, int n, vec2 uv) { float deltaangle = TAU / (float(n) * 2.0); float angle = getangle(uv); float i = floor(angle / delta_angle); return float(int(i) % 2); }

float dashedring(float radius, float width, int n, vec2 uv) { float pizzashape = pizza(radius, n, uv); float ringshape = ring(radius, width, uv); return ringshape * pizzashape; } And now to add rotation we can just rotate `UV` by a specific angle using `rotate` function we already prepared. c float dashedring(float radius, float width, int n, float rotation, vec2 uv) { uv *= rotate(rotation); float pizzashape = pizza(radius, n, uv); float ringshape = ring(radius, width, uv); return ringshape * pizzashape; } ```

Let's test this thing!

fragment_3.gif

We are almost there. The only thing left is to add fading. We did it by combining two fades like so:

fragment_4.png

Aaand that's it!

I hope someone will find this helpful :D

Now you can check out the final result in our game here!

If you are interested more in our game, we have good news for you.

After such an amazing and positive feedback (again, thank you sooo much for that :heart:), we have decided to expand the game and release it as a full-fledged title! If there is something you would like to see in the final game, share your thoughts/ideas in the feedback section or under this post. We will see what we can do :grin:

Play blobs

It's hard.

No, it's not a puzzle game, it's a rage game.. kinda..

..ok not really, we have checkpoints.

But blobs are cute, only game hard.

Yes, the game is stressful.. cute and hard and stressful.

There is timer to make it more stressful, we hope you like it.

Get golden blobs, it's even harder. (They better than brown blobs, and more cute)

(We nerfed this game multiple times already. Play version 1.2 or in the browser, it's easier now)

Play blobs. Blobs hard.

.gif for attention:

pitemwith/emblobsem2/emopt_4.gif

Check out more effort posts here:

Play blobs.

Blobs are cute, only game hard.

Yes, the game is stressful.. cute and hard and stressful.

There is timer to make it more stressful, we hope you like it.

Get golden blobs, it's even harder. (Better than brown blobs, and more cute)

(We nerfed this game multiple times already. Play version 1.2 or in the browser, it's easier now)

Play blobs. Blobs squishy.

pitemwith/emblobsem2/emopt_4.gif

(This is our last post before the rating ends. We don't want to spam the feed section because some games might really need it to escape danger zone. Good luck everyone!)

Check out more effort posts here:

Thank you everyone who played our game!

I'm speechless.. this was my 2nd Ludum Dare and my teammate's 1st one.. and we got to the top 200! (*For comparison my 1st Ludum Dare game got 6 ratings... *)

score2.png

We got soooo much amazing feedback from you all, thank you! After such a positive reception of our little blobby game, just a few days after the jam we decided to continue working on it. We want to create a combination of Jump King and World of Goo that will be fun to play for everyone, with additional, harder goals for those hungry for a challenge. Currently, work and university are taking all of our time, but we would love to start working on this soon and eventually release it as a full-fledged game.

Congratulations to everyone and don't let the ratings make you unhappy! The single fact that you made it this far and finished your games in such a short time is an incredible achievement on its own! Don't let this experience go to waste--keep on game-deving and pursue your dreams!

If you haven't played "Blob, To the Top!" yet.. feel free to give our game a try and leave some feedback. We are open to read your opinion on the game, and we'd love to know what you would like to see in the final version. We are kinda skilled programmers so we might be able to pull off even the most crazy ideas :D

pitemwith/emblobsem2/emopt_4.gif