*** This version is made during a Game Jam event, completely functional and designed to be absolutely free! ***
Want to play a game that looks cool while improving your dexterity and speed of doing math? You've found the right game! SumuZ is a simple game where you are constantly supplied with single digits letting you to get to the target number (at the top of the screen). You'll be rewarded with points and nice visual effects if you pick the correct digit adding directly to it, and the more correct digits you pick the more points you'll get. |
Believe it or not, the inspiration of this game is just a visual trick a friend told me about to indicate time constraints.
I was designing a game where the character needs to keep jumping up. But I wanted to reward skilled players for jumping up fast enough (a certain height within 50 seconds), instead of having something pushing from below to urge the jumps. My friend told me a common trick was to show a line that moves up so the character had to beat. It worked brilliantly, and for some reason I wanted to make a game that featured that line.
But then "chasing a moving line" by itself wasn't that exciting, and so I figured I should add in something for the line to catch. And so instead of the line moving, I designed things that moved towards it and the player gets to decide what to catch. The first thing that came to mind was numbers. Below are the design iterations I had:
Iteration 1 (core game logic):
To keep things simple, everything will just be single digits. And the "correct" digit each time will be one that adds up to 10 with what the player has. For example, if the player has a 1, then she needs to catch a 9. So the game essentially is to pick a digit among a group of random digits moving towards the line.
Iteration 2 (core game logic):
Adding up to just 10 turns out to be too simple, as there are only 9 combinations (need a 9 for a 1, all the way to need a 1 for a 9). So besides expanding to the range of -9 to +9 (still keeping the single-digit design), the target number can go to any possible number reachable from the number that the player has. For example, if the player has a 1, then the target number can range between -8 and 10. This new design also allows a series of numbers to be generated, using this iterative formula: T(n) = T(n-1) + Random.Range(-9, 10); //the range function returns an integer between -9 (inclusive) and 10 (exclusive).
Iteration 3 (core game logic):
Having a "correct" digit means there are "incorrect" digits. Without penalizing the player for catching an "incorrect" digit too much, a combo system rewarding catching the "correct" digit is designed instead. So each time a "correct" digit is caught, the combo count goes up, and the points are added as a function of that. And as an extra reward for dexterity, the combo will go out/deplete if the "correct" digit is not caught in time.
Iteration 4 (core game logic):
One flaw about the combo system in the last iteration is that, to guarantee sustainable combos, the "correct" digit has to be available before the time runs out. While feasible, it will take some effort in programming to guarantee that (e.g., know the "correct" digit in advance, place at least one instance to the game scene ahead). So the time constraint is removed: as long as a "correct" digit is picked, the combo builds up.
Iteration 5 (control mechanics):
The catching part is the main component of the game, and I want to do it right. I took lesson from the good-old Tetris game where you can slide a block split-seconds after it lands. To sell this effect a fade-out effect is used: during the "catching" the digit fades out, and if the player moves away from it before it completely fades out, it will not be caught.
Iteration 6 (control mechanics):
The fade-out effect in the last iteration turns out to be too subtle towards the end. It's hard to determine visually from the fade that the digit is caught or not. So instead a progress-ring is used to indicate the time the player needs to stay to catch the digit.
I was designing a game where the character needs to keep jumping up. But I wanted to reward skilled players for jumping up fast enough (a certain height within 50 seconds), instead of having something pushing from below to urge the jumps. My friend told me a common trick was to show a line that moves up so the character had to beat. It worked brilliantly, and for some reason I wanted to make a game that featured that line.
But then "chasing a moving line" by itself wasn't that exciting, and so I figured I should add in something for the line to catch. And so instead of the line moving, I designed things that moved towards it and the player gets to decide what to catch. The first thing that came to mind was numbers. Below are the design iterations I had:
Iteration 1 (core game logic):
To keep things simple, everything will just be single digits. And the "correct" digit each time will be one that adds up to 10 with what the player has. For example, if the player has a 1, then she needs to catch a 9. So the game essentially is to pick a digit among a group of random digits moving towards the line.
Iteration 2 (core game logic):
Adding up to just 10 turns out to be too simple, as there are only 9 combinations (need a 9 for a 1, all the way to need a 1 for a 9). So besides expanding to the range of -9 to +9 (still keeping the single-digit design), the target number can go to any possible number reachable from the number that the player has. For example, if the player has a 1, then the target number can range between -8 and 10. This new design also allows a series of numbers to be generated, using this iterative formula: T(n) = T(n-1) + Random.Range(-9, 10); //the range function returns an integer between -9 (inclusive) and 10 (exclusive).
Iteration 3 (core game logic):
Having a "correct" digit means there are "incorrect" digits. Without penalizing the player for catching an "incorrect" digit too much, a combo system rewarding catching the "correct" digit is designed instead. So each time a "correct" digit is caught, the combo count goes up, and the points are added as a function of that. And as an extra reward for dexterity, the combo will go out/deplete if the "correct" digit is not caught in time.
Iteration 4 (core game logic):
One flaw about the combo system in the last iteration is that, to guarantee sustainable combos, the "correct" digit has to be available before the time runs out. While feasible, it will take some effort in programming to guarantee that (e.g., know the "correct" digit in advance, place at least one instance to the game scene ahead). So the time constraint is removed: as long as a "correct" digit is picked, the combo builds up.
Iteration 5 (control mechanics):
The catching part is the main component of the game, and I want to do it right. I took lesson from the good-old Tetris game where you can slide a block split-seconds after it lands. To sell this effect a fade-out effect is used: during the "catching" the digit fades out, and if the player moves away from it before it completely fades out, it will not be caught.
Iteration 6 (control mechanics):
The fade-out effect in the last iteration turns out to be too subtle towards the end. It's hard to determine visually from the fade that the digit is caught or not. So instead a progress-ring is used to indicate the time the player needs to stay to catch the digit.
Iteration 7 (control mechanics):
Originally the control scheme was digits falling towards the line near the bottom, player moving her finger left or right to catch the desired digit. However, the falling part turns out to be problematic because the finger will cover the digits, so it's hard to tell the state of the game. Also, there was no way to speed up the fall in case the desired digit is found, or slow down the fall if things got too complicated. So this iteration changes the control scheme into: digits going upwards (also matches the "bubble-up" metaphor), and up or down finger movement control the speed of the rise.
One interesting thing I want to share here is how the progress-ring animation is done. Instead of writing code that draws part of a ring over time, I use a shader to render part of the "ring" transparent over time:
Originally the control scheme was digits falling towards the line near the bottom, player moving her finger left or right to catch the desired digit. However, the falling part turns out to be problematic because the finger will cover the digits, so it's hard to tell the state of the game. Also, there was no way to speed up the fall in case the desired digit is found, or slow down the fall if things got too complicated. So this iteration changes the control scheme into: digits going upwards (also matches the "bubble-up" metaphor), and up or down finger movement control the speed of the rise.
One interesting thing I want to share here is how the progress-ring animation is done. Instead of writing code that draws part of a ring over time, I use a shader to render part of the "ring" transparent over time:
Shader "Custom/RadialProgress" {
Properties {
_Color ("Tint", Color) = (1,1,1,1)
_MainTex ("Base (RGB)", 2D) = "white" {}
_Progress ("Progress (Float)", Range (0, 1)) = 0
}
SubShader {
Tags {"Queue" = "Transparent" }
Pass {
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float _Progress;
uniform fixed4 _Color;
float4 frag(v2f_img i) : COLOR {
float4 result = tex2D(_MainTex, i.uv);
//swapping the parameters for atan2 (it expects y then x)
// effectively rotates the angle by 90-degree
float angle = atan2(i.uv.x-0.5, i.uv.y-0.5);
//if the angle is greater than the threshold, make it transparent
//e.g. zero progress makes the threshold 0, so any +angle will be transparent
//adding the abs treatment to the angle makes the change symmetric
//flipping the comparison symbol reverses the visual effect (0->full, 1->empty)
if(abs(angle) < _Progress * 3.1416) {
result.a = 0;
}
return result*_Color;
}
ENDCG
}
}
}
Properties {
_Color ("Tint", Color) = (1,1,1,1)
_MainTex ("Base (RGB)", 2D) = "white" {}
_Progress ("Progress (Float)", Range (0, 1)) = 0
}
SubShader {
Tags {"Queue" = "Transparent" }
Pass {
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float _Progress;
uniform fixed4 _Color;
float4 frag(v2f_img i) : COLOR {
float4 result = tex2D(_MainTex, i.uv);
//swapping the parameters for atan2 (it expects y then x)
// effectively rotates the angle by 90-degree
float angle = atan2(i.uv.x-0.5, i.uv.y-0.5);
//if the angle is greater than the threshold, make it transparent
//e.g. zero progress makes the threshold 0, so any +angle will be transparent
//adding the abs treatment to the angle makes the change symmetric
//flipping the comparison symbol reverses the visual effect (0->full, 1->empty)
if(abs(angle) < _Progress * 3.1416) {
result.a = 0;
}
return result*_Color;
}
ENDCG
}
}
}
To use it, assign it to a material, and control the degree of opening using mat.SetFloat("_Progress", progress); //progress is 0f to 1f.
Overall, it was a very good thought/design/implementation exercise for me. And I really like the simplicity of the game. Another thing I like about this game is the constraint I imposed: only use monotonic colors (black & white, and a fade out shading). It's very cool too see how much one can do even with just a two-tone color scheme (e.g., animation, speed, ...etc).
This particular version was made in a Game Jam event, and I have made it available on Google PlayStore for free. I might make a separate "Pro version" with waaaaay more cool elements for a low price, but this one will do for now.
Overall, it was a very good thought/design/implementation exercise for me. And I really like the simplicity of the game. Another thing I like about this game is the constraint I imposed: only use monotonic colors (black & white, and a fade out shading). It's very cool too see how much one can do even with just a two-tone color scheme (e.g., animation, speed, ...etc).
This particular version was made in a Game Jam event, and I have made it available on Google PlayStore for free. I might make a separate "Pro version" with waaaaay more cool elements for a low price, but this one will do for now.