This week’s dev-blog is a bit different. Not techie, not about gameplay, not about visuals.
It’s about our first-hand experience with releasing on Steam.
Steam is getting quite a bit of negative attention from customers, developers and press.
Most of the time I don’t agree, including that “Valve is not your friend” article on Polygon. And I’m known to be pretty critical myself.
That’s not to say Steam is perfect.
Many (younger?) developers do not seem to realise how impossibly difficult it used to be to get your game to customers. A publisher and distributor were mandatory because you had to deal with physical goods. Now Steam offers a one-stop solution for distribution and retailing from the comfort of your home/office/garage/attic for a measly 100 bucks. That’s crazy!
What you get:
- Super low threshold access to the largest PC game store with access to the largest gaming community. Only pay when you actually sell something.
- The same features for everybody
- Solid distribution and release management
- Tools to communicate with and build your community
- Detailed sales info and analytics.
- User modding management
- Much additional functionality through the Steamworks SDK
What Steam will not do is:
- your marketing
- providing support to your customers for your product
- develop your game
- make you an instant success
Those last ones sound silly, but after browsing the developers forums on Steamworks for a few minutes you will probably agree that listing them is fair.
People seem to forget that Valve is a company. Companies exist to make money. An often heard complaint is that Steam is not doing enough for their 30% cut. If we, as a tiny Indy developer, would have to develop even the minimum of what Steam offers, we’d probably never finish our game.
Steam does not demand exclusive distribution rights, so you are free to try different ways if you want. Not only that, Steam allows you to sell your game in other ways and thereby omitting the 30%. It doesn’t end there, they even allow you to provide steam-keys to those non-steam customers so they can benefit from the Steam environment nonetheless. That doesn’t sound bad at all!
Also, the fact that Valve is privately held by people that have a personal interest in games and not shareholders who just want to make money strikes me as positive.
Is everything perfect? Of course not.
What could be improved:
- Super low threshold access to the largest PC game store? A bit more threshold please!
- Support doesn’t help you, it gets rid of you
- Developer forum is of limited use, too many people yelling, complaining and worse.
- Documentation is mediocre, clearly more grown over time than designed and sometimes incomplete/outdated.
- No real competition from other digital stores (yet)
Easy access to Steam is positive yes, but it is also a problem. Not just for store visibility. The huge number of games that are released every month forces Steam to become less personal and that is very visible in their developers support.
Like every support department, it is not interested in actually helping you. Their goal is to get rid of you and make sure you stay away. What would happen if they would promptly and successfully help you? You would return every time you had a problem, even before trying to solve it your self. After all, that is what worked last time. So they try to discourage you to approach them.
Not by being impolite, but by:
- taking their time to respond
- expressing how they understand your problem and hope everything will soon go as you wish
- asking for additional information again and again
- waiting another week after each contact (email) before responding
- complimenting you when, in the end, you found the solution yourself or some workaround that does not require Valve to do anything
You feel like a difficult child with Steam a patient mother! I don’t blame them, they must go crazy if support is anything like the developers forum in terms of what they have to deal with. But they opened the floodgates themselves an now we are trying not to drown. They could invest a bit more in good documentation that is up-to-date and also addresses the less trivial situations. After all, what would keep us away from Support more effectively? Also, their demeanour feels a bit condescending to a developer with 20+ years of software development experience. But hey, its a small price for the opportunity to implement your vision.
Ok, so support is not super and you basically have to help yourself. That’s fine, we’ve been doing that for many years. But it gets difficult if problems start to cross to our side of the fence; The software we are writing.
- “Injects” functionality into your application.
- Injected code contains errors!
- Says; Stay on the well-trodden path.
For the Steam-overlay to appear on top of your Software/Game, it gains access to your render surface. In our case, the OpenGL render context.
Everybody who did any OpenGL programming of some size knows that the state-based approach of OpenGL can be difficult to keep in control. A bug somewhere in your code can trigger crashes or strange behaviour in completely different parts of the code. In our case it becomes even more difficult because we do OpenGL vs OpenCL interoperability that requires meticulous guarding of states, pipelines, memory access and synchronisation in both APIs.
For that reason we make sure to use all (of the few) ways to monitor the state and make sure not to trigger an error state.
The Steam overlay code uses a legacy (pre OpenGL 3) way of retrieving so called “extension” functionality. Functionality that is not part of the main API and needs to be queried before use. Since we use a core OpenGL context without support for the legacy API, the GL implementation (driver) generates an error. The resulting behaviour is undefined. In practice things “seem” to work (for AMD and NVidia) and as long as you don’t install an error callback you will never know (they don’t seem to check the error state?). But for us this can be a problem. As far as we know nobody uses OpenCL in games yet and for sure not in the way we do. It is hard enough as it is without third parties messing up our GL context. In this case the Steamworks support mentality no longer feels like a “patient mother“, but rather translates to a “we know better than you puny wannabes” bully. Especially since this issue has been reported for many years already. I still have to hear back from them for this particular issue, so who knows. Maybe they complete transform into a super helpful solution provider that will immediately put their best code chiselers on the issue.
Don’t try to be smart, do what others do. Not my favourite approach.
Comments and reactions to this blog entry can be made on our forum.
More integration hassle.
- It begins with our design of how systems start up.
Every sub-sytem is created, allocated resources (memory) and initialized. We can role back and re-initialise each system. If we change settings that require more memory for example, we destroy and create the subsystem. For example the OpenGL context.
- We use GLFW for OS abstraction.
Unfortunately, GLFW merged Window and OpenGL context creation. So if we need a different context, we will get a new Window.
- To be fair, the OpenGL design suffers from the legacy notion that a context should automatically contain a (main) frame-buffer.
The context should just be state management. All frame-buffers should have been separately created ( and one assigned to the display).
- Steam hooks into the game to provide the overlay functionality.
For development the overlay can be initialised through the SDK so developers can test the overlay even though the game isn’t started from the Steam-client. The hook is done once and part of this is probably retrieving the Window handle to peek messages for input events.
So what happens when we change a video setting?
We destroy the video system and create a new one. GLFW destroys the context and the Window!
Steam doesn’t see this and keeps the original Window handle.
So now the F12 screenshot key and Shift+TAB overlay trigger no longer work!
What Valve should have done is use the automatic hooking if the developer didn’t integrate the SDK.
But if it is, make the SDK initialization leading! This way the developer could determine when to initialise the Steam SDK. For example when the Window handle changed.
This is also a typical example of what happens when functionality is combined for “convenience”:
- Our systems: Creation, resource allocation
- GLFW: OpenGL context, Window
- OpenGL: State and Framebuffer
- Steam: Hook and Window handle retrieval
Assumptions, always a good way to get it wrong.
Something else is demonstrated here. Something I’ve come to understand as a developer: separate data from processing. One of the main reasons why OO design is bad. But that controversial statement probably deserves a blog entry by itself.