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!

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!


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!

Donnerstag, 5. Mai 2016

5 Free, Must-have Tools to Start Out Gamedev

Ever wanted to get into game development?

Yes?

Then read on!

You probably have wondered how to start out making your first game. Maybe you tinkered around with scripts or mods but never made something all by yourself. Fear not, for this article will give you an insight how to start out your development without much hassle.

Out of incredible amount of tools that exist to create games, I now present you 5 tools you should use starting out your first 2D game.


  1. Editor: Unity 3D

    Unity is a cross-platform, user-friendly 3D engine that allows you to quickly get a game and some gameplay running without worrying too much about the technical side of things. It features a huge asset store and many tutorials that help you kickstart your game development. The engine can also be used for 2D games.
  2.  Graphics Program: Krita

    To create all the game art you need, you will need a graphics program. A good choice here is Krita, which is a powerful tool to create your assets. I've used many graphics programs in my life, from Photoshop to PhotoImpact and Paint Tool SAI - and Krita has an astounding amount of features for a program that is open source.



  3. Map Editor: Tiled

    If you want to make a game, you will also need create a world for it. The map editor Tiled comes very handy here. It allows you to create terrain brushes, add images and objects to the world and define properties for each. All in all it's a great editor that is free for you to use. To load Tiled maps into Unit3D, you can get this plugin to add TMX support to your project.



  4. Music Editor: Bfxr

    What's a game without sound? With the free-to-use program Bfxr, you can create your own sounds from scratch - without worrying about permission or copyright.
  5. Organizer: Trello

    If you do your daily dose of development, you also need something to help you keep track of your tasks and bugs! (Believe me, there will be many...) Trello helps you to do just that and get organized. You can create to-do lists and spreadsheets very easily. It's also available as mobile app. (Thank you @PeculiarCarrot for pointing out there is also Hack 'n' Plan for this purpose!)

If you want to check out a larger choice of tools, I recommend you to check the resource page.

Happy coding! If this inspired you, make sure to show me what you've made!