This Week In Veloren 12
This week, there was a ton of progress on the engine. In this blog, we take a look at how 0.2 is coming, as well as what certain programmers have worked on. We have a large section about networking written by @Zesterer, and a new coding challenge! This week's blog was edited by @AngelOnFira, with the art content by @Pfau!
Thank you to this week's programming contributors, @Slipped, @imbris, @Pfau, @timo, @zesterer, @Algorhythm, @desttinghim, @Qutrin, @LunarEclipse, and @YuriMomo!
Programming
Progress on 0.2
This week, we set the (tentative) deadline for 0.2 to be May 28th. This is the anniversary of the Veloren repo being created, so we want to try and get something in working condition to celebrate!
Since we have a due date on 0.2, we now have a burndown chart! This allows us to see how many issues are still left vs how much time is left. You are able to see what the velocity of work being done is, and therefore predict if you are going to hit the deadline. As of right now, we don't have enough Merge Requests completed to see this. But, as we approach the deadline, it will start to have a line tend towards 0. You can take a look at the 0.2 milestone here
The team has also been working on making tasks more accessible. We've been creating many issues to be discussed and worked on, as well as adding tags. This means that there are lots of beginner tasks ready to be worked on! You can see all of them here, and we will keep working on adding more in the next few weeks.
Also, we have seen a massive rise in the number of weekly commits to Veloren this week. Two weeks ago, there were 12 commits by 2 people. Last week had 36 commits by 6 people. This week had 100 commits by 10 people. This is almost half the commits since the beginning of the year! This is great to see, as it means the engine is starting to become more accessible to more contributors.
Other programming progress
@Qutrin has been putting in quite a bit of work this week on quality of life issues and other fixes. He has worked with @Zesterer on animation states, as well as fixes to the single player version and some cleaning of constants. He has also started working on camera zoom interpolation, which is adding some new tick functionality to the engine.
@Timo has also been putting in lots of work on the engine. One of the big changes he is currently working on is client states. This gives a distinction between clients that are connected, registered, character, spectators. This allows the game to have a state that allows the client to use certain features. For example, a client that is only connected can't play because they are not yet registered. And a client with the character state would require certain information, such as player position.
@Timo has also been working on restrictions of networking animations, as well as animation smoothness. He also made some improvements to the Readme. Finally, he is working on character creation, which includes quite large changes to some of the character ECS. The character selection screen is in the game already, but it is not yet functional. It will be part of the 0.2 release though, and should be complete in the next week or two!
@desttinghim has made a lot of progress as well this week. He has worked on creating functioning singleplayer by creating a background thread that will run a private server. He has also worked on setting up a key binding and setting file so that chosen settings can be saved after closing Veloren. He is currently working on networking settings and multiplayer UI improvements.
Networking notes by @Zesterer
Hello, Zesterer here. This week, we’ve made a truly enormous amount of progress. Of particular interest is the way in which the networking systems for Veloren have evolved. Below, I'll explain some of the challenges we've come across, and the way in which we've solved them.
ECS
Veloren uses an ECS (Entity Component System). This is an architecture in which components of each in-game entity are stored separately, but are all tied together by a single Entity ID
.
As an example, an NPC might have a Position
component to store its position in the world, a Velocity
component to store the speed at which it is moving, a Character
component to store information like the species, gender, and class of the character, and an Agent
component to inform the game as to how the NPC should be controlled.
Sphynx
We need to synchronize all of these entities and components (including new components, deleted components, and modified components) over the network such that all connected clients see the same world state. To do this, I've created a Rust library named sphynx
. Sphynx is a layer that sits on top of the existing ECS and watches for changes to entities and components while the game is running. Every tick, it can wrap all of these changes up into a bundle of information that can be sent over the network to clients in other to inform them about how the world state has changed since the previous tick. This works perfectly for most systems and is a really reliable and easy way to do networked gameplay.
Network fighting
However, Sphynx also has some issues. For example: when the player moves around, we don't want to be sending a message to the server to indicate that the player wants to move, waiting for the server to respond, and then updating the position. Such a delay for movement input is simply unacceptable. Instead, we want to be doing movement client-side, informing the server, and then have the server only correct us if we did something illegal (such as trying to fly).
But, Sphynx doesn't understand that this is how we want to do things, and as a result, we end up with the client and the server "fighting" for authority over the player's position. This results in a lot of jittery, glitchy movement.
Sphynx can't do everything
To solve this problem, we've had to move synchronization of the physics information (position, velocity, and direction) away from Sphynx and towards a custom system that's more lightweight and provides the dynamic control we need. We'll still be using Sphynx for most things (like synchronizing inventories, character models, classes, abilities, etc.), but for specific systems that need more subtle control, we're forced to use a custom solution. Thankfully, the code for this has ended up being very neat and we're very happy with the progress of this.
In the future, we'll be using more advanced interpolation techniques such as 'Hermite interpolation' to make networked physics butter-smooth.
Client states
Another thing that's come to our attention is the need for distinct 'client states'. Unlike in most games, Veloren allows clients to choose the way in which they'd like to play the game. We permit chat-only clients (that don't have an in-game character), spectator clients (that can fly around, but cannot interact with the world) and character clients (normal gameplay as you'd expect). In the future, we'd like to support additional client states that allow the game ecosystem to be even more capable than it currently is.
The solution we've come up with is a system that looks very much like the state machines you'll be used to if you've ever studied Computer Science. Each client can be in one of several distinct states, and the game can conditionally move clients through these states according to a set of transition rules.
We've realized that this idea is more powerful than we first imagined, and so we're working on integrating extra states like a death state (used for the period between a player dying and them respawning) and a visitor state (used to allow clients to ping servers and request information, such as when looking at the server list screen). We're confident that this design is the best route to follow, and we're looking forward to exploring just how powerful this design will be in the future.
Veloren Coding Challenge II
With a new blog comes a new coding challenge! If you want to give it a try, you can check it out here.
Also, be sure to check out some of the answers from last week! There were lots of great solutions, and many used very different techniques to solve them.