• Register

The game you are trying to view has ceased development and consequently been archived. If you are a member of this game, can demonstrate that it is being actively developed and will be able to keep this profile up to date with the latest news, images, videos and downloads, please contact us with all details and we will consider its re-activation.

A 2D action, arcade game that blends Breakout with RPG mechanics. You play a knight storming a castle saving a princess from the clutches of an evil dragon rumored to have kidnapped her. Armed with your magical flail and spikey ball, you fight hordes of fantasy-themed evil creatures in a satirical setting.

  • View media
  • View media
  • View media
  • View media
  • View media
  • View media
RSS Articles

This is Castle Mashers' 18th devlog; a development blog dedicated to the process of how we are creating the game and how approach its making process. You can read the previous post here.

This post will be written slightly different from the previous posts as I try to nail down the perfect way to present the information I would like to put up.
We’ve got some stuff to cover already, so let’s go:

Misc:

First allow me to apologize for the disappearance and the discrepancy in post frequency. The past few weeks were literally hectic as we geared up trying to make it for Game Founder’s Submission deadline. For those of you who don’t know, Game Founders is a mentoring program that takes place in Kuala Lampur (Malaysia) for 3 months and you receive up to $25,000 in funds. They pick 10 winners each 6 months.

It was unfortunate that we didn’t know the exact time the submission was prior to that. We only know that sometime close to August Game Founders may announce they are open for submissions. We were wrong; it was at the end of May I think that we first heard the news. The original deadline was on the 10th of June and then at around the 4th or so, it got pushed back to the 20th. Which was good for us.

Prior to that, we were already picking up momentum on development and have been working towards an Alpha anyway. So the good thing once the news hit, we really focused on development. Everyone was literally working really hard. The good thing, we made it and submitted our demo. Albeit, it wasn’t in the shape or form we liked it to be (more on that later below).

On the better side of things, we have a dedicated website! Our fellows at Monkeybar have done a great job with the website. Since we are doing this as part time while we are busy supporting our families with our day jobs, funding Kreed Games is... scarce to put it mildly. We learned of their current offer, they create a custom website for $5 a month including hosting and a free email address that uses our chosen domain (domain not included). So we signed up with their service and I have to say, it has been working out amazingly great. I recommend them strongly if you are ever in need of a website.

Design, Bugs and Code:

In the previous post we talked about many features we’ve added but we never really dug deep on how we managed to do some of them or how to balance them.

The first feature that gave us some head spin; we had to think of mobile (as it is one of our possible release platforms) and still be able to offer freedom for the player. We were at the time starting to implement the melee attack when Sean proposed a cool idea; what if the player melees the ball and that activates the special attack? It was brilliant and we started working on it.

But to do that we had to setup the player script to identify what type of character are you playing; each character had its own special ability.

At first I was going the variable route; create a string variable, store the “type” of enemy as “knight”, “wizard” and “ranger”. But I quickly felt this is going to be messy and it doesn’t feel like a type. So we added an enum to the player script with the three types and exposed that to the inspector so we can change it at will while testing. While at it we did add a second enum for the 3 types of defensive special abilities. We did the same with our ball script; an enum for each attack.

From there it was a matter of checking which type of character the player has now through a switch statement and firing the corresponding ball.

Currently the Knight (the only playable character in the game at the moment) has a penetrate ball ability. Once the player melees the ball, it shoots off with high speed and penetrate everything but the wall. Also the knight gets an Armored ability which reduces damage by a certain amount.

The wizard and ranger are coded in and are active but there is no way for a player (without knowing our debug commands) to change to them. You can see below the three characters that you'll choose from:

Character choices

However, the biggest update we’ve made is the rooms and floors. Sean and I thought it would be great if the player feels like he is actually inside a castle with different rooms around. So he started working on a random level generator.

The idea of this whole thing is that at the beginning of the game you are presented by a floor and that floor contains a few rooms. You always start at the bottom left of the floor. You get random rooms generated around with 1 bonus room, 1 shop room and 1 boss room. To clear a floor you need to kill the boss and that will send you over to the next floor. The objective of the game is get rid of all bosses within the castle. How you get to each boss, however, is something entirely up to the player.

To do this we had to employ a few scripts. Here is a snippet of the main generation process:

If you dislike the formatting below, you can find the code here.

public int numEasyRooms = 3;
	public int numObjectsGroupPerEnemyGroup = 3;
	public List<GameObject> floor1Enemies;
	public List<GameObject> floor1Objects;
	public List<GameObject> floor1EnemiesHard;
	public List<GameObject> floor1ObjectsHard;
	public List<GameObject> floor1BonusObjects;
	public List<GameObject> tutorialEnemies;
	public GameObject tutorialObjects;
	public GameObject floor1BossEnemies;
	public GameObject floor1BossObjects;

	private int lastLevelIndex = 100;
	private int ranObjectIndex = 100;

	[HideInInspector]
	public int numRoomsCleared = 0;

	// Use this for initialization
	void Start () {
	
	}

	public void LoadCurrentLevel(int floor, string roomType)
	{
		if (roomType == "Normal Room" && numRoomsCleared > 0)
		{
			GameObject enemyGroup;
			GameObject objects;
			List<GameObject> floorEnemyGroup = new List<GameObject>();
			List<GameObject> FloorObjectGroups = new List<GameObject>();

			/////Spawn easy enemies and objects
			if (numRoomsCleared < numEasyRooms)
			{
				floorEnemyGroup = GetFloorEnemyGroups(floor, false);
				FloorObjectGroups = GetFloorObjectGroups(floor, false);
			}
			//Spawn hard enemies and objects
			else
			{
				floorEnemyGroup = GetFloorEnemyGroups(floor, true);
				FloorObjectGroups = GetFloorObjectGroups(floor, true);
			}

			while (ranObjectIndex == lastLevelIndex)
                ranObjectIndex = Random.Range(0, floor1Objects.Count);

			objects = FloorObjectGroups[ranObjectIndex];

			//This is for when we have more layouts for each level
			int startingObjectIndex = ranObjectIndex * numObjectsGroupPerEnemyGroup;
			enemyGroup = floorEnemyGroup[Random.Range(startingObjectIndex, startingObjectIndex + numObjectsGroupPerEnemyGroup + 1)];

			GameManager.instance.objectSpawner.SpawnObjects(objects);
			GameManager.instance.enemySpawner.SpawnEnemies(enemyGroup);
			lastLevelIndex = ranObjectIndex;
        }
		else if (floor == 1) //If first level spawn tutoral
		{
			GameManager.instance.gameStates.inTutorial = true;

			List<GameObject> tutorialEnemyGroup = tutorialEnemies;
			int ranEnemyIndex = Random.Range(0, tutorialEnemyGroup.Count);

			GameManager.instance.objectSpawner.SpawnObjects(tutorialObjects);
			GameManager.instance.enemySpawner.SpawnEnemies(tutorialEnemyGroup[ranEnemyIndex]);
		}

		if (roomType == "Boss Room")
		{
			GameManager.instance.enemySpawner.SpawnEnemies(GetFloorBoss(floor));
			GameManager.instance.objectSpawner.SpawnObjects(GetBossObjects(floor));
		}

	
	}

	List<GameObject> GetFloorEnemyGroups (int floor, bool hard)
	{
		List<GameObject> floorEnemyGroups = new List<GameObject>();
		switch (floor)
		{
			case 1:
				if (hard)
					floorEnemyGroups = floor1EnemiesHard;
				else
					floorEnemyGroups = floor1Enemies;
				break;
		}

		return floorEnemyGroups;
    }

	List<GameObject> GetFloorObjectGroups(int floor, bool hard)
	{
		List<GameObject> floorObjectGroups = new List<GameObject>();
		switch (floor)
		{
			case 1:
				if (hard)
					floorObjectGroups = floor1ObjectsHard;
				else
					floorObjectGroups = floor1Objects;
				break;
		}

		return floorObjectGroups;
	}

	GameObject GetFloorBoss(int floor)
	{
		GameObject floorBossGroup = new GameObject();
		switch (floor)
		{
			case 1:
				floorBossGroup = floor1BossEnemies;
				break;
		}

		return floorBossGroup;
	}

	GameObject GetBossObjects(int floor)
	{
		GameObject BossObjectsGroup = new GameObject();
		switch (floor)
		{
			case 1:
				BossObjectsGroup = floor1BossObjects;
				break;
		}

		return BossObjectsGroup;
	}

What Sean essentially did is that he created the script so I would create 1 level layout; we’ll call it Layout1 and then this layout I can create an X number of enemy layouts for it. Then the script looks at the current floor’s layouts Layout1, Layout2, Layout3, etc… and their corresponding enemies; Layout1Enemies1, Layout1Enemies2, Layout2Enemies1, Layout2Enemies2, etc… and then then a random layout it picked then random enemies are picked that match this layout and then spawned. Meanwile to create the enemies I actually don't use the actual objects, I only put up empty Game Objects with a tag identifying which enemy I am using. So for example, if I want an enemy layout with zombies and rats, all I need to do is place some empty game objects around the scene and then change the tag to "Zombie" or "Rat" or whatever else. That way I can create the content and I don’t have to wade through complex code to handle it.

The player then is presented with the floor with all the rooms, he picks whichever room he wants t go on that floor and voila, it works! Here is how it looks like in the inspector:

How the enemy is setup in Unity


Here is also the random generation in action:


Another thing we’ve done is upgrades. We’ve added a dedicated shop that you can go in each floor to upgrade your character. There are 2 types of upgrades for each character; the first is shared among all characters and the second specific to each.

The shared upgrades upgrade your character regardless of type; character Max HP, Max Mana, Ball damage, HP and Mana Potion capabilities. The second type has two subtypes; special attack upgrades and special defence upgrades. These upgrades aren’t shared among characters and affect only the character that uses the upgraded special attack. So for example, if you upgrade the Multiball’s properties to level 3; this provides you with an extra ball (so you launch 3 balls instead of 2 at once). This will not affect your penetrate ball for example, it will still be only 1 ball.

Here is the upgrade screen:

Upgrades screen

Art and Eye Candy:

As you recall from the previous post we changed the animations for many of the characters in the game; the payer, the rat, etc… this is to make them feel more fun and engaging.

However, we quickly found out that spritesheets for some of these characters are HUGE. If we are going to target mobile, it won’t work, even with PCs, these sheets weren’t optimized at all. So what we resorted to do for a quick fix at the current time is ask Serg to divide the sprites.
He would put each animation in a separate spritesheet and make sure that the each sprite is divisible by 4 (since Unity compression option for sprites only works for sheets that can be divided by 4).

Unfortunately some of the source files for many of the creatures got lost when Serg had to save his HDD as it got wiped out. So we resorted into a quick dirty rescale of some of the sprites. The result wasn’t bad and unnoticeable.

This also introduced a point where we have to backup our resources. So far Sean and I have been using Bitbucket for source control on the project. But Serg isn’t included neither is Aleix. So our next step is add them both to the builds (so they can test the game whenever they like) at the same time, I’d share a Google Drive with Serg where he puts up all the sources just in case.

On top of that he has been working on new animations for the submission and one of the changes was the orc's animations, here is the new summoning animation:


They look much, much better than before. However, Serg's a concept artist and not an animator; he is just filling in th gab at the moment. That pushed us to start looking for an animator, however, being a team based on revenue share can't make us any less attractive to animators. It has been a month or so of trying to find someone and we are still looking. If you know someone or an animator that is willing to help, we'd love to chat. You can reach us through contact[at]kreedgames[dot]xyz (no need to alert spam bots).

Audio:

While not always we do have an Audio section in the post, it is refreshing to note the incredible talented Aleix and his work. While he had a loaded schedule he was able to produce the sounds required for the demo. The second patch of SFX were quite good and we were able to incorporate them into the game.

I was also glad to learn of the Round Robin method of playing sound (which while it is very basic, I never knew it had such a cool name). He has also been working on finalizing some of the tracks we have in game, particularly the first one.

You can listen to the track here.

Misc:

Honestly, I did want to include the build we have been working on — it is so close to Alpha. However, I decided against it for now, we’ll continue working on the demo until it reaches an Alpha-worthy-quality then release it for you to check it out.

Meanwhile, for out blog we are going to change the times we post and instead of weekly report we are going to try an post biweekly devlogs. This way we have more to talk about rather than weekly smaller updates.

With that, I wish all you a good day and see you later in another post!

Week 17; the makeover

Week 17; the makeover

News

We take a look at the new changes in Castle Mashers and the devlog format.

Indie Quest -- Week 13; Full Throttle

Indie Quest -- Week 13; Full Throttle

News

In this week we dive into a more design focused post!

Indie Quest -- Week 12; Crossroads & Feedback!

Indie Quest -- Week 12; Crossroads & Feedback!

News

We need your feedback now more than ever, 2 demos to try, can you help us by picking the most fun one?

Indie Quest -- Week 11; refeaturing

Indie Quest -- Week 11; refeaturing

News

A new week a new update, we take a look at why we are trying a new design for the core mechanic that might prove it fun as well as more eye candy.

RSS Files
Linux v0.03

Linux v0.03

Demo

This is the Linux v0.03 (Pre-Alpha) of Castle Mashers.

Mac v0.098

Mac v0.098

Demo 1 comment

This is the Mac OSX v0.098 build (Pre-Alpha) of Castle Mashers.

Windows v0.098

Windows v0.098

Demo

The latest v0.098 build (Pre-Alpha) of Castle Mashers.

Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account:

X