Rami Ismail (ramiismail.com)                             

Event Schedule

Biography

Rami Ismail is the Business & Development Guy at Vlambeer, a Dutch independent game studio known best for Nuclear Throne, Ridiculous Fishing, Super Crate Box, LUFTRAUSERS, GUN GODZ, Serious Sam: The Random Encounter & Radical Fishing.

Through his work at Vlambeer, Rami has come to realize that the marketing & business facets of many independent game developers could use some help. As such, he created the free presskit-creation tool presskit() and is working on releasing its first add-on, release().

Believing sharing knowledge openly is the cornerstone of independent development, Rami has spoken on a variety of subjects at dozens of game events around the world, ranging from the Game Developers Conference to Fantastic Arcade & from University seminars to incubator mentorship.

He is a avid opponent of game cloning after Vlambeers Radical Fishing got cloned. He is also a proponent of searching for new, beautiful things in places no-one is looking for them and thus organized Fuck This Jam, a gamejam focused around making a game in a genre you hate. Rami also works closely with the Indie MEGABOOTH team to enable indie studios to showcase at the larger game conventions.

Rami exclusively drinks cane sugar Coca Cola.

 
 
 

On Full Disclosure

Full disclosure: since a large part of what many voices that co-opted GamerGate are asking is full disclosure, so I’d…


RAMI IS CURRENTLY VISITING THE UNITED STATES.
YOU CAN REACH HIM AT RAMI@VLAMBEER.COM, , , OR BY CALLING +31 (0) 621206363.

The real issues.

Everything is not fine and that’s fine

During an interview last year, popular games website Giantbomb asked me what I thought of the state of the industry. I responded that everything is fine – used in that way where every good friend would know not to ask again. We’re not fine.

I’ve been told by friends wiser than myself to always add nuance to such a sweeping statement. Individual developers might be fine, certain segments of the industry might be fine, in fact – entire platforms might be doing well. But as an industry, I don’t think we’re fine.

Every segment of our industry has gloomy news for us. In mobile, user acquisition has never been as expensive as it is today – with the cost of ‘acquiring a quality user’ now often exceeding the revenue such a user brings in on average. The giants of this industry deal with ever increasing costs, and ever decreasing willingness to buy a sixty dollar game. The aspiring developers of today need to shout louder than swarms of no longer aspiring developers to get noticed at all.

Most major platforms have been pushing for independent development to be featured in a bigger way, but that helped as much as it backfired. While the developers that were gaining momentum in 2010 are still gaining momentum, what do you do about the developers that started last year? As platform developer relation teams reached their maximum capacity, they locked down or opened up – both with the exact same effect. The idea that either a choice for democratic curation or a choice for tightly controlled platforms will somehow fix the fact that there are more games being made than ever feels like a feigned hope.

You don’t have to be an economy major to realize that there’s a problem when the average revenue per sold unit goes down, the audiences don’t grow and the budgets go up. The graphics have to be more realistic, the soundtrack more orchestral, the gameplay tighter and the price – well, many will just wait for a sale or bundle, after all. From what I understand from AAA revenue reports, the gaming audiences doesn’t like buying anything that isn’t paradoxically new and improved ­– the promise of something familiar, masqueraded as something revolutionary. It doesn’t help that expectations are higher than ever – when Assassins Creed launched, the outcry over a massive gamble of that size not being flawless was a fraction of the disappointed response to WATCH_DOGS.

And what is there to gain on mobile anyway? The race to the bottom has pushed the prices down so far that it’s almost impossible to keep making games at all. The people that can buy seats on the gravy train buy more seats than ever, and those still believing you can board the gravy train after it passed their station are left with the illusion that they simply missed the train, instead of understanding that unless they got exceptionally lucky, there wouldn’t have been seats for them anyway.

Then there’s the cruel joke of Kickstarter – once touted as a way to circumvent the troubles of traditional publishers, a few people abusing the system has now turned everybody into a risk-averse cynic that’d make the most careful investor stagger. Early Access, a way of ensuring great feedback during game development, has been exploited for easy money often enough that on our current project, Nuclear Throne, the people that have added the game to their wishlist to buy it after launch is double the number of actual sales after a year of Early Access.

Or what about the fragmentation of the media landscape? Where before, you needed to keep tabs on magazines – then it was magazines and blogs, now it is magazines, blogs, and video content creators. There’s such a high job turnover in those fields that you have to keep fulltime attention to all of them, and too many developers don’t have access to the resources to do so well – and thus end up missing valuable attention for their work. Or the endless torrent of question I get about funding – people looking for less than what an investor requires you to ask to be taken seriously, but more than what a reasonable loan, grant or fund can offer.

We’re trying, as an industry, we’re trying so fucking hard to just be fine. We talk about our successes and our achievements, but we shun mentioning our failures. We talk about the funny bugs in a Ubisoft game for weeks, but take months to respond to harassment happening straight under our nose.

You know what is a failure? That our audiences still believe a game as Destiny is not a risky proposition. Five hundred million dollars, assigned to a project that is an entirely unproven property years ago, with a projected dependency on non-existent internet infrastructure, for consoles that didn’t even exist back then.

You know what is a failure? That when I travel, a complaint I hear more often than not is that people around non-Western world feel excluded from not just the industry – but from the word diversity. While we always define what type of discrimination we face – be it sexism or racism or anything else – we’re sloppy enough to not identify what type of diversity we mean when we speak of it.

You know what is a failure? That rather than pricing our games at the price we believe is right for our work, we price our games where we believe it’ll sell. In our blind rush to make ends meet, we’re continuously hurting both ourselves and others. The expectation of what you’ll get for a dollar has gotten so out of proportion, that on mobile you can’t even say ‘what you’ll get for a dollar’ anymore, because that’s too expensive already. Games launch in bundles, are fine with pricing down over three quarters of the value to get some eyes on the game and are made to bid against each other in terms of how deep we’ll go for major sale events.

We don’t talk about that. We want to – no, need to – let people to know what game development is like, show them what game development is like – but we’re only willing to do it in the proudest possible way – we want to be Starbuck, not SpaceX. Coffee drinkers want to know what beans their coffee is made out of, whether it was prepared in an environmentally responsible manner and that the barista is a professional with a decade-long passion for the heavenly fumes of a perfectly prepared Grande Latte.

Of course, part of the problem with talking about failure and problems is modern culture, so hell bent on recognizing our relative successes as the one unambiguous truth. An apology is a sign of weakness met with nothing but vitriol, a sincere complaint a reason to attack and bad sales figures are a deep personal embarrassment. We’d rather talk about our successes.

There are many victories to celebrate in our industry, and we celebrate them loudly. We talk about our Papers, Please and Gone Home. We cheer at Grand Theft Auto V smashing Hollywood sales records. Twine might be a new breakthrough in making interactivity achievable to anyone who puts their mind to it. Underneath a newly resurrected impenetrable layer of AA studios, a thriving scene of people that are still without financial ties brews. The quality of student work continues to rise exponentially. Worldwide, the amount of people spending time on game development in some way, shape or form is on the rise.

And they’re making beautiful games. We are making beautiful games. The quality of games has increased so rapidly, in AAA, in indie, in mobile. Games are fine. Games, that what we’re here for – games are just fine, and they’re getting better every day. Game development is fine. Maybe as an industry, we’re not doing great right this moment. Maybe, as a community of creators and enthusiasts, we’re dealing with people that represent some of the worst distrust and hatred we’ve seen in the history of the medium. But the medium itself is fine.

I’m nothing but optimistic about the future of this medium, of this industry. It might not survive in its exact current form. It might not be all the same people. It might not be me, and it might not be you. Or we might be fine, or we might be doing something else. When people ask me whether the industry is headed for another 1983, I wonder where they were looking when we crashed over and over again in the past few years. Where do you think premium on mobile went? Did you miss the mid-budget console game go extinct between today and five years ago?  There won’t be the spectacular train wreck in slow motion that everybody seems to be expecting. We lose some things, and then celebrate other things to ignore that and  just be fine.

We’re in a creative industry. Of all people, we should know the way we get better isn’t through celebrating our successes, but by reflecting on our failures. We’re in this industry because we see something special in this medium. We don’t have to brag. We don’t have to prove ourselves. We don’t have to create heroic mythologies to justify our existence. We’re here because we care.

We need to acknowledge our failures so that we can learn.


distribute

Introducing presskit() 2.5 & distribute()

For the last few months, my studio Vlambeer has funded work on a project called distribute(). distribute() is a free developer service that allows independent developers to easily handle their press contact list and (p)review build distribution. It’s created to inform and assist developers in creating a good (p)review build strategy, maintaining relationships with the press and verifying that press requests come from verified sources.

distribute() has been in an early alpha state, with about half the functionality live at the moment. It has been a tremendous success – we have several hundred projects actively using distribute(), including Vlambeers’ own Nuclear Throne, and already a dozen full commercial international releases have run their launch using distribute(), and those releases have reached more than a thousand unique members of the gaming press already – be it written, video or livestream. It’s been wonderful seeing the service grow as we work on new functionality.

presskit() changelog
Today, I also want to announce presskit() 2.5, which silently launched yesterday night. presskit() 2.5 removes a security vulnerability related to e-mail, introduces translations for those of you targeting more than just English-speaking press and establishes a way for presskit() to communicate with distribute(). This is a recommended upgrade for all presskit() users.

Upgrading presskit()
To upgrade, you’ll need to reinstate the install.php file that is in your root (the installation recommend you to rename it to _install.php, if that file is there just rename it install.php). If that file does not exist, just download a new installation of presskit() from the website. In both cases, your presskit() data will not be modified by any of these steps.

After reinstating install.php, just head for your presskit() installation and the update should be completed automatically by following the steps on screen. It shouldn’t take longer than a few seconds to go through the entire process. You might see a few debug messages at the top of the screen after your presskit() goes live again, but these should disappear after a refresh.

Translations
To enable translations, look in the /lang/ folder available in the root of your presskit() installation. In it, you’ll find en-English.xml, which you can save as any other language (ie. nl-Nederlands.xml or ar-Arabic.xml). Edit the new language file, keeping the base lines intact, but modifying the local lines. For languages that are right-to-left, change <local> to <local direction="rtl"> in the local tags.

Save and upload the new file to the /lang/ folder. It should show up immediately in your presskit. If you want to localise the content of the presskit() at well, duplicate the data.xml file and rename it data-nl.xml, replacing nl with whatever you put before the hyphen in the language file. You can do this for both the root data.xml as well as for project data.xml.

distribute() integration
To enable distribute() integration, log into your distribute() account, click games and the game you wish to integrate. If you’ve got presskit() linked, you should see a download key file option. If you don’t have presskit() linked, please edit the game and use the load from presskit() functionality.

Click the download key file button and you should receive a file from distribute(). Upload this file to the appropriate project folder in your presskit() installation and you should be done. Visit the page, and you should see a new section named Request Press Copy. If there is a warning message instead, follow the instructions in that warning – if the error mentions it, for security purposes, you’ll have to delete <press-can-request-copy> tags from your project’s data.xml.

distribute() plans
distribute()’s secretary mode is getting large improvements over the next few weeks, along with SSL-security and e-mail digests for both developers and press. Press will be able to opt-in to a daily, weekly or monthly newsletter with new games, while developers will be able to receive digest about activity on their projects. The verification system will be limited to sites with High or above Reach. Based on user feedback we’ll also be introducing a Event Mode that allows developers to easily let press sign up while at events.

As presskit() and distribute() mature, I continue to look for ways to improve both systems. If you have any feedback, thoughts or ideas, the full source to presskit() is available on github. For ideas on distribute(), please just drop me a line on e-mail.


firesalamander_wip2

Nuclear Throne Daily Runs & Why Assumptions Are Bad Programming

Yesterday, we launched one of the most important Nuclear Throne updates yet. In Update #55, we introduced Daily Runs, a challenge every player can take once a day in a pre-generated level. This way, players can compete with players around the world on the same level, but only get one shot at getting a high score. Obviously, this adds a lot of replayability and challenge to the game for those who enjoy that kind of challenge, without changing the game for those that don’t like to compete with others.

Sadly, there was a problem: for many players, the HUD just kind of disappeared halfway through the game. That doesn’t make for fair competition.

For all of you that think of going into programming, the lesson today is *never make assumptions*. I am obviously not the main programmer on Nuclear Throne, so for me a lot of the code, structure and specifics are not as natural as they are to J.W. Since J.W. was mostly busy today, I decided to take a shot at hotfixing the issue.

The Issue
The core issue was that the HUD was disappearing at random moments, without any clear indication as to why that happened. When we started hunting the bug, the first thing we focused on was trying to create a reproducable method of triggering the bug. Using the developer cheats, we’d try walking around in different worlds and the like. The only way we could get the bug to happen frequently was the ‘trailer cheat’. It was originally created for our trailer creator, Kert Gartner, who needed a way to record video while not being quite amazing at Nuclear Throne. Not only does it bring you to the next world, it spawns a lot of radiation, a big weapon chest and some other stuff – so you immediately look badass for the trailer recording.

The Pause Button
We concluded that one of the ways the bug could be triggered was by pausing the game during the end of the level transition. That was a clue – from what we could tell, the bug would only occur while transitioning between levels. We had something to chase.

So we focused on was figuring out whether the code that draws the HUD was still being executed after the bug.

In Nuclear Throne, the HUD is drawn by two functions: scrDrawHUD, which draws popup text and pickup prompts, which then also calls scrDrawPlayerHUD for each active player. scrDrawPlayerHUD then draws the HUD for the player with the player number provided – number 1 for player 1 and 2 for player 2. We checked in scrDrawHUD, and realised quickly that the HUD was still being drawn. We shifted focus: what if, despite the HUD being drawn, the player HUD was not being drawn? We went back, logged gameplay and realised that this was indeed the case. If we had just been more specific, logging scrDrawPlayerHUD instead of scrDrawHUD, we would’ve noticed that right away. Bad assumption.

The code that calls scrDrawPlayerHUD first checks with the ‘main controller’ if the player exists. Our ‘main controller’ object holds all sorts of important information about the player, including what the ID of the player instance is. Game Maker assigns objects and instances an ID in chronological order (the first created object is ID 0, the 2nd is ID 1, and so on).

If the ID number was higher than 0, we could expect the object to have been created (and thus gameplay to have started properly). If the game is over and the player returns to the main menu, we reset the ‘main controller’ and the value gets set back to -1. Each frame, we check if the value for each player is 0 or higher – if it is, the player was created, so the game has started, and we draw the HUD.

In other words, it would be a good idea to keep track of the value of that player ID in the main controller. We set up a realtime log so we could see the value change while we played, and we started playing in windowed mode. When the bug happened again, we noticed two things: the game suddenly forced itself back to full screen, and the player ID value had reset to -1.

Figuring out why the game goes fullscreen.
Confused, we moved on to see if maybe the surfaces were broken or uneven: that might force the game back to fullscreen.

Surfaces are basically render targets. Normally when we render images, sprites or anything, we do that to a buffer that gets drawn to the screen at the end of the frame. Surfaces are basically a sort of imaginary piece of glass we can draw things on, and then we can later overlay those on the screen. Every shadow in the game is drawn to a surface, and the darkness in dark worlds are also drawn on a seperate surface. Since we’ve had a longstanding bug of the darkness disappearing when resizing windows, we thought maybe the solution could be found here.

The good news: when something changes about the window context – so toggling from full screen to windowed, resizing, turning on or off AA – the surfaces are immediately lost. Chances were that the problem was quite simply that the window was being modified, the surface lost and thus the HUD (and the darkness) no longer drawn. We started looking around, quickly found the bug that caused the darkness to stop being drawn and then searched for the HUD surface.

The problem was: there is no HUD surface. The HUD is being drawn directly to the screen, like most of gameplay. We were back to square one, and already hours underway. All we had learned was that the screen changed, and the player ID was reset to -1.

We searched for code that modified the player ID, and found a number of places where that happens. We painstakingly rewrote code, optimized things and fixed dozens of little problems, but we couldn’t find any place where the player ID was modified. What if, instead of being modified, the controller was being reset? That’d be odd, because it’d mean all information would be lost or modified mid-game.

Or would it? We checked and it turns out most information required to run the game is stored in the Player instance itself, rather than in the ‘main controller’. The controller is used only at the end of the game, and when the two got disconnected you wouldn’t notice it until after restarting – when suddenly you’d be playing a different character, your score was incorrect or your daily challenge run was uploaded incorrectly.

In other words, it could be reset. That’d also explain the screen resize – the main controller is the very first object created at game bootup and sets the screen context. It was time to confirm that the controller was being reset, so we caused the game to display an error each time the main controller was created anew. Within moments, it became clear that that was indeed the culprit: the main controller wasn’t being deleted, it was being overwritten with a new copy of itself.

Big Weapon Chests
We obviously couldn’t just remove or work around that code: it’s being used to initialise the game, and it’d be impossible to change it. We needed to find what caused it to be created anew in the first place, rather than fixing the code in the creation of the controller. Luckily, it’s not hard to find out what object causes something to happen.

The debugger gave us a quite unexpected result: the object that caused the controller to be created anew was the Big Weapon Chest.

So we checked the Big Weapon Chest. There wasn’t a lot of code in there, and we caused the game to throw errors every time it was created. We quickly realised that this was every time we cheated to the next level, and the bug would only occur once every few levels. We were clearly on the wrong track – the chest might be part of the problem, but it wasn’t causing the problem. While the Big Weapon Chest would always be around when the bug occurred, it would be created as part of the cheat without any problems.

But why would the Big Weapon Chest sometimes create a new controller and overwrite the old one? It didn’t make any sense, and since we were stuck anyway, we decided to dig a bit deeper.

This is where I went for dinner, which – because I’d been working all day tracing this bug – also counted as breakfast.

We started looking into where Big Weapon Chests were created instead. Obviously, they were created when we cheated ahead, and under certain in-game circumstances. Specifically, Big Weapon Chests cannot be spawned directly – a normal weapon chest is changed into a big one when certain conditions are fulfilled.

Since the timing of the problem was hard, we decided to step through the code instruction by instruction, seeing what would happen when a big chest was created. The problem was that the code that is normally run when an object is created wasn’t run when the Big Weapon Chest would coincide with the bug. That was another clue: the Big Weapon Chest wasn’t created normally.

The solution!
So we started looking at the one place where the Big Weapon Chest was created through a non-standard method: the scrPopulateChests function, which fills the level with all sorts of chests, cannisters and the like after generation is complete. In it, a weapon chest can be transformed into a big weapon chest using a function called instance_change().

We decided to start ‘stepping through’ the code line by line from the point where the game decides to replace a normal weapon chest with a Big Weapon Chest. The code we were stepping through was the following:

with WeaponChest
{
if random(4) < GameCont.nochest
   {
      curse = 0
      with instance_change(BigWeaponChest,false)
         event_perform(ev_create,0)
      exit;
   }
}

This code is not super complicated. It basically does this:

With the current WeaponChest,
{
   Roll a four-sided dice, and if the number is less than the amount of times players did not pick up a chest,
   {
      Uncurse this WeaponChest,
      Change it into a BigWeaponChest, deleting this chest directly instead of normally,
         Run the 'creation' event on the BigWeaponChest that we just changed from a WeaponChest,
      That's all!
   }
}

It ran through every of those lines perfectly, but at the event_perform(ev_create, 0) object, something odd happened. Instead of executing the ‘creation’ code of a BigWeaponChest, it executed the ‘creation’ code of our main controller. It reset all the values to their default values as they are in the main menu, and thus also our player ID to -1. That’s why the HUD wasn’t being drawn anymore.

But why did it do that? A quick scouring of the Game Maker documentation and a chat with Michael Dailly from YoYoGames provided the answer.

Unlike instance_create(), which creates an instance, instance_change() command doesn’t return a reference to the object created. That means that while:

with instance_create(BigWeaponChest)

will allow you to both create and modify a new BigWeaponChest,

with instance_change(BigWeaponChest)

should technically give an error and fail.

Instead, instance_change() always returns a value of zero. So, instead of what we thought the code did, this is what it actually does:

With the current WeaponChest,
{
   Roll a four-sided dice, and if the number is less than the amount of times players did not pick up a chest,
   {
      Uncurse this WeaponChest,
      Change it into a BigWeaponChest, deleting this chest directly instead of normally,
         Run the 'creation' event on the object that is stored in Object ID 0,
      That's all!
   }
}

Object ID 0 is the first object that is created in the game. In our case, as mentioned before, that’s our ‘main controller’. The BigWeaponChest reset all the values to the base values because we misunderstood the subtle difference between instance_create(), which we usually use, and instance_change(). Instead of creating a Big Weapon Chest, we were creating a new ‘main controller’!

The solution was relatively simple: just remove the word ‘with’.

with WeaponChest
{
   if random(4) < GameCont.nochest
   {
      curse = 0
      instance_change(BigWeaponChest,false)
         event_perform(ev_create,0)
      exit;
   }
}

which translates to

With the current WeaponChest,
{
   Roll a four-sided dice, and if the number is less than the amount of times players did not pick up a chest,
   {
      Uncurse this WeaponChest,
      Change it into a BigWeaponChest, deleting this chest directly instead of normally,
         Run the 'creation' event the current WeaponChest (which now happens to be a BigWeaponChest)
      That's all!
   }
}

Either way, this entire bug stemmed from a misunderstanding of how instance_change() works. We assumed it’d work the same way as instance_create() does, and it doesn’t. Well, there goes Wednesday – maybe I’ll try my hand at one of those Daily Runs myself.


Screencheat

Screencheat

Screencheat is a multiplayer FPS with a twist: the only way you’ll find your opponents is by looking at each others screen. Reminds me of the days in which my younger brother was always a bit better at screen cheating than I was. It’s simple, chaotic and so much fun.


Rami Ismail randomly calls… Danny Baranowsky

Rami Ismail calls indie musician Danny Baranowsky of Super Meat Boy, Desktop Dungeon, Binding of Isaac and Crypt of the Necrodancer fame to talk about the cops, content ID and impostor syndrome.


1086942[1]

Taiso

TAISO is probably the most fun game I’ve played that will totally help you break your phone.



recommendation
11057screenshot-of-knytt-underground2[1]

Knytt Underground

Although it checks off all the ‘indie 2D platformer with a gimmick’-boxes, Nifflas’ Knytt Underground uses its ‘gimmick’ so cleverly…

recommendation
WSDY82

Deios

A beautiful glitch art project by Barchman, Deios is as visually overwhelming and as deeply flawed as it is a…

recommendation

Wuppo!

Work-in-progress student game Wuppo doesn’t really have a website yet (get on that!) but it looks sort of wonderful.