No Escape From Quarantine

Playable at: https://sharemygame.com/@Derek_G/no-escape-from-quarantine

I spent 3 weeks of evenings and weekends building a tower defense game using the BFS / realm rush project as a starting point. It was a tough experience but well worth it.

I played with blender in the past, but I have given up trying to be both and artist and a coder :stuck_out_tongue: So I mostly used lots of Synty Studios assets, and my favorite weapons asset Sci-Fi Arsenal by Archanor VFX.

Blending the path finding and the tower factory code was very difficult for me. I ended up rewriting it several times, and added two way travel to the paths required for picking the right road prefabs. In the end I ended up with an abstract CubeFactory for roads, footpaths, and towers.

I am still trying to fully understand SOLID principals and other coding best practices. So I fell back to single responsibility and keeping things as contained as possible.

  • Don’t make anything public unless you have to. Ben’s “SerializeField” technique is great for this. I don’t see many other instructors teaching this.
  • When things do talk to each other consider the dependencies carefully. For the complex chatty parts I used a centralized GameEvent class. For the simple and useful I used other singletons.

e.g. Lots of objects are interested in enemy’s being hit so the Enemy calls BroadcastEnemyHit method, and lots of classes subscribing to the “onEnemyHit” event:

GameEvent code for the event:

public delegate void OnEnemyHit(int hitAmount);
public event OnEnemyHit onEnemyHit;
public void BroadcastEnemyHit(int hitAmount)
{
onEnemyHit?.Invoke(hitAmount);
}

Code for the subscribing class:

void Start()
{
    GameEvent.Instance.onEnemyHit += OnEnemyHit;
}
void OnEnemyHit(int hitAmount)
{
    score += hitAmount;
}

The simple and useful singletons were mostly UI oriented e.g.

        UIMessage.Instance.QuickError("Blocking path");
        UISound.Instance.SoundError.Play();

I also tried using the UI as a layer of separation. Such as the ‘tower selection panel’ used the tower class, it was not part of the tower class.

9 Likes

Looks Amazing!!! :heart_eyes: :star_struck:
I Appreciate your hard work and your willingness to challenge yourself.
Good Luck for future games
:smile:

1 Like

Fantastic…loving the look / feel and consistency!

1 Like

Amazing game, just one issue, don’t know if it’s my browser’s fault, but the game crashes at wave 13th (It crashed twice in the exact same point). A downloadable version would be great to avoid WebGL issues.

On coding:
Why lots of objects are interested in enemy’s being hit? I don’t get it, I didn’t see anything changing drastically other than a user score, not saying is a bad thing, but calling an event every hit might not be efficient, there are easier, simpler ways to do this, like using Scriptable Objects for each wave, Scriptable Objects can hold data that can be modify by other objects pretty easily, making the game far more efficient code wise, but I don’t remember if you’ll learn about those in the 3D course.

Avoid using singletons, they are considered bad practice for a lot of people, I once even got yelled during a jam for using one, it was kinda funny to be honest, people sometimes get pretty intense about bad practices in coding.

“Ben’s “SerializeField” technique is great for this. I don’t see many other instructors teaching this.”

Yeah, I don’t know why even Unity’s tutorials use Public all the time instead of SerializeField.

Thanks for taking the time to give great feedback Yee.

Wave 13 introduces Taxis, it might be something to do with the asset. Do you know what browser and version you were using? I tested the game on several devices, but to be honest it was only on Chrome due to its market share. And publishing a game binary sounds like a whole other level of support and distribution…

Do you have any links to the scriptable object technique you were talking about? It would be interesting to check out. I did use them to list prefabs for each wave but nothing beyond that.

It would be great to get the kind of game jam mentor experience you got, and making an effort to stick to coding standards can solve a lot of issues. Code that the entire team can work on without friction can be extremely valuable.

You are right that singletons are kind of hackish - especially as I learn more techniques. But, I still can’t help being a fan of the GameEvent singleton + delegate pattern. It acts as a hub that increases code maintainability by orders of magnitude, and I can find any non-obvious dependencies with a simple right click.

The UI singletons on the other hand were pure laziness. UIMessage has 49 references, UISound has 31 references. That is a lot of dependencies to set up for Debug.Log() like functionality.

One pattern I want to explore is a dependency injection like I found in ASP.NET Core tutorials. The startup class marries interfaces and objects together. Each webpage can then use these interfaces as it wishes, e.g. it doesn’t matter if it is an in-memory database or a sql database, as long as it has the same methods. A very cool concept for swapping out parts + having a central hub for visibility. In Unity I imagine a spawner could do something similar - giving each object an IAttackable or an IScoreboard to use. Which in turn would reduce singleton dependencies.

As for performance, I know the game isn’t the best. Before release when I was using the profiler, I found finding objects by name was taking 20 to 30% of the workload, and switching to finding by tag reduced it to under 1%. Two other big performance hogs I can now revisit are lighting and proper queuing. I have learnt more about light performance, and I have written a solution from the fps project for queuing three projectile objects at once: muzzle flash, bullet, and hit.

1 Like

Sorry, I have no videos of that, it’s not really a technique but more of a suggestion that any beginner can implement but it already looks like you are an experienced coder, you are by no means a beginner if you are taking about interfaces, and yes, that can certainly avoid dependencies and make everything cleaner.

I’m using Safari v13.1.1

It’s easier to handle a Mac and Windows version than a WebGL, this is mainly because webGL is kinda crappy, I’ve seen all sort of games with bugs that don’t appear in downloadable versions, you can see it for yourself just with the compile time, it takes almost 10x less times to compile for Windows or Mac. WebGL is super, super, super messy, Unity really needs to fix that.

Privacy & Terms