Skip to content

Release Day

My mind has been spinning over possible next steps for this game. The reception to the testing versions has been mixed - there are a small group of players that have gotten really invested in competing for the top score on the leaderboard, but most users tend to get bored and uninstall the game pretty quickly. Public posts soliciting for feedback on the game have gone unanswered, and even my close friends are long tired of playing the same simple game over and over.

I think we're long past the "minimum viable product" phase, and so we should go ahead and release the game publicly. Unfortunately, due to its simplicity, it's unlikely to do well in the overly-saturated mobile game market. I have to remind myself that it doesn't matter how well the game does, it's just important that I finally achieved my goal of releasing the game.

However, there are a couple of little changes and considerations that I'd like to make before officially releasing the game.

First off, it's already March 2024, so I need to update the copyright notice at the bottom of the title scene. While I'm at it, I think I'll change my real name to my company's name, to match the name of the publisher on the App Store and Play Store.

The footer contains the URL for this devlog, but it's not actually clickable, and I'd like to change that. I created a new UrlHandler interface and exposed it through the Engine via the ServiceLocator interface. I spent some time whipping up the platform implementations of the new interface, which wasn't particularly difficult, but they are very different from one another.

The Apple implementations are the most straight-forward, since Apple provides some nice openURL functions.

alfredo/src/platform/MacUrlHandler.mm snippet

void MacUrlHandler::open(const std::string& url) {
  auto urlString = [NSString stringWithCString:url.c_str()
                                      encoding:[NSString defaultCStringEncoding]];
  [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:urlString]];
}

scampi/src/platform/IosUrlHandler.mm snippet

void IosUrlHandler::open(const std::string& url) {
  auto urlString = [NSString stringWithCString:url.c_str()
                                      encoding:[NSString defaultCStringEncoding]];
  [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
}

Pesto's implementation opens a new browser window by emitting raw JavaScript using Emscripten's EM_ASM() macro.

pesto/src/platform/WebUrlHandler.cpp

void WebUrlHandler::open(const std::string& url) {
  EM_ASM({
    window.open(UTF8ToString($0), '_blank').focus();
  }, url.c_str());
}

Android was by far the most complicated, having to start a new activity from Java code, invoked over JNI.

carbonara/app/src/main/java/com/justindriggers/carbonara/MainActivity.kt snippet

fun openUrl(url: String) {
    val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
    startActivity(intent)
}

carbonara/app/src/main/cpp/jni/Urls.cpp snippet

void Urls::open(const std::string& url) {
  _env->CallVoidMethod(_app.activity->javaGameActivity, _openUrlMethod,
                       _env->NewStringUTF(url.data()));
}

carbonara/app/src/main/cpp/platform/AndroidUrlHandler.cpp snippet

void AndroidUrlHandler::open(const std::string& url) {
  _urls.open(url);
}

Now the user can actually click the link on any platform to go read about how the game was made!

25.2 Monetization Considerations

I've gone back and forth over the idea of putting ads into the game. I absolutely hate how prominent advertisements have become in our society, so I feel very reluctant to do so. Unfortunately, such a simple game has no chance of succeeding with any sort of up-front price tag.

Like I mentioned in the last chapter, refusal to put ads into the game is effectively conceding that game developers shouldn't expect to be rewarded for their efforts. I feel stuck between two horrible options.

The only thing that makes me feel better is that I have kept the source code for this game freely available, along with the commentary of this devlog, hopefully for the benefit of some developer somewhere.

Of course, even if I don't make any money off of this game directly, there's no telling what sort of opportunities will come my way as a result of having built it. Furthermore, if the game does see any sort of unexpected success, I reserve the right to change my mind and sell out.

25.3 Releasing Version 1.0.0

I've set the version numbers for both Scampi and Carbonara to 1.0.0. As part of the official release, I'll be switching both apps to use entirely new leaderboards, both of which I've named "release". I updated the references to those leaderboards in the code, built both the iOS and Android apps, and submitted them for review.

I had to provide more screenshots for Apple using very specific dimensions. My iPhone 13 Pro didn't actually match the resolution for the required 6.5" display screenshots, but I was able to resize the screenshots using the same aspect ratio in Adobe Photoshop. I was also required to submit at least one 5.5" display screenshot, which was a bit more of a pain. I had to launch the game using the iPhone SE (3rd Generation) simulator, but apparently the SelectableFeatureRenderer's texture sampling logic is broken in the simulator, though I'm not sure why. To get around it, I just commented out the sampling logic and took a screenshot of the title screen. The resulting screenshot still didn't match Apple's required resolution, but the aspect ratio was suitable for another resize in Photoshop.

The Google Play Console was nice enough to inform me that I needed at least 4 screenshots to be eligible for promotion, so I went ahead and took a couple more screenshots from my Pixel 3 XL, which unfortunately has a black bar across the top, but it's the only physical Android device I have readily available, and I can't possibly progress far enough in the game to get good screenshots within the emulator.

Now I wait.


Both Apple and Google were very quick to approve the final builds each taking less than 24 hours - so without further ado, I officially introduce Aegis: Infinite!