The Kingdom of Galanor, Playtest Available


[Update: 30-03-2021]
I’m excited to announce that the the first phase of public play testing for Kingdom Of Galanor has commenced.

You can request access to the play test by visiting the Steam store page and clicking on the ‘Request Access’ button here https://store.steampowered.com/…/The_Kingdom_of_Galanor/

Earlier this year we started work on a multiplayer RPG game, The Kingdom of Galanor and have recently reached the point that we can start doing some testing of network code.

We think we will probably use PUN, partly because of our familiarity with it already and partly because of the automatic host migration, because we are opting for player hosted rooms rather than dedicated servers.

In this test (video below, showing two of the clients) we conduct a 20 player test of our latest player (and pets) transform and animation synchronisation code and interest management; With 20CCU split roughly evenly between 2 maps it resulted in a maximum of only 116 msg/s and about 12mb data per hour. (The data will be optimised further).

The test itself was quite busy in terms of constant player movement, and in practise I think the network traffic would probably be lower than the test indicated. Our aim is to be able to support 32 players per game (room) and at the moment it looks like we are on course to be able to fit that into the room limit of 500 msg/s limit imposed by PUN.

We are also well into the development of the quests, combat and work skills/production systems and I’ll post updates on those once we’ve got something to show.

The intention is that this will be a PC only game and will be released on Steam.

Facebook Page
[Update 24-05-2021 New captial city, Elendor]( The Kingdom of Galanor, Playtest Available page-2#post-7171279)

[Update 08-02-2021 Equippable items]( The Kingdom of Galanor, Playtest Available page-2#post-6814355)

Update: 11-01-2021 Latest Alpha game play footage

Update: 17-08-2020 Alpha game video

Update: 15-04-2019 Early look at the starting zone for new characters

Update: 21-10-2018 Alpha test UI demonstration, draggable windows etc.

Update: 06-09-2018 Alpha test of the turn-based combat system.

Update: 07-07-2018 More recent video of the game progress

First video - early alpha test of networking code

10 Likes

Continuing to develop and improve the networking code, we’ve now implemented the basics of a party system, basic network synchronised mob wandering and aggro behaviour, and scene switching for the what will be a turn based combat system.

One of the early problems faced was with how to approach handling the mobs for each map; we needed them to be network aware because we wanted to use RPCs to control their behaviour and be synchronized between clients, which meant that we couldn’t just place prefabs in the scene. So Initially we put placeholder gameobjects in the map scene which contained a script that used InstantiateSceneObject() to create the actual mob when the map loaded.

This approach presented a number of problems, the following being the most annoying:-

  • Firstly the mobs were spawned on all clients, irrespective of whether the client was on the map that the mobs belong to; Which meant that we had to add logic to hide the mobs on clients that were on a different map.
  • It also meant that we were sending unnecessary instantiation messages to some clients, therefore wasting bandwidth.
  • On top of this because of the way RPCs work as standard, the control RPCs for the mobs were also sent to every client, meaning we were wasting more bandwidth and also had to filter them out for clients on other maps.
  • Furthermore, when a map was entered for the first time in any session there was a noticeable hitch on all clients as all the mobs were created.
  • Finally, we had to have some way to remove all the mobs once there were no more players in the map.

After playing around with this for a while it became clear that it was going to be unwieldy and inefficient, so we decided to rethink our approach from the ground up.

After a bit more experimentation, we decided to that we wouldn’t instantiate the mobs as scene objects, and we wouldn’t give them a PhotonView component. Then rather than having a mob spawner placeholder in the map we would just place the actual mob gameobject itself.

This neatly dealt with problems 1,2,3 and 4 from the above list, however we now need a way for the mobs to synchronize over the network. Which is where PhotonNetwork.RaiseEvent comes into its own. Using RaiseEvent we can specify exactly which clients get sent messages, so we can send messages only to those clients on the same map.

We also added a script to the mobs which listens for RaiseEvent messages and filters the messages by the EventCode, so they can take the appropriate action based on the message received. We also needed a way to give each mob a unique identifier (think PhotonView.viewID) that will always be the same for the corresponding mob on all clients, but this turned out to be quite straightforward, by using the build index of the map they are on (multiplied by 100,000) added to the child index of the mob. This gives us more than enough mob unique IDs for any given map and means that if we send the ID in the network message, the receiving mob can tell if the message is targeted at it or not.

So problem 5 is also now dealt with, as the mobs are created and destroyed along with the map as players leave and enter it, which has no effect on other clients.

We also created a couple of helper classes to give us handy functions to send messages to players (all players, other players, only players in the same map, etc.).

Now there was another part of the puzzle to be solved. We needed a way to decide which client should be responsible for controlling the mobs in the map. It can’t just be the current MasterClient, because the MasterClient won’t have any knowledge of mobs in maps that it isn’t itself on. So we devised a method to have each map maintain its own ‘MapMasterClient’ which is automatically updated as players enter and leave maps, and it is this client that will control the mobs for that map.

With the addition of a couple of network messages to invoke functions to synchronize the state of all the mobs when players first enter a map the puzzle was complete. We now have a system that makes it easy to control different sets of mobs for different clients, depending on which map they are on, and which also minimizes the amount of network traffic required to handle this.

As a direct result of this, we’ve take the decision to avoid using RPCs for anything in the game, and instead implement all network communication using RaiseEvent. Also the only thing we will use PhotonNetwork.Instantiate for is the player gameobject.

With 20 clients connected, all the players on the same map and moving around constantly along with the mob wandering logic, we are still only at around 250 messages per second per room, which is within our target. In practice most players aren’t moving constantly and the party system will reduce movement data even further for clients in a party, but we need to allow for worst case scenarios.

We’re still a way off having a playable version, but things are progressing well and as soon as we have something available for testing I’ll post an update here.

Hey, hope the best for your project. How do you calculate the msg/s and setup the pun accordinatly?

Thanks VavylonaEntertainment :slight_smile:

The msg/s is taken from data shown on the analytics page of the PUN dashboard for the game. I’m not sure what you mean with the second part of your question.

My mistake, confused it with Unity Networking. I meant what things do you take in mind when optimizing the network traffic?

The main things are :-

  • How often data is sent - make it as infrequent as possible without compromising synchronization.
  • Send unreliable messages wherever suitable.
  • Restrict how many clients messages are sent to (for example in our game we don’t send updates to players in other maps. Later on down the line we may further restrict this based on proximity.)
  • Be aware of the size of any data that we transmit, so for example we might send a byte instead of an int, and mostly avoid using strings as identifiers. Where it makes sense and doesn’t compromise performance we would also consider compressing the data before sending it.
  • When deciding what data to transmit, check first if it can be reasonably easily calculated on the clients instead, because if it can, you don’t need to send it in the RPC/Event.
1 Like

My next question is about your last dot. Would you throw an projectile and let it be with its rigidbody on both ends, or control it on the client that spawned it and sync it at all ends?

It depends on the circumstances, if it’s something like a missile that has a straight trajectory, I would probably just spawn it on all the clients and provide the aim and force needed to move it and then let the physics on each PC deal with moving it. However, where the movement is more erratic, say like a bouncy grenade I would probably track it’s transform and update it periodically with some kind of smoothing on the remote clients.

In fairness this sort of thing doesn’t really come up much in the type of network games we’ve made, as we haven’t made any fast paced FPS.

1 Like

A few screenshots from a very early build, not what the final product graphics will be obviously, but gives a very rough idea of the style of game we are aiming for.




1 Like

A couple more screenshots of the early implementation of the work skills system.

Have been tidying up the network code that handles parties and combat, particularly to make sure that unexpected disconnects are handled gracefully and don’t result in errors and null reference exceptions for the remaining clients.

The party system is substantially complete and is working exactly as planned. The combat system is partially implemented, with passive and aggressive mob behaviour.

When we originally started developing this we had player stats network synchronised, so any time any player had a stat update (HP,MP, DEX etc.) it was broadcast to every connected client, which created unnecessary network traffic. But it became clear that most of the time access to remote client stats wasn’t required, and it would be more efficient to have stats on the local client only and just send the stats to any interested clients on the occasion they are required.

We currently have a placeholder scene in place for combat, and in that we can see that the party leader correctly receives data from all players in the party, which it will use to calculate the result of the combat, and then transmit that to the other party members as and when needed.

Hopefully the next update should have a working implementation of the turn based combat system.

Players are currently only sending about 1 update a second to synchronise position and rotation (packed into one vector3), which although doesn’t result in absolutely perfect synchronisation is easily good enough for this type of game.

Edit: Forgot to mention have also been experimenting with a shader based random screen transition system.

I am liking the look of your project. Can you give us some detail about pricing. My personal suggestion for an rpg like this :- Make it free and add microtransactions. The free aspect will attract a lot of players because they will be able to try it. And this is a kimd of game where lot of people buy in game items.P.s any beta program available?? Thanks.

Hi @InstinctDevs , thanks for the feedback, much appreciated :slight_smile:

Regarding pricing, we are thinking much along the same lines as you, either free or very cheap with vanity item micro transactions. We’re undecided at present on how we feel about having progression items available for purchase, but we’ll be open to feedback on that aspect.

We are definitely on the lookout for anyone that’s interested in helping with testing and we’ll be sure to announce it on here once we are nearing the point we have a playable version and have some closed beta keys to hand out. It’s highly likely that this won’t be until close to the end of the year though.

Once again, thanks for you’re interest :slight_smile:

@ Munchy2007 :slight_smile: Looking forward to futher development!

1 Like

Can you give us an idea when to expect a beta and global release. Thanks!

`Hi @InstinctDevs , sorry, at this stage of the development we’re not in a position to set those dates yet. I’ll post dates once we are comfortable that they can be met. :slight_smile:

Sure @Munchy2007 it’s your game take your time. Actually its better this way so the game can get more development time and be better.

1 Like

I thought it was about time I posted an update :slight_smile:

We’ve been working on a lot of ‘under the hood’ stuff, making sure the core systems are as stable and maintainable as possible. The worst thing is finding out sometime down the line that some bad early design decisions have come back to haunt you.

One of the first obvious hurdles we had to overcome was how to deal with teleports. Initially, we had a simple design, whereby the teleport gameobject contained a component that had a reference to a destination gameobject and when activated it just moved the player to the destination location.

All well and good, except that as we use a different scene for each map we ran into the issue that as cross scene references aren’t allowed we couldn’t store the reference to the destination in the teleport if the destination wasn’t in the same map.

So a slight design change meant we stored the name of the destination gameobject in the teleport along with the scene path as strings and then when activated, the teleport loads the new scene (if necessary) and once the scene is loaded it searches for the destination gameobject by name and then moves the player to its location.

Job done, or was it? With the number of teleports that will eventually be in the game, this would soon become a nightmare to maintain. Anything that relies on manual entry of strings to make references for anything other than a few objects isn’t going to cut it.

In addition to that, we found that although this worked acceptably in a single player environment once we tried it networked we saw ‘warping’ of the player character because it was at its old location from the previous map for a few frames whilst the teleport located the destination and sent the new location over the network. So we fixed this by adding the location and rotation of the destination as properties of the teleport and sending them along with the scene change message, so all clients could update to the new position instantly.

This, however, meant that it was even more difficult to maintain the link between teleports and destinations and was quite frankly turning into a nightmare. So it was pretty obvious that a rethink was required.

After a bit of discussion, it was decided to move all teleport logic and data to a singleton manager which would store the information for all the teleports and destinations. Which just left the issue of how to easily get that information into the manager in the first place.

Custom Editor Window to the rescue!

We designed a custom editor that enables us to create/edit and delete teleports directly in scenes and it automatically saves the info for each teleport/destination into an asset which is loaded into the teleport manager at runtime. This has changed the task of maintenance from a manual task to visual design. We can quickly locate and update teleports and destination maps/positions and the new information is automatically saved. We can also automatically check for orphaned teleport and destination objects.

Now when a teleport gameobject is activated at runtime, it just queries the manager for its destination information and voila!

Quick snap of the editor in action, and that’s it for this update. See you again soon :slight_smile:

very cool looking :slight_smile: if you need some voice over or some basic sound effects let me know would love to record a few for you to help out.

Hi fantome, thanks very much that would be very much appreciated, I’ll send you a PM to discuss things when we’re ready to start looking at the sound in more detail :slight_smile: