Modding Terraria: Designing a new playstyle

Below is a little brain dump on my thoughts, plans and process for designing the Fist weapons class in my Terraria mod, WeaponOut. This article assumes you have general knowledge about video games, but not necessarily much about Terraria other than that it's a "2D Minecraft"-esque sandbox game where stats are determined by weapons, armour and accessories.


Starting Again

Just as a note: Been busy with social and work stuff, previous game put on hiatus because honestly didn't know what to do with it and poor coding means bugs galore. May revisit concept if I become better at coding.

But now, I will be working with a friend on a mobile game, attempting to bring an accurate retro bomber man experience to the mobile phone, but good! (Unlike most of the apps already there, which are not so good). So I'll keep posted on here some of the various methods we've been getting up to, but at the moment we're just writing notes on a shared Google doc.

Of course, step one is to play the game and find out exactly what makes it run. Breakdown to come.

Note: When is a reference a copy?

In C#, often I find it easier to reference objects by a shorthand than to call the exact place I need it from, such as the case of:
    Circle c = circles[i];
    someValue = c.getNumber()
    c.callMethod();

However, what happens when you actually want to copy the obhect entirely, in the same vein as int i = j;?
Before doing this, understand that ^. Object =/= values, they are unique.
All primitive data types copy when using = by default, whereas complex data types such as objects will reference instead. In the case of objects, in order to create an entirely new duplicate object you would call a copy() function (or at the very least something that fulfills the same role) that effectively creates a new object and assigns all of its primitive values to be the same as the object it is copying. The following would print out "objects are different".
    Circle c = circles[i].copy();
    if (c == circles[i])
    {
        Console.WriteLine("objects are the same");
    }
    else
    {
        Console.WriteLine("objects are different");
    }

And for the fun of it, the same in Java:
    String notCSharp = new String(arrayStrings[i]);
    if (notCSharp == arrayStrings[i])
    {
        System.out.print("objects are the same");
    }
    else
    {
        System.out.print("objects are different");
    }

And that's about that.

Chasing a a Bug, More More UI


This one was particularly bad and I spent the best part of an evening trying to find and fix it, and as usual the error was because of some stupid assignment of variables that I must have wrote whilst half asleep or something. What happened was for some stupid reason I had the scripts activate the pointer in the array index equal to the number of pointer out rather than the first empty pointer slot in the array, meaning the whole thing broke if you added and removed pointers out of order. And the whole thing was dealt with by replacing the index numbers with the for loop variable used for finding the empty array space which I had already done at the start. Blegh.



Other than that, I've actually got a simple thing set up so that the levels can actually switch between each other, as well as a cheeky fade in effect to hide anything that could potentially be loading. Something that I discovered was that you have to enable a scene in File >> Build Settings... (Ctrl-Shift-B) in order to switch to them using code, otherwise you get the error telling you to enable it in the build settings. Unity is great for that kind of thing. It also seems to dictate load order, so I have a dummy scene set up at the top of the build list that initialises the static global variables (like the level the player is on) then redirects to the first actual scene. I'm not sure if this is the right way to do it but it works for me (cue crash to desktop/home screen).

All boring back end stuff, like trying to find out how to get on-scene GUITexture buttons to work, how to keep track of levels and how to make scene changes in code.

All in all, it's starting to come together. Sort of.

Making the End Screen

A winner is you!
So this post is about the process of making the end screen for a level. For starters, it was going to be a 3 star rating system, because its simple and effective. Plus, since the game uses limited tries, I figured that it was close enough to golf to apply similar rules - so each level has a "par" number and a "bogey", which translates to the signals left to give you a 3 or 2 star rating, after which you only get 1 star meaning you completed it. And of course no stars for a failed attempt. With that in mind I ran a few more ideas in my head of how the general structure of the thing would be, then sketched it down. The buttons are based on the standard symbols you find on phones for their corresponding tasks. This is a good inspiration for these kind of design choices.

Chasing a Bug, More UI


via Gfycat


Spent a while looking through code and rigorously testing various conditions whilst staring at the console log after my sister found a gameplay bug that caused Pointers to permanently disappear by randomly tapping on the screen. Turns out the problem was to do with the multi-touch to drag and pointers, which I've implemented in a really dumb way.

What happened was that when when the pointer was tapped on, the script sets the drag boolean to true, meaning it should run its drag code (moving around). The drag then finishes when the drag code detects that the finger was removed from the screen, which checks to see if the position is in the correct area to remove the pointer or not.

The error was caused by another piece of code that ran when the touch count was larger than 1, which set drag back to false again, but without checking for whether the pointer needed to be removed or not. Since drag was false, the event where you untapped the screen would never be registered and many problems were caused.