In engineering, sometimes you run into an issue and it’s actually disguised as another issue. That’s what happened to me when I tried to send the floor definition from the host to the members of the party.
Part of implementing multiplayer is that the host sends the floor definition to all the members so that all the members can be playing on the same floor of a tower. When I tried to do this, the members seem to receive the floor definition as seen in the logs, but wouldn’t move to the game screen.
The first thing I noticed was that the floor definition was being truncated in the logs. In other words, if the floor definition was 300 characters long, but the max is 200, the last 100 characters would be dropped. This would be a problem since we need the whole floor definition to display game screen.
I tried to shorten the floor definition by transforming the tile definition to single characters. For example, “WALL, GROUND, GROUND, GROUND, WALL”, would turn into “wgggw”. This is a good change regardless since having a single tile being a single character would drastically reduces network traffic. However the logs would still show a truncated response. Time to cut further.
The next thing I tried would be a little more complicated. Each floor is divided into 9 rooms. If I sent the floor definition as 9 different responses, then the size of each response would be 1/9 the length. I additionally had to put a small delay between each room definition call because I noticed that packets were being dropped otherwise. This ended up working the way I wanted it to. Each room was being received by the members, and the room definitions were not truncated in the logs. Unfortunately, the game screen was still not being displayed.
Much more frustrated that I did a bunch of work and fixed what I thought was the issue and the game screen was still not working, I started debugging further. I noticed that the code for receiving the room definitions was called, but my code for processing that data was not being called. What is going on?
I suspected at this point that my web socket client was muting an error. I tried debugging my own code to see what was going on. It turns out my web socket client was indeed muting my errors and there was a deserialization error for the room definition that looked like this: “java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 42 path $.definition.doors.” This means the part of the definition with the doors was not being properly deserialized. This is also the only part of the definition where I have a Pair object as the key to a map.
Class object instances are notoriously bad at serializing. I can transform that object to a string instead and back to a Pair object with some middleware. After implementing that, the room definitions were being sent and received properly.
This has me wondering if there was no issue with truncation in the first place, and I’ve split the floor definition into 9 web socket calls for no reason. If that’s the case, it’ll be better to have it all back in a single call. I will come back and add to this post once I’ve tried this.
Edit: Moving everything back to a single call worked. The truncation was indeed only in the logging. I’m going to go lie down now.
Leave a Reply