Getting Started with Sifteo Cubes

Original Author: Peter-Smith

Sifteo Cubes are little 1.5” blocks with clickable screens on the front. They have a number of sensors in them so they can detect their motion, and their neighbors. It is hard to decide if they should be called a peripheral or a platform, but I am leaning towards the latter. They connect to a computer, but you play games directly on them. While the current set of available games feel a lot like tech demos, they create play experiences that seem completely unique to the platform. I ordered my first set of cubes around the beginning of the year, and I got in on an early release. I immediately wanted to make my own game, but it was not until last week that the SDK was made available. I ran into a few issues out of the gate, so I thought I would create a quick tutorial to help others get started tinkering with their own cubes.

First, I should mention a few things, even though the Sifteo Cubes are a unique hardware platform, there is a simulator that you can get started with. So, you don’t need to go buy them before seeing if this is something for you. I used a mac so this tutorial is for mac users. Also, getting started is pretty simple and doesn’t require programming experience, but the API is written in C#. Obviously, if you already know C# it will be easier for you to pick up long term. Finally, the SDK is in an Alpha state, so there are some issues with the documentation. I am primarily writing this to clarify some sticking points I had in the process.

  1. The first thing you will need to do is to go to www.sifteo.com/developers and click “Download Now.” After agreeing to a license agreement, you will be able to download the SDK.
  2. If you do not have the latest build of Mono on you Mac, you should download it from www.go-mono.com/mono-downloads and you will want both the Mono Runtime and MonoDevelop. The Runtime lets Mono run on your system, while MonoDevelop is the IDE you will use to write and run games on the Sifteo Cubes.
  3. Install the Mono runtime on your computer, and then MonoDevelop. I had no issues with either and used the standard configurations.
  4. Download the SitDev SDK for mac. At this point if you are using Windows you would obviously download the other one. The Windows SDK come in an exe installer and seems like it would be easier to deal with. The mac version is a .zip file. The instructions from the Sifteo site reference where you installed the SDK. From my experience this is wherever you extracted the .zip. I put mine in ../Users/Name/Development/ but you could put it wherever you want. The issue will be linking to it later.
  5. From here the current developer documentations explains the anatomy of a Sifteo Project and how to generate one from scratch. For me, it seemed more important to make sure that I had installed everything correctly and that I could build my own apps. To do this I wanted to test the demos found in the /Sifteo_SDK_mac_1_1_2/demos/ directory. If you open the .html file you will see a description of the 4 available applications. The first is “Hello Sifteo” a standard hello world developed for Sifteo.
  6. In order to build Hello Sifteo you need to first open MonoDevelop. I installed this in the applications folder. Once this is open there will be opening splash screen with a section in the top left that says Common Actions. Select Open a Solution / File from there.
  7. Navigate from there to the demos folder in your SDK directory open the 01_HelloSifteo folder and select the 01_HelloSifteo.sln file. This will open the solution in MonoDevelop.
  8. At this point if you were to try to build the project it will not work. You will need to update the references in your project first. To do this goto Project > Edit References. In the popup you will need to delete the current Sifteo Reference.
  9. You now need to replace the Sifteo reference. Still inside the Edit References window, select the .Net Assembly tab, then point it to the Sifteo.dll file.
  10. I spent a lot of time looking for the Sifteo.dll but on mac it is actually inside the Siftdev.app which I found as quite a surprise. It is at <SIFTEO_SDK>/Siftdev.app/Contents/Resources/Runtimes/Mono/Current/sifteo/Sifteo.dll … Obviously. (Thanks to Martin and John on the Sifteo forums for that.)
  11. You can then click the add in the upper-right corner of the window.
  12. Now you can build and run the app. Once you do this, nothing really happens. You get an application output of 127.0.0.1:7000. In the background the app is now running waiting for you to run it in the SiftDev app.
  13. Back in your Sifteo SDK directory you will find an app called Siftdev. When you run it you will be asked to login to your Sifteo Account and after skipping an intro you will be presented with your current games. Now you need to open the Developer Menu and select Load Apps… and load the folder called demos that contains all 4 demos.
  14. The four demos will appear as games that you can run.
  15. If you own cubes you should connect them to the computer at this point. If not you can launch the simulator. This is a program in the SDK directory called “Siftulator 00_05_09 alpha” or whatever version you have. This will open a window that contains 3 simulated cubes.
  16. On the bottom right of “Siftdev” you should see 3 blue connected cubes. At this point you can click on the “Hello Sifteo” Demo as it should still be running in MonoDevelop. This will bring up another screen with an orange play button on it.
  17. Click Play in “Siftdev” and the demo should work immediately in the simulator.

The other demos require similar effort to get working. This should be enough to get you started in the right direction and I will post more as I start building my own apps.

 

 


AAA to Mobile. Discuss.

Original Author: Keith Fuller

Although I’m working with clients in mobile games these days, that’s as a consultant. I’ve never actually been a “team member” with a group of folks making a mobile game. I think that’s a critical difference so I’m really asking more questions here than I’m answering. Particularly if you have in-the-trenches experience in both realms, please comment with your views.

The topic has bounced around in recent days (er…recent months, rather) about what it means to developers to shift from AAA to mobile. There are a ton of great questions to ask. How does that impact your production? What tools make more/less sense now? How is communication changed? Does it increase or decrease your tendency to crunch? Do you feel a lessened sense of stability with regard to continued employment? Even in the phone and tablet space there are still a number of different sizes of projects, but if you’re generally looking at a group of less-than-ten people over less-than-6 months, how have things changed from AAA to mobile?

I think there are some obvious points that leap to mind. Your iteration time has changed regarding the development of game features since your cycle is more like a couple of months instead of a couple of years. With a smaller team your content depth has decreased accordingly since you’ve got maybe 20 or 30 dev-months (or in some cases, only 11), and that’s for production values in the upper end of the spectrum. The cost-benefit analysis of sticking with a particular framework or process is easily upended…why bother with daily standups or weekly TPS reports when each of the five developers already knows what the others are doing?

The issues that I’m more curious about, though, come down to the personalities of the team members and the makeup of ex-AAA mobile teams. If you make this shift for reason of increased creativity or to break off the shackles of traditional publisher-funded development, does that imply a type of mentality that handles the challenges differently? For instance, on your typical 50- or even 100-person AAA team, one of the first things I tell people is that they need decisive leadership with a solid creative vision. While it is hopefully the case that all 23 programmers and each of the 38 artists are encouraged to contribute their ideas, ultimately the project must be steered by someone who knows where it’s going and can tell you what to do to get there. But with a team of four people working for as many months, do you still feel that same need to place that trust in a single driver? Or do you need every person on a successful mobile team to be as driven as the others? I’ve seen AAA projects get done with comparatively few shepherds and a high number of sheep. Can that work for a handful of people trying to carve a niche out of the Android Market? I’m genuinely intrigued to hear people’s opinions.

Most folks realize it’s difficult to get noticed in a flooded market of inexpensive games where everyone and their mom can put something on the App Store even if it’s ganas a required ingredient?

Like I said at the outset, more questions than answers. But if you’ve got an experienced viewpoint to share – and my contention is that many of you do – please contribute in the comments.


A Pre-commit Checklist

Original Author: Ivan-Assen-Ivanov

Technology/ Code /

We have been talking a lot lately in the office about the true cost of easy bugfixing. You often hear that a bug gets more expensive the further down the pipeline it exhibits itself; however, the true cost is easily hidden from the eyes of the programmer, for whom a fix is just a couple of keystrokes. It is tempting to mow down bugs and watch the statistics fly up, but you might just be kicking the can down the road, were a single bugfix today could mean two bugfixes tomorrow.

I’ve been thinking of a semi-formal pre-commit checklist, similar to a pilot’s pre-launch list.

Some of these are trivial, some may not apply to your development process or product; some could be solved by more automation, while others are the kinds of things that should keep technical leads awake at night. “Find someone to talk to” may be added to many of them; and “take your time” to all.

Here’s the list I came up with.

Does it compile?

No, seriously. People seem to be unable to resist the temptation of “it’s a trivial change, I’ll just fix the typo and commit back”. Fortunately omissions of this type are relatively harmless, as they are caught quickly. The embarrassment, however, is real.

On all platforms and configurations?

I recently did a search for “fixed xbox compilation” in our Subversion repository commit logs, and I’m not telling you how many hits I found until I am safely retired. Think of other platforms (PC/360/PS3) and configurations (Debug/Release/RealRelease/EvenMoreRealRelease etc); if possible, try to recompile for all of them. If compilation is so slow that this is impractical, work on your compilation times!

Does it run at all? Does it really run your changes?

This is especially important with dynamically typed languages, where you detect very few problems at compile time. Make sure the game runs, and make sure you are really exercising the code you introduced or modified. Place a breakpoint in your debugger and trace around.

Did you read your changes line by line?

As a wise friend of mine oft says, the job of a programmer is not to write code; it is first and foremost to think. Don’t skim; read carefully every change line by line in your diff tool, and think about them.

Did you clean up prints and supplementary debug code you wrote?

If you added prints, disabled optimizations locally or wrote some debug code to help you find the problem, clean it up! Verbose output logs littered with debug prints are hard to read, hide real issues and often are ignored. If you have built some kind of debugging support which is both non-trivial and likely to be used in the future, then by all means, clean it up and commit it – but do so in a separate commit.

Do you understand the bug? Is it fixed? Did it “fix itself”?

Did you reproduce the bug without your fix and verify that it disappears when the fix is applied? Or did you just happily assume that because you wrote some code and now you can’t observe the bug, it was your code that fixed it? Correlation does not imply causation.

Even in edge cases – errors, hostile user behavior etc?

The bug, especially when coming from testers, was most likely encountered during “normal use”; what happens when you exercise the edge cases? Is the code “around” your change still working? Make sure you test more code in the vicinity of your change, not just its direct effects. For example, if you added a new setting to the options dialog, make sure the entire dialog still works, options are properly saved, loaded, or restored as appropriate on apply or cancel etc.

Did you delete code made unnecessary by this change?

If you deleted code as part of your fix, check if you should delete more. If what you deleted was the last usage of a local utility function or a global configuration variable, think about whether these should also be deleted. Will they be of any use to potential future code? I have seen long configuration files with system and gameplay constants defined that haven’t been used for years; it is easy to add yet harder to remember it needs removing.

Is it the simplest possible code that works (but no simpler!)?

Choosing the right spot on the simple/clean/hacky <–> complex/flexible/over-engineered continuum for each thing you do is ultimately one of the most difficult aspects of software engineering. It is the hardest to put down in rules and it requires the most experience and wisdom. A great amount can be written about it, and still no recipe given. Imagine yourself having to maintain the code ten years from now, at midnight, with a headache, talking to an intern you have never met, on the phone.

Did you properly set up the commit in your source control system?

Did you e.g. add the files in Subversion or git? Did you delete the files no longer referenced by any projects? Are you working in the right branch?

Is the commit message short, informative and clear?

The most important role of the commit message is to help someone reading the log a year from now to find what he needs. Jokes, profanities and passive-aggressive whining might seem interesting, in a literary sense, right now, but chances are they’ll be stale on the next day.

Did you significantly change the performance or memory usage?

Is your change using more memory? Have you changed, for the worse, the Big-O complexity of the code? Does it have significantly more allocations than the old code, directly or indirectly? If using a language with a GC, are you generating more garbage for the collector? If you answer yes to any of those, think about how it affects the overall performance of the system. Can you afford it? Is it warranted, in terms of bang for buck ratio?

Does it work in non-developer mode? Should it?

Many developers run their games in a special “developer mode” during development, where more debug facilities are enabled. Maybe you accidentally made your code depend on this developer mode, and it will not run when QA plays the full release version? Or maybe you left debug functionality enabled in non-developer mode?

Does it affect savegames?

Savegames are finicky, fragile beasts. Is there any new state introduced by your code change which has a need to be explicitly saved, or explicitly forbidden? If you changed anything related to the game world, ensure it works across save and load. (Corollary: strive to have working save/load from day one, and to keep it working.) If the game is already released and you’re working on a patch or DLC, make sure you test both forward and backward save game compatibility.

Does it affect localisation?

If you are changing anything related to the UI (but not only!), think of how your change will be affected by localisation. Did you introduce new text? Is this still allowed, or is the localisation table locked down and sent to be translated? Did you leave enough space in the UI for more verbose languages? Are you letting user-input strings through to the filesystem and does your filesystem allow the encoding you used?

Does it affect multiplayer?

Depending on your multiplayer model, this can cover many things. Did you fix the corresponding parts on the client and the server? If you have a lockstep networking model, did you introduce new desyncs by accessing uninitialized variables and haphazardly pulling random numbers off the wrong generator? Have you allowed the players new ways to cheat or draw penises inside the game?

Does it affect threading?

Anything which touches directly low-level threading code, even a “completely safe” critical section, must be double and triple-checked. Code that introduces new synchronisation primitives or threads, IMHO, must be discussed with and reviewed by another programmer before committing.

Does it affect cert?

This is a huge topic by itself; very few people in the studio can keep in their mind all the requirements for the different platforms; but you should at least know the basics in your area of expertise. For example, if you do any UI work, you should check that you have not introduced any important UI elements near the edges of the screen.

Does the fix require art or game content to be redone? Does the bug affect other pieces of art or game content? How can you find them?

If the bug is related to consuming “content” such as art assets, mission data or localisation tables then sometimes you need to redo them (by hand via the artists) or reprocess them (e.g. if you fixed a pipeline tool). Can you automatically find all other content pieces that would exhibit the same bug? Do you need to let your artists or designers know about the problem? Should they do something differently?

Should the fix be merged into other active branches?

Is the fix relevant to other branches of the same codebase under active development? Let the maintainers of the other branches know about them but do not merge blindly, go through this checklist for each merge destination!

Did you update the adjacent comments in the code?

There is an old adage claiming that “when the code and the comments disagree, they are probably both wrong”. Do not simply ignore comments for the buggy code you just fixed; at least delete them if for some reason you do not update them.

Did you update the documentation relevant to the change?

Here “documentation” can be anything from Doxygen-style function headers and class overviews, tooltips and description texts in tool GUIs, to test plans or external documents such as a wiki. Your change might do more harm than good if it doesn’t also include the documentation.

Are there other bugs for the same issue filed in the bugtracker?

Some types of bugs are frequently misinterpreted by testers and filed numerous times, without them ever recognising it is actually the same bug. Make an effort to seek all instances out and resolve them, this maybe the most pleasant part of this entire checklist!

Are similar bugs likely to exist in other systems? How can you find them?

Think of other places that might have the same problem you just fixed; for example, if your highscore browsing code does not handle network timeouts properly, the probability is high that your user-generated-content browser does not either. Should this be fixed in each place, or should a common part be refactored out of these sections?

Do you understand why the bug was introduced in the first place?

Were there any other bugs introduced by the commit, maybe due to the same mistakes or false assumptions?

Bugs do not appear in the codebase because programmers are evil and it is rarely the case they are intrinsically stupid. Try to find out which false assumption or lack of information led to the bug, and read carefully through the commit that introduced it, especially if it was a bulk commit with a large amount of new code.

Can you prevent it, or other similar bugs from appearing in the future? Better interface, automated tests, more data validation?
With each bugfix, try to improve the usability of your internal development; do not just fix an art bug, instead make the tools used by the artist warn about it as early as possible (export time is better than process time, which is better than load time, which is better than runtime); do not just fix a misused API call, try to redesign the API so that it is easy to use correctly and practically impossible to misuse. If you don’t have an automated test system, think about setting one up. And finally, maintain a “smell map” of the codebase – know what subsystems are due for a cleanup, refactoring or redesign next time you have some breathing space between projects.

 

This is my list. It is probably heavily biased towards my work as a PC/360 retail game programmer; what can you add from your field of work? I’d love to hear your suggestions in the comments.

Writing an iPhone Game Engine (Part 6- Performance)

Original Author: Simon Yeung

Introduction
Performance of a game is very important, it is important to maintain a constant frame rate of a game. So I will talk about how I keep track of the performance of the game. However, the game is not finished, I can only profile the engine with sample placeholder assets, the profiled data might not be match with the final data after the game is finished. Anyway, I will try to talk about my first attempt to profile my engine. (All the data are measured with iPhone 3G).

XCode OpenGL ES Analysis

For profiling the graphics performance on iPhone, there is an OpenGL ES analyzer that comes with Xcode 4. It can detect redundant state changes and give some advice to improve rendering performance. It also help me to spot some bugs such as forgetting to set the texture states to use mip-map.

After using the analyzer, I discover that 2 recommendations that improve my engine rendering performance significantly. The first suggestion is to use the EXT_discard_framebuffer extension after rendering each frame.

Why University is the Best Place to Start a Games Company

Original Author: Daniel Sefton

Looking at many successful entrepreneurs, there is a trend – they did not attend or dropped out of university. Therefore it is a common misconception that university is not necessary, or a waste of time for those who already have the skills, a rad business idea, and entrepreneurial spirit.

There’s nothing wrong with skipping university and going into the big wide world on your own – the way I see it, life is about diving head first and running with whatever you are passionate about. Anything is possible.

But if there’s one thing I learned about running a company, it’s that you NEED help, people and contacts. It’s not just about rattling some lines of code and art and calling it a business, it’s a huge range of skills required from all corners of everything.

Get this: University is one big ass games company!

Fields of study at my university include business studies, music tech, game design, art, management, finance, programming, law. It’s all here. I’ve got all the help I could ever ask for on my doorstep.

If I need any art, no problem, we have game designers and artists – 100s of them. If I need sound, no problem, I’m living in a house with 4 musicians who study at the university. If I need business help, we have a business school.

The university also runs an internal games studio – they have hands on experience. We have expensive dev kits out of reach of most indies. We have software licenses for everything you could want.

I’ve become a better person by being at university – meeting people, attending events, entering competitions, making games in teams, improving my course by attending university board meetings and much more.

Last but not least, I get training. I could have been complacent with what I knew – I started programming C++ 4 years before I even began university. But there are always things I’m learning that I never knew before – theories, maths, low level programming, shaders and so on.

How I Started My Company

About mid way through my first year I finally decided that I wanted to start a business. I knew the basics, since I did business studies for a few years at school, but nothing about filing a company for real. I asked my head of department and he gave me a leaflet about some business events run by an initiative at the university. Luckily one of them started a few hours after I asked.

So I went to it, and with a room full of student entrepreneurs they were discussing issues surrounding Intellectual Property. I was amazed that it was my first time there and already I was learning something useful which applies to games.

I enquired about starting a company after a couple more events and they helped me file all the documents. A week later I was incorporated. Not only that, but bundled for a year I got free office space and meeting rooms, free advice and support, and access to business events in the region.

Advice

If you are at university and considering doing the same, only do so if you really need it, if you have serious product(s) that require incorporation. I worked on mine for years before I incorporated.

Don’t let it get in the way of your studies. Although it’s great that you’re taking advantage of university in ways that most don’t, realise that running a company is not just a case of filing a few documents and sitting on your arse all day, you need to work damn hard and balance it with university work.

Conclusion

If you are the entrepreneurial type, want to start a games company, and have the chance of going to university, I totally recommend that you think twice.

I leave you with an analogy.

University is like a cheesecake. The degree you get is the biscuit at the bottom, and you have to fill in the cream and toppings yourself. With no cream or toppings, it’s a dry experience with a cog-in-the-works outcome.

Disclaimer: I can only speak from the experience of attending one university. The points I make may be different for others, but every university has resources that you can take advantage of.


I never managed to go left on first try.

Original Author: Fabrice Lété

PC gamers in France and Belgium are used to the following routine:

  1. Start playing a brand new game.
  2. Strafe right and move backwards.
  3. Curse.
  4. Go to the options screen.
  5. Resume playing.

About every single game using the WASD control scheme (every FPS basically) forces us to remap the key assignments. A quick look at a closeup of my laptop keyboard will show you the root of the problem: an AZERTY keyboard has a few letters swapped compared to a QWERTY one.

The differences are not that big, only three letters are located differently (A, Z, M), but unfortunately two of these are right in the middle of the most standard keyboard control scheme of modern PC games.

Should you care? Honestly, probably not. As long as your game allows players to redefine their keys, us frog and snail eaters are usually (1) only a few tweaks away of enjoying the game. But that being said, correctly handling this problem in the default mapping is not that complicated either.

What the keyboard sends to the PC are key codes, which are “character agnostic”. They directly represent the physical positions of the keys. The standard way of assigning key codes originated with the IBM PC XT: the Scan Code Set 1. Further enhancements have been named Scan Code Set 2 and Scan Code Set 3.

Nowadays, most keyboards use Scan Code Set 2 to send the data to the computer, but the codes are translated back to Scan Code Set 1 when received (historically because of backward compatibility concerns). So everything dealing with scan codes on Windows can assume a Scan Code Set 1 numbering scheme.

Based on the scan code and the keyboard layout, Windows translates the key presses into Virtual Key codes. And this is where the physical positions are lost. You cannot assume that the key in the top left corner is labelled A, you have to go back to the scan codes.

The Scan Code Set 1 codes for the WASD keys are: 17, 30, 31, 32 (in that order). Notice how the values for ASD are consecutive. And to get the Virtual Key Codes most API require, you only have to call these functions:

1
 
  2
 
  3
 
  4
 
  
forward = MapVirtualKey( 0x11, MAPVK_VSC_TO_VK );
 
  strafe_left = MapVirtualKey( 0x1E, MAPVK_VSC_TO_VK );
 
  backward = MapVirtualKey( 0x1F, MAPVK_VSC_TO_VK );
 
  strafe_right = MapVirtualKey( 0x20, MAPVK_VSC_TO_VK );

Only four lines of code to make millions of people happy, isn’t that great?

Don’t forget to check this article from Keith Judge about input handling for PC games here: /2011/04/25/input-for-modern-pc-games/

And here is some more complementary information:

  • http://msdn.microsoft.com/en-us/library/ms646306(v=vs.85).aspx
  • http://www.georgehernandez.com/h/xComputers/CharacterSets/ScanCodes.asp
  • http://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html
  • http://www.computer-engineering.org/ps2keyboard/
  • http://msdn.microsoft.com/en-us/goglobal/bb964651.aspx
  • http://seit.unsw.adfa.edu.au/staff/sites/hrp/personal/Sanskrit-External/Unicode-KbdsonWindows.pdf
  • http://babbage.cs.qc.edu/courses/cs345/Manuals/ms_scancode.pdf

(1) Not that long ago, right after starting a new game, I tried moving left but instead I inadvertently hit the shortcut for destroying the one and only item that could allow me to progress in the game. After remapping the keyboard I pointlessly walked around for 10 minutes, trying to figure out what I was supposed to do…

Games about Yetis… Proof You Can Never Win?

Original Author: Jon Moore

Earlier this week I had my mind completely blown when I saw something that was almost unbelievable: a game that at first glance seemed like a clone of a game several of my friends made as students a few years back.

The game that my friends made was called Yeti Tracks. The premise of the game is that your character has crashed his plane in a blizzard and you have to use your rifle to both hunt a rabbit for food and fend off a Yeti that is hunting you. You win by successfully hunting the rabbit and returning to your plane. It’s a small, unpolished student game:

What’s interesting is that indie developer Vlambeer showed off a new project of theirs at Fantastic Arcade recently. The game is titled Yeti Hunter… and it looks exactly like what most people would call a clone, but I don’t think that was Vlambeer’s intention. It’s worth noting that they say this game may never find it’s way to a formal release, but it’s certainly gotten more attention than the Yeti Tracks did. The key difference as far as I can tell, is that the point is to hunt yetis instead of staving them off, but the gameplay is eerily similar in this small, unpolished indie game:

You may have noticed Vlambeer in the news recently, their game Radical Fishing got cloned on iOS before they could release the actual iOS version of the game, Ridiculous Fishing. It seems relatively certain that the clone was intentional, and it made my blood boil when I read about the whole incident. But the Yet Tracks / Yeti Hunter similarities also made my jaw drop, and then I realized that it was highly unlikely that the developers found an obscure student game and decided to clone and polish the gameplay.

So what does that leave us? Does it make it alright? If Yeti Hunter’s existence is acceptable, then does that mean that we also have to find Ninja Fishing to be acceptable?

Or can we really have the criteria be based on what the intention of the developer was, so that the similarities in the Yeti games are alright, but an intentional fishing game rip-off is not? Using that distinction is incredibly hard to do. Consider the sciences and engineering: keeping a log of your work can be just as important to prove your work was developed originally, as it is to validate the methods used.

If we want game design to be an art form, wanting that sort of proof that an idea is original would be ludicrous, never mind that it would be infinitely harder to “verify” as well. The whole dilemma seems like a tangled mess, and the thing that really makes me sour is that the student that had the original idea for the game admitted that the existence of Yeti Hunter meant that he could never release a polished version of Yeti Tracks without people constantly making comparisons.

In fact, I wonder if he did a more public release of the game (say, on iPhone), if the community would attack him for “ripping off” Vlambeer, considering their unfortunate situation with Radical Fishing.

Copying pixels from a pointer to an XNA Texture2D

Original Author: Kevin Gadd

In the XNA framework, the only way to load pixel data into a texture is to provide it in the form of a .NET Array. In most cases, this isn’t a problem – you can specify an offset into the array, and the array can be of any type. However, if you’re using a library like Berkelium, you will end up with large blocks of pixel data in the form of a pointer. The only way to turn this into an array is to manually allocate an array of the appropriate size and copy the pixels over every time they change. Not only does this waste memory, but it’s relatively expensive.

In this post I’ll show you a (fairly evil) way to copy pixel data directly from a pointer into an XNA texture using C#, PInvoke, and some knowledge of XNA internals.

The first step is to understand how XNA’s Texture2D.SetData method works normally. I opened it up in ILSpy, a free .NET decompiler.

Looking at the three overloads of SetData reveals that they all call into a private method called CopyData, with this signature:

private unsafe void CopyData<T>(int level, Rectangle? rect, T[] data, int startIndex, int elementCount, uint options, [MarshalAs(UnmanagedType.U1)] bool isSetting) where T : struct

The method is large and complicated, and parts of it don’t decompile into readable, valid C#. But we can understand what it does and how it does it with some research and careful examination of the decompiled code.

The first part of the function spends a bunch of time validating all the provided arguments. It ensures that the texture being modified isn’t active as a render target or attached to one of the device’s texture samplers, and validates other parameters like the size of the texture and the size of the data provided.

However, you start to see rather confusing code like this in the disassembly:

	_D3DSURFACE_DESC d3DSURFACE_DESC;
 
  	initblk(ref d3DSURFACE_DESC, 0, 32);
 
  	IDirect3DTexture9* ptr = this.pComPtr;
 
  	int num3 = calli(System.Int32 modopt(System.Runtime.CompilerServices.IsLong) modopt(System.Runtime.CompilerServices.CallConvStdcall)(System.IntPtr,System.UInt32,_D3DSURFACE_DESC*), ptr, level, ref d3DSURFACE_DESC, *(*(int*)ptr + 68));
 
  	if (num3 < 0)
 
  	{
 
  		throw GraphicsHelpers.GetExceptionFromResult(num3);
 
  	}

If you know enough about .NET bytecode (CIL/MSIL), it may be easier to understand what’s going on here. Bytecodes that couldn’t be mapped to C# constructs were basically spit out directly as if those bytecodes were functions. This is happening because XNA is mostly written in C++/CLI, not C#.

First, the initblk opcode is used to zero-initialize the contents of a new D3DSURFACE_DESC structure. This is equivalent to doing a memset in native C/C++.

Next, the calli opcode is used. Essentially, this opcode allows you to invoke a native function directly, given a function pointer and knowledge of the function’s signature. All of the decompiled code here is essentially describing the signature of the function and then providing arguments for it. You’ll probably never see this generated by C# code, but it’s used often in C++/CLI to invoke native functions – and in this case, it’s being used to invoke a method of a COM interface.

How can you tell it’s being used to invoke a method of a COM interface? There are a few clues here:

First, we notice that ptr contains a pointer of type IDirect3DTexture9 – a COM interface. Second, we can look at the argument list to the calli instruction:

System.Int32 modopt(System.Runtime.CompilerServices.IsLong) modopt(System.Runtime.CompilerServices.CallConvStdcall)(System.IntPtr,System.UInt32,_D3DSURFACE_DESC*), ptr, level, ref d3DSURFACE_DESC, *(*(int*)ptr + 68));

First we have the return type of the function – System.Int32. Next, two modifiers that notify the compiler about the nature of the function – it’s a stdcall, and the return type is a C++ ‘long‘ with the semantics that implies. This doesn’t really matter much to us at the moment, but it’s good to understand the basics.

Next, the argument types for the function are provided: System.IntPtr, System.UInt32, and a D3DSURFACE_DESC *.

Given this information, we now know the signature of the function being called, so we could write an equivalent delegate if we wanted. The decompilation doesn’t tell us the name of the function, but given the name of the interface (IDirect3DTexture9) and the argument list, we can check that interface’s documentation on MSDN and try to figure out which function it is.

Finally, let’s look at the actual arguments being passed when invoking the function:

ptr, level, ref d3DSURFACE_DESC, *(*(int*)ptr + 68)

First, we see the first three arguments are of the appropriate type for the function’s signature and their values make sense. There’s a fourth argument, though, and it looks funny – in fact, it looks like the decompiler didn’t quite make sense of it. What is that?

Well, we know that ptr is a pointer to an IDirect3DTexture9. First, the code is dereferencing the pointer. If you know enough about COM, you will realize that dereferencing a pointer to a COM interface will allow you to access that interface’s vtable. The vtable contains pointers to each function provided by the interface, which allows you to invoke those functions on a given instance.

Given that the code is dereferencing the interface pointer and then adding an offset to it, we can now infer that it’s pulling a specific function out of the interface’s VTable. Again, we can’t immediately tell which function, but we have a lot of information here that we could use to figure it out.

This makes it pretty clear that a COM function is being called on the interface, because we can see the function pointer being pulled out of the COM vtable and passed to the calli instruction, along with a function signature and argument types that seem like a perfect fit for a COM method (HRESULT return value, first argument is the interface pointer).

At this point, we could dig through the vtable and find our way to the necessary method calls to lock the texture and get a pointer to its pixels. Then we could do any necessary pixel format conversion, etc while copying from our buffer to the texture. However, there’s an easier solution!

If you read through the code for the method, in certain code paths, it makes use of a D3DX function called a version of this function that can take a pointer as a source instead of another surface - making it perfect for our needs. We just have to find a way to call that function and hand it our image data pointer and D3DX will handle any necessary pixel format conversion and copy our pixel data to the texture.

Now, to call the function. First, we need to get ourselves an interface pointer. If we’re willing to use reflection, this is quite simple – we can get ourselves a reference to the pComPtr field we see used in the disassembly and use that reference to get the interface pointer for a given texture, like so:

public static class TextureUtils {
 
    internal static FieldInfo pComPtr;
 
   
 
    static TextureUtils () {
 
      pComPtr = typeof(Texture2D).GetField("pComPtr", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
 
    }
 
   
 
    public static unsafe void* GetIDirect3DTexture9 (this Texture2D texture) {
 
      return Pointer.Unbox(pComPtr.GetValue(texture));
 
    }

Next, we can set up the necessary P/Invoke skeleton to be able to invoke the D3DX function. We need two enumerations, a struct, and finally the function itself:

// Some enumeration members omitted for readability
 
  public enum D3DFORMAT : uint {
 
      UNKNOWN              =  0,
 
   
 
      R8G8B8               = 20,
 
      A8R8G8B8             = 21,
 
      X8R8G8B8             = 22,
 
      A8B8G8R8             = 32,
 
      X8B8G8R8             = 33,
 
  }
 
   
 
  [Flags]
 
  public enum D3DX_FILTER : uint {
 
      DEFAULT              = 0xFFFFFFFF,
 
      NONE                 = 0x00000001,
 
      POINT                = 0x00000002,
 
      LINEAR               = 0x00000003,
 
  }
 
   
 
  [StructLayout(LayoutKind.Sequential)]
 
  public struct RECT {
 
      public int Left;
 
      public int Top;
 
      public int Right;
 
      public int Bottom;
 
  }
 
   
 
  // Note that we need to be careful to use the same exact version of D3DX that XNA uses.
 
  [DllImport("d3dx9_41.dll")]
 
  private static unsafe extern int D3DXLoadSurfaceFromMemory (
 
      void* pDestSurface, void* pDestPalette, RECT* pDestRect, 
 
      void* pSrcMemory, D3DFORMAT srcFormat, uint srcPitch,
 
      void* pSrcPalette, RECT* pSrcRect,
 
      D3DX_FILTER filter, uint colorKey
 
  );

At this point, however, you might have realized the problem: This function takes a pointer to an IDirect3DSurface9, not an IDirect3DTexture9. How do we go from a Texture to a Surface? Well, the MSDN documentation shows that there’http://msdn.microsoft.com/en-us/library/bb205912%28VS.85%29.aspx”>GetSurfaceLevel. But given that all we have is a void *, how can we call it? There are a few ways, of course – you could write a tiny C++ library to do the work, or you could add a reference to the Managed DirectX libraries, or something like that. But we’re going to do it the way they do it in C – with pointers!

To make sure we’re on the right track, we can first dig through the disassembly of CopyData to find the spot where it calls GetSurfaceLevel. Since we know the argument types and return type, it’s not too hard to find:

IDirect3DSurface9* ptr3;
 
  IDirect3DTexture9* ptr4;
 
  num5 = calli(System.Int32 modopt(System.Runtime.CompilerServices.IsLong) modopt(System.Runtime.CompilerServices.CallConvStdcall)(System.IntPtr,System.UInt32,IDirect3DSurface9**), ptr4, 0, ref ptr3, *(*(int*)ptr4 + 72));
 
  if (num5 >= 0) {

With what we know about COM method invocations, we can tell this is invoking a method of IDirect3DTexture9 with an integer parameter (0) and a pointer-to-pointer parameter of type IDirect3DSurface9. This is definitely GetSurfaceLevel. This not only tells us what the right signature for the function looks like, but it also tells us where in the interface’s VTable we can find a pointer to the function in order to call it. So, armed with this knowledge, we can write some terrifying unsafe code to pull the function pointer out of the VTable:

// This could be written better, probably. I'm lazy.
 
  public static unsafe void* AccessVTable (void* pInterface, uint offsetInBytes) {
 
      void* pVTable = (*(void**)pInterface);
 
      return *((void**)((ulong)pVTable + offsetInBytes));
 
  }

And, using that function along with an appropriate delegate type, we can put these pieces together to get a surface pointer:

internal unsafe delegate int GetSurfaceLevelDelegate (void* pTexture, uint iLevel, void** pSurface);
 
   
 
  public static class VTables {
 
      public static class IDirect3DTexture9 {
 
          public const uint GetSurfaceLevel = 72;
 
      }
 
  }
 
   
 
  public static unsafe void* GetSurfaceLevel (this Texture2D texture, int level) {
 
      void* pTexture = texture.GetIDirect3DTexture9();
 
      void* pGetSurfaceLevel = AccessVTable(pTexture, VTables.IDirect3DTexture9.GetSurfaceLevel);
 
      void* pSurface;
 
   
 
      var getSurfaceLevel = (GetSurfaceLevelDelegate)Marshal.GetDelegateForFunctionPointer(
 
          new IntPtr(pGetSurfaceLevel), typeof(GetSurfaceLevelDelegate)
 
      );
 
   
 
      var rv = getSurfaceLevel(pTexture, 0, &pSurface);
 
      if (rv == 0)
 
          return pSurface;
 
      else
 
          throw new COMException("GetSurfaceLevel failed", rv);
 
  }

We use the marshalling API to turn the function pointer into a callable delegate with the appropriate signature, and then call it in order to get ourselves an interface pointer. Now, we’re finally ready to call D3DX! Let’s wrap this magic up with a helpful function:

public static unsafe void SetData (
 
      this Texture2D texture, int level, void* pData, 
 
      int width, int height, uint pitch, 
 
      D3DFORMAT pixelFormat
 
  ) {
 
      var rect = new RECT {
 
          Top = 0,
 
          Left = 0,
 
          Right = width,
 
          Bottom = height
 
      };
 
   
 
      void* pSurface = GetSurfaceLevel(texture, level);
 
   
 
      try {
 
          var rv = D3DXLoadSurfaceFromMemory(pSurface, null, &rect, pData, pixelFormat, pitch, null, &rect, D3DX_FILTER.NONE, 0);
 
          if (rv != 0)
 
              throw new COMException("D3DXLoadSurfaceFromMemory failed", rv);
 
      } finally {
 
          Release(pSurface);
 
      }
 
  }

You’ll note that we’re also ensuring that we decrement the reference count on the surface after we’re done with it so it doesn’t leak. To do this, we wrote a quick helper function:

internal unsafe delegate uint ReleaseDelegate (void* pObj);
 
   
 
  public static class VTables {
 
      public static class IUnknown {
 
          public const uint Release = 8;
 
      }
 
  }
 
   
 
  public static unsafe uint Release (void* pObj) {
 
      void* pRelease = AccessVTable(pObj, VTables.IUnknown.Release);
 
      var release = (ReleaseDelegate)Marshal.GetDelegateForFunctionPointer(new IntPtr(pRelease), typeof(ReleaseDelegate));
 
   
 
      return release(pObj);
 
  }

And now, after all that hard work, copying pixel data from an Awesomium WebView into an XNA texture is as simple as this:

var rb = WebView.Render();
 
  WebViewTexture = new Texture2D(GraphicsDevice, rb.Width, rb.Height, false, SurfaceFormat.Color);
 
  WebViewTexture.SetData(0, rb.Buffer.ToPointer(), rb.Width, rb.Height, (uint)rb.Rowspan, D3DFORMAT.A8R8G8B8);

If you’https://github.com/kevingadd/Fracture/blob/master/Squared/RenderLib/Evil.cs”>download it in a ready-to-use form from my GitHub repository. Hope it’s helpful!


Virtual Panel: First Experiment

Original Author: Claire Blackshaw

In what I hope becomes a regular feature, we gather around in a Google Hangout to try our first Virtual Panel.

For our first panel it was suggested we don’t set an agenda and open it up to all AltDevBlog authors. Richard is working on a transcript, but as he says he talks fast 😉 Apologies for the sound levels, in the long term I hope to make use of Google Hangouts, “On Air” functionality which enables broadcast and recording. Brief summary below of the discussion.

Topics Discussed

  • Has “how” you get into the industry changed over the last few years?
  • Interview processes
  • Dealing with player feedback
  • Good Usability and Collection of Feedback
  • How can Indies get good feedback
  • Business Intelligence
  • Audio Levels

Participants

Cameo from

Finally we did agree an agenda or pool of agenda topics needs to be gathered to focus the discussion. It was also suggested that if the community would like, and the author has time is a post-blog post hangout to discuss the article would be a nice focal point. At the moment its a bit of faff with software and such. Though once the “On Air” functionality is rolled out Google+ should handle the broadcasting and recording to YouTube pretty seamlessly. I’m hoping to work with other AltDevBlog authors to bring move Virtual Panel discussions to AltDevBlog.

I hope you enjoy the discussion.

Planning Memory Budgets (Part 2)

Original Author: Darren-Vine

In the last part of this article I covered working out the basics of the memory you have available. I mentioned that the next stage is to break this into modules to help create an effective game budget.

Divide between generic and specific budgets

I divide the memory up into a number of modules.  Each of these modules is either platform agnostic or specific for each platform.  What do I mean by this?  Well some modules (Sound, GFX) will differ in size on different platforms.  For example the Sound module may be forced to use PCM data on one platform and MP3 on another.  Others are platform agnostic.

Typically only one or two modules truly fall into the last category.  I always have one called Game.  The Game module is the core part of your game that is the same on all platforms.  By this I mean the data and code is identical and is the area most of the team work on.  Surprisingly, this is not normally that big either because it doesn’t contain the major memory hogs. A simplistic example is to take an iOS game. The HD version has higher quality GFX or better quality sound than the SD version.  The same goes for games on the Wii and XBox 360.  The actual assets differ but the game is the same.  Note: By same I am generally referring to a game developed in-house by the same team.  Often, if different platforms are developed by different companies this is not the case.

Other modules have the same size on multiple platforms where they share data, while one platform may use different assets to suit the size.  Animation on the PS3, PC and 360 are often the same and only differ on the Wii for example.  Mainly due to a reduced number of bones and key frames.

This is the list I created, along with some guesstimates.  This is based on experience and what I think is likely for the game about to enter development.  In this table I have added a Wii platform to demonstrate the differences a bit clearer.

Module Name Type ~MB (PC/PS3/XBox360/Wii)
Game Generic 8/8/8/8
Animation Specific 24/24/24/16
Physics Specific 64/64/64/32
Sound Specific 32/22/22/8
GFX*1 Specific 256/249 (+32 *2)/286/32
Network Specific 8/8/8/8
Totals 392/407/412/104

*1 GFX comes from the VRAM budget defined in the previous article.  For the platforms that have unified memory this is just taken from the general pool.

*2 I have used all the available VRAM for the PS3 but I also need extra for GPU buffers in main ram.

The astute among you will also have noticed that the Wii memory is way over budget.

Talk to your team members

At this point the list needs expanding.  I have the modules but don’t know beyond reasonable guessing how big they really need to be.  Though I have a rough idea from the Game Design Document, I am not an expert on all areas. Speaking with the people responsible for these areas can help you break the down and build accurate results.  This means talking to the artists as well about what they would like to be able to have and how that ties in with the engines abilities.

After this I have a much better break down of the areas some of these may be split into.  I can also put some numbers together based on what I was told and technical aspects of the platform.

Module Name Sub Module ~MB (PC/PS3/XBox360/Wii)
Game General 8/8/8/8
Animation Char Animation 14/14/14/6
Level Animation 10/10/10/4
Physics General Use 16/16/16/4
Collision Mesh 22/22/22/5
Sound FX 24/18/18/6
Music 8/4/4/1
GFX System Required 0/32/32/0
Frame Buffers 32/22/22/6
Textures 192/203/206/30
Meshes 32/24/26/8
 Network General 4/4/4/4
 Total 362/377/382/82

It is possible to break this list down further but there isn’t a lot of point doing that in my opinion.  Sometimes I do, but this is often just for my records to see how things progress.  Frame buffers are an example that is often good to know.  Either way, I try break the list into things that will be major issues.  The further you go more likely you are to get it wrong.  That just leads to issues later.  Also it doesn’t have to exact.  It just has to be good enough so that you don’t get into trouble and you foresee any problem areas early.

My Budgets

After talking to the artists, designers and programmers I have a pretty good list.  It fits on all platforms and leaves a decent amount of leeway.  With the list above I have a considerable amount of ram remaining on the larger consoles.  Sometimes you do and sometimes you don’t, it can depend on a huge number of factors.  I have also just squeezed it in on the Wii.  I will repeat the steps a couple more times to refine it and ensure I havent missed anything.  After that I review the memory consumption throughout development every month or so.  You don’t need to spend long on this, only enough time to ensure things are on track.

Obviously my budgets listed here have, to a large degree, been plucked out of thin air, though I based it on previous games I have worked on.

Summary

Hopefully this will give you some idea of how to approach creating sensible memory budgets.  It doesn’t matter which platform you are working on or even how many.  At some point you may wish to expand to others and sticking to your budgets now will help with that.  With the number of people now targeting mobile platforms there is more hardware variations than ever before.  The more you can reach, the more money you can make.