If the following reads like a quaint update, I apologize– with the Fall semester having begun, lecturing, lecture prep (don’t underestimate this!), grading, and student / colleague comms is consuming the large portion of my available time. With that said, BTD (Life’s a Beach) continues to advance with new elements of polish, new under-the-hood systems (will have impact later), new art assets, and plenty of small bug fixes. Let’s go!
Daily Active Users for BTD–
A graph of mixed results! The game is being played, though not heavily in any sense (which is no surprise, as no advertising has been done yet). Interestingly, the positive growth trend that developed from late August to September 14th has abaited in the last 5 days or so. One might guess that a bad update caused instability around the 14th, and while there is some data to suggest this may be possible, our crash analytics are not overwhelmingly scary. If this is the case, our recent updates should hopefully restart the growth trend.
It is also possible that a small unknown-to-us community or influencer picked up the game briefly, causing a steady growth to take place. To my knowledge, the game is not being talked about in any significant way, which is good– it is still missing critical features and we have no way to get revenue from it just yet (the shop is closed).
There is a positive here though– it is indeed possible for the game to get into a growth streak, even in its current very-unfinished state. It is also worth noting that, although the game lost the growth momentum it had for a couple weeks, it is currently healthier in its daily player count (5-7 players per day) than it was in late August (2-3 players per day). With luck, in a couple months we will be bemoaning a daily player count of 40-50 players!
Loading Screen Updates
The old pre-game loading screen :
The new pre-game loading screen :
One of the more visible updates this week involves the initial loading screen that appears when players launch the game. A lengthy process on Web builds (not so much on Windows or Mac builds), it is worth investing in, as our analytics indicate that a non-neglegible percentage of players quit before the loading finishes.
The new loading screen adopts a modern, sleek minimalist style, with the only exception being the small south-eastern drop shadow– something that modern UI often avoids, but that is necessary given this needs to work across many different games, and the text will disappear if a particular game has a bright loading screen background (like BTD does).
Compare to the old loading screen– functional but sloppy-looking. It uses an explicit rounded window to house the text, and thus looks less simple and elegant than it could. The loading text underneath shows a number and a message instead of a simple bar, and less the player decide to calculate the 0%-100% “progress bar” in their head, they will be surprised to discover that there are multiple counting sections (downloads, loads, and image atlases) that will throw this computation off, perhaps disappointing them. The message means quite a bit to the developer (particularly when we’re trying to optimize parts of the loading process that are slow), but it’s just visual noise to the player who doesn’t have that motive or context. Scrapping these things and replacing with a proper loading bar was an instant and immediate win. Thank you to my MI game studio friends for snapping me back to this reality.
The loading-timer in the bottom-right corner still uses this style, and should be changed in the future (or excluded from non-dev-builds in the future. I can’t decide if I want players to know exactly how poor our loading times are. Maybe they will feel shorter without the timer? Perhaps I should keep it in, as it provides pressure for me to address these loading times sooner rather than later).
One of my only wishes now was that the “…” elipses would animate up and down. This is due to the fact that there are periods (sometimes a couple seconds in length) where the bar does not move at all, leaving the player to wonder whether the game is truly frozen. If we put each dot on their own section of the absolute sin wave, we could see them hopping together, like something out of the first Rayman game–
While improving the visual appeal of the loading sequence is likely a decent investment, the true long-term struggle for this game is going to be the total loading time. Currently, loads can take 30-40 seconds in the web browser, and 10-15 seconds in Mac and Windows builds. The game loads all of its data into RAM during this load screen, giving us speedy load times in the rest of the game, but this is probably unecessary. In implementing our content-downloading technology for the first time, it was more architecturally straightforward to have the game load all assets at once, as there is currently no easy, built-in way to know whether a particular asset is needed for any given stage, any given menu, etc. If we did know, it wouldn’t help much– our images are compiled into large atlases to help with rendering efficiency, so loading a single image causes many other images to be loaded, eliminating the gains of only-load-what-you-need. One area where we could improve is ensuring that related images are “packed” together into one image atlas. In this way, we could get most of the needed image data for a battle by downloading / loading a single 4096x4096 atlas instead of 5 4096x4096 atlases. This is an interesting technical topic– one that may be worth exploring further in future devblog posts (and with more images to explain how our tech works).
Entity System Updates
Just because an object can’t be seen, doesn’t mean it is gone or doesn’t exist. Object Permanence is an interesting topic in the development of human brains, but it is also interesting in the context of game worlds!
In many smaller Unity games, if an enemy, unit, item, or environmental object disappears from the Hierarchy (scene), it is typically by way of destruction (GameObject.Destroy()).
If it can’t be seen in the hierarchy view, it doesn’t exist. This approach is very straightforward, and very nice if the game design can allow it (we don’t need to worry about a gameobject that doesn’t exist!). Unfortunately, this limits our ability to have large persistent worlds capable of evolving and progressing even if our player avatar isn’t near by. Think of Skyrim–
When you talk to an NPC in Skyrim, they will sometimes run off to take on their own quest, perform some part of the plot, etc, and you eventually see them later. After running away from you and leaving your vision / general area, they “despawn” and the game stops rendering them (critical to preserve game performance). Despite their disappearance and “despawning” however, that “entity” still exists. It is still executing some logic in the background, and is still “exploring” and “existing” in the world, even if in a simplified state. The NPC that ran away to complete an objective may be reduced to a simple “timer” variable in memory, to be spawned back in nearby you when their “timer” runs down. They still exist, even though their “gameobject” does not.
In Arbor Interactive games, the “Entity” system is meant to give us this ability– the ability to have a unit, item, etc exist in the game world without being a gameobject in the current Unity scene. In this way, gameobjects may be thought of as “views” that show us entities that exist in the game’s memory.
In the current build of Life’s a Beach, there exists an “Entity” for each playable character. This entity is created when the player first plays as this character, and it is never ever destroyed or “killed”. This entity is a key-value store, allowing the entity to store things like items, various stats (hp, atk, experience points, etc) and persist these things across runs. Upon a game over, the entity does not lose its items or stats. Compare this to the enemy units in the game– when an enemy unit spawns, a new entity is created, and a new gameobject “view” is created so that we can see this new enemy entity in the game world. These entities are given a team, and they are permitted to die (and vanish forever) when their hp reaches 0. This is different from how player characters work– whenever a new stage begins, a new gameobject “view” is created, but it is told to visualize the existing player entity, since we do not create new player entities.
This is likely a bit confusing– I will attempt to clear things up with images and diagrams in future posts if I have enough time. Here’s the takeaway– our “Entity” system allows us to simulate an enormous world full of units, items, etc– even if they aren’t all spawned in and visible at any given time. This system will come in hand should we decide to make RPGs in the future using this tech. In the current Life’s a Beach version, this tech helps us do things such as persist stats and items for characters across many battles and game sessions.
Progression System Updates
Progression is a tricky topic, as a poorly designed one can lead quickly to design / balancing issues (or worse– save-file-ruining bugs). This week’s progress on Life’s a Beach’s progression system was purely one of design and planning. When implemented, it is likely to have a very straightforward, fairly-vanilla, but-tried-and-true progression in which stats advance kind of like how they do in Gen-1 Pokemon (a very basic system with a few interesting twists).
One of the holdups is in the implementation of such a system. Our Entity system (discussed above) is responsible for storing the various aspects of a character, including HP, ATK, EXP, etc, and so any progression system is going to need to interact heavily with the Entity system. It would be fairly straightforward to simply make HP, ATK, SPD, DEF, etc a function of the entity’s EXP value, but we need these systems to be re-usable across multiple games, and different games will likely want to implement different forms of progression, and we don’t want to hard-code any particular progression approach into either the Entity System or the Progression System. With this consideration, the current plan is as follows–
- Use Lua code (configured in the game’s master cloud-config spreadsheet) to establish how a statistic progresses as a function of another stat (exp).
- The Progression System downloads this lua code, and establishes the necessary Interrupts on the EXP stat for any entity that is created.
- When an entity’s EXP statistic changes, the Progression System detects this (through interrupts registered in the previous step), and re-calculates the entity’s HP, ATK, DEF, etc– any stat that had some lua progression code supplied for it.
With this high-level approach, we have easy-to-customize progression (via the lua code) that allows us to easily tweak how progression works on a game-by-game, stat-by-stat basis. We have a fairly clean architecture, where the ProgressionSystem is reusable (and changes its behavior slightly based on the lua code in the config spreadsheet), and we have an Entity System that has no game-specific code in it, leaving it clean, generic, and ultra-reusable. It is likely we will run discover some limitations of this approach when our first implementation finishes (hopefully this coming weekend), but the plan appears reasonable enough to invest in a prototype.
The old arborinteractive.com–
The new arborinteractive.com–
The new website (in its current form) is a downgrade in terms of polish, professionalism, and readability, but is far better in a few important ways–
- This website is entirely static, not relying on a wordpress installation. This should save the company ~$15 per month in Amazon EC2 hosting fees (this may not sound like much, but it’s an extra piece of artwork monthly!). The website is much lighter weight, loading much faster than the old version (which will boost the website’s accessibility and SEO). The website is structured as a Jekyll site, meaning it is very, very easy to add new blog posts, and customize the front page with new games, links, etc. The old website was using an outdated plugin, and would no longer accept any changes.
A website (or web game) optimized for SEO will receive increasing organic traffic over time, as the website begins to attract players through better placement in search engine results. It’s the kind of thing that won’t change any game’s fortunes overnight, but since Arbor Interactive’s entire business plan is to survive, survive, survive via frugal development and technology re-use, it’s worth investing in these kind of “small wins” early, so that we can enjoy the results in 2-3 years.
The new website needs some work, particularly in its reasability and polish. The logo and head banner looks ok, but the banner needs to make it more instantly clear that this is a game dev / digital media consulting company, which is not immediately obvious right now. The top banner also re-uses a banner from Life’s a Beach, which features Shadia staring into the player’s soul– a distracting thing to put in the banner (more variety– images from a variety of Arbor Interactive games– would be nice).
- Life’s a Beach has very little variety in its content right now due to a lack of towers, tower types, and unit types. I expect the game’s retention to improve substantially as this aspect of the game improves.
- The game lacks progression in any way except item accumulation. While the game has a rank up screen, it is not yet functional due to ongoing under-the-hood work on how to represent level ups and stat increases. The game’s retention should improve dramatically once we have a basic progression system implemented.
Mac + Windows Builds
- Currently, Life’s a Beach’s web build runs somewhat poorly. Some users report an overall slowness to the game, which is very disappointing. My team will always place a high value on game-feel and responsiveness, so this must be addressed with optimizations in the long-term. In the short term, the current Mac and Windows builds both run at superior framerates to the web version, so it may be worthwhile upgrading the build process to post them underneath the WebGL version of the game. For SEO purposes, it may be worthwhile to give Life’s A Beach a landing page at lifesabeach.io, where users may choose how they wish to play the game.
Blinking / Damage Character Portrait Aesthetic Updates
Some fun new art assets this week!
If you play the game, you will see your current selected character in the bottom-left corner. They hang around there during gameplay, during stage select, in the menus, when upgrading, in the shop, etc. If you click on them, you get the choice to change that character, and you can even see some stats– it’s one of my favorite new UI techniques.
However, if we look closer, something may begin to feel a litte off.
Ah! The character isn’t blinking!
Since you and your selected character will be spending a good bit of time together, it makes sense that we invest in the character corner mugshot aesthetics. A quick improvement we can make is allowing the character to blink, and having the character react to events such as taking damage. To this end, our phenomenal artist, Sam Olson, has produced some new frames of animation for the three main playable characters–
Please look forward to seeing these in-action within a week or so!
Grand Alliance Launch!
Crunchyroll’s partnership with local Ann Arbor-based game studio Gaudium has yielded Grand Alliance– a new mobile RPG / Beat em up with an awesome anime style. Michigan’s gamedev community has been exhibiting some great talent as of late, so let’s keep it rolling and keep this community improving!