Tuesday, October 24, 2017

The Whole Package: An Appeal to Polish

Hey all,

This month, I want to talk about a subject that game design schools rarely talk about. It's a subject that is really just common sense, but I'm going to mention it anyway.

Honestly, my thoughts on game design schools in general could be its own topic.

Anyway, I see a lot of young game designers, or young indies, showing their games, and I've noticed a trend. A lot of the games I see have solid gameplay, but other aspects of the game are lacking. It seems as if they were taught "make the game fun", and took that as "the ONLY thing that matters is gameplay." I then see these young'uns try to sell what would have gotten them a "B" in class as a retail product.

Capitalism will not be kind to those people. While fine for school, these products would be consider lackluster once their creators start asking for money.

I'm not trying to be toxic to young indies, in fact, what I'm saying should be taken as a letter of challenge.

Games are so much more than just the gameplay. While the gameplay is, indeed, the most important factor (no one worth their salt would debate otherwise), there are many other things that propel a game into greatness. Things such as a clean look, clean sound, and solid music will only make a game better. If everything in a game is as good as the gameplay, it'll only make the game appear THAT much better.

Do you think Tetris would have gotten as far as it did with gray blocks and no music?

To those young'uns: Think about the whole package.

Before people get on my case, I'm not debating against simplistic looking games, not at all. I will argue, backwards and forwards, that Tetris is one of the greatest games of all time, and that game uses colored blocks! What I am debating against are games that, while solid in fundamentals, use the following in any combination:
  • Unequalized sound / music
  • Royalty free sounds / music
  • Unpolished, barebones, boxy graphics (If boxy is your aesthetic, at least make it look polished.)
  • Menus are simple text, using Arial or similar font.
  • A clearly not well thought out color palette.
  • Lack an options / settings screen.
  • Lack a logo / title screen.
Before you ask, yes, I've seen games try to sell themselves as retail products with some of the above.

If you are an up and coming indie / designer; on top of your game being fun / feeling good, ask yourself: "does EVERYTHING in this game feel as good as the gameplay?", as well. That way of thinking will help propel your game into greatness.

I'm not asking for much, just polish your game as much as possible.

Jimmy

Saturday, September 9, 2017

The Idiot Box

Hey all,

There's something that's been in my mind lately, and I really can't hold back talking about it anymore, so here goes.

It really goes without saying that we live in an incredible time, we can communicate across the world, can look up information at the moment we think to look up something, and can project our opinions out to the world, as bad as they may be. (See what I did there?)

But there's a concern that I have, and I'm not the only one to feel this way.

We carry devices in our pockets everyday: idiot boxes.

Idiot boxes aren't designed to enable their users to create, they are merely designed for their users to consume: apps, news, entertainment, opinions, etc. Idiot boxes enable people to be more connected than ever, yet lonelier than ever. Idiot boxes allow us to embrace superficial relationships over real ones. Idiot boxes make people available at someone else's beck and call. Idiot boxes enable people to look up other people's opinions on subjects to avoid forming an opinion of their own.

What is an idiot box? You're probably reading this post using one right now: it's called your cell phone / tablet. Combined with the internet, idiot boxes have allowed people to engage in the behaviors I mentioned earlier.

I call these devices "idiot boxes" because they are not used to create, these devices are used for consumption, a lot like TV. Frankly, I think people use these devices as a crutch to consume content, to not think for themselves, to avoid critical thinking (hence "idiot").

Now, I'm not saying to throw away your cell phone, I use one everyday, if only because of work.

I pose to you a few questions:
  • How many of your friends on social media are your "real friends"? How many of them would care if you were feeling down, not superficial "I'm sorry" caring, but really feel for you? Will these friends hurt if you are hurting, and vice versa?
  • How many hours a day do you spend on YouTube, Spotify, Buzzfeed, etc.? How many hours of productivity have you lost?
  • Have you noticed that your attention span has shortened, even to the point that sitting and doing nothing for 10 minutes is agonizing?
  • How many times has someone asked you a question (via text or social media), and then expected you to reply almost immediately?
  • How many times have you been to dinner and noticed that a LOT of people are on their idiot boxes, not engaging with the people literally around them? 
  • How many times have you looked up a film review or game review and formed your opinion on said subject based on the review?
Idiot boxes and social media have turned people into a product, where people show only their best sides to the world, it's incredibly hard to make real friends in this way. "Friends" is simply a number that goes up based on your popularity. When times get rough, if all someone has is their social media "friends", that someone may not want to expose such feelings to the world, it can create a feeling of loneliness. Connected, yet lonely.

Having unlimited entertainment at our fingertips has given us instant gratification, we don't have patience anymore. We have grown accustomed to always having something playing, entertaining us; so much so that not having something around is the exception, not the norm.

Always being connected has allowed people to contact us at any time, for better or worse. People may expect an answer from another person immediately after sending a message, even when that person may be introverted or may not want to talk. We have become a product for other people to consume.

In some cases, people don't even pay attention to those around them, instead they choose to consume media from the idiot box. I don't know about you, but when someone does this to me (at dinner or something), I feel lonely, boring, or inadequate. Frankly, I find it rude.

Lastly, it's easy to avoid thinking critically when you can simply look up someone else's opinion and borrow said opinion.

All I ask is that every once in a while, break away from your idiot box, pay attention to those around you. Be understanding, be kind, and care for those immediately in front of you, they're people too. Spend time with your friends in the real world, talk with them over lunch or dinner. Take a few minutes out of the day to just exist, no entertainment.

Who knows, you may notice something you didn't before.

Jimmy

P.S. I find it amazing that we can communicate as much as we can now, just be sure to interact with the real world every once in a while.

P.S.S I want to make a game surrounding my feelings on this subject someday. Frankly, I hope by the time I get to making the game, my concerns are addressed and then I won't need to make the game at all.

P.S.S.S Don't form your opinion based on mine, think for yourself.

Tuesday, August 1, 2017

Game Engine Design 101: The Factory Design Pattern

Hey all,

Wow, it's been a while since I made a tutorial / learning series.

But I'm back, and I'm taking a 15 minute break from coding.

While coding up something, have you ever noticed that it would be nice to be able to create objects, but not worry about the specifics of the object you are handling? Maybe you would like to create an object "for now", but it may change later, and you don't want to rewrite all of the sections that use your object? Do you want to centralize all of the logic of creating objects of a specific type?

Good news! There's a design pattern for you!

Known as the Factory Design Pattern, this pattern allows you to specify the way in which you create objects, and let you not worry about the specifics of creating an object nor the specifics of what kind of object you are handling, so long as the objects derive from the same base. Another benefit is that all the logic to create derived types is in one place, rather than strewn about your code base.

All examples pulled from: JFramework

An example: Let's say you want to create a material (for chemistry stuff, think gold, steel, cloth, etc.), but you may create different kinds of materials based on certain parameters.

We start with a basic ChemistryMaterial class. This class can be derived from, or used as is.

#ifndef __JFramework__ChemistryMaterial__
#define __JFramework__ChemistryMaterial__

#include "Component.h"
#include "Common.h"
#include "ChemistryManager.h"

class ChemistryMaterial : public Component
{
private:
  // Members

public:
  ChemistryMaterial(ChemistryManager* aManager);
  virtual ~ChemistryMaterial();
  
  // Virtuals derived from Component
  virtual void Update();
  virtual void SendMessage(Message const& aMessage);
  virtual void ReceiveMessage(Message const& aMessage);
  virtual void Serialize(Parser& aParser);
  virtual void Deserialize(Parser& aParser);
};

#endif // __JFramework__ChemistryMaterial__
If you want different behaviors for a ChemistryMaterial, just derive from this class.

Next, we create a Factory class as an abstract class, which means in order to use these methods you need to derive from this class and implement them yourself, there's a reason for this.

What if you want different kinds of Factories to have different behaviors, but still be usable in the same places in the code base? That's why.

In JFramework's case, I can't possibly account for the numerous types of Factories, with distinct behaviors, that a user may want to make, and purposefully leave it open ended by allowing the user to create, implement, and change Factories within the engine.

#ifndef __JFramework_ChemicalFactory_h_
#define __JFramework_ChemicalFactory_h_

#include "ChemistryMaterial.h"
#include "ChemistryManager.h"

class ChemicalFactory
{
public:
  ChemicalFactory() {}
  virtual ~ChemicalFactory() {}
  
  virtual ChemistryMaterial* CreateMaterial(ChemistryManager *aManager, HashString const &aName) = 0;
};

#endif // __JFramework_ChemicalFactory_h_

Now, we derive a Factory.

#ifndef __JFramework_DefaultChemicalFactory_h_
#define __JFramework_DefaultChemicalFactory_h_

#include "ChemicalFactory.h"

class DefaultChemicalFactory : public ChemicalFactory
{
public:
  DefaultChemicalFactory();
  virtual ~DefaultChemicalFactory();

  virtual ChemistryMaterial* CreateMaterial(ChemistryManager *aManager, HashString const &aName);
};

#endif // __JFramework_DefaultChemicalFactory_h_

#include "DefaultChemicalFactory.h"
#include "ChemistryManager.h"

DefaultChemicalFactory::DefaultChemicalFactory() : ChemicalFactory()
{
}

DefaultChemicalFactory::~DefaultChemicalFactory()
{
}

/**
 * @brief Create new material.
 * @param aManager Manager associated with creation.
 * @param aName Name of material.
 * @return New material.
 */
ChemistryMaterial* DefaultChemicalFactory::CreateMaterial(ChemistryManager *aManager, HashString const &aName)
{
 ChemistryMaterial *material = new ChemistryMaterial(aManager);
  return material;
}

Making a Factory is simple now.

ChemicalFactory *mFactory = new DefaultChemicalFactory();

You can now create ChemistryMaterials with your Factory and do whatever you'd like with them like so:

/**
 * @brief Create new material.
 * @param aName Name of material type.
 * @return New material.
 */
ChemistryMaterial* ChemistryManager::CreateMaterial(HashString const &aName)
{
  ChemistryMaterial* material = mFactory->CreateMaterial(this, aName);
  AddMaterial(material);
  return material;
}

At this point, you can do whatever you want with your ChemistryMaterial that you could do with any other ChemistryMaterial.

To make things interesting, let's make our Factory return a variety of ChemistryMaterial types.

Assume that all materials referenced here derive from the ChemistryMaterial class.

#include "DefaultChemicalFactory.h"
#include "ChemistryManager.h"

DefaultChemicalFactory::DefaultChemicalFactory() : ChemicalFactory()
{
}

DefaultChemicalFactory::~DefaultChemicalFactory()
{
}

/**
 * @brief Create new material.
 * @param aManager Manager associated with creation.
 * @param aName Name of material.
 * @return New material.
 */
ChemistryMaterial* DefaultChemicalFactory::CreateMaterial(ChemistryManager *aManager, HashString const &aName)
{
  if(aName == "Steel")
    return new SteelMaterial(aManager);
  else if(aName == "Cloth")
    return new ClothMaterial(aManager);
  return new ChemistryMaterial(aManager);
}

If you were to do this, all the code that you wrote previously around the Factory would still be valid! You don't need to handle the particulars of the different ChemistryMaterial types yourself, and if you want to create a new ChemistryMaterial type, just change the CreateMaterial function in the DefaultChemicalFactory.

As you can (hopefully) see, the factory design pattern is great when you want to "set and forget" a particular implementation of an object. It's great when you need to make a variety of different types that derive from the same object, and you don't want to worry about the particulars of the derived object itself. It's also great when you want to centralize the creation of objects that share the same base.

With my time up, I'm gonna get back to work.

tl:dr of this whole article:
  • Make a base object that created objects will derive from.
  • Make a Factory object that has a method that creates objects of base object that.
    • Make that method take whatever parameters it needs to make objects.
  • Replace all uses of new on base object type, replace with you Factory creation method.

Jimmy



Tuesday, July 4, 2017

A Sound Plan Beta: Announcement!

Hey all,

I've been hard at work on A Sound Plan and Chang-e for the past few weeks, so I've kind of neglected this blog for a bit.

But it was all worth it, because I'm proud to show you this:
A Sound Plan Beta

The story behind this build is a bit of a long one, so I'll keep it short:
We had to get something ready for Seattle Indie Expo.

Dean and I had to work really hard, but we managed to get a stable build out into the judges hands, we're waiting on final review on whether or not we'll be in the show. (Crossed fingers)

Some things that have changed include:
  • New power up rocks
  • Dust clouds
  • Audience
  • Body parts fly around
  • Menus are a bit smoother
  • New art
  • New sounds
There are more features, but I'm drawing a blank right now.
If you have any questions after watching the video, feel free to ask here or on Twitter: Twitter

Thanks,
Jimmy

Monday, June 5, 2017

Randomness and Player Agency

Hey all,

Have you ever felt like a random number generator (RNG), not the game itself, caused you to lose? Have you ever said "RNGesus beat me"?

Have you ever felt like RNG has led to your victory?

Today, I would like to discuss the use of random number generation and game design, specifically about player agency.

Agency: The capacity of an actor to act in an environment.
(At least I didn't OPEN with a definition. Sure, the definition came in about only 4 sentences, but who made you the authority on article / essay writing? Also, why are you counting?)

RNG is an interesting topic in games, because when applied correctly, it can allow for emergent possibilities that are more fun for your target players. When applied incorrectly, RNG can be an incredibly frustrating element for your players.

Think I'm exaggerating on that last sentence? Take a look at people's thoughts on Five Nights at Freddy's 20/20/20/20 mode.

In short, players want to feel like that no matter what happens, that the results of an encounter / battle / whatever are caused by their own decisions, by their own skills, not by the game itself. The player is an agent within the game's rules, and acts to cause reactions, and the results of the game should be a reflection of those actions.

That doesn't mean that all RNG is bad, however. For that, let's take a look at a few examples.
  • Texas Holdem' Poker: Cards that are dealt are essentially random, as cards are dealt, the possibility space (the cards you can possibly get) decreases. Any one player can beat another player during a single game of Poker. Randomness is mitigated by playing a set of games. Good players are capable of playing the odds and wagering when the odds are in their favor, or bluffing (playing the other player), resulting in a win over the course of a set.
  • Mario Party: Movement is random by rolling a die, the possibility space in that sense is constant. Mini games may have elements of randomness in them, sometimes deciding winners arbitrarily, but there are so many mini games played during a session to mitigate the effects of a single adverse mini game result. The end game star allocation makes the possibility space wide open, leaving players who are the best at mini games or map navigation to be subject to losing, potentially rendering an entire game of smart play as moot. Any one individual game can be so random that caring about winning is really a test in insanity. (I call this the absurdity principle.)
  • Mario Kart: Item allocation is a weighted random, where players who are lagging behind are given a higher chance of getting better items. Items create new possibility spaces by knocking leading players out of the way, or giving lagging players a speed boost. The amount of variance is limited, and may cause a better player to not land in 1st place. Good players can mitigate the effects of the items through skilled play, item management, and maximizing opportunities over a set of races.
Notice something about the first and third entries? A good player can win by taking advantage of opportunities caused by helpful randomness, and mitigating the effects of adverse randomness (by either playing well or playing over a large set.). There's a key in there though, a skilled player HAS the opportunity to mitigate the effects of adverse randomness. Like I said before, "The player is an agent within the game's rules, and acts to cause reactions, and the results of the game should be a reflection of those actions".

Good use of RNG opens up the possibility space (the amount of possibilities that can be generated), but in a limited amount. Players continue to have agency in the outcome generated by the use of RNG. You can quote me on that.

Discussion about Mario Party is a great example of bad use of RNG. Ever heard someone say to you "I was winning, and then the game decided to give my friend all of the stars", or something equivalent? Dice rolling is one thing, handing out game winning tokens at the end of a game, when players can no longer take action, is another. Ever had that friend who almost ended a friendship with you because of Mario Party, or heard such a story? Mario Party becomes more fun when players give in to the "Absurdity Principle", which is essentially admitting that the game is crazy and to not take it seriously.

A bad game will use RNG to potentially affect the outcome of a game, and not give a player the opportunity to change the outcome based on said RNG, or severely limit the amount of actions that a player can take, removing or crippling their agency. A bad game will let RNG blow the possibility space wide open and essentially decide winners and losers. I literally have a phrase for it, "Deciding winners and losers.", don't let your game do that, if you're making one.

Bad RNG removes a player as an agent within the game, not letting their actions have an effect on the outcome. You can quote me on that, too.

Following the "Absurdity Principle" is hard to achieve, and the designer is walking a tight rope and relies on the player's subjective definition of fair and competition. I'm not saying to not make a ridiculous game that uses RNG, just be careful.

When making your game, if you choose to have an RNG element to your game, consider these things:
  • What does this use of RNG do to my game's possibility space? (What results can come from it?)
  • Does this use of RNG limit what my players can do, and if so, by how much? (How much agency will my players have?)
  • Does this use of RNG decide winners and losers?
  • Can players overcome the results of this use of RNG?
If any section in here needs clarity, let me know.
Jimmy

Sunday, April 30, 2017

A Topic About Persona 5

Hey all,

Today, I wanted to discuss a mechanic of a game that has been making some waves. Before I really get started, I want to say that I'm enjoying Persona 5 so far, I'm about 84 hours in and about to wrap up the final chapter.

I'm not here to talk about the game as a whole, however. I'm here to talk about one mechanic, specifically the monster recruiting mechanic. I'm going to be 100% frank here, I think it's not as good as it could be.

To the uninformed, Persona 5 is a new game from Atlus in which the player controls a group of teenagers who use their new-found powers and friendship to save the day, while staying true to themselves. This game allows players to recruit monsters into their party by communicating with the monster after it has been struck by a critical attack or its weakness while in combat. Once the communication has been initiated, the player must answer 2 questions from the monster correctly. Each question has three possible answers, and the answers are based on the monster personality, which can be viewed before initiating communication, but not during.

I have several problems with this mechanic:
  • A lot of the answers to the questions involve lying to the enemy. In a game whose narrative is about being true to yourself, why do you have to lie to the enemies? Doesn't this oppose one of the points of the narrative?
  • Not being able to view the monster personality during a conversation in order to gauge what kind of answer will most likely be correct, is bad.
  • If the player gets one question right and the other "half right", the monster will randomly either give an item (and run away) or join the party. I dislike random chance in situations like these.
  • Not knowing what kind of answers are correct essentially makes the answers random, and when the player gets these questions randomly wrong, the player may feel cheated. Also, in this case, the optimal way to play IS to guess randomly, removing any agency the player may have in this scenario.
  • The tutorial about monster recruiting isn't exactly helpful: "Gloomy monsters like vague answers." Sometimes, none of the possible answers to a question fit the description, maybe this is a translation issue, but I dislike it nonetheless.
Now, I wouldn't just complain about something and not have a solution of my own. This is just me spitballing, but I think even this would be a better mechanic.

Have the monster say something about their personality over several turns, the player is allowed to either get another personality hint or select the person on their team whose personality best matches the monster (or make an educated guess on the personality type or whatever) to convince the monster to join their team. The player gets extra money or experience for convincing the monster sooner before the maximum turn limit. Think of it like a game of Mastermind. The randomness would be removed and player's would still have to engage with the monster's personality. Maybe if the player has a narrow miss of recruiting the monster, they will get an item instead, but NOT by random chance.

I just made that up, seriously.

To be clear, I'm not against random number generators in games, but I am against them in select situations where player agency is involved. Maybe I'll go over this in a separate post.

Oh well, at least this mechanic as it stands is better than Shin Megami Tensei 4? That game was not as good as everyone said it was.

Jimmy

Monday, March 13, 2017

A Chemistry System?!

Hey all,

So, I got this idea from my trip to GDC last week, from Nintendo's The Legend of Zelda talk. The idea was to make a chemistry system for games, since physics engines already exist.

You can see the commit here: JFramework

Basically, I created a component (called material) with properties such as melting point, freezing point, boiling point, conductivity, temperature, etc. that keeps track of properties of a material. This component can essentially set objects to freeze, or melt, or whatever I need it to do given the right conditions.

On top of materials, I created an element component, which radiates a temperature and/or wattage.

The rules of the system are as follows:
  • A manager will have a global temperature to apply to materials.
  • Materials can exchange temperature and wattage from other materials, and elements.
  • Elements can exchange temperature and wattage from other elements. (i.e. a flame can be put out by water.)
It's a pretty basic rule set, and may be adjusted later.

I thought I would discuss what I was working on while NOT playing The Legend of Zelda: Breath of the Wild.

Speaking of Zelda... Play it. It's now my favorite game of all time, maybe a full review later?

New A Sound Plan footage here: YouTube

Thanks,
Jimmy