Research & Development? Whats that?

Posted in Programming on August 30th, 2010 by Philipp
No Gravatar

Hi! I’m Philipp, Lead Programmer of Rough Sea Games’ Research & Development department. And when I mention this, I often hear things like “R&D? Oh, you’re the Tools-Guy” … or … “Ah, so you do all the stuff nobody else likes to do”. Well, it seems to me as if there are some Clichés attached to the job as an R&D Programmer. And since “Myth-Busting” is the latest cool thing nowadays, I’ll totally jump onto that train! With this and the following blog posts I will try to show you what R&D is about “by example”. Maybe it will help you to decide if you want to be an R&D Programmer, or, if you should establish an R&D department in your company.

So, rumor has it that R&D is just about Tools. And indeed, the R&D of Rough Sea Games is responsible for the Gui-, Map-, and Asset-Editors, used by our Designers to create content for our game. Furthermore, we have created an Admintool to administer our game servers. Thomas will go into more detail about this in his blog posts. Anyhow, it seems as if the Clichés are true…these are all tools.

Well, but that’s only half of the story, it is the “Development” part of R&D. In the Research part, we are investigating into new render techniques, new frameworks, and as you might know from previous posts, into new platforms. The goal is to find new technologies that advance our workflows and products here at Rough Sea Games. And yes, that implies working on the engine and game framework.

But why do we need a whole department for that? Can’t we spread the research-tasks to everyone in the company, so everyone does “some” research. Well, of course we could. But most of the time, everyone else is far too busy doing game development, and in our opinion, research shouldn’t be done alongside other tasks. If you distribute the research tasks among the project workers, the tasks are in competition of priority with the project tasks. Usually, the research tasks will “loose” against the project tasks, and thereby they won’t get the recognition and resources they should have.

But of course, having an own R&D department can be expensive. If you can’t cover the costs through your project, you can’t effort an R&D. Right? – Wrong! It’s not an easy decision to make, but you could try to gain some profit out of your R&D if you develop your tools  in a way that they can be used as middleware, which could be licensed to other parties. We would like to try this with our Admintool. So far we can’t share any experience there, it is still work in progress. But we will let you know as soon as there is something to write about.

As you can see, R&D is most of the time about providing and maintaining technology, be it middleware or new engine technologies. And in some companies, this is even called the “Technology Group/Department”. If you like this term better, it’s fine with me. The important thing is that, in my opinion, a company will profit a lot from a group like that, to be well prepared for future things to come.

“Yeah yaeh, yabber yabber, technology, middleware….is this even Game Development anymore?” you might ask. I guess this question has the same taste as the beforementioned “Ah, so you do all the stuff nobody else likes to do”. But before I start writing about “what is Game development” or start a discussion about likes and dislikes, I will show you some examples of what we do here in R&D in my next blog posts, and you can judge for yourself.

Popularity: 5% [?]

  • Share/Bookmark
Tags: ,

Singletons for AS3

Posted in Programming, Tips on June 21st, 2010 by Manuel
No Gravatar

Singletons the curse and blessing of many coding projects. ;) Among other pitfalls, you’ll basically introduce a global variable in your system, making UnitTests much harder.

Why Singletons?

Despite the possible problems they can present, they are just so darn handy sometimes. If there is some part of your code that needs to be accessed from almost anywhere in the system (like the sound system, or a global error text console and such) there is hardly a better way to achieve that.

Alternatives?
A global messages system to communicate between objects can achieve the same effect. We used to make heavy use of such a system system. However, according to our experience, maintaining that system is fairly time consuming for it gets more and more complicated over time. Besides, if a messaging system allows queing, you’ll never really now where and why a message was sent because you loose the stacktrace. So, right know we are reducing the work-load done by the message system, handing it over to direct singletons access. By this, we increased debugability and clearity of data transfer. Besides, using singleton access is much faster than routing it through our messaging system.

How to Do It?
The web already offers a bunch of solutions (1). Most of them boil down to implement the singleton code over and over again in each singleton. We didn’t like that and tried to come up with a better solution. When we define a singleton it looks like that:

/**
* Accesing this class somewhere in the code looks like this:
* cSomeController.GetInstance().DoSomething();
*/

public class cSomeController extends cSingleton
{
    public static function GetInstance():cSomeController
    {
        return cSingleton.GetInstance(cSomeController);
    }

    public function DoSomething()
    {
        trace("Yes, I can.")
    }
}

That is much simpler than copying&pasting the complete singleton code over and over. The corresponsing cSingleton-class looks like that:

package rsengine.patterns
{
    import flash.utils.Dictionary;
    /**
    * Singleton base class
    */

    public class cSingleton
    {
        private static var m_instances:Dictionary = new Dictionary();
        private static var m_unlockConstructor:Boolean = false;            

        public function cSingleton()
        {
          if (m_unlockConstructor == false)

          throw Error("You cannot create an instance of a singleton."
          + "Use GetInstance instead!");
        }

    /**
    * Returns an instance of the specified class
    * @param _class class
    * @return instance of specified class
    */

    public static function GetInstance(_class:Class) : *
    {
      if (m_instances[_class] == null)
      {
        m_unlockConstructor = true;
        m_instances[_class] = new _class();
        m_unlockConstructor = false;
      }
      return m_instances[_class] ;
    }
  }
}

Our singleton implementation significantly reduced the amount of code you have to copy&paste compared to the other singleton implementations out there on the net. We do know that our implementation of GetInstance() is a little slower (because of the Dictionary look up). Since you shouldn’t have too many calls to the GetInstance method this is probably nothing to worry about too much. Nevertheless, you could cache the result of GetInstance() if you do need to access the singleton more than once (e.g. in a loop).

Have fun and happy coding
Manuel

AS3: Singletons, ActionScript 3 Singleton Redux, google

Popularity: 17% [?]

  • Share/Bookmark
Tags: , , , , , ,

InnoDB the “case-sensitive monster”

Posted in Programming, Server Administration, webdesign on June 4th, 2010 by Ole
No Gravatar

Hello,

this posting is about InnoDB’s limitation of lower / upper cases and the resulting problems of
InnoDB database migrations to different operating systems.

THE TASK:

Import an InnoDB database from Mac OS  MySQL  5.x to Linux MySQL 5.x (in our case Rhel 5 ).

No big deal, I thought.

Made a mysql dump and imported the dump to Linux.   5 minutes work, just the way  admins love it ! ;-)

THE CHALLENGE:

Imported the dump. I am done! That’s what I thought. Just let’s check the app that accesses the freshly imported DB.

Running the app brought me exceptions. Some tables couldn’t be found… URGH! Checked the tables… everything was fine. The dump was fine… the tables were present. WTF!!!!!

THE SOLUTION:

After 10 hours of pain, we found the solution.

MySQL and especially the storage engine InnoDB depends on the case sensitivity of the operating system. Windows and Mac OS (by default) are not case-sensitive.  So if you are importing a Mac or Win DB-dump to a case-sensitive operating system (like Linux), the DB will be handled case sensitively, although the dump is not a case-sensitive one. I think this problem should be fixed. I know fixing this problem is nearly impossible because the OS has to be capable of doing this. But giving some sort of warning while importing a non-case-sensitive DB to a case-sensitive DB-Server… that can’t be so difficult !

How to fix our specific problem:

Add the following line to your MySQL Server Config:

lower_case_table_names=1

By default Windows MySQL uses lower_case_table_names=0 and MacOS MySQL lower_case_table_names=2

The MySQL documentation advises setting lower_case_table_names=1 for InnoDB. For more information, please read the MySQL documentation.

Popularity: 18% [?]

  • Share/Bookmark
Tags: , , ,

Numeric Enumerations (Enums) for AS3

Posted in Methodology, Programming, Tips on April 14th, 2010 by Manuel
No Gravatar

Something I really missed in Actionscript 3 were enums. If you need ascending unique numeric ids ( e.g. for naming array indexes ), enums are your friend.

For our current project we programmed a messaging system. The system uses unique numeric ids for message types and message channels. The list of messages and channels grew over time and right now each list contains more than a hundred entries. In the beginning we did the numbering ourselves like that:


    public static const MSG_OPEN_WINDOW:int = 0;
    public static const MSG_CLOSE_WINDOW:int = 1;
    public static const MSG_REGISTER_TIMER:int = 2;
    // .. and so on

For code beauty we were always trying to group related message ids, which often meant to re-index dozens of entries if we inserted an id somewhere in between. This was a pain!

The net already has assembled quiet some wisdom about “fake enums ins as3″¹, which do fit different needs (like some have type safety) but unfortunately not ours. Most of them are String based, which is what we did not want. So after putting in some thought we came up with a solution that worked for us. Now we can define our enums like this:


    public static const MSG_OPEN_WINDOW:int = cEnum.Enum(0);
    public static const MSG_CLOSE_WINDOW:int = cEnum.inc;
    public static const MSG_REGISTER_TIMER:int = cEnum.inc;
    // .. and so on

Now, by using static methods and a static counter we can create an arbitrary amount of coherent numeric values, which comes in very handy from time to time! Re-indexing is in the past now!

We want to share our little enum class with the web, so here it comes:


public class cEnum
{
	private static var m_currentIncrement:int = 0;

	/**
	 * Adds an enum value to the collection
	 */

	public static function Enum(_v:int) : int
	{
		m_currentIncrement = _v;
		return m_currentIncrement;
	}

	/**
	 * returns the next increment
	 */

	public static function get inc():int
	{
		return ++m_currentIncrement;
	}
}

Bottom line, if you need a neat way to maintain a list of static coherent numeric entries while type safety is not a big issue … this is an fairly easy way to do it. May this help you out there as much as it helped us.

Have fun and happy coding
Manuel

¹ Further readings on AS3 enums can be found here: e.g. http://www.herrodius.com/blog/87,
http://scottbilas.com/blog/faking-enums-in-as3/
or http://blog.petermolgaard.com/2008/11/02/actionscript-3-enums/

Popularity: 29% [?]

  • Share/Bookmark
Tags: , , , , ,

Effortless Text Localization

Posted in Methodology, Programming, Server Administration, Tips on September 29th, 2009 by Thomas
No Gravatar

Automatization of repeated work is one of the keys to productive development. Another is abstraction of common problems to allow concentration on project specific work. Localization is one of the problems you have in nearly every project, especially in iPhone projects. The iPhone SDK brings interesting solutions that abstract many parts of the localization process.

The tool ibtool, for example, extracts strings from an interface automatically. The strings are placed in a .strings file, a textfile with key/value pairs. To localize an interface, you have to translate .strings and merge the strings back into the interface again. Because you have individual interfaces for every localization, it’s possible to adjust widgets individually for each one.

genstrings is another tool inside the iPhone SDK. It extracts textIDs from the source code and write them into a .strings file. You may ask how the tool knows which texts need localization and which do not. The solution is the macro NSLocalizedString, which will be replaced by a .strings file lookup method by the preprocessor, but also searched for by the genstrings tool to create the files.

Both tools help you to create a localized application without paying much attention to localization itself. But you cannot expect the localization department to search for .strings files inside your project and create localized versions of them. Of course this would be possible, but not very convenient, because you have to migrate the translated texts back into the interfaces using ibtool. Another reason for us at Rough Sea is that we use a localization interface from our publisher. This interface is well known to the localization department and the content is placed in a centralized database on a server.

So we have the great tools from Apple that help us to separate texts from the project and we have the great tool from our publisher that handles the whole translation and reviewing process. Now we need something to tie those tools together, because we do not want to insert new texts from the .strings file into the publisher’s localization tool manually or vice versa. This glue tool has to execute the Apple tools, extract the texts from the .strings files and insert them into the publisher’s loca tool. On the other hand, it has to check for new localized texts from the publisher’s loca tool, build the required .strings files from the results and merge them back into the interfaces. Sounds quite easy, but of course there are some obstacles to get there. You have to handle other things, like the deletion of a text entry or changes to an already translated interface. So you have to know what has changed since the last update and stuff like that.

It turns out that you only have to integrate this glue tool into the build process of your build server. The tool will update the localization database whenever the code or the interface changes and it will update the localized versions when the database changes. As a coder you only need to remember to use the text macro around your text id. You don’t have to add this text id in a file or anything else. As you commit your changes, the build server will do this for you. As an interface designer it’s the same: just create your interfaces in the primary language and commit it. After the localization department finishes localizing those texts, they will be inserted into the localized versions automatically. Of course you have to make adjustments to the interface if there are loca bugs like labels that are to small to hold the translated text.

As you can see those localization tools are a big black box for coders, interface designers and translators. The coders only have to write code, the interface designers design interfaces and the translators translate texts. At the end there will be a localized product.

Popularity: 66% [?]

  • Share/Bookmark
Tags: , , , , , , , ,

Random Map Generation

Posted in Art, Programming, Tips on August 24th, 2009 by Manuel
No Gravatar

Designing an appealing and huge game world from scratch will take even really fast designers a looooong time: valuable time that can be spent in better ways. This is where generated content comes in handy. With the push of a button a designer can create a whole world (oceans, land, forests, deserts, mountains, cities, … ) in an instant. So this is what we decided to do for our game … and here is how we got to the finish line:

On the bumpy road to an actual working map generator we decided to split all map generation tasks into small modules: heightmap generator, water generator, forest generator, desert generator, and so on. In the map-generator GUI the designer can put these modules into a task list and define the order in which they are executed. Each module also has parameters that affect the characteristics of the generated map. Even though it is supposed to be a random map generator it is especially important to have deterministic behavior. Consequently, each module that actually generates content has at least a “seed” parameter for the random number generator. With the same seed the generator will create the same results every time. Changing the seeds will create a different map.

map generation steps
In the little animation above you can see the output of some of the modules.

Heightmap Generator
At first we create a heightmap. We use Perlin noise since it is built into the AS3 BitmapData class and it is amazingly fast. In the beginning we experimented with our own implementation of the diamond-square algorithm, but it was way too slow.

Water Fill
In the next step we apply water to the world. We simply declare everything below a certain height level as being under water.

Mountains
By looking for local peaks we detect mountains and flag the areas accordingly.

Humidity Map
By defining a water contingent that grows over water and decreases over land we can flag dry and wet zones on the continents. To make things easier we define our whole world as a west-wind zone. The centers of most bigger continents will be dry (yellow), coast regions will be mostly humid (green) and continental areas lying east of a big stretch of water will be very humid (dark green).

Climate Zones
Next we define climate zones in the world: tropical areas, temperate zones and polar regions. With this information we can easily place polar caps in the world.

Forest Generator
Using the information from the climate zones and the humidity map makes it possible to place different types of forests into the world. Jungle (purple) will be found in the hot and wet regions around the equator, while coniferous forests will be found close to the polar caps.

Desert Generator
The desert generator also uses the information from the humidity map to detect dry regions and place desert areas into them.

Well, now you had a look at some of the modules in our map generator. They are not only capable of creating earth-like maps (like the small sample map above) but also completely different maps by changing the parameters: a lake landscape, a waste land, a desert or whatever our games may need. With this we are able to quickly create new game content of any size for the players to explore.

Cheers,
Manuel

Popularity: 100% [?]

  • Share/Bookmark
Tags: , , , , , , , , , ,

R&D goes iPhone

Posted in Company, Programming, Tips on August 3rd, 2009 by Thomas
No Gravatar

Hello out there,

my name is Thomas and I am the first programmer in our new R&D department. Like most of the other guys here at Rough Sea, I’ve worked on games for consoles (Nintendo DS and Wii) and PC before. I’m very excited to develop sophisticated software that helps us to make state-of-the-art games. Of course this is only technically, but I’m pretty sure that Rafael and Jan will assure this for the design part too.

I assume you’ve read the headline already, so you know what the R&D department will work on in the coming months. We’ve decided to do some research on the iPhone, because we think the way you use the iPhone is almost the same as how you play a browsergame. You get your iPhone out of your pocket, use it for a few seconds and put it back again. You have nearly the same procedure with browsergames: you open your browsergame window/tab, change a few settings and go back to work.

So the first thing to do is getting your working environment running. The only legal way to do this is to buy a Mac. I’m not really happy about that, because I’m a Windows guy and there are some differences in using MacOS instead of Windows. Maybe Apple only invented the app store to sell some of their Macs to iPhone developers. Nevertheless after some adjustments the Mac became usable. The nextStep (pun indended) was the installation of the iPhone SDK and all the tools that belong to it. It’s quite easy to get from the installation of the SDK to the first Hello World on the simulator (especially if you compare this to console development).

We at Rough Sea use test driven development and continuous integration to assure that we always have  a deliverable product at hand. Unit Tests are already integrated into the SDK and it was easy for Ole to set up a build server on a Mac Mini with hudson and the makefile-like shell tool xcodebuild. You don’t have a makefile: the tool just uses the settings of the project file to know how to build. Another thing is that you can add and change text macros for the XCode IDE. Text Macros are very useful to write code much faster. For example, you can add an alloc-init call [[class alloc] init] simply by typing the letter a and then escape. There are macros for if, for and while too. Because we have different coding guidelines than the apple guys, I had to change some of the macros. You find them in /Developer/Applications/Xcode.app/Contents/ PlugIns/TextMacros.xctxtmacro/Contents/ Resources. Copy the TextMacros.xctxtmacro folder to Library/Application Support/Developer/Shared/Xcode/Specifications in your home directory. Just open the *.xctxtmacro files with a text editor to change the macros. You can add your own file and project templates too. This is very nice, because you can set up a default project with many settings, like Unit Test Targets, already in place, and use this project to create new ones with only one click. To add a new project template, create the project the way you like it and copy the whole project folder to Library/Application Support/Developer/Shared/XCode/Project Templates/GROUP_NAME/PROJECT_NAME. For file templates you should just copy the File Templates folder from /Developer/Library/Xcode/ to Library/Application Support/Developer/Shared/XCode/ and change or add the files you like.

Next time I will write about Objective-C and libraries from the iPhone SDK like UIKit.

Popularity: 64% [?]

  • Share/Bookmark
Tags: , , ,

Secure your Webserver (part 2- A)

Posted in Server Administration, Web security on July 20th, 2009 by Ole
No Gravatar

Hello everybody,

Finally you are able to read Part 2 of “Secure your Webserver”. Part 2 will be about Linux, Webserver and the other important services.

As I mentioned in Part 1, I will not write about Windows, MacOS or  other operating systems, because the most common one for a webserver  is Unix / Linux. Part 2 will have a part A and B. Today I am going to write about distributions,  user managament, user rights, secure shell and their enormous importance for security.

Before you start, choose the right distribution of Linux for your aims.  There are a lot of Linux versions (distributions) on the market. Most of them are free or have a free community edition. The most common free distributions are CentOS, Debian, Fedora, Gentoo, OpenSuse, Mandriva and Ubuntu. Of course there are also commercial destributions like Red Hat Linux Enterprises (RHEL) or Suse Linux Enterprises.

In general all these distributions are fine for a webserver. Their differences are minor and more a personal choice than a real technical question. A NEWBIE should maybe use OpenSUSE, Ubuntu or Fedora, as the support of the community seems to be bigger for them. Commercial products are usually superior to free distributions in their support system. They grant better support via phone, etc.

After you have chosen the right distrubtion for your purpose and installed it on your server machine, it is time to think about security.

1. User-Management and Shell-Access. (Secure Shell Daemon)

Linux security is mostly based on user rights. User rights are essential to the security concept of Unix and Linux systems. Usually all distributions are very strict and separate services (daemons), users, administrators, essential services like a webserver, MTA & MDA (Mail Transfer Agent & Mail Delivery Agent) into different groups and users.

All these groups and users have different write and read accesses. Usually groups are created to give a bunch of users the same rights. Therefore groups can make your administrator’s life far easier.

The most important “user” is called root. Root is the highest ranked user on a system. The “root user” has full read and write access. In the Windows world it would be the “Administrator”. This is the reason why it is not smart to use the root user in your everyday work. The root user should only be used for system critical and important parts. In all other cases it is wise to use a “normal” user, which you have created.
It is also possible to run root commands via your user account. Important commands for this purpose are “sudo” and “su”. Sudo runs a command line with a special user. The command su makes it possible to log in as another user via your own user shell. Of course you need the right password of the user to perform these actions.

X11_ssh_tunnellingIt is common for Linux to allow remote login via secure shell (SSH), especially if your webserver is not reachable for you in person, e.g. a dedicated server in a data centre of your webhost. All connections via SSH are encrypted. It is nearly impossible to decrypt the data via your client and your server (Maybe the NSA or the CIA are able to decrypt this – who knows?). You should take care to choose the ssh version 2 protocol. This is safer, as recently some weaknesses were discovered in protocoll version 1. A common SSH-client for Windows is “Putty”.

It is possible to permit or forbid login via SSH for specific users or user groups. Maybe it is not wise to allow direct root login via SSH. It is also possible to login via a certificate. You create an public and private key. Upload the public part to your server (usually: /homedir/.ssh/authorized) and log in without password. Of course it is wiser to secure your private key with a passphrase. In this case you need to type the phassphrase to decrypt the private key to log in.

Next part will be about firewalls, virusscanners and how to avoid spam problems.

Popularity: 26% [?]

  • Share/Bookmark
Tags: , , ,

Feel the groove

Posted in Programming, Tips on June 16th, 2009 by Joerg
No Gravatar

Our server code can be built with one click. The build process does not take long. To be precise, the build server says “last build: 1 minute 38 seconds”.  That’s cool. (And mainly it’s because the code is not that complex yet…)

But despite fast builds and because they are definitely going to get slower as the project progresses, we need the ability to change certain parts of the game logic with a minimum of work. So far this is mainly for the game designers, who want to be able to change some equations that influence the game’s balance. Defining stuff in config files that are read on server startup is nice, and we use this as well, but starting the server takes time, too. A better way is to be able to change game logic at run time.  So a scripting language was the way to go.

We decided to use groovy. Now groovy is not a scripting language at all, but more or less an object-oriented programming language that can be used as a scripting language for Java. Groovy has some advantages over Java like e.g. dynamic typing.

Unlike in other scripting languages, the groovy code is not interpreted at runtime but compiled into java byte code. So don’t forget to automatically reload the scripting files every now and then to make sure that changes in the files are actually applied.

We haven’t yet decided whether to keep the scripting in the release version of the game or not, since implementing the logic in the code is surely better for the performance. People on the Internet tend to accuse groovy of weak performance in comparison to other scripting languages.  But it is very pleasant for experimenting during development. If you don’t believe me, go ask our designers…

Popularity: 9% [?]

  • Share/Bookmark
Tags: ,

ByteArray Beats Regular Array

Posted in Methodology, Programming on April 21st, 2009 by Manuel
No Gravatar

To compare the performance of different approaches for handling large data I wrote a small test suite.

This application contains one test class (cDataHandlingTest) that writes to and reads from an abstract data class (iData). Each data class offers an unified interface but is implemented in different ways. The test class repeats each test several times, records initialization times and accessing times and then calculates the average for each data class. If you want to have a closer look on the code, you can download the FlashDevelop-project here. You can check out the test application at the end of the post.

Three-Dimensional Array (cDataArray3D)

This data class uses a three-dimensional array to store the data. Initialization takes a very long time because you need to cycle through several nested loops allocating the data. Access times are ok.

Linear Array (cDataArray1D)

Here I used a linear array for the data. Initialization for a linear area is lightning fast. The draw-back is the access, though. Calculating the offset of the data in the array is pretty complex:

var index:int = (((_y * m_width ) + _x) * m_entries) + _entryType;

This makes working with a linear array really slow if you cannot predict in what order you will access the data. If you will usually access the data in the exact order it is stored in the array, you would actually be really fast. Unfortunately, this is usually not the case. The linear array is about 10 times slower than the three-dimensional one on random access.

ByteArray Int-Based Access (cDataArrayByte)

In this example I used a ByteArray. The position is calculated in the exact same way as in the linear array example. Data is extracted by using a readInt() command on the stream, data is written by using the writeInt() command. I expected this approach to be really slow. Well it isn’t! On my computer it already outperforms the three-dimensional array in all areas. (It might not on others, though).

ByteArray Byte-Based Access (cDataArrayByteOpt)

If you only need values between 0 and 255 you can use the array operator [ ] of the ByteArray class. This is the fastest way to access the data. Initialization times are really good and access is on my computer about 25% faster than the three-dimensional array.

Test Application

This is the test. Click into the window to start. Be careful, it needs a lot of resources. If you have significantly less then 2GHz per core or only one core I recommend not to try it because it will lock up your computer for too long to be convenient.

Popularity: 7% [?]

  • Share/Bookmark
Tags: , , , , , , ,