All posts for the month February, 2014

Is pretty much what I’ve been working on for a bit. I want to clean it up, add some more options and also focus on synchronization of all numbers. So, some things I intend to sync that aren’t working yet:

  • Laps
  • Max players
  • Player position in the race (e.g: 3/8)
  • Player checkpoints passed
  • Player velocity (rendered text, that is)
  • Score-board throughout the race but also at the race’s end (was mismatched earlier and currently does not function at all)

Besides that I kind of want to go in and add more variables for tweaking like a proper adjuster for gravity, friction and restitution, physical damping of various sorts and maybe lighting. We’ll see how it goes. I still haven’t really thought of any good method to synchronize attributes automatically, but have also begun to wonder if you ever would want that. Usually you will always have to optimize in the end and make sure that you only send what you need to for your application’s needs.

Some other things I did earlier that I might have forgot to mention was adding/incorporating a PreferencesManager I developed in the previous lab, and enabled it to save and load some basic audio attributes like audio enabled/disabled and also volume. Network preferences could be stored in a similar fashion, but I don’t feel like adding them there just yet, what with all rapid iterations.

I redid the Ogg Vorbis streaming which I had disabled, which now supports pretty much perfect looping, and because of that also got inspired and threw together a simple music player with support for sleep fade-in/fade-out. I am considering trying to throw in support for network therein, either to be able to request playback of music or stream from/to it. If not soon I might look into that after this project has ended instead.

Now some screenshots from the latest in linux development, first one which I failed to upload to the last blogpost, second one from today’s reworkings (mostly code, but there is slight changes in the visuals too) and the third one is a screen from the music player I began to create this weekend (screenshot taken in windows).

Screenshot from 2014-02-24 18:56:40 Screenshot from 2014-02-25 15:56:40 Screenshot 2014-02-24 00.03.40

On a side note I also took some time yesterday to work on the third (or rather, second) game project, RuneRPG. There I am also working on the UI system (since it’s still under development), but I can say that it’s starting to feel real good now that some things just work automagically (i.e, how I want them to, straight away).

Oh, and yeah. The CMakeLists file I had been using earlier actually got improved to support multiple project just a few days ago (I had been using bothersome #ifdef’s earlier in the code…), which kind of triggered or at least enabled me to start working on the other two projects. :)

Also not directly related to networking, but the audio (OpenAL) doesn’t seem to work in my usage of it on Linux (at least not on the computer I am currently testing). Not sure if I should put any effort in there, since I’ve got enough to do as it is.

Just a brief update. I took a few hours to make sure the Linux-version of the game works, but it will need some more testing. Also held a testing session for UDP, which when working didn’t seem to differ much from the TCP solution. This actually puzzles me, and means that I might have to re-think a bit, if I’m testing things right or what. Anyway, my next course of action is to improve gameplay in general, properly sync and send messages for passing checkpoints, and after that start looking at client-side physical simulation, in order to remove any apparent lag (if possible).


Apparently my UDP solution wasn’t working earlier (which I kind of noticed, but still not). I had refused to completely use recvfrom and sendto, which seemed to bind the sockets in a TCP-like fashion, and the UDP test was also not working as intended. Both of these seem to have been resolved now, and I think I noticed slight improvements with using UDP even on localhost (when spamming >100 updates per second, totalling to around 45kb/s in bandwidth).

Along with this I improved the UI system a bit more, so that I can now compile and insert complete UI interfaces or elements from other files wherever I want. So if you want to look at how many packets the UDP test has sent and received you can just press “U” in any game state and it will be pushed to the top of the UI stack (exit with ESC or right mouse button).

Beside that I have taken some time off, during which I’ve managed to create some new music to that game too. I’ll have to take a day or two to re-implement the Vorbis stream again which I left broken after Theora was added.

Screenshot 2014-02-20 20.45.30

So, it just took a bit of re-thinking to discover the issue. I had all along thought it was with the collission code, since the velocity was increasing where we collided alot… however, what I didn’t think about earlier was that there was some turning going on too!

In the code related to turning I had added a parameter to retain momentum to a certain extent in the new direction. The idea itself is harmless, but the execution I had done earlier had some (problably) floating point precision errors, resulting in velocity gains of 0.1~0.2% at times! No wonder the ships would go crazy after a while. Currently trying to solve it, I’m going to use some simple damping (which I by the way also added to the collission handling code, too, that can probably be removed now).

Something along the following seems to do the trick:

                 /// And apply some damping or it will increase.
                float dampingDueToRotation = pow(0.99854f, angularVelocity);
                dynamicEntity->physics->velocity *= dampingDueToRotation;

Might have to tweak it a bit more, but yeah, happy to solve a bug quickly after taking a break is always nice :)
Also considering adding several physics options since I guess this kind of error could potentially vary from machine to machine..? Or just fun to test out various combinations.. ^^

I don’t really feel like I’ve had much meaningful progress since the last update, but things have been done nonetheless that are worth mentioning!

Firstly, I optimized several calls to Sleep the threads, resulting in a much higher network update frequency, but also a higher CPU consumption. Secondly, I added support for selecting both player ships and level to race in, since I managed to complete a second simple test level. Thirdly, I held another testing session with the help of my friend Karl Wängberg (who lives in Skövde) again, since the distance (nearly 1000 km) makes the test feel a bit more “real” when thinking about lag than testing locally or with peers in Skellefteå.

The test went well, and playability has apparently increased to ~90% (compared to ~80% earlier), probably mostly due to the network update frequency, which increased from ca. 20~40 to 60~120 updates per second. One thing that I noticed, however, was that UDP seemingly did not activate, meaning that the test that is performed at the beginning must have failed, which in turn must have meant that all those updates were handled with TCP. How or why it failed was also not printed. This leads me to a new short-term goal: improve visualization (for the host at least) as to all network-related testing, and also enable viewing of a list of what transmission protocol is active to which peer (including average packet delay, if possible). Currently both TCP and UDP can be selected from the peer- or client-side, although UDP will only be made active if the previous tests succeeded. The second short-term goal is that  I will have to make the UDP test more robust, and also properly link its results to the visualization.

On another note, not related to networking, I added support for playing Ogg Theora (tested with Open movie project Big Buck Bunny), which I intend to try and use to visualize levels before the players get to play them, if I find the time to do it beside the networking. This also meant some restructuring for the main Ogg stream and how I’d handled Ogg Vorbis earlier, meaning that audio is currently not working until I fix that.

I still intend to add client-based prediction, but as I want to focus on the underlying structure for now, that will maybe have to wait until next week or whenever I get the UDP tools to work correctly.

Below we have a screen of the new level (which is a standard elongated Torus pretty much) and the Theora test.

Screenshot 2014-02-14 05.45.27 Screenshot 2014-02-17 09.04.43

Oh, yes, bugs… There is currently a bug in which players, when accelerating against a wall at a certain angle, gain absurd amounts of velocity boost. This bug, although funny at times, is disrupting and distracting the tests. I have sought a bit, but haven’t found the reason nor a solution yet, and hope to do so soon.

Spent half the day adding UDP, which is now working decently on localhost, and the second half dealing with a memory leak, which was due to not releasing a gl vertex array(important!) in the UI system. I also spent some time removing unneccessary sleep time in order to try and improve network latency further.

An issue I had a little while with UDP was that I had a strange 5 ~ 20 second delay on all packets. Apparently when I tried to use the regular recv function with it it only wants to read 1 datagram at a time, while my TCP-sockets that I’ve been working with so far usually have dumped all their current contents into the buffer. Easy fix by placing it a in while loop after realizing the error.

As a note on design and ports, I decided to lock host UDP port to 33002 and client UDP port to 33003. This way no communication is needed beforehand, but on the other hand it limits the amount of usable ports and also testing to a maximum of 1 client per device. This makes my total number of used ports at 4 now, in the following order:

  • 33000: TCP SIP primary communication
  • 33001: TCP Space Race communication
  • 33002: UDP Space Race host rapid communication
  • 33003: UDP Space Race client rapid communication

Screenshot as usual, added another input for the clients, so that they may request themselves if they want the host to deliver new in-game data via TCP or UDP (for testing purposes, as usual). The little I’ve tested myself hasn’t given too much (from what I can tell), and I’ll have to poke a few people for testing it again soon, maybe tomorrow.

Screenshot 2014-02-13 15.18.38

Thought I’d actually try the techniques I talked about earlier with testers, which ended up being a wise choice! Things did not work out as intended and both techniques created more or less chaos! The interpolation was slow and reacted with a 20ish second delay, while the extrapolation was jerking and kicking around in far too many ways to be comprehended sanely.

The clients were still rendered correctly at the host, and the effect on the interpolation gave a clue as to the issue. After discussing a bit with my tester he synchronized his system clock to within a few seconds of my own. Voila! He could nearly play the game! This made it perfectly clear that it was my usage of time that was the culprit, and I realized I had to create a form of game time. However, since the current time function is in use pretty much everywhere and I do not want to create more time-classes (since I think it just adds to the confusion), I added a time adjustment variable, so that it is possible to change the perception of current time. Not wanting to completely remove the availability of system time, though, it is still possible to fetch it simply by passing a ‘true’ argument to the same function.

I haven’t really posted any code in this blog yet, so I guess I can show you the declaration of said function at least:

	// Returns the current time. If true, returns unmodified machine time, if false will return synchronized time as set with SetAdjustment.
	static time_t GetCurrentTimeMs(bool machineTime = false);


Milestone 2 is here, and in addition to the above I tried tidying up a few other issues (audio, thread deadlocks, etc.) before preparing the new build. A zipped archive of the prototype is now available in the MS2 repository. Unfortunately I have not prioritized documentation nor usability, which means that it might crash or behave strangely.

To try the game, simply click on Network, then either Host Game or Join Game. By default the target IP is my computer, which I will try and run throughout the day for anyone that wants to test connecting (assuming it doesn’t crash). I’ve tested it a bit, so hopefully it’ll survive! If you want to play the game you or your friends might have to host it, since my server will probably only facilitate test-connections throughout the day.

I’ll also mention some command-line arguments that I’ve added:

  • ‘mute’, will disable all audio-playback. I opted to include some of my music which I intend to include with the game later on, but this is useful for sparing ears no matter what reason.
  • ‘networkTest’ or ‘testNetwork’, which tries to either host a new game, or if that fails tries to join a game. This is similar to running the below two command-line arguments.
  • ‘host_game’, which automatically hosts a game.
  • ‘join_game’, which automatically tries to connect to a predefined host. By default this host will be my computer since I’ve got everything set up.

Running it on Windows via Git Bash for example could look something like the following:

$ SpaceRace.exe mute join_game

If there are any uncertainties or you need help testing it, go ahead and contact me!
Below some new screenshots just to try and make it a tradition.

Screenshot 2014-02-10 09.48.19 Screenshot 2014-02-10 09.48.14

… talking about discovering issues, I just tested and realized that the chat does not work between clients. Will have to enable chat-packet re-transmission so that everyone gets them and not just the host.

Since the last post a bunch of things have been done. Some issues from the previous playtests have been fixed (like the white-sphere shield bug, it was just there for appearances’ sake anyway), a new font has been designed (yes, it actually helps if testers can read it), and UI components have been adjusted to not be interactable if they haven’t been tested fully by me.

Some pictures below.

Screenshot 2014-02-07 06.32.43_cropScreenshot 2014-02-07 07.40.46

Screenshot 2014-02-07 07.49.36Screenshot 2014-02-07 12.18.22

Interpolation works, but it’s not really enjoyable, so I haven’t gotten around to asking testers to try it yet. Think I might try and add extrapolation and investigate why it jerks around sometimes first.

Beside that I’ll probably try and polish it a bit further before monday’s MS2 deadline.

I cannot really remember much hardship these past 3-4 days, with the exception of writing my own GIMP script to be able to work with the font in a manner that doesn’t infuriate me, but that is kind of unrelated to the networking parts. Will try to throw up a new post right away the next time I solve a network-related problem.. :P

Glad to say I managed to connect my two computers over a LAN and test the game now!
It’s all still not working quite as intended (for example the connection time was far too long), but it’s a step in the right direction! :D

There have been several issues that I’ve had to deal with, and some design changes have been in order, but more of those details will come toward the end of the week, maybe as an update to this post.

Screenshot 2014-02-04 21.53.50

Post-night update:

Managed to fix some connection issues with some testing support from Aksel (cheers!), which ended up in some test sessions with up to 4 players~!

The overall response was suprisingly positive, even with a very rudimentary position-update system! The criticism was mostly due to appearance and choice of font, which is a given, but I might take a look at that once I’ve iterated a bit more, since a few more bugs appeared that might require fixing first…

Too busy enjoying the fruits of labour, I forgot to take decent screenshots of the gameplay, but I’ll try and make a copy of the prototype available for MS2 on monday. Hopefully the lobby screenshots proves my point to some extent. Synchronization delay or flow will require a video to display anyway…

Screenshot 2014-02-05 02.27.48Screenshot 2014-02-05 02.45.50

For those interested in development issues and solutions:

– The long connection delay was due to protocol suggesting to connect using IPv6 before IPv4. As I have yet to see a decent IPv6 solution (and have barely grasped IPv4) I chose to disable IPv6 connection attempts until further notice. Optionally one might just want to sort the various solutions and try IPv4 first and IPv6 later, but using IPv6 at all requires the ability to host games with the same uh… addressing scheme, which I don’t think (although I’m not sure) is available automatically? Might actually have to test that too now…

– Addresses. Earlier I thought that it might be clever for the host to inform the players (via SIP) of the addresses where the games are available. This did not work as well as I thought, since it would probably require a different approach, using static IP addresses for a public server etc.. which is not really what I had in mind.

– I had previously thought that I should place all related variables in a game state, and then use packets to manually synchronize them. Also, players should be managed in the lobby state! Now after thinking and trying some other things for a bit, it seems much wiser to use an independant entity to store and handle these, in this case the SRSession (Space Race Session). Storing and managing players in this object helps clarify which bits have to be synchronized, and also allows for switching of game states without tearing everything apart. It also allows for some packets to be handled right after they’ve been received, instead of having to post them to the active game states for reading at the next iteration. This may be a more complex solution, allowing players to be in different game states, but it allows more freedom, which is one of my main goals with the engine and my games in general, so I will try to stick to it if possible.