Sonntag, 29. Mai 2016

Game Localization using Java Bundles


I toyed around with two ways how to implement Localization in Java. Let me present you the two ways I've implemented and which are better for you to use. I am assuming you know how to use Java Resource Bundles. If not, the check oracle the tutorial here or check this video I made here. In my examples, I will be using LibGDX, however, the code is almost the same.


The methods have both up and downsides which I'll discuss later.


Using Object Reflection

This method I worked out runs over all fields of one class and translates String types of fields (including fields in superclasses). The value of that field is being used as localization variable. Fields to be translated are marked with an annotation. This is helpful when you don't want to translate every single String in a class, and say, use untranslated Strings for object IDs.

You have a localization annotation like this:

/**
 * Marks a field to be localized.
 * The content of the field is being used to localize it.
 * @author B5cully
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Localized {
   
}


A very simple class. It's just a marker, after all.

The object is being localized like this:

  
    private static I18NBundle translations= ... // init the the bundle. This is libgdx specific, 
                                             // but works the same with a java resource bundle
                                             // the call may look a bit different
    /**
     * Localizes an object.
     * @param o
     */
    public static void localize(Object o) {
        Class current = o.getClass();
        do{
            try {             
                Field[] fields = current.getDeclaredFields();
                for( Field field : fields ) {

                    //the following is a hack to make the field temporarily accessible
                    boolean accessible = field.isAccessible();
                    field.setAccessible(true);
                    //check if the annotation exist
                    Localized annotation = field.getAnnotation(Localized.class);
                    if( annotation != null ) {

                        //localize the content of the field here
                        String localized = translations.get((String) field.get(o));
                        field.set(o, localized);
                    }
                    field.setAccessible(accessible);
                }
            } catch (SecurityException ex) {
                ex.printStackTrace();
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(Localization.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                Logger.getLogger(Localization.class.getName()).log(Level.SEVERE, null, ex);
            }
            current = current.getSuperclass();
        } while( current != null );       
    }


An object I want to translate may look like this:

public class CTWindow {

    @Localized
    public String title = "loc_window";

    public String id = "Window001";
}

Using this code, only the title will be translated by the localize() method. However, this may not work as elegantly for switching languages in a live system.



Using Field Names as identifiers

The other method is to use canonical names in your properties file. For example, your property file has an entry like this: com.neutronio.Infantry.hitpoints = Hitpoints. When you translate the field of an object, all you have to do is to get its class and field to obtain the localization.

What sounds nice in theory, isn't as easy in practice. We need multiple methods to achieve this.

    private static I18NBundle translations= ... // init the the bundle. This is libgdx specific, 
                                             // but works the same with a java resource bundle
                                             // the call may look a bit different
    /**
     * Gets the standard file path for a locale. This is required to

     * to turn a path of a properties file into desired format using its tag.
     * @param locale
     * @return
     */
    public static String convertPath( Locale locale) {
        String tag = locale.toLanguageTag().replace('-', '_');
        return tag;              
    }
  
    /**
     * Obtains a localized variable by
     * a simple field name and class.
     * @param field
     * @return
     */
    public static String localizedVar(Field field) {
        if( field == null) return "";
        return field.getDeclaringClass()

                    .getCanonicalName()+"."+field.getName();    
    }
  
    /**
     * Gets a field by name and class. Null if none was found.

     * This method works recursively in all superclasses.
     * @param name
     * @return
     */
    public static Field getField(Class clazz, String name) {
        Exception exception1 = null;
        Exception exception2 = null;
        Class current = clazz;
        Field result = null;
        do{
            try {              
                Field[] fields = current.getDeclaredFields();
                for( Field field : fields ) {
                    boolean accessible = field.isAccessible();
                    field.setAccessible(true);
                    if( Objects.equals(field.getName(), name) ) {
                        result = field;
                        break;
                    }
                    field.setAccessible(accessible);
                }
            } catch (SecurityException ex) {
                ex.printStackTrace();
                exception2 = ex;
                Logger.getLogger(Localization.class.getName()).log(Level.SEVERE,
                        "No acess to Field " + name + " in " +           

                         clazz.getCanonicalName() + ".", ex);
            }
            current = current.getSuperclass();
            if( result != null) break;
        } while( current != null );
        return result;
    }
  
    /**
     * This is the method that ultimately translates the field.

     * Obtains a statically defined localized string.
     */
    public static String getLocale(Class clazz, String name) {
        Field field = getField(clazz, name);
        if( field == null) return name;
        return translations.get(localizedVar(field));
    }


While this sounds like a handy approach there is one huge downside to it: Say my CTWindow class is extended with a MainMenuScreen. So what happens? Due to the nature of this algorithm, I can't define anything like MainMenuScreen.title = Main Menu instead of CTWindow.title= Some Title in my properties file. That means the String in the CTWindow.title local variable is stuck and cannot be redefined by subclasses. That is because of the field.getDeclaringClass() part in localizedVar(). You can work around this if you change the methods by providing the class of the object instead class where the field is being declared, like so:

    /**
     * Obtains a localized variable by
     * a simple field name and class.
     * @param field
     * @return
     */
    public static String localizedVar(Class declaring, Field field) {
         if( field == null) return "";

         if( declaring == null) return "";
         return declaring.getCanonicalName()+"."+field.getName(); 
    }

I haven't tried this out yet, so I cannot say for sure if this works! Let me know if it does. ;)

You also can still use the localize() method ontop of this, as described further above, so both of these methods can be combined together. If combined, they may actually offer the possibility to change language in a live system, as the field names are used directly for translation.

But how do you treat lists or collections of Strings?!

That's a topic for another article!


I hope I brought you closer to the topic of localization. Thanks for reading! I hope you enjoyed it.

Samstag, 28. Mai 2016

7 Ways to Boost Your Productivity

We've all been there once, wasting our time then wondering where it went. So how do you actually boost your productivity?

I collected a few helpful tips here:


  1. Get rid of all distractions. Get your focus right! Log out to all your social network accounts. Turn of your phone. Turn off internet, too, if it's not crucial. Spend a few hours doing what you planned without any distractions. DO IT!


    https://i.ytimg.com/vi/Z6gG3tKDBlk/maxresdefault.jpg

  2. Find a way to organize yourself. Keep a to-do list. If you're an indiedev, you can use HackNPlan. Don't lose track of what you're doing - which leads me to the third point.

  3. Review how far you've come and ask yourself if it helps achieving your goals. You HAVE to do this no matter what you're trying to achieve (no matter if you want to become better as a person, live a better life, or fulfill your biggest dreams). Dream big and make it happen!

  4. Make sure your work environment is well-lit. Bright light encourages your brain to focus more. Too less and you get in sleepy mode!

  5. Make sure your work environment is tidy if you work on tasks requiring a lot of brain juice. For creative tasks, a bit of a chaos may actually help finding ideas.

  6. Make sure you don't work with a full belly. That's when all your blood is in your intestines instead of your brain. The best time for mental work is with empty stomach after a walk, workout, or cold shower, when your metabolism is all fired up, feeding your brain with valuable oxygen. Breathing exercises in fresh air may help, too.

  7. A cup of blueberries and other fruit can help boosting your mental capabilities.

    https://upload.wikimedia.org/wikipedia/commons/0/0b/Blueberries-In-Pack.jpg


How do you keep your productivity high? How do you keep it? Let me know in the comments!

CamoTactics 7.0 is out! [+Download]

I am very happy to announce the CamoTactics 7.0 Build is FINALLY online. Get it here!

CamoTactics 7.0


I hope you enjoy stealing your enemies' stuff...



... and sneaking up behind them!



After you have finished them off, of course!

animation 1


Got praise? Got suggestions? Got something you don't like? Please share that with me!

Make sure to check out my blog. Follow CamoTactics official twitter for updates or my personal twitter for indiedev ramblings!

Donnerstag, 26. Mai 2016

Censorship in games: A Means of Control & Power

There have been quite a few outcries in the gaming scene lately. People have asked developers to remove the suggestive animations of Mika from Streetfighter and Tracer from Overwatch. Now disregarding the hilarity of people getting offended by moving 3D models of women and considering the scope this phenomenon seem to have acquired - I personally do not think this is about "sexual objectification of women" anymore. This is about control. Control over content creators (here: game developers) and their creative decisions.

Let me elaborate and put this into a bigger context.

Society needs ideas and information to grow. In order to figure out the ideal living circumstances, and mind set for their personal growth and the ideal, humans need both of these things. Because humans are gregarious creatures, we are always often in contact with others and learning from those around us. Not only we learn for ourselves, but also as a community. We are in a constant state of "collective learning".
The more information we have, the likelier we are to connect the dots - and thus find new ideas and perspectives (if equipped with the appropriate intelligence). I think you can call this an "evolution of ideas": the more diverse these ideas, the better. They evolve faster than laws, rules, hierarchy and (infra-)structure of a society, too.

And this is where it gets interesting.

An attempt to control this process is an attempt to control humans and the society we live in.

Individuals with their own thinking capability can have powerful thoughts. Thoughts that may pose a danger to established rules and holders of power. Remember: ideas evolve faster than laws and rules. It's why we are still stuck with fossil fuels (coal and oil) that have been around society for 200 years or more. And that's exactly what suppressing new things does: make society slow down or even move backwards.


If an idea gets enough momentum, it may pose a danger to the current status quo.

See why censorship is a powerful tool, no matter the form? (Not only in gaming... just look over to the tech scene...)

If game developers give in to "sexually objectified" 3D depictions of women, they will easily give in to other demands as well. Give them mobs a finger - they'll take the entire hand. Happens a lot if you raise children the wrong way, too.

It is important to censors to feed and maintain an angry mob of cronies (mentally unstable, desperate people) that transform into a state of outcry when something is not going as they want. Then, they will fire up their outlets and moles disguised as independent journalists to mobilize the mobs and fabricate outrage. Gaming isn't the only media this is happening to, either.

It does not matter what political spectrum this mob aligns itself with. They are all pawns in the same game.

Feeding these angry mobs is an invaluable asset, as it kills multiple birds with one stone. For one, it thwarts those whose ideas are ahead of their time (or at least attempts to). It distracts people from the real issues and the ones pulling the strings. Someone who is in distress and seeking comfort in authority and being part of a cult group cannot form critical thoughts themselves - and therefore cannot become a dangerous wolf in the process.

The aim is to create a downwards spiral of negativity, outrage and despair to keep as many people as possible away from the feat of creativity and critical thinking.

After all, you wouldn't want those wolves to destroy your shitty click-bait site business you've built up over the years.

Oh wait...

https://pbs.twimg.com/media/Chj35u3VEAAx_aB.jpg 


So if you are a creator let me tell you this. Create whatever you want with whatever ideas you have, even if they are controversial - know that controversy is needed for human society to evolve.

Know that just because someone has a megaphone doesn't mean they are the majority or an actual or potential costumer (or in other words: matter). 

If you piss off the right people, know that you're doing something right: namely standing up for yourself and what you believe in.

And that's what life should be all about.

Cheers!

Mittwoch, 25. Mai 2016

CamoTactics Devlog #2: Weapon Mods, Camouflage

With the switch to libGDX as framework CamoTactics received a huge setback in development. However, this is compensated by a much more powerful framework that allows me to polish up the game more than before. More precise graphics, lighting systems, improved camouflage mechanics, better physics simulation are only a few examples.


I hope you enjoy this demonstration of the soon to be released demo version 7.0!




Watch how camouflage, stealth and customized weapons work here. Includes insight on versions to come.






7 is my lucky number - I hope it's yours too!

Thanks for reading!

Stay tuned for the demo!


Dienstag, 17. Mai 2016

A Message To Fellow Indiedevs

Hello fellow Indiedevs.

I want to speak to you about something.

About something I think is very important.

We live in an age where people lose trust to large faceless corporations. All over the world people are distancing themselves from institutions that neglected their will, looking for real faces who are authentic and human. Anyone who is not will not survive on the market in long-term, I am sure.



Considering all these changes, I want to encourage you to be true to yourself and your principles. Be yourself. Be authentic. Be honorable. Do good deeds. Do not hide yourself or your talents.

Eventually, you WILL attract the right people (and the right consumers) in your life. Quality before quantity.

Why do you need to buy followers, readers, views or clicks if you can have a few loyal friends and customers? People that actually engage with you and care enough for you and whatever you are producing?

Why hide yourself when it could be used to coin your brand? You know, giving it a personal touch. Why not making use of it to promote yourself and the games you are making?

That being said, we both know that there are forces in the works that take influence in the process of making games. I want you to not bow to anyone when you are creating your works of art. Do not give in to no matter what side they may come from. Do whatever you think is right with your game. If you're rustling people's jimmies, know that you are doing something right. Know that this is exactly what a real artist is supposed to do.

Know that you are born strong by nature. It's important to realize and acknowledge that strength. You don't have to please everyone - only yourself. You only grow if you struggle.



Find niches... serve and please those who appreciate your genuineness - and reward you for it. Those very same people will have your back if you are being attacked by whoever.

Make a business out of who you are and market your game along with it to the right people. It's a tricky task but I am persuaded it can be achieved.

Be living proof of this!

Thanks for taking the time to read me!
Happy creating!

Montag, 16. Mai 2016

6 Things that make Your Box2D world freeze

Ever encountered problems with your Box2D setup freezing or locking up and you don't know why?


Yes?

Then read on!

There are quite a few things you can do wrong with Box2D. I have collected a few common mistakes here. These mistakes include...


1) ... Changing the position of a body manually!
Generally, it's a bad idea to modify any body information directly, e.g. by using Body.setTransform() or changing position with Body.getPosition().set(x,y). This makes all contacts currently processed by the simulation invalid and ocreates unpredictable behavior.

Solution: Applying changes to velocity or position (including setting transformation) should always happen after the world has stepped. To do this, you can create a list of operations that is then processed after the world step. This can look a bit like this:
      
   world.step(...);
   if (!operations.isEmpty() )
   {
     operations.perform();
   }

See stackoverflow for more of this issue. You can also try copying the vector to avoid modifying it when using vector math.


2) ... Destroying physic bodies during a callback!
Raycasts and Queues are solved during a timestep. Modifying bodies during that process will cause Box2D to crash. Do not ever do this!

Solution: The code setup in 1) can help you out here. Send your destroy operations to a list containing bodies to be destroyed, where it is processed after the world has stepped. I do this in my game and it works perfectly fine.


3) ... Vectors getting NaN as values!
This happens if you apply an enormous amount of angular or linear impulses to your physic bodies, to the point they get catapulted to nowhere, because they adopt infinite velocity (and thus position).

Solution: Check your formulas and make sure the values are usable! It's a good idea to include a check on whether your values are valid when doing calculations; and throwing an error in case they don't.


4) ... References to destroyed physic bodies!
Once you have destroyed a body, it should not be referenced anywhere again.

Solution: Once destroyed, a body reference should always be set to null!


5) ... Creating physic bodies when the world is in the middle of a time step!
Because if you do, granted, you will get a freeze! This has caused me a lot of headaches personally.

Solution: You can use a similar solution as in 1): creating your objects after the world has stepped by putting them in your operations queue. 


6) ... Creating physic bodies that are created inside other physic bodies!
This causes your created physic bodies to be slung away like a bowl of peanuts gone crazy - if it doesn't crash first! In my experience, this happens when you have shooting mechanics, but the spawned projectiles touch the entity they were shot from.

Solution: There are numerous ways to solve this. You can either make sure your bodies are small enough and far away enough from a defined projectile spawning point - or if collision behavior doesn't matter too much, you can use collision groups and masking to avoid them touching each other.



I hope this helped you with any issues you had! If you still have problems, let me know - I'll be happy to help you out.

5 Reasons Why Your Game Should have Achievements


A while back I was asking my twitter followers about achievements and their significance in a game.
The general sentiment was that achievements were an important feature that you should consider adding. Let me present you the results and explain why.

Achievements...


1. ...Make Players Stick to your Game
Gamers want challenges. So by providing them achievements they can complete you are also giving them a sense of accomplishment once they finished them. They will want to complete as many achievements as possible and play your game longer, too. Even better if you're also giving them rewards while doing so!


2. ...Make Players explore Your Game
When a player sees a certain achievement, they will spend time trying to do things that may help them get it. This gives them a very good reason to explore your game and scoop out all possibilities.


3. ...Add Replayability & Variety
In case your game has mechanics that allow usage of different strategies or play styles, achievements are the best way to let many gamers experience as many aspects of the game as possible. If you want to promote creativity, reward players for doing things differently. Having your hands on the knob called variety is, in my opinion, a very crucial tool of game design. I think Team Fortress 2 does this very well - even though in practice it doesn't always turn out so well!

http://65.media.tumblr.com/35534564b0c069dc16e53688db64aeb9/tumblr_mhrbwedGhv1qmp4f4o1_500.jpg

4. ...Provide Guidance
Achievements can give important information to the player, such as how the game is being played or what else can be done in your game. Players will know what gameplay, items etc. to look after just by checking the list of achievements - if you are providing them with one.


5. ...Encourage Competition 
Especially in online gaming communities, achievements are often worn as a badge of honor and proudly shown off to others. Paired with a leaderboard, that also increases the chance someone plays your game longer.

http://www.mememaker.net/static/images/memes/4342839.jpg

I remember playing too much agar.io trying to get on the leaderboard in the first place...


Summary
Achievements are a great way to enhance your game, even if it is a small one. They increase variety, add more challenges and makes players explore your game more. All of which that, if done right, eventually results in more fun and time spent playing.

For further reading, you can check this video on which types of achievements are the best ones (Youtube). Thanks for Mr. Aqua for showing me this, you know who you are!

Thanks for reading!

Dienstag, 10. Mai 2016

What really makes a game fun and worth playing?




What makes a game fun?

That seems like a so simple question. The more I contemplate it, the more multilayered it becomes.

What is fun? 
 
What triggers a fun experience?

How to create something that is fun?


Fun is all about:
  • challenge
  • reward
  • taking risks
  • exploration
  • the rush of the unknown
  • taking opportunities
  • collecting things
  • messing around and testing out limits
  • answering the question, "what would happen, if...?"
...all in a playful way. It's how nature makes all life learns its lessons. Fun can also be something that brings back childish wonder and curiosity and allows us to reconnect to this deepest part of ourselves many of us learned to "grow away" from. Maybe that's why games are generally liked by many people - whether it be tabletop games, video games, or also the games you played on the playground, or later the "mind games" adults play (games that sometimes turn into not so funny ones..).


How does fun in games look like? 

I can think of a couple of things. Generally spoken, flashy-ness and the right aesthetic can make a HUGE difference in making a game fun.

If your explosions look amazing, the player will have endless fun making things blow up. For a while, they'll try to cause explosions whenever they can (exploration & testing out your limits).

If your GUI features detailed LED displays that lighten up, players may act similarly. Good sign: when you're coding something like this and notice you end up playing with it instead of just testing it!

If the sound design is exceptional, like in Don't Starve, only the act of opening up the build menu already contributes to the user having fun.


But it's not only aesthetics that make a game fun.

Rewarding the player for interacting with the environment, like loot drops from enemies or treasure chests, is also a good way to make a game more enjoyable.

To a degree, randomized outcomes (loot) gives uncertainty and make the player strive for more (rush of the unknown). Even if procedural generated content potentially becomes repetitive after a while, it can still give variety and spice up a game considerably. This is very well demonstrated in the game DoomRL or Phantasmal: House of the Shunned Ones, where each run will be different due to the fact the maps are generated and you find different equipment and enemies each time. Then, if you're lucky and good enough, you might even get to the end!

Let's take a look at Minecraft. The sheer amount of possibilities to play the game and build whatever is on your mind is probably the most important reason why it has gotten so popular. Players would create new challenges for themselves and take on them as they build whatever is on their minds.

In Fallout 4, I had a lot of fun just by collecting all weapon mods and using the best mods for my guns, because I am little perfectionist gun nut! Collecting things generally is a good idea, no matter what you collect: achievements, items, coins, badges, titles, obligatory notes that - as a whole - tell a story... or just screenshots of Fallout teddy bears!
 https://pbs.twimg.com/media/CWIptp3XIAADnF8.jpg
In games like the Fallout series, it was also fun to test out your limits in dialogue with the characters and see how they react - without suffering from potential backlash, as would happen real life. This can be a valuable social learning tool.

Things that can spoil fun a game:

A reliance on too much luck can potentially spoil a game if the outcome becomes too unpredictable. It's important to mix in an adequate amount of player skill required if the player wants to advance in a level.

Game mechanics that don't go too well and are in conflict with each other are another aspect that can spoil much of the fun.

For example, take a look at Don't Starve: it's a survival game taking place in a procedural generated world, but exploration is actually discouraged by the fact time is very limited and you die in the dark. Damn Charlie stealing your soul at night! This also puts the player under a lot of pressure. Of course, this can be fun for certain players, but after a while patience runs low and most just prefer to quit the game instead. Something you, as someone who makes games, should avoid!


I hope my insights gave you an interesting perspective on the topic "fun". Thanks to @TheSnee for giving me some ideas for this article!

If you want to check some more game development related articles, you may be interested in how to store your data in a Java game or check these 5 useful tools to start out gamedev.

Montag, 9. Mai 2016

CamoTactics Report #8: Gifs Galore & Version 7 imminent!

Hello my friends, b5cully reporting in with some new stuff to show to you!
I'm proud and happy to announce that a new build is in the works and that it will be ready in 30th this May. Finally!


With the port to libgdx framework, 70% of the game had to be completely redone from scratch. That practically means I created a new game using ideas and a bit of code from the old prototypes I had. The result of that you can see here: Blood, sweat and tears, but oh boy, it is worth it! Let me show off some awesome features of the new build while it's still hot!


Camouflage is now more interesting than before: Tanks got a camo pattern now and become more transparent the more the camouflage color matches the ground color. This not only affects your own vision - this stuff also affects the vision of all bots you will play against!


camo2camo1


The interface got a complete makeover, for example with a better attachment editor for your customized weapons:


CamoTactics Attachments 2


Weapons also change size once you attach a scope or magazine to it (something that didn't work before Version 7). Attachments do not have a function yet (except the magazine). Oh and you can change equipment in a very similar fashion!


Check this fancy main menu that slides out when you hover over it:


CamoTactics Slide Menu


Items that lay on the ground use their original icon and change their scale to highlight they can be picked up. The HUD below the soldier is also noteworthy, as it displays health, ammunition and reload status. It will be later replaced by a better, more stylish HUD and the possibility to set your current target by pressing a button.


CamoTactics Wobble


Inspired by an older dev build I had, I also made this nifty parallax main menu.


CamoTactics MainMenu 2


There are still a lot of features unnamed, and few more left to port from older versions!


I hope you're as hyped as I am for this demo version 7!
Stay tuned and thank you for reading!

Samstag, 7. Mai 2016

7 Tips for Your Indie Game Marketing

I've been observing Twitter for a long time now, trying to figure out marketing tricks and also acquiring the mindset that successful marketing requires. It's a hard thing to do when you're naturally shy and rather introverted like me. However, there are a couple of things that I figured out and that you might find very useful, too.

So here's the list of 7 tips for your indie game marketing:

  • 1 - Find out how your audience ticks. There's certain wordings that are more catchy than others - and therefore may grant you more interest and retweets. You have to choose your words in a way your target audience can relate to.

  • 2 - Always include images, or even better, videos to your posts and tweets. This will grant you a larger chance of engagement.

  • 3 - In general it's recommended helping and serving your target audience with your products or services. Expressing that helps too.

  • 4 - Keep your wording and posts personal, enthusiastic and honest. It will show your audience that you, after all, are human too, and not a untouchable corporate entity. Share your story and add your own flavor. Your passion needs to be contagious!

  • 5 - Always keep a link to your platform (blog, website) on your profiles. This allows you to let interested people find more of what you do. Also do this when creating content (graphs, pictures, screenshots, memes...). Keep a link to your site as watermark on those. In case your content spreads on the internet, the source (your blog, facebook site, twitter handle...) will also spread. It's not going to give you extra exposure directly, but may create more awareness: "Oh look, I've seen this somewhere before, I want to know what it is!". I admit, I am slacking on this one at times!

  • 6 - Use humor to make your content more interesting (and memorable). Humorously showing a newly discovered bug feature in your game is worth a couple of additional clicks.

  • 7 - Ask your audience what it wants (e.g. with polls). There are studies out there that indicate certain trends. While without doubt helpful to figure out a direction, these trends may not apply fully to your own audience. This is why it's important to figure out what YOUR audience wants - not the one who participated in those studies. After all, your audience could be a very special subset that behaves very differently. This can help your ability to detect trends. And only a flexible and adaptable salesman or saleswoman is a good one!


Summary



I want to encourage you to experiment by yourself. Trial and error are one of the best teachers. Then write down your results and share them with the world. Be like a scientist! That alone can drive your engagement into new highs. It does for me ever since I started doing it, and it's been only a couple of days! Imagine what would be in a span of a few months. Exciting!

Freitag, 6. Mai 2016

How to find Quality Hashtags to expand Your Reach?

Today I was wondering what hashtags people on twitter use and which hashtags have a good chance to create engagement (either retweets, faves or replies). Out of curiousity, I conducted a short study about this topic.

Using the service social bearing I took a closer look how different game development and gaming related hashtags performed. The hashtags I examined were #gamedev, #indiedev, #gamersunite, #gaming, #indiegames and #indiegame.

The sample sizes here are small and I had to pep up the data manually. Despite of the sample size, the results speak volumes.



Reach per minute: How many unique users are reached per minute on average.
Impressions per minute: How many impressions/views are given per minute on average. Includes combined followers and multiple views by the same users.
RTs/min: How much is retweeted per minute on average.
Faves/min: How much is faved/liked per minute on average.
Replies/min: How many replies are received per minute on average.

To visualize the data better, I created some charts here.






It looks like the #gamedev and #gaming hashtags are great to reach a lot of people, but if you want to connect to the community to keep in touch, ask questions or exchange ideas, #indiedev, #indiegame and #GamersUnite may be a better choice. Completely irrelevant seems the #indiegames hashtag here.


Is the data coherent with practice?



Now I was curious whether this holds any truth, so I looked at the data using twitter analytics. Before this, I was wondering how to make my game, CamoTactics, more fun and interesting and tweeted about it.

Take a look at this tweet. I was trying to ping on devs with this one.


Now compare with the same tweet, where I used different hashtags, trying to approach gamers.


Interestingly enough, the results of my small study were somewhat similar to what actually happens.

At the time I'm writing this, the first tweet had more retweets, but 100% of them were by bots. It got a few favs from real accounts with an engagement rate of 2,3%. Only one real person replied to this.
The second tweet is more interesting. Some of my followers jumped into the conversation, including someone who I've never seen around. There was only one retweet, but four replies. The engagement rate of this one is 2,8%.

The second tweet actually made people engage with me. This is interesting, because according to the social bearing data, since #gamersunite may have less reach, but generated more replies. This could have many reasons and the fact I posted on that hashtag doesn't necessarily needs to be one of them.

More social experiments are to come soon! In the meantime, you are most welcome to download a demo build of my game, CamoTactics, here.