I used React Native to build a cross-platform game for iOS, Android, Windows, and the web. SudoBlock is a cross between Sudoku, jigsaw puzzles, and Tetris.
You can find SudoBlock on the web, App Store, Google Play, and the Microsoft Store.
React Native only supports iOS and Android, but I used react-native-web for the browser, and react-native-windows for Windows desktop and phone. The UWP app can also run on Xbox One and HoloLens. I also experimented with react-native-macos and react-native-appletv, but they’re not being maintained.
Here’s some of the things I learned while building SudoBlock:
I’ve heard good things about Godot and Unity. These game engines support iOS, Android, Windows, and Linux. Unity supports many other platforms.
Making a simple game was a great way to learn React Native, but it’s not the best tool for the job. However, people have started working on some game libraries for React Native, such as react-game-kit and react-native-game-engine.
It’s not the easiest way to make a game, but it’s also not impossible. The built-in Animated library is great, and I also used react-native-animatable. I used a library to play sounds. I wrote native code to integrate with iOS Game Center and Google Play Game Services. I used libraries to integrate with InApp Billing on Android, and in-app purchases on iOS. I also wrote native code for ads and in-app purchases on Windows. There’s a RN library for particle effects (although you’d have to add support for Android), and react-game-kit provides a way to manage sprites and animations.
I want to make some more simple 2D games, and I’m going to stick with React Native for now. I can fork SudoBlock and reuse a lot of the code that I’ve already written.
If your goal is to quickly build a cross-platform mobile game, then I’d recommend learning Godot or Unity.
This is a no-brainer. No one uses Windows Phone and Microsoft have abandoned it. I wanted to explore and learn new things, so I decided to do it anyway. I enjoyed the process of installing Windows, working with Visual Studio, and writing some C#. I also figured out how to write cross-platform npm scripts using scripty.
react-native-windows gives you a UWP app that can run on Windows Phone, tablets, desktop, Xbox One, HoloLens, and other Windows platforms. But:
I also did a lot of work on react-native-blur. When I first tried to use it, it was completely broken on Android, and there were lots of problems on iOS. It took a lot of work to get everything running. I could have just skipped the blur and used a darkened overlay, but I enjoyed the work and learned a lot.
I also had to write native code to integrate with iOS Game Center and Google Play Game Services, and for ads and in-app purchases on Windows. I also wrote a small library to manage vibrations and haptic feedback across iOS, Android, Windows, and the web (using the Vibration API.)
React Native is pretty stable, but there’s a lot of unmaintained libraries, and most libraries don’t have any tests. React Native is a bit like jQuery, in that it smooths over a lot of quirks and inconsistencies and provides a consistent API. But there’s some tricky edge cases, and I often had to read the React Native source code to figure out why something was happening.
Android was particularly unstable. Not just React Native, but Android itself. I didn’t have too many problems with iOS.
I wrote an iOS app with Swift a few years ago, and I’ve actually had a much better experience with React Native. When I was working with UIKit, I remember constantly fighting with things like layout, contraints, and font rendering. I uncovered some actual bugs, and found long threads on the Apple forums that were being ignored. It was really nice to let React Native handle all of the rendering. I had no rendering issues on iOS or Android, and just a few problems that I fixed on Windows.
Swift was also very unstable at the time, and Xcode upgrades took a lot of effort. My Obj-C code still compiles a year later on the latest version of Xcode. If I was using Swift, I think it would take at least a day to upgrade to Swift 4.1 and update all of the third-party libraries. I believe Swift is more stable now, and I love the language, so I might start using it again on future projects.
I had a lot of headaches with React Native, but it wasn’t as bad as Swift v1 and UIKit.
I tested Facebook ads with $50. I reached about ~7,000 people and got ~50 clicks. One person ended up buying the game for $2.99, so I made $2. You can’t spend $50 to make $2.
I posted on Reddit a few times:
A German website published an article about SudoBlock.
I tried to capitalize on #covfefe, which didn’t work at all. But I repurposed that new code into an Emojidoku mode.
I found a game publisher who was going to handle all the marketing and split the revenue. They even promised to get the game featured on the App Store. We signed the contract and I took the apps down for a while, but the publisher fell off the radar and stopped replying to my emails.
I finally got around to writing this blog post.
I switched from Sublime Text to VS Code near the beginning of the project. VS Code is awesome. It’s super fast and very customizable.
I starting doing some functional programming with lodash/fp and ramda. I had fun refactoring some code in a more functional style.
I really enjoyed working with redux-saga, which helped me clean up a lot of messy code.
I learned a lot about Reactive programming. This post is amazing: The introduction to Reactive Programming you’ve been missing. I started playing with RxJS and redux-observable.
I set up CodePush, so that I could push JS changes without releasing a new version to the App Store. The setup guide is very helpful.
I had to debug some memory issues on Android, and this article was really helpful: React Native Android App Memory Investigation
I learned about the webpack DLL plugin, which made development a lot faster. You can compile everything in
node_modules as a separate bundle. You only need to do that once, so it saves a lot of time.
I released a boilerplate project with my webpack config for react-native-web.
I learned about the Babel AST while working on an issue in a Babel plugin, related to react-native-web.
I wrote a script that stripped unused glyphs from icon fonts, to reduce the app size.
I tested the app while simulating a slow network connection in Chrome. This revealed a bug where the counter started ticking before everything had finished loading.
I discovered that it takes a huge amount of effort to actually launch a game. Once I had a playable game, it was another 2 months before everything else was finished. Things like in-app purchases, ads, analytics, high scores, achievements, tutorials, app store listings, screenshots, icons, social media accounts, etc.
This was about 3 months of work, and I was in a state of flow most of the time. I learned a lot of new things, and I really enjoyed the whole process. The game has only made about $50 so far, but I have some more ideas for grid-based games, and I can reuse a lot of the SudoBlock code. I’m also a freelancer, so this is the only way I can pick up new skills.
Thanks for reading! If you have any questions, please leave a comment on Hacker News.