- Tasks and Challenges
- Future Prospects
- Pull Requests
- Useful Links
Project: Metal Renegades Multiplayer
Organization: The Terasology Foundation
Project link on the GSoC website.
Terasology is an open source voxel based online multiplayer sandbox game. Metal Renegades is a new gameplay template for Terasology. It is set in a fantasy setting of a Wild West populated by robots and aims to give players an RPG style gameplay with different factions and quests. My project focused on adapting basic gameplay systems from other modules into this one and have a playable multiplayer in the end. The module also provides the necessary framework to build upon and implement more complex systems.
The unique settlements and terrain form the basis of this game mode. Most of my goals were successfully accomplished and the ones that had to be left have no impact on the gameplay.
The terrain generated by the map is a simple desert with minor height variations (of three blocks) generated randomly. It also has some mountains and hills originally generated using Perlin Noise, which was deprecated in the course of this project. They now use Simplex Noise. It is calculated as
surfaceNoise.noise(position.x(), position.y()) * 3 + 10)
1. The surface temperature and humidity at a point define a biome. I was trying to manipulate these two parameters in a way that would give me the
PLAINS biome occasionally on the map, but wasn't able to achieve satisfactory results. For now, the temperature and humidity values are constant, resulting in a desert throughout.
2. The lakes shown in the image below were also removed because of performance issues in the Lakes module.
The DynamicCities module was used to add them. One necessary change was that the DC module checked for grass when it chose locations to build a city. As our desert map doesn't have grass at all, this check had to be removed. A number of other changes were also made to the module to facilitate other features. All changes can be seen below in the PRs section.
An icon was added to the minimap marking cities that have been discovered. This makes finding cities that you've already found easier. The icons are clamped to the border of the map by the following code in
Rails was a critical part of Metal Renegades from the start, due to its industrial setting. Some new improvements were made to the module, but many more network issues came up and had to be left for later.
Before I started connecting cities with rails in MR, I first had to connect cities by roads in DC. Once that was completed, I only had to create a rasterizer in MR which would lay down custom blocks on the roads created. I also implemented a priority system for rails to solve the problem of which rail from the family should be laid down in case we have multiple options. The system checks if some rotation of a higher priority block is available. If not, it goes down to a lower priority. The following is the code to do that, in
1. There's a huge performance hit when a new city is found and the road is calculated, despite things being cached all the time and using custom block placement classes from DC. After the road is laid the game turns back to normal. This will need to be investigated more thoroughly later.
2. The road is laid in segments which are directed portions of the road. The
RailRasterizer needs improvements to fix some issues at segment boundaries, like the ones shown in the image below.
3. Information about surface height is not handled properly. This works for MR which has a largely flat world, but doesn't work for mountainous terrains and other modules, like TutorialDynamicCities. In those cases, roads but through mountains and clear everything on top, forming a chasm.
A new AdvancedRails module was created to extract some stable features from AdditionalRails. The locomotive cart was extracted.
This is where most of the problems with rails lie. I mentioned some of them in this post. Apart from that, I couldn't reliably reproduce issue #39 to find the cause. Multiple other bugs were found, like #47. Most of these bugs had to be left to proceed with the project. These need to be worked on in the future.
A Pistol and a Gatling Gun was added. These are implemented as bows only, with different fire rates. Bullet projectiles are just arrows that have a golden texture. Implementing weapons this way allowed me to have a prototype up and ready quickly. A more gun specific implementation can be attempted in the future, with magazines and reloads. Pistols are given to all players at spawn along with 32 bullets. The gatling gun can be obtained with the
give gatling command.
Animas and Loot
Animals are implemented through the WildAnimals module. They have a default flee-on-attack behavior and drop meat when killed. I modified the
WildAnimalsSpawnSystem to get more control in the MR module. Basic configuration options were exposed and the ability to set a custom function to decide where to spawn animals was added. This allowed me to tune the number of deer I wanted and the size of a group. I also used the custom function to have the deer spawn only outside the city. So as the cities grow, spawn points are shifted away.
I then use a
spawnSystem.setSpawnCondition(this::isValidSpawnPosition) to pass this custom function to the actual
Just like looting animals, players may also loot other players. As shown in the GIF below, players drop all inventory items on death.
I modified the inventory management that CombatSystem did to add some items to the player's inventory on spawn. The problem here was that I was creating item entities in an authority system and then telling the CombatSystem module to pass them to the players. This resulted in all items being owned by the host. This also resulted in an interesting bug #33. I had to fix this before I could add player drops because a client can only drop items it owns.
Currency has been implemented like any other resource and a wallet has been given to each player to store their cash. An early version of the wallet UI can be seen on the left in the screenshot below.
Although currency is a resource in itself, currency in a player's wallet is not modified through the events provided for resource manipulation in the Economy module, i.e. I'm not using the
ResourceStoreEvent to modify currency in the wallet. This works for simple applications for now but will need to be changed when we implement economies for our settlements. The city itself would have some wealth and if all transactions happen through these events, we can easily build up interdependent economies.
Markets have dedicated citizens assigned. The player just has to interact with them and select whether they want to buy or sell. The screenshot below is the selling interface. There is a
MarketUISystem which fetches all resources that the city has (in case of buying) or fetches all items from the player's inventory (in case of selling). All resources are converted into a
MarketItem, which is a data class holding other information that needs to be shown in the UI, like the description and cost. When a transaction is confirmed, the resources in the city, items in the player's inventory and the money in the wallet are appropriately modified. The
buy() method is given below as an example.
1. The way that the items are collected doesn't treat block families right. All of them show up as
2. The market UI doesn't come up in multiplayer. This has to do with the way events travel and which system processes those events.
3. Resources which "belong to the city" are not synced properly. After a transaction, their quantity is set to zero. This also includes chests in the blacksmith's building. Items that you put in those chests come up in the market, but once a transaction is done, the city treats it as having quantity zero.
Trade works just like the marketplace, but this time we can directly manipulate inventories. Involving the economy module is not necessary. To trade with an NPC, players first have to select what they want from the left list and then select what they'll give from the right list. If the costs of both the items are about equal, then the NPC considers the trade and will accept with some predefined probability.
Only a basic fetch quest was implemented, using the Tasks module. Every church in a settlement has a quest point, which gives the player a quest. The player needs to bring back 2 pieces of meat in exchange for a cash reward. Implementation is fairly straightforward and was done with QuestExamples as a reference.
1. The Tasks module works with quest items. When you reach a quest point, you get a quest item which activates the quest when it is used. I wanted to turn the quest point into a beacon when the return home task was initiated, so I had to know from which quest point my quest actually came from.
2. Having multiple quest points with the same quest also meant that the beacon ID defined in the quest prefab was the same for all of them. So when a player completes the quest and starts another one, the return task on the second quest is already completed because the beacon with the same ID has already been reached.
3. The minimap overlay that shows the beacon doesn't accurately pinpoint the location of the beacon.
- Test and fix minimap overlays for multiplayer
- Rails: Needs a networking overhaul. Also extract carts into AdvancedRails
- Diversify the terrain with more biomes
- Create a settlement-wide economy with proper resource exchanges and production
- Add more quests and fix existing fetch quests
- Better support guns in the CombatSystem module. Add support for different magazine sizes and reloading. Maybe even add hit indicators or health bars above other players
- Optimize performance: Because a lot of the code comes from other modules, this will be a very major undertaking
Cool features to add:
- Player stats and crafting
- PvP duels
- Larger rails and scheduled trains. Could be passenger or goods trains
- Allow the players to ride on horseback
- Organized raids on buildings/settlements
- Add more weapons
- Allow players to trade among themselves, not just NPCs
- Metal Renegades: #1, #2, #9, #12, #13, #14, #18, #24, #27, #30, #34, #35
- Dynamic Cities: #41, #42, #44, #46, #47
- Combat System: #39, #40, #42
- Economy: #10, #11
- WildAnimals: #29, #30
- Tasks: #13
- Minimap: #11
- Rails: #46
- AdditionalRails: #31
- AdvancedRails: #1
- MetalRenegades: #23, #32, #38, #39, #40
- AdvancedRails: #3
- Rails: #47, #48
- CombatSystem: #41
- DynamicCities: #52, #53
- Lakes: #3