Kristjan Vedler, Andrus Lall, Juta Mae
Shape Fight is a classic 2D run-and-gun multiplayer platformer, where you control a shape of your choosing equipped with a variety of weapons and/or skills. The shape is equipped with a “jetpack” that allows the shape to fly for a short duration until its fuel runs out and has to be regenerated.
While the controls and mechanics such as jetpacks, wall jumping and different weapons are simple and easy to understand, the game has a high skill ceiling, making the game suitable for both casual and hardcore gamers alike. The large selection of weapons and skills the player can choose from can lead to all sorts of spectacular combos, making every match an unique experience.
More info here: GDD
Milestone 1 (17.11)
- Component-based weapons system
- Movement and shooting animations
- Explore networking options (i.e. UNET vs Photon)
Juta Mae (animations)
4-11-2016: Added a hand that indicates shooting direction. It was tedious to figure out how Quaternions work but with hours of googling and trial&error I think I have finally succeeded. Next, I adjusted missiles' spawn point to be from inside a hand instead of player's pivot. Weapons and stuff actually fall under Lall's category but since this task is tightly related to hand movement, it was not too hard to apply the same concept on weapon spawning: just circle around the pivot and move a bit further away from it towards the target point.
17-11-2016: Copied our weapon system code to create a Partice Pool. It can later be used to handle other particles (than those of rockets) as well. All credit goes to the guy who created the weapon pool first, my work is just a copy.
Right now particles appear on rocket collision, in the right spot, but don't spread yet.
All this linear algebra is driving me nuts :')
18-11-2016: Tweaked the code a little bit, stole an idea from groupmates, added random direction and an enumerator for particles' lifespan. Ended up like this:
24-11-2016: SCRATCH EVERYTHING ABOVE. Got some recommendations and used Unity's built-in ParticleSystem instead, got this:
Kristjan Vedler (networking)
After experimenting with using alternative networking frameworks for Unity, specifically Photon Unity Networking, I have decided to stick with it because we like the current results.
Although I'm still working on making the movement extrapolation better, the networking seems to work pretty well so far. We are currently only syncing position and velocity and interpolating/extrapolating on those values, but I plan to test out also syncing Unity physics' AddForces on which our whole movement system is based on, so that the networked movement would appear even smoother. Once I can make the movement predictions work well enough, I will start working on making the networking server-authorative and implementing shooting and other event-based stuff.
Results of the current networking test:
One problem I will have to face with the authorative server networking is how to efficiently and smoothly predict and synchronise the player's own movement when we take latency into consideration. Since the server is authorative and every result of the input we send to the server will be received with latency, I will have to figure out a way how to update our current position taking into consideration where the server tells us we should have actually been in the past.
If we receive the result of the movement command 200ms after we sent it, we have to compare our local position 200ms ago with the position that the server sent us and then based on that, update our current position. If Unity's physics were fully deterministic and there was a way to "re-simulate" all of the inputs again between now and 200ms back with the new position that the server sent us, this wouldn't be that big of a problem. But instead we will have to figure out a way to smoothly and efficiently reposition ourselves based on the difference of positions/velocities 200ms ago and also at the same time deal with not clipping into walls, because any physics that might have happened within those 200ms would have affected our actual position that we should be at. Another alternative would be to write our own deterministic physics system, but that seems like too big of a task for us to tackle.
Later on I will also have to implement a lag compensation for shooting, so that we wouldn't have the Battlefield-esque problem of "hey I was already behind a wall and you still killed me". We have already looked at many resources that help to deal with the server-authorative shooting problems, few examples here:
- Gabriel Gambetta's "Fast Paced Multiplayer" guide
- Valve's Source Multiplayer Networking Lag Compensation
Andrus Lall (component based weapon system)
Previously, we had only one weapon type, which was a prefab fed to unity using the inspector. The goal of my assignment was to create a base for a weapons system which later in the project would allow to easily switch between multiple weapons using a GUI, and allow an easy creation and management of different types of weapons.
For that I created 2 interfaces, 2 abstract classes, a weapons selection manager and a new type of projectile. One interface was created for the abstract class used to call methods dealing with the moving of projectiles. The other interface for the abstract class used to call methods in the effect component that will be added to projectiles later on. These abstract classes are crucial for the prevention of code duplication, since every weapon has a method for firing, movement and how it behaves when it collides with something. A second weapon was also enabled, allowing the player to shoot 2 different weapons.
The newly created weapon selection manager now puts every weapon in our weapons folder into an array and for now, sets the 2 default weapons - rockets for main weapons and bullets for alternate weapons.
What this has achieved: after creating different effect types, we can combine projectile and effect types to create weapons that behave differently, drop them into our weapons folder and, in the future, allow the user to switch between them using a GUI.
Milestone 2 (01.12)
- Finish networking
- Get basic gameplay elements done (damage, TDM gamemode, respawning)
- Add in more weapons
Andrus Lall (more weapons)
For this milestone, I added 2 more weapons and a cooldown property for each weapon.
The first of the new weapons is a shotgun, which shoots pellets in a randomized angle and speed. One of the features of this weapon is it's variable spread - the closer your crosshair is to your character, the bigger the spread, the further away it is, the more accurate your spread. Images to demonstrate:
The shotgun also has range and air resistance - once the velocity of the pellets reaches a certain standstill, the pellets disappear.
The second weapon is a simple grenade launcher
Juta Mae (effects and gameplay elements)
Sooo~, for starters I added jetpack particles!
before I didn't even know the jetpack was implemented and working, hehe
It's essentially an empty child object with particle system attached that rotates during flight according to input and movement (left, right, straight up). At first it turned out pretty ugly but as soon as I realized it was emitting particles only in its local space (and fixed it), it got waaay better...
I also dabbled with the element of fuel. PlayerCharacter now has a fuel meter that depletes during flight (especially when bursting upward extra fast) and slowly restores while you're grounded (literally). So you can't keep flying forever!
I swear I didn't fall willingly!
Next up, damage. Since rockets go 'KABOOM!', I made it so that you take damage if you're too close to the centre of rocket explosion (and the closer you are, the more you get hurt), instead of plain collision. Don't worry, if you touch it directly you're dead anyway.
Oh, and you have 100 HP! If you run out of them, you respawn.
Notice the red/white blinks
You noticed it too, didn't you? The player changes colors on respawn and gets a random color at the start. It works on multiplayer, too:
However, everyone sees themselves and others in different colors (isn't it less racist this way?)
Last but not least, other players take environment damage as well:
Though you can just keep doing that forever. They can't die of your attacks yet, only suicide allowed at the moment ;)
Actual gamemode mechanics will be implemented after the networking branch gets done and polished. Also planning to merge my progress with new weapons next and perhaps try to get a visual representation of health and fuel bars.
As usually, it was hard-ish to get the rotation to work right. Likewise, it took me some time to figure out assigning colors e.g. the right classes, the right method and the best values to get really bright colors without a hint of grey. Surprisingly, even though I couldn't get much done in 2 weeks, the last evening turned out very productive: after our 5 hours long meeting and finishing my homework I fixed a bunch of issues and implemented the whole damage system between 1:30 and 3:30 AM.
Milestone 3 (15.12)
- Implement minimalistic UI
- Implement free-for-all gamemode
- Finish all gameplay mechanics
- Particle effects for new weapons, SFX
Andrus Lall (background music, SFX)
For the final milestone, I decided first to work on implementing some background music for the game. To do that, I found some tracks from freeplaymusic.com that were free to download with an 'Educational' license. Next, I created a music mixer, so that I could have finer control over how and when the music starts playing. My desired goal was to start playing the tracks as soon as the first player hits the ground, not when the play button is pressed. To achieve this, I created an invisible trigger slightly above the ground. In a new script I then told the music mixer to transition into the first track as soon as the trigger was entered. Sadly, the player entering the trigger didn't call the onTriggerEnter method and it took me over 2 hours to get why it doesn't get called. Finally, with the help of Juta, we managed to figure out that I had tried to use a 3d trigger for a 2d object.
Juta and I also finally merged our two separate branches, Her graphics and my weapons branch. Luckily, not much was overwritten so the merging process didn't take as long as we feared. We also searched for some sound effects for weapons, which took longer than expected, because everything free sounded like they were from a 2002 Miniclip game, but alas, they're free so I can't really complain.
Juta Mae (UI, mechanics)
The merge process was indeed really smooth because instead of an automated merge I created a separate repository cloning Lall's branch and carefully integrated my code into it by small bits, letting Lall test every bit before proceeding to the next one. So essentially the old Graphics branch got abandoned and left hanging while Weapons branch got all the progress to itself.
Added different damage and range values as well as particles to the new weapon types. Did a bit of jetpack fuel balancing, too. Removed the respawn functionality so that we could have a better version of it as soon as networking receives its final touches.
Tried making a HUD with health and fuel bars... it turned out to be more complicated than it seemed, so it's not quite done yet. But I'm working on it!
Kristjan Vedler (networking, core)
We decided to simplify our networking model for the last presentation and currently the latency and lag seems manageable enough. Further work on networking would mean doing late physics updates to do reconciliation or switching to a different movement model or a physics engine for which we decided we didn't have time for in the scope of this project.
Over the course of this development period, we have now tried 4 or 5 different combinations of networking models and libraries and what we can take away from this, is that next time we should handle networking as the very first thing, as it is the most likely component to introduce restrictions on the rest of the project ideas and implementations.
Final product (TBA)
- Optimize netcode
- Balance the game
Final Report (11.01.2017)
As our finished product we have a fully working free-for-all gamemode for a multiplayer shooting platformer which features 4 different weapons and jetpack movement (slightly limited by fuel). Even though the game doesn't have any player customization and is essentially endless, the networking aspect was an enormous accomplishment: we had to synchronize , from tiny pellets and particle effects to players taking damage and respawning. It is a pity that we happened to make this game during this especially busy semester but it was all worth it and we're happy to present the result!