RTS4 Update 4

I had to move house so had less time to code, but this month I focused on bug fixing, cleaning up the code, and improving the visuals. I’ve also switched to my own pathfinding solution which can (most of the time) avoid the grid zig-zag effect with very little extra cost, but it’s incomplete and can break in situations (when more than 1 unit tries to use the same navigation result).

RTS4 Update 4; new building models, procedural foliage

The terrain supports cliffs and will cut the mesh (using a geometry shader) and insert cliff geometry to fill the gaps. A compute shader procedurally places foliage instances based on the terrain type. I bought the Toony Tiny RTS Set and switched the buildings out, they overlap with the AOM buildings surprisingly well except that the Town Centre is actually a blacksmith and many of them are too tall. (Note: These will be replaced with something less cartoony eventually)

I’ve more closely replicated the AOM camera angle, but after seeing the AOE4 gameplay trailer, I’d like to try a wider FOV.

Standard RTS Camera FOV (15° FOV 125m distance)

I was hoping to get a public WebGL build up, but many of the recent changes have made the game incompatible with WebGL, so I’ll need to disable them or build fallbacks first.

RTS4 Update 3

We’re 1 month in on the project reboot! I’ve fixed up the lobby UI and switched multiplayer to a relay server (having trouble with UDP Punchthrough on Azure).

In the game above, the two players desync after the Pegasus is trained. This has been fixed now, but it was caused by the “cheat” command (to instantly give a player resources) which I used for favor, did not serialize its data, so didn’t execute correctly on the other client.

The game has also been more heavily optimised so that it will run in WebGL, and I’ve been working on simplifying some of the internal simulation logic (ie. so that all things that deliver resources to players use a unified system).

RTS4 Update 2

Over the last week I’ve added LOS, D*Lite pathfinding, hitpoint bars, upgrades work (but only ones which affect prerequisites), and the UI has been updated with better placeholder graphics (the same used in the previous RTS4 attempt).

The random maps still generate incorrectly. Forests seem to fail randomly, but breakpointing in the code suddenly makes them work again.

NAT punchthrough looks a lot simpler than expected, so I’d like to try that next, along with some of the server-side player profile management and game listing.

RTS4 Attempt 3

I’ve restarted the RTS4 project and made a lot of progress very quickly thanks to pulling in existing code from the previous attempts. It’s not quite up to where I was in the previous attempt but getting close.

Currently the following is implemented:

  • Parsing the AOM format of proto.xml, terraintypes.xml, clifftypes.xml, forest.xml, waterbodies.xml (partial), techtree.xml
  • Parsing and executing random map .xs files
  • Primary unit actions (Move, Gather, GatherDrop, Attack, Build)
  • Building placement
  • Networking (only direct IP, no punch-through)

To speed up development, I’ve pulled in code for the following

  • Parser logic comes from ReGE (PhD project)
  • XScript runtime is (a modified version of) what was used in XNA RTS4
  • Math and Networking is based on that used in Unity RTS4
  • Simulation has been completely recoded and is implemented in Unity ECS

It’s not much to look at, but here is how it looks currently

There is currently no pathfinding and technologies cannot be activated, and there are several bugs. Food amount starts as -1. Ranged attacks work but are instant and do not use projectiles, and all attacks work off of the global clock instead of per-unit timers. Something is wrong with random map constraints and water decorations (purple boxes) are being spawned in base, and the starting forest rarely spawns correctly.

(Started 20 Feb 2020)

Minimum code for Android Alert Dialog Box in Unity

This was difficult to find, so here it is; the smallest snippet of code to present an AlertDialog (with OK button callback) to the user:

private class OnClickListener : AndroidJavaProxy {
    public readonly Action Callback;
    public OnClickListener(Action callback) : base("android.content.DialogInterface$OnClickListener") {
        Callback = callback;
    }
    public void onClick(AndroidJavaObject dialog, int id) {
        Callback();
    }
}

public override void ShowAlert(string title, string content) {
    AndroidJavaObject activity = null;
    using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) {
        activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
    }
    activity.Call("runOnUiThread", new AndroidJavaRunnable(() => {
        AndroidJavaObject dialog = null;
        using (AndroidJavaObject builder = new AndroidJavaObject("android.app.AlertDialog$Builder", activity)) {
            builder.Call<AndroidJavaObject>("setTitle", title).Dispose();
            builder.Call<AndroidJavaObject>("setMessage", content).Dispose();
            builder.Call<AndroidJavaObject>("setPositiveButton", "OK", new OnClickListener(() => {
                Debug.Log("Button pressed");
            })).Dispose();
            dialog = builder.Call<AndroidJavaObject>("create");
        }
        dialog.Call("show");
        dialog.Dispose();
        activity.Dispose();
    }));
}

Note: I’m assuming all AndroidJavaObject objects need to be disposed (even when the same instance is returned in the case of the Builder), but that may not be the case.

You can remove the OnClickListener class and pass null as the final parameter for setPositiveButton if you do not need a callback.

BAR Extractor improvements

Texture support was (possibly) fixed for BTX (and DDT support added) to the BAR extractor. Just drag a BAR file into the page and it’ll load up thumbnails for all images within. I’m using it to look through the Age of Mythology files; I dont have Age of Empires 3 installed, but it should work with that too.

BarExtractor.jpg

Visit here to use the tool.

Procedural Caustics

A few more under-the-hood fixes (mainly around value auto-swizzling). The newest version is here https://weesals.com/Releases/HTML/Surface/R8/

I made a caustics generator in it (load the example project to see). Unfortunately PerlinNoise has a grid artifact, so cannot be used, and SimplexNoise does not wrap. I’ll need to add another noise generator once I find a suitable one.

Caustics (1).png

 

Distance fields

Added distance fields using an algorithm called “jump flooding”. It can be used to add bevels. The second output contains the distance values, ill swap them around at some stage.

DistanceTest

http://weesals.com/Releases/HTML/Surface/R6/

I found this animation helpful in understanding the concept https://www.shadertoy.com/view/4syGWK, they use a power of 2 when spreading values, but I found a power of 3 works great too, and is much cheaper – that is what the Quality slider controls.