Advertisement

How to make an Idle game or incremental game?

Started by November 05, 2017 01:22 PM
26 comments, last by CubeUser 7 years ago

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;
}

Languages I have been in touch with: Unity3D, C#, Lua, VB, VB.net, Blitz3S, BlitzMax, DarkBasic, C++

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.

Advertisement

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?

Languages I have been in touch with: Unity3D, C#, Lua, VB, VB.net, Blitz3S, BlitzMax, DarkBasic, C++

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.

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

Languages I have been in touch with: Unity3D, C#, Lua, VB, VB.net, Blitz3S, BlitzMax, DarkBasic, C++

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

 

Advertisement

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.

 

   

Languages I have been in touch with: Unity3D, C#, Lua, VB, VB.net, Blitz3S, BlitzMax, DarkBasic, C++

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.:)

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.

Languages I have been in touch with: Unity3D, C#, Lua, VB, VB.net, Blitz3S, BlitzMax, DarkBasic, C++

You can store individual values in the 10's.

So:  private int single, private int ten, private int hundred, private int thousand, private int tenthousand

score.text = tenthousand + thousand + hundred + ten + single;

This topic is closed to new replies.

Advertisement