My Problem With Cryptocurrency: There’s No Room for 1

This is one of my main guidelines when designing mechanics for a game: Whatever underlying system you have, there should be some meaning to the lowest number. It doesn’t mean that you should be able to see a ‘1’ in text, in front of you, during the game, but there should be a meaning to that increment/decrement. Because, going from a 1 to a 2 might be too drastic a change in your system as that’s a 100% difference. But there should be a 3 and 4, or even just 99 and a 100. Because, if there isn’t, you’re probably just inflating numbers to make it look better and haven’t examined your systems deeply enough. And so, while I hate the way Souls-like games do it, the fact that E is lowest rank and the highest is A or S, or that the best upgrade you can get is a +10, makes every little uptick meaningful.

It started to bug me when I played Warcraft III originally. In I & II, characters had double digit HP, some big or hero characters had triple digits. But the upgrades you could make, for weapons or armor for example, were 12 to 13 or something like that. That was a meaningful upgrade. If your knights did 1 more damage per hit, they could take down an enemy in 3 strikes instead of 4 and that really upped your attack group’s survivability as well. Then, in Warcraft III, everyone started having HP in the tens and hundreds of thousands, everyone was hitting for thousands of damage. And for what? It worked basically the same except there were higher numbers. In Starcraft, if you could let that SCV repair a fraction of a second more or let that Zealot’s shield recharge a fraction of a second more, you got a few more hull or shield points and that was important.

I think it’s also the reason why I tend to get bored quickly and stay away from idle games: at the start you have to click ferociously to get one more point but then you upgrade a bit and the numbers grow so big you can’t even refer to them as real numbers anymore. The journey from 1 to 100 is massive. Even from 1,000 to 10,000 is meaningful. But when you’re at 420E39 and you want to get to 69E40, it doesn’t feel like much of a difference.

What does it have to do with Cryptocurrency? The detachment from any real-world value of currency.

The point of any currency is to replace the bartering system with something that we can all agree conveys value in an equal system. Which is also why I prefer the Big Mac Index to anything else when comparing the economy of two countries. If I toss you an exchange rate, it won’t really stick in your mind whether it uses Shekels, Pounds, Francs, Yen, or Rubels. But if you know a Big Mac costs you ~4 USD and I tell you it costs me slightly under 20 NIS, you’ve got a better comparison of what things cost in Israel and how strong the dollar is compared to the Shekel.

But what can you buy with one BTC or one ETH? I don’t know. And if you knew yesterday, you’re probably wrong today. You might be able to buy a Big Mac in New Mexico for 0.005 BTC (I don’t really know how much it is) one day but it’ll cost you 0.007 in Istanbul the next day. Because it fluctuates so much, because it has gone so far, it lost 1 in the mirror a long time ago. Because Cryptocurrency is no longer real currency (if it ever was to begin with), it’s a speculative financial product at its best and Pyramid Scam/Pipe Dream at its worst.

And then, you need to factor in “Gas” prices.

When you make a cryptocurrency transaction, it’s not just cash money changing hands. One computer (and usually a computer farm) needs to accept this transaction (and there’s usually a small bidding war for it), then use its power, its electricity cost, its runtime, its pollution, its wear and tear, to process the transaction, write it, and propagate it. And the people who do it want to be compensated for their role in it. At time of writing, this price was fluctuating between 2-5$ depending on where you were checking on which currency. I couldn’t find confirmation but I remember that at one time it was 200$. Meaning, that is the added cost for each time you want to transfer cryptocurrency. So, if you want to make a 1$ transaction, you’re actually paying 6 times as much for the privilege, another few dollars just gone. Then, why would you make a transaction lower than, say, a hundred dollars, where the gas price is worth the amount your sending?

Which is exactly where we lose the meaning of 1 and where we get away from something that is usable by everyone. If you can’t buy a loaf of bread or a dozen eggs with it, it’s not usable by everyone. It’s not currency anymore, it’s detached from real world value, it’s a speculative tool for the rich and/or stupid. And since it’s not tangible, not even an abstract representation of value (like a stock that gives you partial ownership of something), it’s useless in the real world.

And NFTs are built on the same concept, just one level more abstract (and ridiculous). While there are established places where you can convert your cryptocurrency into real money and vice versa (and the transaction is probably always in the changer’s favor), for an NFT to be valuable, you have to convince someone else to pay you for it. And since it’s a just a reciept that points to a URL online that you can access freely anyway, what does it really matter that you “own” it? That is why you get stories like these of people selling themselves their own NFTs to drive up the prices. By the way, It’s called a “wash trading scam”, and it was very prevalent in stock trading until it was outlawed.

That’s it. Rant over. But if you want to know more, I highly recommend this video by Folding Ideas. It is long (over 2 hours) but he goes in very deep on Cryptocurrency and NFTs and it’s the best explanation of the whole thing that I’ve seen so far.

Over here is a shorter video (only 30 minutes) by Christopher Natsuume that explains my all of this is bad for the gaming sphere and why any game that builds NFTs into its scheme is just going to be a bad game that hurts its players.

And I want to add another thing after the rant on NFTs in video games: No company in their right mind will want to allow you to take something they made, their intellectual property, and do with it what you want in another company’s game without benefitting from it. So, if they want to keep it in-house, they have their own servers, their own code, they don’t need NFTs. We’ve seen it done before. And if two companies would like to participate in a scheme like this for a specific reason… something like, I don’t know… cross-promotion, then that is also something that is already being done (Fall Guys and Shovel Knight are the biggest examples that come to mind) and doesn’t need NFTs.

Posted in Life by with no comments yet.

Useful C# Features (or “Cool Things You Didn’t Know You Could Use in Unity”)

1. Tuples & Discards!

Tuples is something more dynamic languages like JavaScript have been holding over the more static languages for a while. It allows you to do more with less action (higher level ones, that is). While tuples have existed in C# before as a class of their own, they are now getting a proper implementation. It basically makes a complex variable/object without having to predefine it using a class or a struct.

var alphabetStart = (Alpha: "a", Beta: "b");
Console.WriteLine($"{alphabetStart.Alpha}, {alphabetStart.Beta}");

You can even use it to return more than one element from a method(!!!). Unfortunately, the Unity editor doesn’t support handling those kinds of returns yet but they are still useful inside your scripts.

Discards are those underscores you see in the example below. It allows you to deconstruct a tuple and discard the data you don’t want, only keeping what you actually need in its own named variable.

using System;

public class Example
    public string NewYorkCityName
            var (_, name, _) = QueryCityData("New York City");
            return name;

    private static (string name, int pop, double size) QueryCityData(string name)
        if (name == "New York City")
        { return (name, 8175133, 468.48); }

        return ("", 0, 0);

2. Pattern Matching!

Pattern matching allows you to test a runtime type in an if or switch statement and then convert it to that specific type all in a single statement!

if (input is int count)
{ sum += count; }

It also increases the power of switch, allowing you to do a lot more with less and create much more complex testing blocks.

public static int SumPositiveNumbers(IEnumerable<object> sequence)
    int sum = 0;
    foreach (var i in sequence)
        switch (i)
            case 0: break;
            case IEnumerable<int> childSequence:
                foreach(var item in childSequence)
                { sum += (item > 0) ? item : 0; }
            case int n when n > 0: sum += n; break;
            case null: throw new NullReferenceException("Null found in sequence");
            default: throw new InvalidOperationException("Unrecognized type");
    return sum;

3. Local functions

Local functions is currently one of my favorite features in C#. You could already create functions inside functions by assigning a block into an Action or Func variable but now you can just define an anonymous function and not worry about what returns or not returns a value or where exactly you defined which variable. So, if you need a complex block or calling the same function multiple times but you don’t want it available outside, Local Functions are here for you.

private static string GetText(string path, string filename)
     string AppendPathSeparator(string filepath)
     { return filepath.EndsWith(@"\") ? filepath : filepath + @"\"; }

     var reader = File.OpenText($"{AppendPathSeparator(path)}{filename}");
     var text = reader.ReadToEnd();
     return text;

4. Switch Expressions!

You can now rephrase your Switch blocks into something much nicer and readable.

public static RGBColor FromRainbow(Rainbow colorBand) =>
    colorBand switch
        Rainbow.Red    => new RGBColor(0xFF, 0x00, 0x00),
        Rainbow.Orange => new RGBColor(0xFF, 0x7F, 0x00),
        Rainbow.Yellow => new RGBColor(0xFF, 0xFF, 0x00),
        Rainbow.Green  => new RGBColor(0x00, 0xFF, 0x00),
        Rainbow.Blue   => new RGBColor(0x00, 0x00, 0xFF),
        Rainbow.Indigo => new RGBColor(0x4B, 0x00, 0x82),
        Rainbow.Violet => new RGBColor(0x94, 0x00, 0xD3),
        _              => throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand)),

5. Property Patterns

This is another wonderful extension to the switch statement allowing you to switch on a structure and get output depending on its internal properties rather easily.

public static decimal ComputeSalesTax(Address location, decimal salePrice) =>
    location switch
        { State: "WA" } => salePrice * 0.06M,
        { State: "MN" } => salePrice * 0.075M,
        { State: "MI" } => salePrice * 0.05M,
        // other cases removed for brevity...
        _ => 0M

6. Tuple Patterns

This is another cool extension to the switch statement, allowing you to match a case based on individual items inside a tuple breakdown.

public static string RockPaperScissors(string first, string second)
    => (first, second) switch
        ("rock", "paper") => "rock is covered by paper. Paper wins.",
        ("rock", "scissors") => "rock breaks scissors. Rock wins.",
        ("paper", "rock") => "paper covers rock. Paper wins.",
        ("paper", "scissors") => "paper is cut by scissors. Scissors wins.",
        ("scissors", "rock") => "scissors is broken by rock. Rock wins.",
        ("scissors", "paper") => "scissors cuts paper. Scissors wins.",
        (_, _) => "tie"

7. Using Declarations

One of the really nice things in C# over C and C++ is that it is a managed language. Yes, there are performance differences (which Unity has almost 100% taken care of) but it is a huge load of responsibility off the developer. The Using declaration is a great way to take advantage of it. When you need to open a file or create a web request but just for a short time and you want to dispose of it properly… you can go through the whole rigmarole or just enclose the code in a Using block that takes care of everything for you.

static int WriteLinesToFile(IEnumerable<string> lines)
    using (var file = new System.IO.StreamWriter("WriteLines2.txt"))
        int skippedLines = 0;
        foreach (string line in lines)
            if (!line.Contains("Second"))
            { file.WriteLine(line); }
            { skippedLines++; }
        return skippedLines;
    } // file is disposed here

8. Indices and Ranges

First of all, you can now define a range in C#.

Range phrase = 1..4;

And you can use those numbers or that Range to access a sub-range or a sub-group of another variable. However, be careful because range accessors are beginning inclusive and ending exclusive.

var words = new string[] { "The", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dog" };

var quickBrownFox = words[1..4]; // "quick", "brown", "fox" and no "jumped"

var lazyDog = words[^2..^0];
 // The from-end index accessor. ^0 is the end and not included
var allWords = words[..]; // contains "The" through "dog".
var firstPhrase = words[..4]; // contains "The" through "fox"
var lastPhrase = words[6..]; // contains "the", "lazy" and "dog"
var text = words[phrase]; // is like quickBrownFox

9. Null Coalescing Assignment

The Null Coalescing Operators are some of my favorite features in new C#. It allows you to check for Nullls and then do things accordingly. The null-coalescing assignment operator checks if the left side is null. If it isn’t, it’s returned. If it is, the right side is assigned to it and then it’s returned. It’s a great way to do lazy resource assignment and/or creation. 

List<int> numbers = null;
int? i = null;

numbers ??= new List<int>();
numbers.Add(i ??= 17);
numbers.Add(i ??= 20);

Console.WriteLine(string.Join(" ", numbers));  // output: 17 17
Console.WriteLine(i);  // output: 17

Posted in IT, Life, Programming by with no comments yet.

News: Average User has no Concept of How Much Game Dev Costs

Recently, some clueless joe on Twitter said he will pay 10,000$ to the person who adds a multiplayer aspect to Zelda: Breath of the Wild. If he was going to donate to a modder who was working on it, that would have been fine but it seems like he was thinking that he could hire someone to do something like that for that kind of money.

Here is a long, detailed response to this which you should read but here’s the summary: 10,000$ would pay for about two work months of the average+ programmer. Also, networking is hard. The hardest networking challenges in gaming usually arise in fighting games because they usually need to be exactly per pixel and per frame accurate and, probably over distances where network traffic takes more time to go back and forth than it takes pro players twitch reflexes to react. You can see how important this is if you go back and read about the network woes of Street Fighter V.

Now, the demands of a PvE, open world, action RPG would probably be a lot less strict but these are still difficult problems. Especially if you’re talking about tacking on something like this onto a game that was definitely not designed for it.

You want a more current example? On the one hand, Battlefield 2042 is out now and it’s buggy as hell. On the other hand, Halo Infinite’s multiplayer is also out and it’s much better. Probably because the team is backed and overseen by a very strict corporate overland. On the other other hand, Halo’s campaign will come out in a week but the Co-Op campaign will only come out in May 2022. MAY!!!

343 Industries have been working on the Halo games for over 10 years! They are backed by one of the biggest corporations in the world! [According to Wikipedia] They are 750 strong! And it’ll take them — yes, assuming they have more going on than just Halo Co-Op — five months from campaign release to co-op campaign release.

And some people think you can just add co-op mode on a massive game for 10,000$.

Posted in Gaming, Less Interesting News, Practice, Programming, Thinking Out Loud by with no comments yet.

Activision-Blizzard Proving Again That They Just Don’t Care

Activision Apologises and Removes ‘Insensitive’ Quran Pages from Call of Duty: Vanguard.

Seriously? I mean, really? I did my basic Arabic studies and I know that the Quran (like the Bible and the New Testament) is Islam’s holiest tome and they do take it very seriously with how you treat iconography. But even if you didn’t know that disrespecting the Quran would whip up Islamic people into some kind of rage, imagine what it would feel like to you (or your more religious friends/family members) if there were pages of your religious texts on the ground where everyone is expected to walk.

Or, because you’re one of the hugest game companies in the world who want to sell your games to as many people as possible, have some freaking sensitivity consultants.

Posted in Life by with no comments yet.

The Only Way Out is Through

Just keep going.

Posted in Life by with no comments yet.

Doggos: As Above So Below

Those are, in fact, the cutest couple of dogs in the world.

Posted in Life by with no comments yet.

Beautiful Sky

Saw this on my walk this morning. Just wanted to share. Have a good.

Posted in Life by with no comments yet.

Make time to loaf yourself

I use this Keto Almond Bread recipe with some modifications.

— SGHF, Eran

Posted in Life, Mixing by with no comments yet.

Just wanted to let you know our dogs are cute floofs

— SGHF, Eran.

Posted in Life by with no comments yet.

Found this outside one day

Looks like James Bond hopped in for a visit.

That’s it for today.

— SGHF, Eran.

Posted in Life by with no comments yet.