The narrative of Life’s a Beach hasn’t received all that much thought– something that should be clear within about 10 minutes of playing the game. While its characters are charming (thanks largely to Sam Olson’s artwork and some playful voice acting), their motivations and backgrounds are at best dead-simple, and at worst non-existant. Improving the characters is a necessity, as meeting fun new people and learning their story is one of the great joys of existence (as scary as it may be for some of us).
Where to begin? If we look at the game right now, looking at its enemies, its playable characters, the intro cutscene, and general gameplay, there are a few things that cannot change–
- Sandy and Drift are building castles (proven through cutscene).
- Shadia doesn’t like it (proven through cutscene).
These two things cannot change because we don’t want to throw out solid (expensive) 1920x1080 artwork. We will use it to the death.
Here are a few more observation of things that can change–
- The player has an antagonistic relationship with wildlife, being fought by crabs, etc (proven through battles and enemy waves).
It occurs to me that we can adjust this latter item to give much-needed context to the two “things we can’t change” above. We should…
- Flip the relationship between Sandy and the crabs. They should be allied strongly (proven through 1-2 new cutscene slides showing crabs entering the new castle, and showing affinity for Sandy and Drift).
- Adjust gameplay enemy waves such that crabs no longer appear in them as enemy units.
- Create an automatic, guaranteed player unit posse of 2-4 crabs per-stage that will fight for you.
- Adjust marketing to no longer reference “pesky crabs”, as this no longer makes sense.
These changes allows us to (a) Motivate Sandy in building these castles. She doesn’t just love architecture (as referenced by her hat)– she also loves wildlife and wants to create a grand home for the local crabs. (b) Motivate Shadia’s short-term antagonism towards Sandy and her castles, as crabs are considered an invasive species in Michigan, could be seen to be annoying for beach goers, and Sandy’s rising popularity is a threat to Shadia’s power.
From a gameplay perspective, we gain the ability to spawn in 2-4 allies per stage (crabs) and have it make total sense. Positioning allied units to help defend chokepoints and support towers is a neat (and unique) part of gameplay, so it may help gameplay out a bit too.
This change, and specifically the fact that crabs are considered invasive in Michigan’s freshwater great lakes, gives us an avenue to push a more poigant idea as well– the idea of belonging and “otherness”. The poor crabs. Perhaps they really are upsetting local habitats, rebalancing local food chains, and causing some havok, but is it their fault? They’re just trying to survive, right? I wonder if my environmentalist friends will talk to me after this game launches.
A serious improvement to gameplay will require a serious improvement to testing and iteration. Waiting through an entire game load, menu navigation, stage select navigation, then intro cutscene won’t cut it. We need the ability to spawn in any enemy at any time. We need the ability to buff certain units with cheats such as infinite health so we can study how our AI, attacks, etc are working over a long fight. We need the ability to adjust (and persist changes to) testbeds such that we can test our technologies in diverse environments (and create unit tests out of them to prevent regression). The last few weeks of improvements to our landing page and load times were spurred by an improvement in our measurements and analytics in those areas. Our first step in improving gameplay should be to establish a more formal and rigorous measurement, analysis, and verification approach for gameplay-related problem areas.
In the current iteration of Life’s a Beach, a system called the GameplayManager takes responsibility for spawning enemies in the waves defined in the cloud config spreadsheet, running the stage intro cutscene, spawning the player’s posse, spawning initial currency, monitoring victory and defeat conditions, etc.
Note that none of these things are technically required for testing games. While we do need to eventually spawn units to test combat, we certainly don’t need to spawn them in a spreadsheet-defined way. Why can’t we just click a block and say “spawn 5 of unit type X on team “enemy” at this location?
- Upgrade : An affordance should be created simply titled “AffSpawn”. This affordance should be a right-click-only affordance, and be attached to any tile in the map. It should launch a window that displays a list of categories of “things” to spawn. Clicking a category should produce a window of all of those “things”. Clicking a thing should cause it to spawn at the initial location.
Facebook Ads Launched
Facebook ads (a whopping $3.00 daily) were launched on 10/06/2020, targeting those in the SE Michigan area with interests in tower defense, bloons TD, kongregate, and browser games– a much more specific set of interests than we were able to configure with google ads. Time will hopefully tell whether one approach is superior to the other.
In a typical RPG, stat increases come at the cost of time. Players grind battle after battle, and eventually the game decides it’s time for a level-up. It can be a straightforward transaction, as in the early Pokemon games (units stats advance immediately upon level-up),
In some games there are other ways to increase a unit’s statistics, often by finding items (rare candy, etc) or sometimes using common currency (River City Ransom, Scott Pilgrim vs the World).
Released in 2010, the Scott Pilgrim vs. The World game used River City Ransom-style shops, allowing players to convert cash into stats of their choosing through the purchase of specific food, books, etc.
In Life’s a Beach, we could make stat increases a function of time invested. In other words, a unit or tower could have its stats increase by taking down enemies or dealing damage. Runescape follows this approach, with every point of damage dealt contributing to EXP for the attack, Strength, HP, or defense statistics. This is a neat approach, as it is…
- IRL intuitive (the mechanic works like it would in real life. The thing you practice is the thing that improves).
- Allows unit customization and differentiation (Units become specialized by ignoring certain abilities and approaches).
I’m not sure if this approach would be meaningful in the current iteration of Life’s a Beach, as a unit that fights is one that takes damage (do fighting will increase atk power and )
One of the addictive things about Runescape’s simple combat is its probabalistic nature. The amount of damage an attack does can vary wildly based on a number of conditions, with a big one being simple luck. Many RPGs include the concept of a “miss” and “critical hit”, which can occur out of no where and lead to an unexpected, exciting result.
In the current version of Life’s a Beach, a unit will always do the same amount of damage per attack, as it is missing these concepts. In addition–
- Attack damage is non-probabalistic. The attack power your unit wields will be the same on each hit.
- All unit defense statistics are 0. An attack that does 10 damage against one enemy will do 10 damage against another.
Adding an accuracy statistic could make the simple battles a bit more interesting, but I think another approach might help more.
Currently, when a fight breaks out there is no value in strategically positioning yourself. In the movie 300, the tactical value of forcing a chokepoint at the narrow “hot gates” mitigated the Spartans’ strategically-doomed low population. In a game like Diablo, a lot of combat value can be had from hiding behind chokepoints like doors, or even jumping into a corner, as the former allows for one-on-one fights and the latter allows for no worse than 3-on-one (If I recall). These things go out the window a bit of a ranged enemy is present, but the idea that enemies cannot stand atop one another to fight you could be a powerful tweak to combat depth.
Any units on the same team will try to move away from one another if close. Poor crab.
While enemies can now be blocked by other enemies (positioning matters), the simplicity of their AI is now visible.
Boids separation is a very simple rule that produces nice results locally, but can fail locally as seen above. Units must notice when their progress has been impeded, and should begin attempting other directions to find a new route towards their destination. We can do this by…
- Taking the “separation push” vector that causes our unity to stay away from each other…
- Check how different it is from the original intended direction of movement…
- Perform a cross product on the separation push vector and the global up vector to get the destination we should shuffle in to move around the blockage.
The result is the following slightly-more-intelligent behavior.
As a result of these changes to combat, it is now practical to hole up in a corner during fights–
As we can see above, the player unit is no longer taking damage from all directions at once– only two enemies (two crabs at that) can engage. The dangerous goose enemies are held at bay, where the player’s towers could chisel away at their health and hopefully pick them off.
or otherwise create hot-gates-style chokepoints. The stage environment and structure now matters just a bit more than it used to.
- Routing has been upgraded– units will now run in straighter lines when possible, even when they cannot see their target, rather than stick to grid-based movement.
- Routing update : Boids separation is now used to prevent units from getting super-duper close together.
Still a bit glitchy, the new arborinteractive.com navigation bar includes playful icons for each of our games.
(^ This log-in screen is now delayed. Players no longer see it until 10+ minutes into the game. See the section far below.)
- This may be one of the most disappointing weeks for Life’s a Beach on record, as we are receiving more traffic than ever, but have hit new absolute lows when it comes to players-reaching-title-screen. We may be driving people to the website who do not expect to play a game (or are on mobile). If this is true, we should consider putting some extra work into the Android / ios port, and simply redirecting users to a store page if we detect they are on mobile. That would not be a cheap investment, but is something we may inevitably need to do simple for the audience size.
- Perhaps our marketing efforts are targeting players who are too casual. Perhaps we could take some better in-game screenshots and use those for our ads instead of large art assets. Perhaps we could take some cool 3-4 second video and run some video ads.
Something I would like to do is see how people interact with the game. I really wish there was a place I could pay that would send me recordings of people playing. COVID is preventing in-person playtesting sessions, but perhaps I could organize something virtually. We have the budget for it, so that is data I would like to acquire if possible.
- After seeing the carnage on 10/06/2020, two ideas came about. (1) The disable audio button may be failing us, so people leave anyway due to the audio. (2) We are sending a bunch of people from facebook who are on their mobile devices, which the site and game are not optimized for. At 3pm on 10/07/2020 I disabled mobile placements for our facebook campaign.
- After another day of destruction (~75% churn) on 10/07/2020, we pushed a new build to production that totally forgoes all loading screen music in webgl builds.
- IDEA : Joshua Marshall helped me discover the fact that Unity will stop playing.
Loading Screen Optimization
- Before internet-related activity begins (downloading of assets, config, creation of user account, log in, etc), the game reaches out to ArborNet with a ping request– a request that does nothing but verifies that the user’s internet is working. This may seem innocuous, as such a simple request, heading to AWS infrastructure, should return negligibly fast. This is not the case however due to an unusual problem that affects only Lambda-based backends– the cold boot. As described in a previous post, Cold Boots occur when a piece of backend technology is suddenly contacted after 4-6 minutes of inactivity. A cold boot causes any request, no matter how simple, to take a minimum of 6 seconds as the backend software loads and launches. Removing this check makes particular sense in WebGL builds, as builds do not.
New Utility Technologies
- The Windows and Linux downloadable desktop versions no longer come in a weird /tmp/ArborBuild/ archive. When you download these versions on https:///lifesabeach.io, there will just be one level to their directories. It’s a small win for the desktop download UX.
- Blog posts now have tables of contents. With how long these things can get, it really helps navigation. It also provides a nice at-a-glance summary of the week’s work.