Last on Land
On this page you will find copies of the Devlogs documenting the experimental progress I have made on this project. If you would like to see the original copies of these Devlogs you can find them over at my DawnsCrow itch.io page:
HERE
Last on Land: Devlog #1
Experimental Project:
This project is a fun little experiment of mine in order to try out some new things in a new engine that I have never used before. I am making this project in the Godot Game Engine. I will be using this project to try out and learn methods of procedural generation and multiplayer networking.
Game Concept:
Last on Land is a new 2-4 player game. The objective to the game is simple, you and your friends must fight to remain the last player on land. The map is a tile based grid map with varying levels in which the players will be able to destroy tiles in varying methods in order to attempt to force the other players to fall into the water, all the while attempting to navigate the slowly decaying map to stay on land.
Early Development / Testing:
Grid Map and Tiles:
I started with a simple grid map utilising 3 basic tiles to represent Dirt, Grass and Water. This grid map allows for simple but effective fast map creation, this will also form the basis for the map destruction in the future by removing tiles from the level as they are damaged by the players.
Procedural Generation:
Using the Grid Map tile system I have implemented a simple procedural map generation for the game. The final product should have several hand crafted maps for the players however I wanted to give the option of slightly less structured and more chaotic maps that could keep things interesting and I felt procedural maps was the best way to handle that. Starting out with the procedural maps also meant I wasn’t spending time making a map that may not work as well once more features are added but the maps being used for testing are also a bit more interesting and a better representation of a real map rather than the flat tier based map I had when I first added the grid map.
The map generation is done by generating an OpenSimplex noise map and then running through that to select the tiles for the map. This method was simple enough that it does the job for now but also leaves room for extra improvements later down the line. OpenSimplex noise also provides me with a lot of control over how random the map actually is, by adjusting the period of the noise you can decide how “Scattered” or “Uniform” the generated map is.
Last on Land: Devlog #2 - Problems with Gridmaps
Player Controller:
Implemented player controller for the player character, made First and Third person player characters for testing and after playing around with each felt that the game feels much better in First Person and this perspective fits with the gameplay the most. By using First Person perspective and a very fast playstyle it increases the risk of falling into water as the player has a much more limited angle of vision into pits and the speed of the player movement gives players very little chance to react. The player movement is currently basic and will most likely have further work done but is intended to feel very Quake esque with fluidity of movement playing a major role in the gameplay.
The player's camera is controlled with mouse input with the left and right controlling the rotation of the whole character model but the up and down controlling only the camera and the weapon. Player now has a simple testing weapon that fires a large rocket like round in the direction the player is looking.
Tile Deletion:
I have implemented a basic start to the map destruction with player weaponry, with the new player weapon system in place I began to work on detecting the collision of the bullet with the Gridmap and removing the tile that was collided with, this feature was set to be the primary concept of the game with an increasingly diminishing map until there is a single player left on the map. This feature is mostly working and in place and the player does have the ability to shoot and remove individual tiles however the system felt very inconsistent and there were many occasions where collision did not seem to be detected and the bullet would simply pass through the map either entirely or through some tiles and would eventually collide with and remove a tile in the distance. Unfortunately after spending days attempting many different methods to reduce the inconsistency of the detection and attempting to find a solution, I finally found the actual cause to the problem. The problem with Godot Gridmaps:
The main issue with gridmaps in godot at the moment is their very limited ability to detect which cell in the gridmap the collision happened in. I discovered that there was actually no issue with the detection itself but a collision can only detect whether it has collided with the gridmap itself as a whole and the current best method of identifying the cell is to use the world_to_map method gridmaps have which in short takes a world position in the map and then compares it with the gridmap to identify which cell occupies the the same position. This sounds perfect right? All I have to do is pass in the colliding bullets world position and problem solved, I thought so and thus the reason why I questioned the collision detection and not the gridmap cell detection. Well after some further investigating I realised that the key issue is with the world_to_map, as you pass in the bullets position in the world as soon as the collision is detected the bullets current position in the world is technically still the adjacent tile, and as I am ignoring cells that are blank and removing cells that contain a mesh I am often passing through the object as the bullets position was not within the desired tile I hit when it attempts to remove the cell. I discovered this by reversing what I was doing and instead of setting a cell to be blank I was setting the cell to be a dirt block and I noticed how often when a tile is hit at an angle the block is placed on top rather than replacing the tile.
Conclusion:
I intend to have more of a play around with this detection system and see if I can come up with some kind of work around and improve the system but I am not certain that gridmaps in their current state are the optimal system for me to use for this project and I may need to reevaluate my map generation method.
Here you can see the player controller and the map destruction in its current state with the inconsistent tile detection.
Last on Land: Devlog #2 Part 2 - Goodbye Gridmaps, Problems Solved
Gridmaps abandoned:
After some further research into Gridmaps I have come to the conclusion that they are not suitable for my needs in the case. Grid maps are a fantastic tool for fast and easy map building however due to my need for an ever changeable map layout with the block destruction playing a key role in the gameplay Gridmaps lack the functionality for collision based tile detection.
New map generation:
After abandoning the Gridmaps I looked into other methods of generating my block styled maps. I spent some time looking into Zylanns work in particular (can be found here: https://github.com/Zylann/godot_voxel ), this module for godot helps generate voxel terrains both blocky and smooth and is a very powerful tool, I would highly recommend checking out Zylanns work to anyone looking to generate terrains in godot. After spending some time looking into this however I decided it was more than necessary for me as it is a tool to generate large world terrain whereas I require only small lower layered maps for my game. Using Zylanns module would be like using an Olympic sized pool to store my single glass of water. For that reason I decided to simply generate the maps out of block mech instances into the open world space. This would be a problematic way of handling things in a much larger game but due to the smaller nature and simplicity of the style of game I am currently able to generate and play maps more than double the size of any maps I may wish to have in the final product without any performance issues, this however does not mean that there will never be performance issues and so I do intend to work on optimisations in order to reduce any potential performance issues in the future as more features get added to the game, one of the first places for me to look will be the MultiMesh node in godot which is designed to take large groups of same mesh objects nearby together and pass them through the GPU as a single call rather than each object being called individually, this should be able to help performance in the future.
New map destruction:
With the new map generation method I am now able to identify exactly what object has been collided with and remove that object from the map. This new system is now far more reliable and seems to work almost flawlessly with (so far) no performance issue even when spamming the deletion.
Last on Land: Devlog #3 - Steam Network Lobbies
Networking Options:
The Godot engine provides very useful but somewhat basic high level networking options built right into the engine. This is very helpful and easily functional using simple RPC master and puppet calls in order to replicate in game situations across all users connected to a game server. This was my first trial of game networking with Godot in which I got basic player an map replication working allowing two separate players to see each other move around the map and also see the tiles they have shot get removed from the map, this forms the base for the in game networking that is being developed with more on that coming in a later devlog. The main issue with this built in high level networking is the hosting of and inviting to servers, as this method required direct IP connecting meaning anyone wishing to play with friends would need to send over their IP address and most likely would need to port forward the port they wish to host on. This method obviously is not ideal and in my opinion is quite simply not an acceptable method of playing with friends. The end goal is to get this game on steam so I thought why not just look into Steamworks integration for Godot sooner rather than later and so after doing some research I discovered the GodotSteam module by Gramps (GodotSteam Github repo).
Steamworks Integration:
The first stage to using the GodotSteam module was to download both the latest stable branch of Godot 3.2 and GodotSteam, then compile the engine with the GodotSteam module and the Steamworks sdk compiled into the engine code, then using this new Godot compile I could generate the export templates which allows my game export to utilise the Steamworks functionality.
With the GodotSteam module fully integrated into the Godot engine the Steamworks functionality can now be used and the first thing is to have Steamworks initialise itself on the games load, once the initialisation is complete the game will perform a quick check to make sure the user is connected to a steam account and if the connected user has access to the game (game has been purchased). If either of these are not true then the game will terminate.
If the user is connected and is permitted access to the game then the game will grab the Steam ID and current Steam Name of the connected player.
Lobby System UI:
The lobby UI was designed to be clean and concise, providing all the information and functionality without the need to jump through several menus. The main menu will likely contain a few options one of which (Play) will lead to this scene providing the ability to create and join lobbies. The UI is currently plain and rather bland but this is simply for testing purposes. Although the UIs layout will likely remain relatively similar to its current state varying slightly over time the look and feel will be updated as the games UI gets a theme design.
Lobbies and Chatting:
With the Steamworks integration users can now use this lobby menu. At the top right of the screen the users Steam Name will be displayed, users can create lobbies providing a lobby name if they wish, this lobby will then show up in a lobby search (at a later date users will be able to set their lobbies as private or friends only), with a lobby created users will be able to use the steam overlay to invite their friends or friends will be able to join as long as a they are currently in a lobby. The players menu on the left displays the current number of players in the lobby as well as displaying the names of the users in a list. The main Lobby display in the centre shows the user lobby related information such as players joining and leaving as well as being the chat box for players in the lobby to communicate while waiting for the game to be started.