Seafarers is the second and most recent game released. Seafarers is much more ambitious, and is much more complex. It’s a considerably more ambitious and intricate project aimed at honing my programming skills, particularly through the development of complex base mechanics. Seafarers was released on August 2nd, 2021, and took about 4 months to complete.
The general structure of Seafarers consists of three scenes, the Main Menu, the outside world, and towns. There are 48 towns in the game, and each one buys/sells 4 different kinds of cargo, out of 16 total kinds of cargo in the game overall. The player can open a map and select a town to travel to, and the ship will automatically drive itself there. When you get to a town you can walk around and talk to various NPCs, and talk to the merchant to buy/sell cargo and even negotiate the price of the cargo you are buying. The prices are all determined by a supply and demand system. The economy is town dependent, so if there is a silver crash in one town, the next town over might be just fine. In addition to this, there are boats that sail around in the background buying and selling goods to keep the economy moving worldwide, since there are 48 towns and 1 player.
This game’s primary mechanic is the economy, and therefore the most time was spent developing this system. Each cargo type possesses a base price and a buying/selling price set 10% above/below the base. For example, if Salt is 100g, you can buy Salt for 90g, and sell it for 110g. I chose for the economy to work this way so that there is an inherent profit of 20% to buying and selling goods. As previously stated, each town’s prices are dictated primarily by the Supply/Demand system that is kept flowing by the ships buying and selling cargo in the background. As you buy more of a specific cargo from a town, the price changes accordingly, and over time will return to normalcy.
To manage this complexity, the game utilizes a spreadsheet with towns on the Y-axis and cargo types on the X-axis, with each intersection indicating the town’s current supply for a specific cargo. If the number is positive, it represents how much of the cargo they have in surplus, which affects the price at which they will buy that cargo from you. If the number is negative, it represents an undersupply of that cargo, and so the town will only sell you that cargo at a much higher price. This structure allows players freedom in trading while emphasizing caution against overbuying/selling to maintain profitable margins. If the player is not careful, they can end up buying and selling goods at a complete loss.
Each town’s economy is not only affected by the player and the ships in the background, but also random events. There are random world events that can happen that will affect an entire continent and the prices of specific goods accordingly. Each world event affects the price of goods affected by the event, so for example a hurricane would make every town on the continent to suddenly need lots of building supplies such as iron, wool, and wood in order to rebuild. The player can use these to their advantage to change up their strategy and make more money. Typically, players will eventually settle into a route of 3-4 towns that they will rotate between to buy and sell goods, but World Events and the Supply and Demand system forces the player to change up this tactic and think about what region they want to trade in.
The background ships in Seafarers are surprisingly complex. The logic for the ships in the background consists of a simple neural network, being trained continuously during the game as the player plays using a genetic algorithm.
To start, the Game manager spawns in 50 ships (each with completely random weights for its two input nodes) at various towns, and each AI Ship will determine what to buy by using their neural network. The neural network is a very simple one, with only two input nodes and one output node.
The decision-making process of these ships is based on two primary inputs: cargo supply and price. These inputs were intentionally selected because they mirror the information available to players. Although players don’t directly observe cargo supply, they can discern when an item is unusually expensive, implying scarcity. For instance, if a town offers a high-value cargo like Gold, the ship might prioritize buying it for potentially higher profits. However, if the price has surged due to extensive trading, the ship might reassess its decision, illustrating the delicate balance between potential profit and market volatility.
Using the weights of each Input node, the AI makes a decision on which of the 4 pieces of cargo to buy and then will sail to a random Town that will buy it, in order to sell its cargo. After the initial trading rounds, the Game Manager evaluates each ship’s profitability, considering it as the ship’s “score.” The weights of the most successful ship are preserved, while 39 new ships created, with slight adjustments to the saved ship’s weights. Then, 10 ships are created with completely random weights to try new strategies entirely ensuring the AI doesn’t potentially get stuck trying to optimize a suboptimal strategy. This approach ensures that AI ships retain their progress in learning while making slight adjustments to encourage continued exploration of trading strategies. For instance, if one ship heavily prioritized the price of goods over supply, minor weight adjustments could encourage a more balanced decision-making approach.
This learning process mirrors real-life economic cycles, evolving over time. Initially, ships often heavily invest in high-profit goods, triggering widespread market crashes. However, as they learn from collective experiences, they adapt, considering both price and supply dynamics, creating a dynamic economic environment within the game. Interestingly, after prices stabilize, ships tend to revert to over-investing in high-profit goods like Gold, mirroring real-world economic cycles. This cyclic behavior contributes to a realistic economic simulation, akin to real economies facing periodic crashes due to similar market forces
There are 48 towns in the game, and each one buys and sells 4 different kinds of cargo. Each town internally has a different type, depending on what the town buys and sells. For example, a town might be a mining town that sells iron, copper, silver, and gold and it could be a poor town that is just getting off the ground that needs basic building materials and food such as chickens, wood, cloth, etc. The different buildings within the town are dictated by the type of town it is. Mining towns have mines and blacksmiths, rich towns have big fancy houses, etc. When choosing the cargo list for each producing and consuming type a town can have, I made sure to balance the overall economic power of the town, and made sure that a town never could buy and sell the same cargo, so that players had to sail to new towns to trade. This leads to some slight quirks, the biggest being that Towns of the mining type could never be prosperous/rich, because mining towns sold gold and silver , and rich towns buy gold and silver. This is confusing when using common sense, but from a balancing point of view it ends up being a good thing, as Gold being in a town automatically makes it very popular with players and AI alike, but since it doesn’t make a lot of sense conceptually, there is probably a more elegant solution to this problem.
The bartering system allows players to have more control over their trading, and adds another dimension to the trading system as a whole. When buying goods from a town, you will be prompted with a bartering screen. The player gets 3 tries to try and negotiate with the merchant for a lower price, and will propose a percent discount to the goods, and if they propose too high of a discount, the merchant will get mad and the player will lose 1 try. If the player fails to negotiate a price then they will pay full price for their cargo.
While the player is traveling the world, they are able to walk around their ship, and are able to play a fishing minigame as well. The player keeps any fish they catch during the minigame, provided they have the cargo space for it. This serves multiple purposes, as the player can use this mechanic to earn extra income early in the game since it is harder to fill up your cargo space fully earlier in the game. Additionally, this allows players to “fish themselves” out of a hole if they make a series of bad trades and end up with no money. This is obviously problematic since the entire game requires you to spend money to make money, so players can slowly come back using the fishing minigame if necessary as well.
Similar to Toast Defense, this game has significant room for improvement in terms of code efficiency and readability. While these aspects weren’t a notable concern in Toast Defense due to its smaller scale, the expanded scope and lines of code in this game have made it challenging to navigate and comprehend the entire system.
From a game design perspective, the gameplay became repetitive after 2-3 hours, prompting my attempt to introduce Crew Members as a solution. These characters were meant to be found and recruited throughout the world, each offering unique quests and bonuses upon joining your crew. Unfortunately, this implementation fell short as the dialogue system, quests, and bonuses lacked the depth and sophistication found in other RPGs. Interaction with NPCs and Crew was limited, without the ability for players to respond, and the quests mainly revolved around gathering goods and interacting with NPCs. The complexity of this system demanded considerable time for implementation, leaving insufficient room for expanding these systems before the game’s launch. In hindsight, a different approach could have been more effective in diversifying the gameplay loop.