Unity3D: replace Uma.dll with source code

If you want to replace the UMA.dll with the source code from¬†https://github.com/huika/UMA, Unity3d will loose references to essential scripts such as SlotData.cs, OverlayData.cs …

The following script will replace the corrupted references.
1. remove UMA.dll from your project
2. add source code of the dll to the project (https://github.com/huika/UMA)
3. press the menu “UMA/Replace UMA DLL”

Some reasons to replace the dll with source code:
– remove UMA.dll and LitJson.dll from your build project
– debug UMA to find bugs or learn how it works (I have a bug in my case, but I’m not sure if its UMA or something else)

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;

/// <summary>
/// If you want to replace the UMA.dll with the source code from https://github.com/huika/UMA, Unity3d will loose references to essential scripts such as SlotData.cs, OverlayData.cs ...
/// 1. remove UMA.dll from your project
/// 2. add source code of the dll to the project (https://github.com/huika/UMA)
/// 3. press the menu "UMA/Replace UMA DLL"
///
/// Good read how fileID and guid work with DLLs:
/// http://forum.unity3d.com/threads/reducing-script-compile-time-or-a-better-workflow-to-reduce-excessive-recompiling.148078/#post-1026639
/// 
/// Hint: This is script is not optimized for performance, because you only run it onces ūüėČ
/// </summary>
public class ReplaceUmaDll 
{
	[MenuItem("UMA/Replace UMA DLL")]
	static void Replace()
	{
		List<UnityReference> r = new List<UnityReference>();
		r.Add(new UnityReference("e20699a64490c4e4284b27a8aeb05666", "1772484567", "e20699a64490c4e4284b27a8aeb05666", "11500000")); // OverlayData.cs
		r.Add(new UnityReference("e20699a64490c4e4284b27a8aeb05666", "-1278852528", "73c8549c3cf080440a73c4e2ccd18008", "11500000")); // SlotData.cs
		r.Add(new UnityReference("e20699a64490c4e4284b27a8aeb05666", "-335686737", "0255b874991cce440bf9d7aeb881d411", "11500000")); // RaceData.cs
		r.Add(new UnityReference("e20699a64490c4e4284b27a8aeb05666", "-1571472132", "e7c16015bfeffbf46a4f40de1f687493", "11500000")); // UMADefaultMeshCombiner.cs
		r.Add(new UnityReference("e20699a64490c4e4284b27a8aeb05666", "-946187639", "fd3c35f1684963b4c8693ace7a4e9751", "11500000")); // UMALegacyMeshCombiner.cs
		r.Add(new UnityReference("e20699a64490c4e4284b27a8aeb05666", "-1550055707", "8c8e9aa6f57f2fb4ab4808b7dd814787", "11500000")); // UMAData.cs
		r.Add(new UnityReference("e20699a64490c4e4284b27a8aeb05666", "-1708169498", "ca64bee1dd859ab498a3045e0e682a1a", "11500000")); // UmaTPose.cs
		r.Add(new UnityReference("e20699a64490c4e4284b27a8aeb05666", "-1175167296", "a4beb7632b1d45f44b433df8b2d28f9a", "11500000")); // TextureMerge.cs

		ReplaceReferences(Application.dataPath, r);
	}

	static void ReplaceReferences(string assetFolder, List<UnityReference> r)
	{
		string[] files = Directory.GetFiles(assetFolder, "*", SearchOption.AllDirectories);
		for (int i = 0; i < files.Length; i++)
		{
			string file = files[i];

			if (EditorUtility.DisplayCancelableProgressBar("Replace UMA DLL", file, i/(float)files.Length))
			{
				EditorUtility.ClearProgressBar();
				return;
			}

			if (file.EndsWith(".asset") || file.EndsWith(".prefab") || file.EndsWith(".unity"))
			{
				ReplaceFile(file, r);
				FindNotReplacedFiles(file, "e20699a64490c4e4284b27a8aeb05666");
			}
		}

		EditorUtility.ClearProgressBar();
	}

	static void ReplaceFile(string filePath, List<UnityReference> references)
	{
		var fileContents = System.IO.File.ReadAllText(filePath);
		
		bool match = false;
		
		foreach(UnityReference r in references)
		{
			Regex regex = new Regex(@"fileID: " + r.srcFileId + ", guid: " + r.srcGuid);
			if (regex.IsMatch(fileContents))
			{
				fileContents = regex.Replace(fileContents, "fileID: " + r.dstFileId + ", guid: " + r.dstGuid);
				match = true;
				Debug.Log("Replaced: " + filePath);
			}
		}
		
		if (match)
		{
			System.IO.File.WriteAllText(filePath, fileContents); 
		}
	}

	/// <summary>
	/// Just to make sure that all references are replaced.
	/// </summary>
	static void FindNotReplacedFiles(string filePath, string guid)
	{
		var fileContents = System.IO.File.ReadAllText(filePath);
		
		// -?        number can be negative
		// [0-9]+    1-n numbers
		Regex.Replace(fileContents, @"fileID: -?[0-9]+, guid: " + guid, 
	        (match) =>
				{
				if (match.Value != "fileID: 11500000, guid: " + guid)
				{
					Debug.LogWarning("NotReplaced: " + match.Value + "  " + filePath);
				}
				return match.Value;
			});
	}

	class UnityReference
	{
		public UnityReference(string srcGuid, string srcFileId, string dstGuid, string dstFileId)
		{
			this.srcGuid = srcGuid;
			this.srcFileId = srcFileId;
			this.dstGuid = dstGuid;
			this.dstFileId = dstFileId;
		}
		
		public string srcGuid;
		public string srcFileId;
		public string dstGuid;
		public string dstFileId;
	}
}

Global Game Jam 2014

I ¬†participated at the Global Game Jam this year. It was in Karlsruhe at HfG Karlsruhe. I had a lot fun and met at lot of nice people. The theme this year was “We don’t see things as they are, we see them as we are.” It was quite difficult in my view and we had a lot of ideas. 30 minutes of brainstorming ended with the floor full of post-it.
SAMSUNG

After pitching our ideas, I joined Moritz and Till to develop Will to Survive. The story and idea of the game:

You go through a terrible memory of the past. In order to win, carry your will to survive. A shining orb represents it. Beware of your father who just killed your mother. He will try to stab you.

Till made the design and animation of our main character and the vater. Moritz made art for the background and level design. I programmed the game in Unity and put very thing together. The character was controlled by the 2D physic engine that was added with Unity 4.3. The animations were blended with Mecanim.

WillToSurvive_Mecanim

The AI of the father was quite simple. He run with a predefined speed. In front of each obstacle was a trigger, that forced the father to jump with a predefined force and a maximum speed, while he was in the air. With this is place, we were able to trigger small, high and long jumps.

You can find the game and some more details at the Global Game Jam Site

WillToSurviveDSC01634

DSC01616

ASP.NET Identity – invalidate all sessions on SecurityStamp update

I develop the account system for my upcoming game Battlefall with ASP.NET Identity and ASP.NET MVC 5.
I came across the problem, that ASP.NET Identity will not invalidate sessions if the SecurityStamp has changed. This behavior is very important. Let’s say you are logged in from two different browsers with the same user. If you change the password in one browser, the same user in the other browser won’t be logged out!

To add the described behavior, you must modify the following code from a new generated ASP.NET MVC 5 project.
I basically added the SecurityStamp as a Claim to the user session. Every time a user requests a page, I will compare the SecurityStamp from the Claim with the current value from the Database.

AccountController

private async Task SignInAsync(ApplicationUser user)
{
    Claim rememberMeClaim = AuthenticationManager.User.FindFirst("RememberMe");
    if (rememberMeClaim != null)
    {
        bool rememberMe;
        bool.TryParse(rememberMeClaim.Value, out rememberMe);
        await SignInAsync(user, rememberMe);
    }
    await SignInAsync(user, false);
}

private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
    var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
    identity.AddClaim(new Claim("SecurityStamp", user.SecurityStamp));
    identity.AddClaim(new Claim("RememberMe", isPersistent.ToString()));
    AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}

//
// POST: /Account/Manage
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Manage(ManageViewModel model)
{
    bool hasPassword = HasPassword();
    ViewBag.HasLocalPassword = hasPassword;
    ViewBag.ReturnUrl = Url.Action("Manage");
    if (hasPassword)
    {
        if (ModelState.IsValid)
        {
            IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
            if (result.Succeeded)
            {
                // update SecurityStamp to prevent logout of this user
                await SignInAsync(IdentityManager.User);

                return RedirectToAction("Manage", new { Message = ManageMessageId.ManageSuccess });
            }
            else
            {
                AddErrors(result);
            }
        }
    }
    else
    {
        // User does not have a password so remove any validation errors caused by a missing OldPassword field
        ModelState state = ModelState["OldPassword"];
        if (state != null)
        {
            state.Errors.Clear();
        }

        if (ModelState.IsValid)
        {
            IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
            if (result.Succeeded)
            {
                return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess });
            }
            else
            {
                AddErrors(result);
            }
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}     

Startup

public void ConfigureAuth(IAppBuilder app)
{
    // Enable the application to use a cookie to store information for the signed in user
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Account/Login"),
        Provider = new CookieAuthenticationProvider
        {
            OnValidateIdentity = ctx =>
            {
                var ret = Task.Run(() =>
                {
                    Claim claim = ctx.Identity.FindFirst("SecurityStamp");
                    if (claim != null)
                    {
                        UserManager<ApplicationUser> userManager = new UserManager<Models.ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
                        var user = userManager.FindById(ctx.Identity.GetUserId());

                        // invalidate session, if SecurityStamp has changed
                        if (user != null && user.SecurityStamp != null && user.SecurityStamp != claim.Value)
                        {
                            ctx.RejectIdentity();
                        }
                    }
                });
                return ret;
            }
        }
    });
    // Use a cookie to temporarily store information about a user logging in with a third party login provider
    app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
}

Fortunately, the Katana Project is open source. It helped a lot to solve this issue.

Tower Lords

The game has finally a name. It’s now called Tower Lords instead of ActionRPG. That name is easy to recognize and reflects the idea of the game. You play a Lord and you can build Towers.¬†Coincidentally, it also has my initials TL. Here is the logo I made:

TowerLordsLogo_1000

My focus is to improve the 3rd person controller. The old level Town was designed for an isometric camera and I create a new level. It’s called Dawnwood. ¬†I’ve added a Crosshair to improve aiming, smoothed animations and ¬†added sprinting with a nice trail renderer. Multiplayer works with this new level as well.

Tower Lords 3rd Person with Logo

 

multiplayer, 3rd person camera prototype, ice spell and ice tower

Last week was a public holiday in Germany and I could spend some more time in the development of  my game. I achieved quite a lot, much more that I have every thought could be possible. In total I spend +40 hours last week.

I implemented the foundation for the multiplayer mode for my game. You are able to play with multiple player¬†simultaneously. The game runs with the server-client model. One player starts a server and the other players can join the server. The server is in charge of handling the main components of the games like spawning waves. ¬†I implemented the¬†Entity interpolation¬†algorithm of the source engine that is powering games like Counter Strike to compensate lagging of movement. Next to that I wrote a generic script that takes care of replication. You can define in the editor a property (e.g. hp, mana) that must be synchronized with other players. ¬†You can decide if a property should be send reliable (TPC) or unreliable (UDP) . Property are only replicated if their value changed. The script does even take care to replicate everything to player that join a running game. If for instance a player joins, the current hp is send to the new player and you don’t have to worry about it. Interactive components like casting a spell are even more complex, you must synchronize casting animation and so on. I have implemented this in a very generic and even simple way to extend it in the future. I basically serialize a object like the spell, send it to all other player and execute it. ¬†The executed version at the other player has slightly different behavior ¬†than the person who actually cast the spell.

Most tower defense games employ either a isometric camera or a top down view. My game should take this to the next level so I implemented a prototype to bring the player closer to the action with a 3rd person camera.

The effect of the fireball has been replaced with a new one that looks much better. I added the iceball spell and the ice tower. In conjunction with the new ice spells, I have rewritten the fire one in a generic way. So I just have to tweak some parameter in the editor to create a fire or ice spell. That was also useful for the multiplayer support: I have only one piece of code that takes care of synchronizing the iceball and fireball.

The sneak preview video of this week is much longer. I even did some video editing to put everything together. I hope you enjoy it.

3rd person camera prototype

2013_11_04_02

 

New ice tower

2013_11_04_03

Multiplayer test with 4 games running on my laptop

2013_11_04_01

main menu, pathfinding, linux and action system

A lot has happened this week, so lets get started.

I have rewritten the player controller to adapt the feel of games like Diablo3, Torchlight 2 and Path of Exile. I also put some more time in game play polish, scaled the spell size and other stuff for a smoother gameplay.

My next goal was to add the basics of network to check if my existing systems work remotely. To start and stop a level at a defined point (required for the network) I had to implement the basics of the main menu. Therefore was my next step the main menu. I can only tell you one thing, it looks amazing and fresh. Check the video below to see the animated main menu in action.

20131027_01

20131027_02

20131027_03

The pathfinding system is back in the game. It’s basically a grid system and the A* algorithm to compute the shortest way from A to B. The grid that determines where a play can walk is backed on level start. Next to that, I also added logic to dynamically update the grid if the player places a tower, such that the player walks around the tower. See the video below for a demonstration.

A friend of mine asked me about linux support. It set up a virtual machine with the latest version of¬†Ubuntu . Unfortunately, some shaders did not work. I will definitely look into that later, because linux doesn’t offer many tower defense games.

I’ve also been working on a system to separate a method invoker from the handler. I came up with an idea that is between writing an actual script and a full visual scripting solution like Kismet of the Unreal Engine. I coded the core framework and it worked very well. I’ll put it as proof of concept into my game and expand the system. I don’t want to talk in detail about the system because yet, I just call it Action System.

Level polish and new fire tower

Weekend was fun and I worked on my game.

The first level called¬†Town was nice so far. If you compare the graphic with some other games, it’s obviously no the best one. I put a lot of effort to polish every aspect of the level design. First of all with some new props to improve the look of large empty areas.¬†After that, I tweaked every light setting. Started from the ambient light to the sun light. Followed by the adjustment of the post processing effects.

I replaced the dummy graphic of the fire tower with a new one that looks just awesome.

I profiled some bottle necks and improved the overall performance significant. Especially the  settings of some light were the performance killer.

The goblin minions were placed by rat-like creatures.

ActionRPG_20131020_02

ActionRPG_20131020_01

ActionRPG_20131020_03

ActionRPG_20131020_04

 

WIP ActionRPG

Some new screenshots of my new game. As mentioned before, I’ve added the mini map. You are also able to build new towers. Towers only have dummy graphic so far.

ActionRPG ActionRPG2 ActionRPG4 ActionRPG3