CubeUser

Unity How to make an Idle game or incremental game?

Recommended Posts

Hello, I am trying to get a grasp on those "Idle games/Clicker games" or "Incremental games". I want to write one in Unity3D, but I am not sure how to deal with those high numbers. I wonder how they do to present this? Does anyone here know a trick? Just to make one thing clear first though: I don't think they are all using "Arbitrary precision data types", Sure you _can_ use them but that would probably be like using military/space spec. components in a game console (you _can_ but very much more expensive (creepingly slow in this case)). There are several games out there from several companies, for several platforms, including small battery driven devices, and those do simply not have the power to shuffle that much data without becoming too battery/CPU hungry. So hence I am sure they must have different solutions. So is there any idea on how to implement this _without_ using "Arbitrary precision"? I have googled for a clear description with well commented C# code for use with Unity3D but nothing. Some Youtube video however suggested that for each "Exponent" they divided or multiplied the main number with 1000 but that was not explained either fully. And asking Hyper Hippo would not work I am sure. (As for the rest of the game I am sure there are tutorials, how difficulty is controlled and so on.)
I intend to use Unity3D/C#

Share this post


Link to post
Share on other sites

So you never said what the problem with high numbers is for you so I am assuming that you reached the int limit: 2,147,483,647

First thing. If you use values like a 100 for each tic/click/whatEver then keeping score and dividing by 100 is a easy way to store data.

So player does 2 click gets score as 200 you divide by 100 and store the int as 2. So you store the clicks not the score.

 

The whole point behind making a clicker game is to solve the problem of storing numbers, so read the following at your own risk:

Spoiler

 

The common way of storing numbers like this is to use tens, I forgot what it's called but here is a example:


int one;
int ten;
int hundred;
int thousand;

//So we can store player score as:
//player score = 1500
thousand = 1;
hundred  = 5;
ten      = 0;
one      = 0;

Debug.Log(string.Format("Player Score: {0}{1}{2}{3}", thousand, hundred, ten, one));
//Returns: "Player Score: 1500"

As you can see there is no limit to the above system and all you need to do is add a new int for every new digit. Because each only uses 0-9 you never cross the int limit.

 

 

Share this post


Link to post
Share on other sites

That's one problem yes, the limit. Another is, how to have multiple "adders"? (Called "Profits" in AdCap), All of those need to be able to store data the same way, and also, how to do maths between this, for example if an adder is supposed to multiply it's value by a vertain number. Doing one of the four calculation operations (+-*/) on them, they need to be compatible somehow. But how to do that?

Share this post


Link to post
Share on other sites
1 hour ago, CubeUser said:

That's one problem yes, the limit. Another is, how to have multiple "adders"?

You would make a class for handling the numbers.

That class would have a get and a set function. Inside the class you would store numbers like that but when dealing with the math you would getplayer score as a structure made from those numbers. You would do the math per int channel and then store it back again.

Share this post


Link to post
Share on other sites
Just now, Scouting Ninja said:

You would make a class for handling the numbers.

That class would have a get and a set function. Inside the class you would store numbers like that but when dealing with the math you would getplayer score as a structure made from those numbers. You would do the math per int channel and then store it back again.

How would all that look like? How would the math be done?

Share this post


Link to post
Share on other sites
4 hours ago, CubeUser said:

How would all that look like? How would the math be done?

Piece by piece. You would use an array to make things smoother.

Tried and tested:

Spoiler

 


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour {
	//This is a class
	public class KeepScore
	{
		//Here we define our variables
		public int[] ThousandMax; //The [] is a array
        
        //When we create a new copy we can input these values. Note it's the class input
        //It has the same name as the class
		public KeepScore(int InThousands, int InHundreds, int InTens, int InOnes) 
		{
          //Here we say how many itmes is in the array then what each is
			ThousandMax = new int[4];
          
			ThousandMax[0] = InThousands;//arrays start at 0 so our 4 array is 0-3
			ThousandMax[1] = InHundreds;
			ThousandMax[2] = InTens;
			ThousandMax[3] = InOnes;
		}
		//The above class now keeps the score
	}

	//We make a normal function to add the scores piece by piece
	public KeepScore AddTwoScores(KeepScore InScoreA, KeepScore InScoreB){
      
		KeepScore OutScore = new KeepScore
			InScoreA.ThousandMax[0] + InScoreB.ThousandMax[0],//Add the Thousands
			InScoreA.ThousandMax[1] + InScoreB.ThousandMax[1],//Add the Hundreds
			InScoreA.ThousandMax[2] + InScoreB.ThousandMax[2],//Add the Tens
			InScoreA.ThousandMax[3] + InScoreB.ThousandMax[3]);//Add the ones
		
		//Next we check if one value exceeds 9
		int IndexCounter = 0;
		foreach ( int increment in OutScore.ThousandMax){
			if (increment > 9) {
				OutScore.ThousandMax[IndexCounter] -= 10;//if it does subtract 10
				if (IndexCounter > 0){ //Don't add if it is more than a thousand 0 is the first array item and is thousand
					OutScore.ThousandMax[IndexCounter-1] +=1; //Remember the larger number is lower in the array
				} 
			}
			IndexCounter +=1;
		}

			return OutScore; //Return it as a score
	}
	//Lets make a string converter
	public string ScoreToString(KeepScore InScore){
		string OutString = string.Format ("{0}{1}{2}{3}", InScore.ThousandMax[0], InScore.ThousandMax[1], InScore.ThousandMax[2], InScore.ThousandMax[3]);
		return OutString;
	}

	//now lets use what we made
	void Start(){//Unity calls this at the start
		//Make two scores
		KeepScore Player1Score = new KeepScore (1,2,0,0);
		KeepScore Player2Score = new KeepScore (0,9,0,0);

		KeepScore Total = AddTwoScores (Player1Score, Player2Score);

		print(ScoreToString(Total)); //returns : 2100

		//Now lets try to break it
		Player1Score = new KeepScore (9,9,9,9);
		Player2Score = new KeepScore (9,9,9,9);

		Total = AddTwoScores (Player1Score, Player2Score);

		print(ScoreToString(Total)); //returns : 9998 because it is 1-9998 but we don't support that much
	}
}

 

 

 

 

You could also do it as a function in the class. 

Here I turned the add function to auto so that you don't have to type each one. I just wanted to show how it works first.

Spoiler

 


	public KeepScore AddTwoScores(KeepScore InScoreA, KeepScore InScoreB){
		KeepScore OutScore = new KeepScore(0,0,0,0); //Make a empty one
		int IndexCounter = 0;
		foreach (int increment in OutScore.ThousandMax){
          //##########Change###############
			//Add each value
			OutScore.ThousandMax[IndexCounter] = 
				InScoreA.ThousandMax [IndexCounter] + InScoreB.ThousandMax [IndexCounter];//Add the increment
          //##########Change###############

			//Next we check if one value exceeds 9
			if (OutScore.ThousandMax[IndexCounter] > 9) {
				OutScore.ThousandMax[IndexCounter] -= 10;//if it does subtract 10
				if (IndexCounter > 0){ //Don't add if it is more than a thousand 0 is the first array item and is thousand
					OutScore.ThousandMax[IndexCounter-1] +=1; //Remember the larger number is lower in the array
				} 
			}

			IndexCounter += 1;
		}

			return OutScore; //Return it as a score
	}

 

 

If I do any more than this for you it would be my game. Good luck :)

Share this post


Link to post
Share on other sites

Thank you :-) It's quite a lot so I will save this to disk. In the now obsolete Microsoft VisualBasic 6 there was a data type called "Double" that could save really huge values, it could reach as far as "Adventure Capitalist". But I am not sure if that data type is in Unity C# and if it is, I doubt it is possible to cast the values to a string to check what number somes after "+E" to control things or translate. I guess it was there for some database purpose. I will experiment and see if I can find something similar once I get this you helped me with clear :-D

Share this post


Link to post
Share on other sites
1 hour ago, CubeUser said:

"Double" that could save really huge values

They are in all languages that I know.

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/double

10 hours ago, Scouting Ninja said:

So you never said what the problem with high numbers is for you so I am assuming that you reached the int

That is why I wrote this. I assumed you knew there was doubles and longs but for some reason could not use them. So I showed that way instead.

 

Edit:

I feel I should clear up something.

Doubles are inaccurate and Longs don't store much higher numbers.

int     = int32 = 2 147 483 647

long = int64 = 9 223 372 036 854 775 807

So if you started your game in the thousands it isn't that long before it breaks past int64.

 

Doubles are unstable and in your game this will matter.

for example: 1/3 will produce 0.333 to what ever number the double can hold. However it will be wrong because it's a infinite number stored on a finite computer.

To take advantage of the doubles storing you need to devide, so sooner or later you will get mistakes. Because the integer part of a double has a similar limit to a int64.

Also subtracting a double from a double will often lead to inaccuracies.

 

For this reason games that use large numbers often use the system I showed before.

Edited by Scouting Ninja

Share this post


Link to post
Share on other sites
On 2017-11-06 at 1:49 AM, Scouting Ninja said:

They are in all languages that I know.

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/double

That is why I wrote this. I assumed you knew there was doubles and longs but for some reason could not use them. So I showed that way instead.

 

Edit:

I feel I should clear up something.

Doubles are inaccurate and Longs don't store much higher numbers.

int     = int32 = 2 147 483 647

long = int64 = 9 223 372 036 854 775 807

So if you started your game in the thousands it isn't that long before it breaks past int64.

 

Doubles are unstable and in your game this will matter.

for example: 1/3 will produce 0.333 to what ever number the double can hold. However it will be wrong because it's a infinite number stored on a finite computer.

To take advantage of the doubles storing you need to devide, so sooner or later you will get mistakes. Because the integer part of a double has a similar limit to a int64.

Also subtracting a double from a double will often lead to inaccuracies.

 

For this reason games that use large numbers often use the system I showed before.

Do why not implement a division routine that that divides the double value and then truncates like for instance  "int(value1*100)/3"/10?  (Somehow the result should be cast back to a double). I mean anything divided with 3 will be inaccurate anyway sooner or later anyway  as it is an infinite number of 3's. I also searched the web for Adventure Cppitalist and "double" and it came up that someone said it uses that type. Also there are more things to the original method you mentioned: Those large values are also found in upgrades, their prices and also how they influence the "Score". They must be able to also subtract, multiply and divide. How are those operations done on your array example?

Edited by CubeUser

Share this post


Link to post
Share on other sites
9 hours ago, CubeUser said:

Do why not implement a division routine that that divides the double value and then truncates like for instance  "int(value1*100)/3"/10?

Because you convert to a int. So you lose the precision of the double. If you use a int at any time it will become your bottleneck.

You will basically cut away the number if it's larger than what the int can take. For example:

double MyDouble = 0.1 111 111 111 999
MyDouble  * 10 000 000 000 000 = 1 111 111 111 999

(int)MyDouble * 10 000 000 000 000 = -2147483648 //This is the int failing to store the value of the double.

So using your above trick you would be limited to what a int can store. So your back to problem one, int can't store much.

9 hours ago, CubeUser said:

. I mean anything divided with 3 will be inaccurate anyway sooner or later anyway  as it is an infinite number of 3's.

Yes exactly. You can't use a computer to divide by 3. It's one of the common problems you will get while working with games.

To avoid division errors you can use multiplication  1 /2 = 1 *0.5 = 0.5;    100 *0.5 = 50;

This keeps things in what number system you are using because 1/3 =0,3333333(float) but 1 * 0.333  = 0.333. So it's a easy way to limit numbers without using int or min and max.

9 hours ago, CubeUser said:

I also searched the web for Adventure Cppitalist and "double" and it came up that someone said it uses that type.

You are free to use it. It's your own choice. Doubles should do all you need.

9 hours ago, CubeUser said:

their prices and also how they influence the "Score". They must be able to also subtract, multiply and divide. How are those operations done on your array example?

Piece by piece using basic math. So 120 /2 

The key is to work from the Ones upwards.

Ones 0/2 = 0;

Tens 2/2 = 1;

Hundreds  1/2= 0.5; // We use a if statement to send the 5 to the tens.// Tens is now 6

= 0 6 0 = 120 /2 = 60;

555 / 4 = 138.75

Ones 5/4 = 1.25 // We discard the 0.25 as it isn't supported.

Tens 5/4  = 1.25 // We discard 0.05 but keep the 2 as a one// Ones is now 3

Hundreds = 1.25// We add 2 to Tens and 5 to ones. // Tens is now 3 // Ones is now 8

= 1 3 8 = 555/4 = 138.

 

This system has a name I just can't remember what it is. It's used in large 3D games to keep track of measurements. Like in space games. In fact I learned it for space games. I had whole planets shaking around in space because of the doubles.

 

This number system Is a shortcut. Where instead of trying to store data smartly on your PC, you hack it and store each ten in it's own 2-4 bytes. A googol is 1 to the 100th power. You would need a 101 int to store it using the system I showed. That is 4* 101 = +/- 404bytes depending on many factors, less than a single profile picture.

A googol is 101 digits, looks like this 10,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000

A double can store 52 + 971 = 1023 digits. More than 10 googols.

So for a game where players only see the numbers they won't notice the errors of the doubles. You can use them safely.

Again, your original question did not make clear your problem, so I assumed you had problems with using doubles and decimals.

Edited by Scouting Ninja

Share this post


Link to post
Share on other sites

It's interesting to know this. Also "borrowing" for subtraction would be done I guess? Good for space games as you said, but I am not sure if I need that for an incremental game, because I doubt it will matter as I will only be using double, unless I can extract the espression "+E15" or anything, and "scan" the number after the "E" to controll the "xx-illion". I am still not sure how to extract that so a "case" can be used to present this in a readable manner. Also I googled a lot about this and found there are many extremely complecated formulae and applying them to a Double would be easier than to an array like that I think.

As for your claim that "double" would not hold precision enough, I did a test that repeatedly divided 10+E301 (max) down to way below 0.1 by 33 and then I multiplied it by 33 up again repeating the same amount of multiplications. I even added square and square root to the test and with all tests I ended up with a number that was the exactly same down to several decimals, those can be cut away according to some googling

(javascript implementation)

function prettify(input){
    var output = Math.round(input * 1000000)/1000000;
    return output;
}

Share this post


Link to post
Share on other sites
2 hours ago, CubeUser said:

As for your claim that "double"

//Rextester.Program.Main is the entry point for your code. Don't change it.
//Compiler version 4.0.30319.17929 for Microsoft (R) .NET Framework 4.5

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //Your code goes here
            Console.WriteLine("Hello, world!");
            double FirstValue  = 0.121412;
            double SecondValue = 0.121411;
            //int FirstInt =
            
            Console.WriteLine(((FirstValue - SecondValue)*1000000).ToString()); 
          // returns 1,000000000001
            
            FirstValue  = 0.144421412;
            SecondValue = 0.144421411;
          
            Console.WriteLine(((FirstValue - SecondValue)*1000000000).ToString());
          //returns 0,999999999473644
            
            FirstValue  = 0.2147483647;//int max
            SecondValue = 0.2147481080;//int max -2567
          
            Console.WriteLine(((FirstValue - SecondValue)*10000000000).ToString());
          //returns 2567,00000006438
            
          //################################################//
            //FirstValue  = 0.214748364710000000000;//
            //SecondValue = 0.214748108010000000000;// -2567
          
            //Console.WriteLine(((FirstValue - SecondValue)*1000000000000000000000).ToString());
          //returns Integral constant is too large
            //Doesn't work because the int is too large. So from here we can't shorten our answer
          //###############################################//  
            FirstValue  = 0.214748364710000000000;// 
            SecondValue = 0.214748108010000000000;// -0.0000002567 or 2,567 e-07
          
            Console.WriteLine(((FirstValue - SecondValue)).ToString());
          //returns 2,56700000006438E-07 is 0.0000002567 or 2,567 e-07
            
            FirstValue  = 0.111111122220000000000;//
            SecondValue = 0.111111111110000000000;// -0.0000001111 or 1,111 e-07
          
            Console.WriteLine(((FirstValue - SecondValue)).ToString());
          //returns 1,11100000033115E-08  = 0.00000001111 is 0.0000001111/ 1,111E-07 //reduced it by a whole digit
          
            //The last one was shocking but I tried the math many times and it did indead go from e-7 to e-8
            //It's the same as going from 1 000 to 100
          
            FirstValue  = 0.23148811122220000000000;//
            SecondValue = 0.23148811111110000000000;// -0.000000001111 /e-09
          
            Console.WriteLine(((FirstValue - SecondValue)).ToString());
          //returns 1,11100018074239E-10 //reduced it by a whole digit again.
        }
    }
}

As you can see it is no claim, it's a fact. I used a online compiler, you can just copy and paste this to see what you get.

http://rextester.com/

2 hours ago, CubeUser said:

that was the exactly same down to several decimals

The decimals is your problem. Remember that you plan on using it to store large values that can't be stored in a int. That means you would have to depend on the double.

The error starts small but as the numbers grow and the complexity of the math the numbers get less accurate.

2 hours ago, CubeUser said:

(javascript implementation)

function prettify(input){
    var output = Math.round(input * 1000000)/1000000;
    return output;
}

Won't help. Because look at my above code. By the time we reached values where a double is needed, after the //###// mark the number went out by 10, round would just keep that mistake. Once we start working with larger numbers it will go out by much more.

Also the multiplication part will only work while there is space in the doubles integer, a double's integer is a long integer. So when a long can't hold the value the multiplication won't work.

A much easier way to solve this is to use a long/ 64int. Then when you reach the point where you need a double you just switch to one.

 

For the most part you can ignore the double's error. Who cares if they get 10000000000 or 100000000000 to the human eye it looks the same.

Edited by Scouting Ninja

Share this post


Link to post
Share on other sites

I am not really sure where you would get. I take it that once rounded just once, it starts to grow "errors". But if I don't use int at all in any place, this should not matter, or why is double at all available as a data type if it is this incorrect? And also, it's MUCH easier to apply those complex maths involved in idle games with a double than with that array. I guess that java script was a demonstration on how to prepare the values for display only. Not to be calculated with. But I will experiment with the array too ofcourse. And I calculated those values with a calculation software and got 1,111e-10. Should it be that? In the software, the number was  0,0001 or so larger. But how can that matter in a game?

Share this post


Link to post
Share on other sites
2 hours ago, CubeUser said:

why is double at all available as a data type if it is this incorrect?

Because it's more accurate. Double stands for double precision. Yes that's right, the errors we get is accuracy.

Just to note, because I don't know if you checked the link of variables: it's short, integer, long. Followed by: Float, Double, Decimal.

As in Decimals are more accurate at the cost of more performance. As in the doubles took 0.09sec, Decimals took 0.14 sec. Same code but now we get the right answers:

Spoiler

 


//Rextester.Program.Main is the entry point for your code. Don't change it.
//Compiler version 4.0.30319.17929 for Microsoft (R) .NET Framework 4.5

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //Your code goes here
            Console.WriteLine("Hello, world!");
            Decimal FirstValue  = 0.121412m;
            Decimal SecondValue = 0.121411m;
            //int FirstInt =
            
            Console.WriteLine(((FirstValue - SecondValue)*1000000m).ToString()); 
          // returns 1,000000
            
            FirstValue  = 0.144421412m;
            SecondValue = 0.144421411m;
          
            Console.WriteLine(((FirstValue - SecondValue)*1000000000m).ToString());
          //returns 1,000000
            
            FirstValue  = 0.2147483647m;//int max
            SecondValue = 0.2147481080m;//int max -2567
          
            Console.WriteLine(((FirstValue - SecondValue)*10000000000m).ToString());
          //returns 2567,0000000000
            
            FirstValue  = 0.214748364710000000000m;// 
            SecondValue = 0.214748108010000000000m;// -0.0000002567 or 2,567 e-07
          
            Console.WriteLine(((FirstValue - SecondValue)).ToString());
          //returns 0,000000256700000000000
            
            FirstValue  = 0.111111122220000000000m;//
            SecondValue = 0.111111111110000000000m;// -0.0000001111 or 1,111 e-07
          
            Console.WriteLine(((FirstValue - SecondValue)).ToString());
          //returns 0,00000011110000000000
          
            //The last one was shocking but I tried the math many times and it did indead go from e-7 to e-8
            //It's the same as going from 1 000 to 100
          
            FirstValue  = 0.23148811122220000000000m;//
            SecondValue = 0.23148811111110000000000m;// -0.000000001111 /e-09
          
            Console.WriteLine(((FirstValue - SecondValue)).ToString());
          //returns 0,00000000011110000000000
        }
    }
}

 

 

 

In Java they are called "bigdecimal" I think. In short they are 128 bit.

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/value-types

Learn them and decide what you want to use.

Edited by Scouting Ninja

Share this post


Link to post
Share on other sites
7 hours ago, Scouting Ninja said:

Because it's more accurate. Double stands for double precision. Yes that's right, the errors we get is accuracy.

Just to note, because I don't know if you checked the link of variables: it's short, integer, long. Followed by: Float, Double, Decimal.

As in Decimals are more accurate at the cost of more performance. As in the doubles took 0.09sec, Decimals took 0.14 sec. Same code but now we get the right answers:

  Hide contents

 



//Rextester.Program.Main is the entry point for your code. Don't change it.
//Compiler version 4.0.30319.17929 for Microsoft (R) .NET Framework 4.5

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //Your code goes here
            Console.WriteLine("Hello, world!");
            Decimal FirstValue  = 0.121412m;
            Decimal SecondValue = 0.121411m;
            //int FirstInt =
            
            Console.WriteLine(((FirstValue - SecondValue)*1000000m).ToString()); 
          // returns 1,000000
            
            FirstValue  = 0.144421412m;
            SecondValue = 0.144421411m;
          
            Console.WriteLine(((FirstValue - SecondValue)*1000000000m).ToString());
          //returns 1,000000
            
            FirstValue  = 0.2147483647m;//int max
            SecondValue = 0.2147481080m;//int max -2567
          
            Console.WriteLine(((FirstValue - SecondValue)*10000000000m).ToString());
          //returns 2567,0000000000
            
            FirstValue  = 0.214748364710000000000m;// 
            SecondValue = 0.214748108010000000000m;// -0.0000002567 or 2,567 e-07
          
            Console.WriteLine(((FirstValue - SecondValue)).ToString());
          //returns 0,000000256700000000000
            
            FirstValue  = 0.111111122220000000000m;//
            SecondValue = 0.111111111110000000000m;// -0.0000001111 or 1,111 e-07
          
            Console.WriteLine(((FirstValue - SecondValue)).ToString());
          //returns 0,00000011110000000000
          
            //The last one was shocking but I tried the math many times and it did indead go from e-7 to e-8
            //It's the same as going from 1 000 to 100
          
            FirstValue  = 0.23148811122220000000000m;//
            SecondValue = 0.23148811111110000000000m;// -0.000000001111 /e-09
          
            Console.WriteLine(((FirstValue - SecondValue)).ToString());
          //returns 0,00000000011110000000000
        }
    }
}

 

 

 

In Java they are called "bigdecimal" I think. In short they are 128 bit.

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/value-types

Learn them and decide what you want to use.

I tried to calculate something that would end up with the value 1,e+21 in Windows calculator. This ended up with an error: Value too large. But a "Double" can handle it despite those errors. I suspect those errors are not that severe, at least not in Adventure Capitalist, I tried once to buy something costing 1.34 Quintillion I guess, I had just that value but yet, not until it was almost 1.35 quintillion or something, that thing was able to be purchased. So I don't know. Going through the hassle with advanced calculations, including Square Root (For Prestige points) using endless arrays of "ints" like you suggested (How is that even possible without writing a CPU emulator of some sort?), or deal with small errors, a few hundred gold points would that matter indeed when you have around quintillions? I wish Unity3D had a template for these kind of games, because it is so popular and I seen templates for other genrtes, including puzzle.

Untitled.png

Edited by CubeUser

Share this post


Link to post
Share on other sites
20 minutes ago, CubeUser said:

How can I implement that in Unity3D? If there is already such a data type in Unity,

It's in the language you use. Java will have BigDecimal and C# will have Decimal. You can just google how to use it but here is the short.

//Java
BigDecimal MyBigDecimal = new BigDecimal("0.0000001"); or BigDecimal MyBigDecimal = new BigDecimal(0.0000001); //The quotes sets a limit 

//C#
Decimal MyDecimal = new Decimal(0.0000001m) //Note the m. It's f-Float d-Double m-Decimal

 

Share this post


Link to post
Share on other sites

Well what I tried to show was that this "decimal" was not "big" enough for storing more than around 28 exp. It is used mostly with real money. I think it's why "m" is used as suffix.

(-7.9 x 1028 to 7.9 x 1028) / (100 to 1028)

28-29 significant digit

As I said the method you describe looks great for storing infinite numbers, but as for those advanced calculations involved with idle games, prestige points, bonuses logaritms etcetera, it starts to get really troublesome. That was why I think double would work better. How severe would those "errors" be in a scenario that it is used in an idle game? Either a double or some kind of "library" that works with Unity3D that has such data type.

 

   

Share this post


Link to post
Share on other sites
2 hours ago, CubeUser said:

How severe would those "errors" be in a scenario that it is used in an idle game?

Your errors start at 1 000 000 000  and is in the 100 or 10. So it's a small error that can be ignored.

2 hours ago, CubeUser said:

at least not in Adventure Capitalist,

I assume they just ignore it. Most developers wouldn't put much effort into a clicker game.

2 hours ago, CubeUser said:

sing endless arrays of "ints" like you suggested (How is that even possible without writing a CPU emulator of some sort?),

Easy a int is 4 bites. It's so small it can be ignored. It only matters when your working with shaders.

Why do you think a CPU emulator would be needed and what would a CPU emulator even be? The computer is the CPU, so a CPU emulator would be a way for your CPU to be a CPU.

The int array, is a very simple work around to a problem that many games have. It's very easy to do and a shortcut.

2 hours ago, CubeUser said:

a few hundred gold points would that matter indeed when you have around quintillions?

It's more like millions while you are at quintillions. But yea, it doesn't matter much.

2 hours ago, CubeUser said:

I think it's why "m" is used as suffix.

m is used because d is used for double.

2 hours ago, CubeUser said:
(-7.9 x 1028 to 7.9 x 1028) / (100 to 1028)

28-29 significant digit

By this same calculation a double is ±5.0 × 10−324 to ±1.7 × 10308 or 15-16 digits.

It's after 16 digits that your double looses it's accuracy. It's after 29 digits that a decimal looses it's accuracy.

A double is a 64bit decimal a decimal/ Bigdecimal is a 128 bit. So Double < Decimal.

But Decimal have there own problem. That is the thing, there is no best way to do this, just the way you decide.

2 hours ago, CubeUser said:

but as for those advanced calculations involved with idle games, prestige points, bonuses logaritms etcetera

You would only make one function to deal with it. That code I uploaded first is more than 50% done.

2 hours ago, CubeUser said:

I wish Unity3D had a template for these kind of games, because it is so popular and I seen templates for other genrtes, including puzzle.

If you feel it would help you, you can hire a developer. A game like this takes about a week.

The thing is that it would have more complex function than the math for the transactions. There is a very high chance that if you looked at complete game you would have even less of an idea of what to do.

 

If you feel like using doubles then do so. Your the developer and who knows maybe the slightly unpredictable values could have a positive effect on the game.

A clicker game is very simple, your menu is going to be more complex. I wish you luck and I hope your research helps.:)

Share this post


Link to post
Share on other sites
18 minutes ago, Scouting Ninja said:

A clicker game is very simple, your menu is going to be more complex. I wish you luck and I hope your research helps.

Thank you, but the claim that it is simple to make such games is not going well together with the claim that that it would have more complex function than the math for the transactions, to me. But well I googled more and there are claims around that say a double would be enough for a game. But also other approaches. And I think lots of the games out there actually do the same. But what would be more complex than the maths? Iy's all about getting those curves to fit in in a manner that there is always something interesting to do. For example when there is no gold left for any upgrades, except for one, that one should be the one that is coming close to a mile stone.

Share this post


Link to post
Share on other sites

One int between 0-9 for each number in the total value would be an array of at least 300 elements for a "full" use idle game I guess? I would really love to see a C sharp library that works with unity that has something like that, or soe similar method to store huge values with precision like that, unless "double" works. I will start experiementing soon, I had trouble after a reinstallation that screwed the VS 2017 installation up and I had to downgrade Unity a few version numbers because of some internal server service not working.

Share this post


Link to post
Share on other sites
On 11/15/2017 at 8:47 PM, CubeUser said:

One int between 0-9 for each number in the total value would be an array of at least 300 elements for a "full" use idle game I guess?

Using arrays like this is fast and powerful, remember that repative tasks is what computers are made for.

Upgraded version of the example I showed above.

Spoiler

 


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NumberSystem : MonoBehaviour {

	//This class is made so that we can work with very large digits.
	public class BaseTen
	{
		//String for out
		public string TheBase;

		//When we make a new BaseTen() we want a string input
		public BaseTen (string NumberAsString){
		TheBase = NumberAsString;
		}


		//So we can add a base into this one
		public void AddBaseIn(BaseTen InBaseTen){
			//Wen the base is smaller we need to increase it's size
			while ( TheBase.Length - InBaseTen.TheBase.Length  < 0){//negative means TheBase smaller
				TheBase = "0"+ TheBase;
			}
			//Now add the numbers
			int Index =0;
			string tempString = "";
			sbyte[] ArrayA = new sbyte[TheBase.Length];
			foreach(char Digit in TheBase){
				//Add the two inside the array to keep it whole. 
				///We also need to start from the smallest:((x-1) - index)
				ArrayA[Index] += sbyte.Parse(TheBase.Substring((TheBase.Length - 1) - Index,1));

				if (Index < (InBaseTen.TheBase.Length)) {
					ArrayA [Index] += sbyte.Parse (InBaseTen.TheBase.Substring ((InBaseTen.TheBase.Length - 1) - Index, 1));
				} else {
					ArrayA [Index] += 0;
				}

				//Pass over the one if it's larger than 9
				if (ArrayA [Index] > 9) {
					ArrayA [Index] -= 10;
					//Add the one to the next index if there is space in the array
					if (Index + 1 <= (ArrayA.Length-1)) {
						ArrayA [Index + 1] += 1;
						tempString = ArrayA [Index] + tempString;//reverse
					} else {// if there isn't space Add 1 to the front
						tempString = ArrayA [Index] + tempString;
						tempString = "1" + tempString;
					}
				} else {//If the number is under 9
					tempString = ArrayA[Index]+tempString;//reverse
				}

				Index +=1;
			}
			TheBase = tempString;//Set the base to the new value
		}//AddBaseIn


		//To allow adding of a string to a base
		public void AddStringIn(string InBaseTen){
			//Wen the base is smaller we need to increase it's size
			while ( TheBase.Length - InBaseTen.Length  < 0){//negative means TheBase smaller
				TheBase = "0"+ TheBase;
			}
			//Now add the numbers
			int Index =0;
			string tempString = "";
			sbyte[] ArrayA = new sbyte[TheBase.Length];
			foreach(char Digit in TheBase){
				//Add the two inside the array to keep it whole. 
				///We also need to start from the smallest:((x-1) - index)
				ArrayA[Index] += sbyte.Parse(TheBase.Substring((TheBase.Length - 1) - Index,1));

				if (Index < (InBaseTen.Length)) {
					ArrayA [Index] += sbyte.Parse (InBaseTen.Substring ((InBaseTen.Length - 1) - Index, 1));
				} else {
					ArrayA [Index] += 0;
				}

				//Pass over the one if it's larger than 9
				if (ArrayA [Index] > 9) {
					ArrayA [Index] -= 10;
					//Add the one to the next index if there is space in the array
					if (Index + 1 <= (ArrayA.Length-1)) {
						ArrayA [Index + 1] += 1;
						tempString = ArrayA [Index] + tempString;//reverse
					} else {// if there isn't space Add 1 to the front
						tempString = ArrayA [Index] + tempString;
						tempString = "1" + tempString;
					}
				} else {//If the number is under 9
					tempString = ArrayA[Index]+tempString;//reverse
				}

				Index +=1;
			}
			TheBase = tempString;//Set the base to the new value
		}//AddStringIn
			

	}//Class

	BaseTen NumberA = new BaseTen ("11");//First large number
	BaseTen NumberB = new BaseTen ("22");//Second large number

	public void BtnDebug(){
		System.Diagnostics.Stopwatch Timer = new System.Diagnostics.Stopwatch();
		Timer.Start();

		NumberA.AddBaseIn(NumberB);
		print (NumberA.TheBase);

		Timer.Stop();
		Debug.Log(Timer.Elapsed);

	}
}

 

 

 

Be warned that expanding the above code will require a understanding of how the math works. You would be better off building your own version.

Numbers.thumb.jpg.117539158fe2817cbb8b277564295206.jpg

This image shows my performance test. I ran it 5 times very fast to test the time it takes. It on average it took a little more than a tenth of a second (1 second /10). That is faster than the Unity button animation.

Feel free to try it.

On 11/8/2017 at 5:06 PM, CubeUser said:

Thank you, but the claim that it is simple to make such games is not going well together

Incremental games is the basics of the basics.

A good example is that I am a artist, not a programmer. A real programmer would run my little number system here into the ground. Python is a example of what a programmer can do, there is no math function it can't run.

 

Edit:

I had to reduce the size of the number. It was causing problems with the web page. Just fill in any large numbers you want.

Edited by Scouting Ninja

Share this post


Link to post
Share on other sites
20 hours ago, Scouting Ninja said:

Using arrays like this is fast and powerful, remember that repative tasks is what computers are made for.

Upgraded version of the example I showed above.

  Hide contents

 



using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NumberSystem : MonoBehaviour {

	//This class is made so that we can work with very large digits.
	public class BaseTen
	{
		//String for out
		public string TheBase;

		//When we make a new BaseTen() we want a string input
		public BaseTen (string NumberAsString){
		TheBase = NumberAsString;
		}


		//So we can add a base into this one
		public void AddBaseIn(BaseTen InBaseTen){
			//Wen the base is smaller we need to increase it's size
			while ( TheBase.Length - InBaseTen.TheBase.Length  < 0){//negative means TheBase smaller
				TheBase = "0"+ TheBase;
			}
			//Now add the numbers
			int Index =0;
			string tempString = "";
			sbyte[] ArrayA = new sbyte[TheBase.Length];
			foreach(char Digit in TheBase){
				//Add the two inside the array to keep it whole. 
				///We also need to start from the smallest:((x-1) - index)
				ArrayA[Index] += sbyte.Parse(TheBase.Substring((TheBase.Length - 1) - Index,1));

				if (Index < (InBaseTen.TheBase.Length)) {
					ArrayA [Index] += sbyte.Parse (InBaseTen.TheBase.Substring ((InBaseTen.TheBase.Length - 1) - Index, 1));
				} else {
					ArrayA [Index] += 0;
				}

				//Pass over the one if it's larger than 9
				if (ArrayA [Index] > 9) {
					ArrayA [Index] -= 10;
					//Add the one to the next index if there is space in the array
					if (Index + 1 <= (ArrayA.Length-1)) {
						ArrayA [Index + 1] += 1;
						tempString = ArrayA [Index] + tempString;//reverse
					} else {// if there isn't space Add 1 to the front
						tempString = ArrayA [Index] + tempString;
						tempString = "1" + tempString;
					}
				} else {//If the number is under 9
					tempString = ArrayA[Index]+tempString;//reverse
				}

				Index +=1;
			}
			TheBase = tempString;//Set the base to the new value
		}//AddBaseIn


		//To allow adding of a string to a base
		public void AddStringIn(string InBaseTen){
			//Wen the base is smaller we need to increase it's size
			while ( TheBase.Length - InBaseTen.Length  < 0){//negative means TheBase smaller
				TheBase = "0"+ TheBase;
			}
			//Now add the numbers
			int Index =0;
			string tempString = "";
			sbyte[] ArrayA = new sbyte[TheBase.Length];
			foreach(char Digit in TheBase){
				//Add the two inside the array to keep it whole. 
				///We also need to start from the smallest:((x-1) - index)
				ArrayA[Index] += sbyte.Parse(TheBase.Substring((TheBase.Length - 1) - Index,1));

				if (Index < (InBaseTen.Length)) {
					ArrayA [Index] += sbyte.Parse (InBaseTen.Substring ((InBaseTen.Length - 1) - Index, 1));
				} else {
					ArrayA [Index] += 0;
				}

				//Pass over the one if it's larger than 9
				if (ArrayA [Index] > 9) {
					ArrayA [Index] -= 10;
					//Add the one to the next index if there is space in the array
					if (Index + 1 <= (ArrayA.Length-1)) {
						ArrayA [Index + 1] += 1;
						tempString = ArrayA [Index] + tempString;//reverse
					} else {// if there isn't space Add 1 to the front
						tempString = ArrayA [Index] + tempString;
						tempString = "1" + tempString;
					}
				} else {//If the number is under 9
					tempString = ArrayA[Index]+tempString;//reverse
				}

				Index +=1;
			}
			TheBase = tempString;//Set the base to the new value
		}//AddStringIn
			

	}//Class

	BaseTen NumberA = new BaseTen ("11");//First large number
	BaseTen NumberB = new BaseTen ("22");//Second large number

	public void BtnDebug(){
		System.Diagnostics.Stopwatch Timer = new System.Diagnostics.Stopwatch();
		Timer.Start();

		NumberA.AddBaseIn(NumberB);
		print (NumberA.TheBase);

		Timer.Stop();
		Debug.Log(Timer.Elapsed);

	}
}

 

 

 

Be warned that expanding the above code will require a understanding of how the math works. You would be better off building your own version.

Numbers.thumb.jpg.117539158fe2817cbb8b277564295206.jpg

This image shows my performance test. I ran it 5 times very fast to test the time it takes. It on average it took a little more than a tenth of a second (1 second /10). That is faster than the Unity button animation.

Feel free to try it.

Incremental games is the basics of the basics.

A good example is that I am a artist, not a programmer. A real programmer would run my little number system here into the ground. Python is a example of what a programmer can do, there is no math function it can't run.

 

Edit:

I had to reduce the size of the number. It was causing problems with the web page. Just fill in any large numbers you want.

Thank you, but as you say, the maths would be the issue, because for a Prestige points system, estimating the amount of prestige points will involve things like Square Root. Doing that with this method... well :-/.... So it might mean there are some libraries available somewhere for use with Unity3D, I just hope there are, if I ever want to exceed xxE+300, below XXE+300, double would probably do,  As for the "Basics" you are talking of, yes. I saw a lot of tutorial on youtube and there are web pages on how to create the curves on how "hard" the game should be (i.e how much patience it should require to play, and at some points be frustratingly slow but suddenly fast again for a little while). One person on Youtube did a very through educational video, but the game used just single so the game he claimed to have developed, some infect-the-world- type game with viruses, germs and bacteria. Just to test it, I ran that  and pushed it real hard. Not long before it showed "NaN" and stalled. As for Python, I try to avoid those languages, I am finishing a project as we speek written in one of those kind of languages, it will be the last I do with them. They are made to be easy to use, but the problem they tend to be slow and easy to make errors in them.

Share this post


Link to post
Share on other sites
1 hour ago, CubeUser said:

As for Python, I try to avoid those languages, I am finishing a project as we speek written in one of those kind of languages, it will be the last I do with them. They are made to be easy to use, but the problem they tend to be slow and easy to make errors in them.

They are slow because they have support for things C# doesn't. Browsing there libraries could give you the answers you need.

1 hour ago, CubeUser said:

estimating the amount of prestige points will involve things like Square Root. Doing that with this method... well :-/

No reason you couldn't. The system I made here is a base 10 system, as in the one we use in our day to day lives. All of the math you know can be done using this system, you just really need to understand how it works.

For example to find a Square root you would only need to know what a Square Root is.

1 hour ago, CubeUser said:

So it might mean there are some libraries available somewhere for use with Unity3D

If you find them consider sharing them with people here. 

I found a few but they all died in production or just use doubles and decimals.

The upgraded version of my code, the one using strings, was something someone else tried and gave up on. It's why I want to finish it.

 

Most suggestions and info I found on incremental games is:

Use an array system. Use the largest number set you have (Decimals) or fake it by writing "100 billion" "2 googol" and so forth.

Share this post


Link to post
Share on other sites

There got to be libraries for this, as there are many games out there. Either Double is far better in practic use in a game than it looks like when you show inconsistencies, and the games use them plus a routine that checks the end of the string for any "E+xxx" and translate it, or, there is some library they use for stuff that needs to go beyound "e+300", I have seen one of those games actually and it is written in Javascript, I have checked and there is a compiler+runtime for javascript that was included in the same folder. But as you stated, I will start looking for this. General C# libraries, how could they be made to work in Unity3D?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Forum Statistics

    • Total Topics
      628288
    • Total Posts
      2981844
  • Similar Content

    • By Simplepg
      https://play.google.com/store/apps/details?id=simple.gplay.GamesInABox
    • By Simplepg
      https://play.google.com/store/apps/details?id=simple.gplay.GamesInABox
    • By ForgedInteractive


      Who We Are
      We are Forged Interactive, a small team of like-minded game developers with the sole purpose of making games we love! We're a team of artists, animators, programmers, level designers, writers, composers, producers, and other creative minds. We want to make games that you, the modern gamer want to play! We hope to build a community that enjoys our games as much as we love creating them. With your feedback and support we will be able to achieve that.

      About the Game
      GAME NAME is a fun, action-packed army builder with unique characters, challenges and engaging levels. Set forth on an adventure to protect friends, family and countrymen from new adversaries. Once defeated your enemies turn coat and join you in your adventures. Players can enjoy a range of troops and abilities based on their gameplay style which become more important as maps introduce more challenging terrain, enemies and bosses. Strong orc knights, dangerous shamans, and even a dragon are out on the prowl. Knowing when to fight and when to run, and how to manage your army is essential. Your actions alone decide the fate of this world.

      Previous Work by Team
      Although we are working towards our first game as a team, our team members themselves have past experience in the industry.
      This includes members who have worked on titles including:
      Final Fantasy Kingsglaive, FIFA, Xcom 2 and Civilization.

      Who are we looking for? 3D Modellers Concept Artists Marketing Specialists Level Designer

      What do we expect? Reference work or portfolio. Examples what have you already done and what projects you have worked on academic or otherwise. The ability to commit to the project on a regular basis. If you are going on a two-week trip, we don't mind, but it would be good if you could commit 10+ hours to the project each week. Willingness to work with a royalty based compensation model, you will be paid when the game launches. Openness to learning new tools and techniques
      What can we offer? Continuous support and availability from our side. You have the ability to give design input, and creative say in the development of the game. Shown in credits on websites, in-game and more. Insight and contacts from within the Industry.
      Contact
      If you are interested in knowing more or joining. Please email or PM us on Skype. Myself or Colin will reply to you within 48 hours.

      E-mail: Recruitment@ForgedInteractive.com
      Skype: ForgedInteractive

      Regards,
      David and Colin

      Follow us on:

      Facebook: https://www.facebook.com/ForgedInteractive/
      Twitter: @ForgedInteract
      Youtube: https://www.youtube.com/channel/UCpK..._as=subscriber
      Reddit: https://www.reddit.com/user/Forged_Interactive/
    • By Eck
      I just saw their courses were knocked down to $10 each and figured I'd share the info here. They have stuff for Unity, Unreal, drawing, business, etc. I haven't used their stuff before, but the previews I looked at seemed pretty good and there is a user review system as well.
      https://www.udemy.com/courses/search/?q=Unity&src=ukw
      - Eck
       
  • Popular Now