Skip to main content

Posts

Showing posts from 2016

Rewarding players for playing every day in Corona SDK

Rewarding players for coming back and playing your game every day is nothing new, and is probably used in most successful games out there in one way or another. I don't want to miss an opportunity to keep my Ice Trap players for a little longer if possible, so I've implemented a simple daily rewards solution in Corona SDK to handle this. My solution is the simplest possible really: Give the player a reward if he/she plays two days in a row. The reward will be the same every day regardless of the number of consecutive days played. I guess you could make this just as advanced as you like, with increasing rewards after a specific number of days, different rewards on different days and so on. But for the moment I don't see a need for that, and a flat reward will do just fine to start with. Recently I implemented a concept in Ice Trap called level keys, allowing the player to unlock the next level if getting stuck. The player starts the game with a few keys, and can then ea...

Generate app icons using bash script in Windows

Generating an app's icon in all necessary sizes for both Android and iOS can be really time consuming and boring. It would be ok to do this work manually if you'd only have to do it once for each app just before release. Unfortunately that's not the case since the final app icon is most likely something that evolves through iteration. Needless to say, there is time to save by finding an efficient way to automate the icon generation. There are many tools out there that can help out with this. I've tried a couple of them and they've all worked just fine. The problem is that I've found that they don't actually save me that much time in the end. For iOS, you need a completely square icon and iTunes/iOS will handle the rounding of the corners for you. For Android on the other hand, you have complete freedom when designing the shape of your icon. I prefer to have my Android icon look as similar to the iOS icon as possible, which means that I'll have to cre...

Ice Trap is making progress

Lots and lots of new levels have been created for Ice Trap  in the last couple of weeks. Countless types of varied puzzle mechanics and level designs have been tested. Some of them went straight to the trash while many of them ended up in really cool levels sure to give the players loads of tricky puzzles to solve. That's some neatly stacked boxes! Right now I think that I might actually have too many levels for v1.0, so I probably need to sit down and prioritize which levels should make the final game and polish them into perfection. I guess that has to be a lot smarter than creating even more levels just because it's so much fun... The ice bubble seems to do just fine instead of a helmet.

Organizing display objects in layers in Corona SDK

Working with display objects and display groups in Corona SDK is fairly straightforward. Every Corona developer probably knows the basics of this and how you can organize your display objects in a hierarchy of display groups. All this is also pretty well documented by Corona Labs right here , so I'm not gonna go into details about any of this. Instead I'll show you how I've created a simple helper class called DisplayManager which I find very useful when it comes to leverage the concept of layers and to keep track of all display objects to avoid creating memory leaks by not cleaning up the display objects properly. What I want the DisplayManager class to help me with is basically a few things, that otherwise requires quite a lot of attention when coding: Leverage the concept of visual layers, and encapsulate functionality concerning layers in an object-oriented way, making it easy to extend when needed. Make sure that all display objects are cleaned up as they shou...

Testing GameAnalytics v2 for Corona SDK

I've been trying out the new GameAnalytics v2 plugin for Corona SDK recently. It has some nice new features, especially the progression events which simplifies tracking your players' progression through the game. After the initial setup of the plugin, which is really simple (unless you make stupid typos...), you can fire progression events like in this example: gameanalytics.addProgressionEvent { progressionStatus = "Complete" , progression01 = "world01" , progression02 = "level01" , progression03 = "phase01" , score = 100 } For Android I got my events flowing pretty quickly, but when testing on an iOS device, no progression events at all showed up in my GA dashboard. Searching through the log file from my device I found the following error message: Nov 8 14:27:36 iPhone Ice Trap[1869] <Notice>: Info/GA/Analytics: Validation fail - progression event - progression02: Cannot be empty or above 6...

Converting wav files to mp3 the easy way

I have often found myself in need of converting audio files from wav to mp3. As you all know, mp3 files are a lot smaller than wav files, which make them a much better match for mobile apps where you want to limit the final bundle size as much as possible. Another very important aspect is that Android devices seem to have a lot of problems playing wav files. I'm not sure why this is and haven't dug any deeper to find out. Instead I just accept the fact and make sure that all my audio files are in mp3 format, since that's better when it comes to file size anyway. There are probably a gazillion options available to convert between differents audio formats, both desktop tools and online tools. I've tried a bunch of these tools, and my favorite tool is by far  http://online-audio-converter.com/ . It's super easy to use, it's fast, completely free, and there are almost never any problems during format conversion. One of the best features that many other online to...

Creating a game video

Yesterday I decided to create a little teaser video for Ice Trap , showing off different ways of dying in the game. I believe that failing in a game should be almost as fun as playing it, so I try to put some extra attention and details into that part of my games. Being primarily a programmer, my expertise when it comes to video editing is - to put it nicely - very limited. I had a clear idea what I wanted to achieve, but no clue which tools to use. Also, my tight budget limits me to use free or very inexpensive tools which heavily reduces the number of available options. What I wanted to do was: Record some actual gameplay sessions where I fail in different ways Trim each session to only a couple of seconds Crop each session, zooming in on the area where the actual dying is going on Compile all the short clips into a single video file Add some sound effects Convert the video file to an animated gif I won't go in to details about all the different approaches I tried....

Avoiding pixel overlap between sprite frames

When working with sprites in Corona SDK I've quite often run into a problem with sprite sheet frames occasionally overlapping each other. When I say occasionally I mean that it doesn't happen for every new sprite I create even though the same sprite sheet is used, and it doesn't happen on all device resolutions. This is what it might look like when the overlap happens. Not pretty... The sprite's image sheet Sprites in action, pixel overlapping between frames To work around this problem in the past, I've just padded my sprite images with a couple of transparent pixels so that the possible overlap won't be visible even though it might still be there. This has caused some additional work both to set up the sprite sheet images, as well as calculating the frames' positions within the sheet. So I figured I was gonna look for another solution to be able to create sprite sheets without padding that still look good. Tough luck it turned out. The pixel o...

App icon and landing page for Ice Trap

Ice Trap is getting closer to release. The game engine is almost complete and runs really smooth on all the devices I've tested on so far, including a crappy old Asus Android pad. The number of levels are increasing at a steady pace much thanks to the new level editor, and the graphics are also starting to feel really good and fitting for the overall atmosphere of the game. Some work still remain, such as adding music and sound effects, some social media features, and finalizing the levels design, finding just the perfect overall difficulty curve. Today I felt that it was time to spend some hours on polishing the exterior of the game, so I decided to create a brand new app icon, and also set up a simple landing page allowing people to register for email notifications about important news such as release dates. Ice Trap app icon If you visit the Ice Trap landing page , please let me know what you think about it. Especially if you notice any problems displaying it on you...

GameAnalyics plugin V2 for Corona SDK

I just received an e-mail saying that GameAnalytics has released an updated plugin for the Corona SDK. This is great news! In my last game Dragonflies I used the GameAnalytics plugin and was planning to do so in Ice Trap as well. It's an incredibly easy and efficient way to track your users' behavior, and if you're not doing it already I strongly recommend you to have a look at GameAnalytics. I haven't had time to test the new plugin yet, but will definitely do so in the near future. You can  read the full news about the plugin here .

Ice Trap level editor

One of the mistakes I made during the creation of my first mobile game Dragonflies was to not spend some time building a level editor. I figured the time it would take to finish the editor would be better spent just implementing the levels the fastest possible way. In my case this meant playing around with pieces of colored paper on a hand-drawn coordinate system, and then manually do the conversion from paper to json files. It actually worked out quite well in the beginning, until I started making more complex levels... Not only did it take a lot more time than expected, but designing levels became so incredibly monotonous and tedious. That's not exactly what you want when you're trying to be creative and come up with cool, new level ideas. Lesson learned. For my upcoming game Ice Trap I started out the same way, by just hand-crafting the level files in json format. But this time I knew it was only going to be temporary. When I got to the point where the gameplay felt soli...

Collision filters and bit masks in Corona SDK

Ok, so you're working on a game and you have some objects that you need to configure how they should (or shouldn't) collide with each other. If it's the first time you're doing this you'll probably end up at the Corona Labs page about collision detection pretty soon. You read through the section "Collision Filtering" and can't help but wonder: Does it really have to be this complicated? No, it doesn't. There is absolutely no reason to force knowledge about implementation details like category bits and bit masks onto the developer. All you want to do is specify if objects of type A should collide with objects of type B or not. But to do this, you need to assign unique bit identifiers to each object type, calculate the bit masks yourself, make sure that two colliding object types cross reference each other and so on. It gets really nasty as the number of object types grow. Consider the example from the Corona Labs documentation in which there ...

Simplifying sprites and image sheets in Corona SDK

I like many things about Corona SDK, but one thing I don't like very much is the API provided for handling of image sheets and sprites. In my opinion it is difficult to use and very fragile because of poor encapsulation and coupling, including things like: No common way to create images and sprites from the same image sheet. You're left using display.newImage() , display.newImageRect() and  display.newSprite() . Selecting frame from an image sheet is done using frame number, for example display.newImage(sheet, 1) . Not only does this expose implementation details, it also makes the code really hard to read since you don't know the meaning of the integer unless you examine the image sheet and actually count the frames. Imagine having a large image sheet with 20+ frames trying to figure out what image will be displayed by display.newImage(sheet, 13) ... And if you ever want to change the frame order within the sheet, you must also change every call to display.newImage() ...

Use Bfxr to make 8-bit sound effects for your game

A really useful online tool that I came across during the making of Dragonflies is the free sound effect generator Bfxr found at http://www.bfxr.net/ . As the author describes it: Bfxr is an elaboration of the glorious Sfxr, the program of choice for many people looking to make sound effects for computer games.   You have full rights to all sounds made with bfxr, and are free to use them for any purposes, commercial or otherwise. This is truly awesome to get for free if you're looking to create cool 8-bit sound effects for your game such as exlosions, powerups, coins etcetera. I used Bfxr for almost every sound effect in Dragonflies , and I'm pretty satisfied about the end result. At least I know I couldn't have done better without spending way more time or having to pay someone else to create the effects for me. Bfxr online sound effects tool   So if you haven't already tried Bfxr , I think you should definitely give it a shot. Besides being a very useful...

Updated FPS calculator for Corona SDK

A couple of weeks back I wrote this post about how to calculate the actual frame rate of your game rather than just hoping that the target frame rate found in display.fps will be met. Back then I only used it as en experiment, but today I wanted to implement it in my game Ice Trap to be able to reduce or disable some animations on slower running devices. I ended up rewriting the frame rate calculator in an object-oriented fashion to make it cleaner and more reusable. It should be very easy to use. Just create a new instance of the FPSCalculator, passing in a callback function and some optional configuration parameters. In the callback function you'll have access to the current FPS as well as the FPS ratio, i.e (actual_FPS/target_FPS). If none of the optional config parameters are specified the callback will be invoked once every second, regardless of whether there's been a FPS drop or not. Check out the whole source code below, including some example usage code, and make m...

Swiping objects sideways in Corona SDK

Just the other day I needed to create a "swipeable menu" for my next Corona SDK game called Ice Trap, where I want the player to be able to swipe left/right to select among a number of chapters in the level selection scene. Basically, what I wanted to achieve was this: 1. Have a number of display groups, each one representing one of my game's chapters 2. Only one chapter (display group) visible at the screen at a time 3. Allow for the user to swipe left/right to select chapter 4. Prevent swiping too far left or right 5. Use transition effects to slide the chapters into place nicely 6. Display a clickable thumbnail for each chapter, allowing the user to quick jump to any  one chapter. Also highlight the currently selected chapter Here's a simple sketch of the idea: After scanning the Internet for half an hour or so I still hadn't found a complete solution for this, so I decided to roll my own instead. What I did find was this small tutorial from Co...

Corona Labs announces splash screen control for $99/year in free version

Corona Labs recently announced a new major release of the Corona SDK platform, including a long list of fixes and features as well as iOS 10 support. The release notes state that "In the current development cycle, our engineers have been working hard on addressing infrastructure and core improvements to Corona to make a more stable platform" . This is really good news and I sure hope that it is as true as it is welcome. Making the core platform better in any way possible has to be the number one focus for Corona Labs at all times in my opinion. But what probably caught most peoples' attention was the following paragraph about changes to the splash screen: "One of these features is new “splash screen” controls, a system which will drastically simplify splash screen implementation. Starting with this build, a default Corona-branded splash screen will appear briefly when the app starts. We continue to believe in keeping Corona free to use, but we also need to gr...

Corona SDK newRect() vs newImageRect() performance comparison

My next Corona game contains quite a lot of explosion effects in pixel art style, where I basically just scatter a number of single-colored squares in different directions. The squares are all created using display.newRect()  which I figured had to be both the easiest and most efficent way for creating these simple geometrical shapes. Explosion close-up from Ice Trap But then it kind of hit me: What if using newImageRect() with a 1px image scaled to the desired size could actually be faster than newRect() ? Not very likely, but since I have no idea how the Corona SDK graphics engine is implemented I had to try it out with a little sample program. I decided to run three separate tests. Not scientific in any way, but at least it should give me a clue of which function performs best. In each of the tests I just created a bunch of squares of the same size randomized across the screen, and measured the time taken to create them. The three tests had the following setup: 1. Use...

How to check the actual frame rate (FPS) with Corona SDK

EDIT: This example has a follow-up in this blog post containing improved and object-oriented source code for the frame rate calculator. In Corona SDK you set the target frame rate in config.lua to either 30 or 60 FPS (Frames Per Second). Then during application execution you can get this value through display.fps . However, remember that this is only the target  frame rate, and the actual frame rate is something completely different. The actual FPS will fluctuate during program execution and can be significantly lower than the target FPS in case your app has too much to handle at any given moment. I couldn't find any built-in way to get the actual FPS, so I decided to roll my own very simple solution to handle this. My frame rate calculator is just a Lua function that sets up an enter frame listener which then counts frames and calculates FPS based on time passed between the frames. The function  startFrameRateCalculator  accepts a single argument which is a callba...

Changing color theme in ZeroBrane Studio

My favorite Corona/Lua IDE is  ZeroBrane Studio . When I started building games with Corona SDK I didn't even know it existed, and instead purchased a license for Lua Glider since that was the only reasonable editor I could find with build-in support for Corona. Lua Glider was such a pile of crap that it doesn't even deserve linking to. It might have evolved now but when I bought it, it was so painfully slow and full of bugs that I would have done better using Notepad++ or just about any text editor without the Corona support. So, good thing that ZeroBrane Studio showed up to save me! ZeroBrane Studio is a simple and fast Lua IDE with great Corona support. I don't use half of the features and customizations it offers, but I'm still very satisfied with it, just because it's so fast and easy to use. One thing I don't like very much is the default color theme, since I prefer a darker background with soft but clear text colors. ZeroBrane provides this too, it can ...

Corona Labs sold. Again.

Wow! It feels like it was only yesterday that Corona Labs was aquired by Perk Inc. I believe it was somewhere around November-December last year (2015), and now it's time for another ownership change. Perk sells Corona Labs: http://www.businesswire.com/news/home/20160915005710/en/Perk-Sells-Corona-Labs-Retains-Exclusive-Rewards Not really sure if this is good or bad, but I hope and believe that it will be mostly good. The year that's passed since Perk took over hasn't really pushed Corona SDK in any clear direction, at least not from what I can tell. The Corona platform still suffers from many of the same issues as it did a year ago, such as poor performance, not enough focus on core functionality, and bugs that take ages to fix. Hopefully we'll see a more focused and dedicated company in the future, bringing us an even better 2D game development platform. Because despite the flaws that I just mentioned in the paragraph above, I still believe that Corona SDK is a ...

A quick introduction

So, who am I and what is this blog about? My name is Markus Ranner, a Swedish software developer with 15+ years of experience, mostly with backend focus using Java but also numerous other programming languages. In 2012 I started looking into mobile development out of curiousity, and began building an iOS app in Objective-C just to learn the language, as well as the iOS platform and the whole Apple eco system. After only about three months of development I released my first version of Avocado Meal Planner on the App Store. And from there on I knew that I wanted to do more mobile development! Avocado Meal Planner for iOS I didn't realize it back then because I had nothing to relate to, but it was actually quite a success right from the start with several hundreds of downloads each day! Unfortunately the first version wasn't all that good, so not many people wanted to pay for the full version. But just knowing that people all around the world were downloading and using ...