Current Status


I started making this game in early February, as I've made a lot of progress I thought now would be a good time to start a blog to track my progress and write down what it "done". I say done because even though a feature can be ticked off my list, there are improvements that can be made. I've tried to write it in a modularised way so I can change a piece without greatly affecting other systems.

As I don't want this to be a very long post, I'll write separate posts later about details on the features.

It's come a long way from my prototype stage

This was built with primitive objects. Even the subs are just 3 primitives: 2x cylinders and a sphere. Once I thought this was enjoyable enough I improved the looks a bit.

Today it looks like this


There are still lots of visual improvements that are needed, like: the clouds don't move, the ship doesn't sway, I've not touched the lighting and I'd like to add a small distortion effect when the subs fire.

The water effect is from the asset store and works well except from a web version of the game, where the shader doesn't work and obstructs the view. I'll have to use an alternate water effect for the web version. The web version of the game is only for testing anyway.

Features that are done

  • Player can move their ship - I think this can be improved though. At the moment I'm adding an Impulse to the rigidbody. They can't hold the button down and instead need to pulse it to move more. I'll add a cooldown timer so if the move is held it'll continue to add a push.
  • Player can shoot a barrel left and right side - When the left (or right) mouse button is held a force is built up, shown in the bar at the top, when released the barrel is thrown. If using left mouse button it'll get thrown left, and right button will throw right. I think this works fine. Once it hits the top of the water any X velocity is zeroed out and so the barrel goes only down. 
  • Player can only throw a limited number of barrels at a time - There is a limit to the number of barrels on screen. So if they throw 5 barrels out straight away, they can't thrown any more until those barrels have exploded, either on an enemy or on the sea floor.
  • Player has health - player ship has health and can receive damage and it'll show feedback. When there is no health, there is an animation that'll tilt the players ship to show they've died.
  • Player Enhancements - I've added a script to allow the player object to have enhancements which will modify the player stats while the script is active. It uses a base class "GameEnhancement" which has two methods Add() and Remove(). Currently I only have one implementation which will grant the user 2 extra barrels. I expect this could be extended later on for more interesting enhancements from speed boost, to temporary invulnerability or perhaps a debuff like reduce speed for a period of time.
  • Enemy moves - I have one working enemy to test with. It works, but I'm just using a tween at the moment to move between 2 positions, rotate the sub and then go back.
  • Enemy fires - Sub can fire. There is currently a 50% chance on whether it'll fire a 5 second cooldown and only 2 projectiles at a time can be fired.
  • Enemy has health - has health and will show feedback when it gets hit. It'll also die when it has no health
  • Player almost misses enemy - There is a script that checks where the player hit the player and if it's a certain distance away then the game will regards is a a "Close call". I have locator transforms set to the left most and right most of the submarine. If the player hits within .3 units of these it's a close call. This will then trigger a (Damage Numbers Pro) feedback which will show the text "Close Hit", to show the player that they almost missed
  • Level stats - a script that gathers various events that occur in the game. e.g. enemy killed, player got hit
  • Player gets a kill streak - When a kill occurs it tells the Game Manager, this then logs it. When CurrentKillStreak > 1 a feedback is shown.
  • Game Manager - this handles various things within the game. It will tell the LevelManager to Load the Level from a file. It will also populate the WaveManager with the enemies.
  • Level manager - this creates the level objects. It will also load the level from a json file
  • Wave Manager - this creates the waves within the level, it'll monitor those enemies and once all are gone it'll decide whether to create a new wave, depending on the details in the level file. Enemies are not destroyed, but are disabled when not needed and then reset and reused.
  • Achievement Monitor - this took a while to create, I spent some time designing it in my head and now it's done and working it needs refactoring. It hooks into various events that objects trigger. e.g. Player object will have an event for Player Fired, Health Changed ; GameManager will have PlayerWon, PlayerLost, LevelLoad, KillStreak. These events have parameters too, so health changed will show the previous health, current health and what damage was taken to change the health. Whereas Kill Streak will show how many kills there are. For each achievement there is a listener, if the achievement  is unlocked, then it'll do nothing. If it's still locked and not achieved then it will listen to the events that concern it. When the criteria is met, it'll unlock. The AchievementsList is stored in a json file in the resources folder.
    The AchievementsList contains a list of AchievementItems
    The AchievementItem contains the Achievement ScriptableObject, the current progress and whether it is unlocked
    The Achievement ScriptableObject contains data on the achievement: title, icons, sounds, progress target, what value are needed and what fields to check.
    I have 3 achievements created to test: Player fired left (Progress based, fire left twice to achieve), Kill Streak of 2 (get a kill streak of 2 to achieve), Level Finished (finish a level to achieve/unlock).
    I know platforms have their own Achievements api's, but I've not looked into them yet, so it's good to know how to write one and being internal means I can then use the others when I need to.
  • Localisation - Only the main menu has fields that'll change when a different language is selected. I went through a couple of different format versions. The one I'm using is a CSV with one line per text key. e.g. 
    MENU_MENU_SETTINGS,Settings,Ajustes,Paramètres
    Column headers are: Key, English, Spanish, French
    This is generated from a Google sheets with a formula for generating translated text. It's not perfect, but good to have a system in place so it is easier later on.
    There is a LocalisationManager which will load the localisation file (which contains all the translations in) from the resources folder. It then waits a second and searches for all the localised textboxes and notes them down. A localised textbox is a textmeshpro object with a script added "LocalisationTextMeshPro". This script just contains a key, which will be looked up in the localisation table. When the language is changed the LocalisationManager goes through its list of localised textboxes and tells them to update. When they update they just request the string using the key from the localiation manager e.g.: LocalisationManager.Instance.GetLocalisedText(key).
    The LocalisationData class only has 3 properties: key, langauge Id (e.g. en, es, ja) and value
  • Main Menu - The UI is from LayerLab, and it works well. The one I have looks a little cartoony and gives it a mobile game appearance, so I may change it later on. For now it's better than making it all myself.
    The Main menu has buttons for Start Game, Settings, Acheivements and Exit. All are working.
    Windows / Panels (e.g. Settings, Achievements, etc.) are shown and hidden using a Tween, currently I'm using PrimeTween. This creates a nice slide effect.
  • Main Menu - Start Game - This will show the Stage screen, allowing the user to choose a stage. I plan on having 4 stages:
    1. Tutorial - you'll use a raft
    2.  16th Century - You'll command a Galleon
    3. 18th Century - You'll command a steam ship
    4. 20th Century - You'll command a steel destroyer.
    The years maybe a little off for the type of vessel, more research needed.
    Once a stage is selected, a level select screen is shown. This will show how many stars they have earned in that level. Once they click on a level. The game scene will be loaded with that level.
    To pass messages to another scene I used a GlobalVariables class: GlobalVariables.Set("currentLevelIndex", level). This is basically just a static class with a static dictionary to set values.
  • Main Menu - Settings - This allows the user to turn the music and sound effects off in the game. Also they can change the language. When they click OK the settings are saved. Except language, that change happens instantly.
  • Main Menu - Achievements - Shows all the achievements. This is grouped under headers, with Unlocked at the top and Locked underneath. This will show the locked or unlocked icon, the title, description, a slider showing their progress and a number for it.
    This was the first time I used a ScrollRect and I was surprised how easy it was to implement and how simple adding a scrollbar was.
  • Toaster notification - There is a simple Toast system, currently only used for showing when an Achievement has been unlocked. This will popup a message in the bottom right and make a sound. The code for this needs renaming as I've called it AchivementDisplayer but it should be more generic. It uses a Vertical Layout Group, so new items stack up and will fade out nicely using a canvas group.
    When a notification does get shown a prefab is instantiated, This prefab contains the script AchievementDisplayItem. This could easily be generalised so that different types of popups can happen. I also think there could be some similarities between this and the items used on the the Main Menu - Achievements Panel.
  • GameDataManager - this holds the data on the game:
     - Settings for the game (Music volume, etc.)
     - Stats for the Player: Career Kills, total playtime
     - Level stats (per level: best time and star rating)
    These are stored in files in the path of: dataPath = Application.persistentDataPath. On Windows this is in the users AppData folder.


Major Features yet to start

  • Tutorial - I'm still working on the code. It's a simple game to pick up, so I think a screenshot of the controls might be good enough.
  • Introduction Movie - I've written some dialog just need collect images and compile it into a (skippable) intro movie. 
  • In Game Menu - This will allow you to pause the game and make changes to the settings.

Extra Content

  • Planes - allow for aerial attacks 
    • Create a new enemy that can fly (Jet or helicopter), drop bombs/missiles or shoot guns
    • The ship will need to have AA guns. Upgradeable? more than one? Galleon could have people shooting muskets, steam ship could have a gattling cannon, the destroyer would have missiles, laser (keep it on target for a while) or a a high speed gun.
    • Would need a different camera view to see the sky.
    • Might add birds - don't shoot the birds for a bonus
  • More projectile types - content creation - for the player, but mostly for the enemy
  • More Enemies - need to make sure they are mostly orthogonal enemies and the player has sufficient ability to counteract them.
    • movement patterns
    • speed
    • attack strength
    • health
  • More Levels
    • Height Change
      • Attack from the sky - planes, helicopters, bombers, etc.
      • Shallow attack from under water
      • Normal attack from under water
      • Deep underwater attack
    • A level about hunting fish with dynamite
    • A level about hunting fish with a fishing rod and the fish can drag the boat around, move the ship or the cord will get snapped
    • Different weather conditions: Wind, lightning, etc.
    • Different times of the day: day, sunset, night
    • Endless level / mode - where enemies keep coming at you. How long will you survive? 
    • Different look for the water
    • Different sea bed

Leave a comment

Log in with itch.io to leave a comment.