Search Unity

Games The Kingdom of Galanor, Playtest Available

Discussion in 'Projects In Progress' started by Munchy2007, May 22, 2018.

  1. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    So, it's been quite a long time since my last update, not because there hasn't been much progress, but entirely due to the fact that there's only so many hours in a day and time spent putting together forum posts means less time working on the actual program.

    I've spent the last year improving and adding to all the core aspects of the game. I've greatly enhanced the quest system with amongst other things, the addition of scripted actions following acceptance and completion of quests. I've also made the scripted actions system generic, so it can be used with any interactable object in the game.

    I've also added the facility to show on the character when main hand and off hand items are equipped with different models depending on what is equipped. Eventually this will be extended to all equipment.

    Maps now have named areas, which make it easier for quest objectives to indicate where the area of interest can be found. There is also a prototype world map which shows the player's current location, which also helps in finding your way around.

    There is now the facility to do direct trades with other players and also a market place system, whereby you can set up a stall in the market which other players can browse and buy from all the time you are online. There is a plan to add a persistent auction house, but that is currently in the investigation stage.

    There are currently around 30 different maps, 20 of which are building interiors, the remaining maps making up the 4 current main areas (Fernville, Poppy Valley, Emerald Hills and Aldoril) and their sub areas (caves, dungeons etc.). Currently the quests will take players up to around level 21-22.

    There's also now around 160 different quests for characters to undertake, some of which are repeatable (daily or less frequently). As it stands, most quests are available for all classes (but some reward class specific items), the eventual goal is to have some class specific quests to give more variety when levelling alts.

    I've resisted adding too much extra content for the sake of it for the time being, because I'm still at the stage when some aspects of the game could still undergo fundamental changes, and the more content involved the greater the potential work required to make the changes.

    I've have however, spent a lot of time optimising the network side of things to reduce not only bandwidth but also messages per second sent.

    One of the biggest changes to come from this is how the mobs are synchronised between clients. Initially I had it so that they synchronised their position and whether they were dead and waiting to re-spawn between all clients. This led to a couple of issues.

    Firstly and probably most obvious, it led to a certain amount of network traffic, which while not a massive amount, did tend to add up with a lot of players concentrated in one area with lost of mobs as each mob has to send it's location information to every player in the same map as the mob.

    Secondly, it caused issues with players encountering areas with no mobs to kill because someone had been along a few minutes before and cleared them all. Initially I experimented with increasing the number of mobs and reducing their re-spawn times, but this had the downside that it could make it very tiresome having to work your way through a map that had a lot of aggressive mobs. Also having worked your way through a dungeon on a quest for example, it was annoying to find that when walking back 10 minutes later everything had re-spawned!

    So the solution I came up with, was to not synchronise the mobs as a matter of course, which meant I could tune the quantity of mobs and re-spawn times to suit the individual player. This solved both the issues I mentioned, but raised another, which was how to handle things when players teamed up in a party. It looked odd when your party leader attacked a mob which you couldn't see on your screen, or ignored mobs that were right next to you, because he couldn't see them on his screen, or they were in a location further away.

    The final solution was to implement a system whereby only players that are teamed up receive mob synchronisation information, and to further optimise that, the party leader client only sends synchronisation info for mobs that it can see on screen. The upshot being that instead of all mobs sending sync info to all players all the time, only the few mobs that are currently on screen send update info the the (max)4 other players in the party.

    The result, synchronised mobs when it really matters and hardly any network traffic. Along with the optimised player synchronisation this has resulted in each client sending less than 1 network message per second on average. As a consequence I think I should be able to support 50+ connected players per room (although I haven't yet tested this quantity).

    One thing that I wasn't entirely prepared for when I undertook this project was the amount of time I'd need to spend designing and writing tools to help create, organise and maintain game content. At the time of writing I've got 14 different custom editors and tools to help with things like quest design, NPC placement, teleports, resource locations and so on. But one thing's for sure, the custom editors and tools I'm writing now and far better and quicker to make than the ones I produced back at the start.

    Bit of a rambling post, but it covers most of the important developments, I'll attach a few pictures to finish. 20200817090302_1.jpg 20200817090356_1.jpg 20200817090511_1.jpg 20200817090552_1.jpg 20200817090631_1.jpg
     
  2. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    Video and some more screen shots



    20200817090631_1.jpg 20200817090751_1.jpg 20200817091131_1.jpg 20200817091306_1.jpg 20200817091435_1.jpg
     
  3. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    I've been trying for some weeks to work out a clean way to incorporate stun and silence effects into the current combat system. After 2-3 abortive attempts I've finally managed to work out a way that I'm happy with, which didn't involve major changes to the underlying system.

    Here's a short video showing one of the new stun skills in action. This skill only stuns, but the system allows for effects to stack, so I can just as easily create a damage skill that also stuns and so forth.

     
  4. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    I've decided to tackle a task that's been on my to do list for some time, but is one of those jobs that is tempting to put aside for another day because of what's involved.

    The issue relates to how I originally implemented the skill bar. When I first started designing the game I decided, that although visually the skill bar and things like inventories looked and behaved in a similar fashion, i.e. you can drag and drop elements onto them, there were sufficient differences that they shouldn't share the same base class. Specifically, the design called for skill bar buttons to only work during combat and that no inventory items could be dragged onto the skill bar and vice versa. Inventory items for use during combat (potions etc.) were to be made available via a different system.

    However, as time went by, it became obvious I needed to add the facility to allow spells to be cast out of combat and also, for convenience, the skill bar needed to be able to accept certain inventory items for quick access, somewhat blurring the differences between the skill bar and inventory functionality.

    The drag and drop system I have designed was flexible enough to cope with this, not really caring what the content of a button is and leaving validation up to the button containers. However, the combat and skill system was more of a challenge to adapt, as initially it fundamentally had no concept of accepting inputs as anything other than a skill ID and now it had to deal with items that were not skills and didn't share any common code.

    I did eventually find a solution for this, however, speaking honestly, the word 'workaround' might be more appropriate. On top of which, there has also been a long standing bug, where very occasionally, the skill bar buttons will clear when you join the game, meaning you have to repopulate it from the available skills dialog window, and I've so far been unable to track down the cause of that.

    On the other hand, as time has gone by, the inventory and game item systems have become more flexible as I've improved them to handle other tasks in the game (I'm a big fan of reusable code) and it's reached the point where it seems to make sense to re-implement the skill bar as an inventory and adapt skills to be an inventory item. Because of the way I've designed the inventory item system and skills class it will be easy to have inventory items that contain the existing combat skills information, avoiding the need to change all that existing code and data.

    The goal being, once all this is finished, is that I can dump a load of duplicated code that was specific only to the skill bar system, making it easier to maintain and also lose all the conditional code and workarounds that enabled the combat system to deal with two types of input (which, as I write this I realise was a really terrible idea in the first place).

    The reason I've put this off for so long, is that I've got a 99% working system currently and I know that in the short term at least, I'm going to change that into a broken system while I iron out all the bugs that making such a large change is going to cause. But for the long term it's something that can't be avoided.

    You've probably realised that my writing this fairly long post is just another way of delaying starting this job :)

    Anyway, can't put it off any longer, hopefully it won't be too long before I'm back here reporting it's all hunky-dory!
     
    Last edited: Aug 25, 2020
    guicamarotto likes this.
  5. guicamarotto

    guicamarotto

    Joined:
    Jun 23, 2020
    Posts:
    25
    I really like your game!! its looking so amazing, its very pretty and funny. I want to play that for sure. congratz to you for this project man.
     
  6. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    Hi @guicamarotto , thanks for the nice comments and interest in my game :)

    Keep an eye on this log because at some point I'll be offering a limited amount of free Steam keys to get help with testing and feedback from a larger number of players than at present. Anyone that has indicated interest in the game prior to that will be given first refusal.
     
    guicamarotto likes this.
  7. guicamarotto

    guicamarotto

    Joined:
    Jun 23, 2020
    Posts:
    25
    yeeeyyyy
     
    Munchy2007 likes this.
  8. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    Quick update on the progress made so far with the skill system upgrade outlined here.

    The core changes are in place and working as intended, I've achieved my aim of making skill buttons and associated containers inherit the same base code as inventory elements. I've added some extra properties and settings to facilitate enabling the different behaviour of the containers by selecting different options in the editor.

    This has also enabled me to strip out quite a lot of conditional code that was required to handle drag drop interaction between containers that didn't container the same type of content. Which quite frankly, was a bit of a mess previously and didn't allow me to set things up exactly as I wanted in all cases.

    I've been able to fix a number of other ongoing issues that were caused by the original poor design and also refactor some other parts to make things cleaner and more flexible.

    I think I've probably got about another week's work to tidy up all the loose ends of this update, but when finished I will have a much cleaner combat skill system overall with the option to add features that wouldn't have been possible (or at the very least, difficult to implement cleanly) before.
     
  9. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    So, I've finished the update of the skills system and everything seems to be working as it should. It was a lot of work but the benefits more than make up for that.

    The main changes that this update has brought about are:-
    • Less complex and more easily maintainable code.
    • Tamed pets can now have a different set of skills to their wild counterparts.
    • As well as the standard set of skills that are specific to each class of character/pet, they can now learn extra skills from various sources such as NPCs, special drops and vendor items.
    • The pet skill bar is now reorderable the same as the character skill bar and can accept usable game items.
    • New skills are automatically added to the skill bars when learnt (if there is free space).
    • The random loss of skill bar contents bug is fixed.
    • Less network data sent during combat when in a party.
    • Introduction of the concept of 'roles' for pets (currently the only role implemented is combat).
    Another improvement that came about as I was planning and implementing this upgrade, was the removal of the requirement for all game item prefabs to be loaded via Resources.LoadAll when the game started (not sure how much of an issue this might have become once the count of items started to number in the thousands, but that's by the by now). They are now stored in a list in a ScriptableObject asset which in turn maintains a number of dictionaries that allow the different items to be queried using different types of key (guid, name, path etc.) via methods in the asset.

    This last bit has now highlighted a further area for improvement in the quest and inventory system, to take advantage of the way the game item prefabs can now be referenced.

    When I initially designed the game items system I decided to use the asset resource path as the unique ID for each item prefab and I used the AssetPostProcessor to store the resource path in a component on the prefab so I could refer to it at runtime via a dictionary.

    Whilst this worked fine, it suffered the drawback that if I moved or renamed an asset it would no longer be found when loading inventories or quests that contained references to the old name/path, in which case I just replaced it with a placeholder 'missing item'. But going forward, I knew this needed to be addressed, as I couldn't have players losing their epic items or being unable to complete quests just because I needed to correct a spelling mistake!

    The reason I initially adopted the resource path as the unique ID was because I had been unable to work out a way to reliably generate a numerical unique persistent ID for each prefab. But I solved that problem whilst implementing the skill system update, so at some point soon I'll upgrade the game item system to use the new numerical guids rather than the resource path.

    However, before that, I now need to rewrite the skills editor I made previously to make it compatible with the new system, but hopefully that shouldn't take much more than a couple of days.
     
  10. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    It took a little bit longer to redesign the combat skills editor than I was hoping, but it's now finished and far, far better than the old version.

    I actually ended up splitting the task between two separate editor windows to keep the code less cluttered and it worked out pretty well I think.

    This is the end result of all my hard work (well, I say end result, but it's a pretty safe bet I'll end up tweaking it some more over the next few weeks.)
    Skill Editor.png

    The underlying structure of the combat skill classes is fairly complex now, to allow it to deal with all the different variations and depending on some of the settings, some of the other variables and properties aren't used or have only one sensible value. Previously I had to try and remember this myself, but now the editor takes care of that and hides or automatically updates values where necessary. I can also navigate the project hierarchy for the various assets entirely through the editor now.

    Once I've used this to set up all the skills for the characters, pets and mobs again, it's on to the redesigning the game item system to be based around a numeric ID identifier rather than the current string identifier. This can be done in stages though, as most of the groundwork is already complete and it's just a matter of converting the the various other game components (inventory system, quest data, etc.) to query the game items by their numeric ID.
     
  11. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    Phew! Finally finished the two big updates to these core systems.

    Strangely enough the 2nd phase, which I thought was going to be the bigger job of the two, actually turned out to be far less work than upgrading the skills system.

    One of the biggest headaches I faced was noticing a null ref bug after making some changes to the game item serialisation code and then spending the best part of three hours going back over what I'd changed and double checking everything, only to eventually find that the bug was caused by something entirely unrelated that I'd changed a few weeks ago and hadn't spotted the bug at the time.

    I really hate it when that happens!

    I managed to do this and still be able to have existing characters retain their progress, with hardly anything in the way of extra code to manage this, specifically one single line conditional check when deserialising game item information.

    Once I've tested things a bit more to ensure I haven't missed any other major bugs, I can get back to adding more game content :)
     
  12. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    Something I've been working on for some time now, which I've never been happy with is the way the combat system handles the order that attacks are played out each round.

    The goal was to have them ordered primarily by dexterity, so that faster combatants get to perform their attacks before slower ones.

    But then I wanted all similar entity types (i.e. player, pet, mob), to attack at the same time, so the fastest players will always attack first, followed by the fastest pets, then the fastest mobs. But, I also wanted to further break this down, so that the attack order amongst entities in the same 'phase' would be all melee attacks, followed by all matching ranged attacks. I also wanted to have the option to override these base rules on a skill by skill basis.

    Basically, the way the combat system works, is that all the attacks each round are collected into a list, which is then sorted into attack order (fastest attackers going first) and then each attack is performed and the outcome is stored in another list. At this point there is no visual representation of the attacks.

    Once I have the list of stored attack results, this is sent to remote clients if in a party and then the list is parsed by all party members and the visual representation of the fight is played out.

    The problem I was struggling with, was how to properly sort the attacks, and from the list of results, how to generate each 'attack phase' of the round. But I'm pleased to say that I've finally come up with a solution that works how I wanted, by using a two step system, that starts with a custom sorter for the attacks, and then a parser for the sorted list that generates each of the attack phases. Previously, all ranged attacks were being cast one after each other and only certain melee attacks would be grouped, which made the combat sequence for a large party of players and mobs a little tedious.

    This final solution was made far easier to implement by the previous recent updates to the skill system.

    Here's some of the code if it's of interest to anyone.
    Code (CSharp):
    1. class AttackSorter : IComparer<CombatAttackInfo>
    2. {
    3.     Combat combat;
    4.     Skill xSkill;
    5.     Skill ySkill;
    6.  
    7.     public AttackSorter(Combat combat)
    8.     {
    9.         this.combat = combat;
    10.     }
    11.  
    12.     public int Compare(CombatAttackInfo x, CombatAttackInfo y)
    13.     {
    14.         xSkill = QuerySkill(x.skillID);
    15.         ySkill = QuerySkill(y.skillID);
    16.  
    17.         var dexCheck = combat.entityInfos[y.attackerInfoIndex].stats.DEX.CompareTo(combat.entityInfos[x.attackerInfoIndex].stats.DEX);
    18.         if (dexCheck != 0) return dexCheck;
    19.  
    20.         var entityTypeCheck = combat.entityInfos[x.attackerInfoIndex].stats.type.CompareTo(combat.entityInfos[y.attackerInfoIndex].stats.type);
    21.         if (entityTypeCheck != 0) return entityTypeCheck;
    22.  
    23.         var skillGroupCheck = xSkill.skillGroup.CompareTo(ySkill.skillGroup);
    24.         if (skillGroupCheck != 0) return skillGroupCheck;
    25.  
    26.         return x.skillID.CompareTo(y.skillID);
    27.     }
    28.  
    29. }

    Code (CSharp):
    1.     public IEnumerator DoCombatPhaseAnimations(List<CombatAttackInfo> networkAttacks)
    2.     {
    3.         var phase = GetCombatPhase(networkAttacks);
    4.         yield return StartCoroutine(ShowCombatPhaseAnimations(phase));
    5.         phase.ForEach(c => networkAttacks.Remove(c));
    6.     }
    7.  
    8.     List<CombatAttackInfo> GetCombatPhase(List<CombatAttackInfo> networkAttacks)
    9.     {
    10.         var phase = new List<CombatAttackInfo>();
    11.         phase.Add(networkAttacks[0]);
    12.         if (networkAttacks.Count > 0)
    13.         {
    14.             // Find all attacks that share the same AttackGroupID (Additional multi-target attacks) and add them to this phase
    15.             for(int n = 1; n < networkAttacks.Count; n++)
    16.             {
    17.                 var attack = networkAttacks[n];
    18.                 var entityInfo1 = entityInfos[attack.attackerInfoIndex];
    19.                 var entityInfo2 = entityInfos[phase[0].attackerInfoIndex];
    20.                 if (attack.attackGroupID == phase[0].attackGroupID) phase.Add(attack);
    21.             }
    22.  
    23.             for (int n = 1; n < networkAttacks.Count; n++)
    24.             {
    25.                 var attack = networkAttacks[n];
    26.                 var entityInfo1 = entityInfos[attack.attackerInfoIndex];
    27.                 var entityInfo2 = entityInfos[phase[0].attackerInfoIndex];
    28.  
    29.                 if (!entityInfo1.InSameGroup(entityInfo2)) break; // End the combat phase if this attack is by an entity not in same group as first attack
    30.            
    31.                 // Now check for differing skill groups to see if the combat phase should be ended
    32.                 var firstSkill = Doofah.Skills.SkillManager.QuerySkill(phase[0].skillID);
    33.                 var attackSkill = Doofah.Skills.SkillManager.QuerySkill(attack.skillID);
    34.  
    35.                 // skillGroup -1 always plays separately
    36.                 if (firstSkill.skillGroup == -1 || attackSkill.skillGroup == -1) break;
    37.  
    38.                 // skillGroup 0 == melee attacks, play these together
    39.                 if(firstSkill.skillGroup == 0 && attackSkill.skillGroup == 0)
    40.                 {
    41.                     if (!phase.Contains(attack)) phase.Add(attack);
    42.                     continue;
    43.                 }
    44.  
    45.                 // skillGroup 1 == ranged attacks, play together all that share the same game item ID
    46.                 if (firstSkill.skillGroup == 1 && attackSkill.skillGroup == 1)
    47.                 {
    48.                     if(phase[0].skillID == attack.skillID)
    49.                     {
    50.                         if (!phase.Contains(attack)) phase.Add(attack);
    51.                         continue;
    52.                     }
    53.                 }
    54.                 else if (firstSkill.skillGroup == attackSkill.skillGroup) // custom skillGroup values will be grouped together
    55.                 {
    56.                     if (!phase.Contains(attack)) phase.Add(attack);
    57.                     continue;
    58.                 }
    59.  
    60.                 // If we got here, end this combat phase
    61.                 break; ;
    62.             }
    63.         }
    64.  
    65.         return phase;
    66.     }

    Short video showing the new combat sequencer in action.
     
    Last edited: Sep 22, 2020
    guicamarotto likes this.
  13. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    Been doing some more work on Emerald Hills, the level 20-25 area. Here are some screen shots of Newbarrow and nearby points of interest. Newbarrow is one of the villages in Emerald Hills, which is the home of the Saursela, a race of imps and is the hub of a quest line concerning them.

    Facebook Page

    938020_screenshots_20201006204725_1.png 938020_screenshots_20201006204924_1.png 938020_screenshots_20201006205228_1.png 938020_screenshots_20201006205413_1.png
     
  14. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    Facebook Page

    One of things I struggled the most with when first planning this game, was how to handle increases in stat values as the players and mobs gain higher levels and at the same time balance the amount of damage done by attacks.

    One of the fundamental problems is that the rate of increase in either can't be linear and still produce pleasing results. Once you add to this the variables of defence and other buff/debuffs it becomes a nightmare to find a calculation that will produce sensible numbers over a large range of levels. For example what works in a fight between level 10 players/mobs will produce wildly differing results at level 80.

    So in the end I decided to first of all just work out a system that produced a rate of HP increase that I liked and then decide what to do about damage after that. After some experimentation I came up with a system for generating HP as an entity levels up that gave a nice growth curve.

    So then, in terms of how I wanted this to work with the damage, what I was looking to achieve was a system whereby, when a player of a particular level is fighting a mob of a particular level, the amount of damage done as a percentage of the target's health pool should remain roughly the same regardless of how high or low that level may be, let's say say around 5% for arguments sake.

    So if a level 5 player with 100 health gets hit by a level 5 mob, he would take 5 damage. Whereas at level 20 with 3000 HP the player would take 150 damage from a level 20 mob. Obviously this is a much simplified example, and the actual calculation will take other factors into account and add a small amount of randomness, but the nett result would be a damage system that produces sensible numbers no matter what level the combatants are.

    So having sorted the HP growth calculation I played around with various damage calculation algorithms, taking into account the stats of each entity, their relative levels and the type of combat skill used. I worked out a few that that produced good results between levels 1 to around 20, but as the levels increased, the damage quickly moved away from the percentage amount I was looking to achieve.

    After struggling with this for a while I hit upon the idea of using a final modifier to the damage calculation based on a value obtained from an animation curve with the entity level as the timeline. By adding keys and tweaking the curve accordingly, I can multiply the final damage value by a value obtained from the curve based on the target's level. The result being that the damage can be kept to roughly the percentage of HP that I want.

    Having that final piece of the puzzle in place I just needed a way to quickly test the result of fights between combatants at all levels (current max for the game is set at 200), creating and levelling characters in the game and then testing fights to check the results of the various settings is far too time consuming (even with cheats to quickly add levels), so I knocked up an editor tool that allows me to quickly set up and test fights between combatants at any level and stats with just a few clicks, speeding up the iteration time for working out the damage curves immensely.

    This is the editor I made (still needs more work to allow testing of elite mobs and equipment with bonus stats).
    Skill Damage Tester.png

    This is the damage modifier curve for mobs.
    Damage Curve.png

    I've also being doing some more work on the Emerald Hills map. This is Fairreach Hamlet.
    Fairreach Hamlet.png
     
    Last edited: Oct 14, 2020
  15. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    Over the past few months as more and more detail and complexity has been added to the maps (especially the larger ones), I began to notice a gradual increase in the time it took to switch maps, to the point where it was now taking as much as 30 seconds to load one of the main maps. Something needed to be done!

    The first thing I did was perform some tests to see where the time was being taken, so I could work out the best strategy to tackle the problem. What I noticed was that after a scene change was triggered Unity effectively locked up for the duration of the loading of the next map, so I thought maybe using LoadSceneAsync might somehow come to my rescue.

    It soon became apparent however, that it wasn't Unity's scene loader that was the problem, because Load Scene and LoadSceneAsync were both completing in 1-2 seconds when I timed them, and then Unity was sitting there doing nothing (from the player's viewpoint) for the rest of the 30 seconds.

    In fact it wasn't doing nothing, it was busy setting up all the stuff that forms the scene as designed in the editor. This 'glitching' during scene loading seems quite a common problem judging by the Google search results, and the usual advice is use LoadSceneAsync and just switch the new scene in one it's loaded. The problem with this approach is, that when LoadSceneAsync has finished, the baulk of the work is yet to be be done, i.e. loading and instantiation all the prefabs, meshes and other resources that go to make up the scene, and it does all this work on the main thread, and stalls everything else until it's finished. Which can take a loooong time for a complex scene.

    Following this discovery, I worked out, by selectively removing stuff from the scenes, that the long setup time was split roughly 50/50 between all the scene geometry and all the mobs, so I decided to tackle each of them separately.

    I was already aware of an asset called MegaScatter, which promised to deal with exactly this type of problem for objects placed in scenes, so I purchased a copy of it and got to work adapting one of the maps to make use of it.

    It has two methods of dealing with scene objects, it can either collect up a group of objects and combine them into a single mesh, or it can generate a list of the objects and spawn them at runtime. (Either way the originals should be removed from the scene before saving.)

    Thinking that combined meshes were going to be best for performance, I went with that as the first option. Two problems here though...First of all, the mesh data was stored in the scene file, which meant that the scene file quickly exceeded the 100MB max file size for Github, so to get around this I saved the meshes made by MegaScatter to assets instead. But the second and killer problem, was that loading the combined meshes actually increased the time it took for the scene to finish initialising!

    Okay, I thought, I'll use the second option and have MegaScatter instantiate all the bits and pieces after the scene has loaded, it has an option to restrict the amount of items instantiated each frame, so this should prevent frame rates tanking while it's doing so.

    However, no matter what I tried, Unity just sat there while all the objects were being instantiated (with nothing appearing each frame), until everything all appeared at once after a number of seconds, during which time framerate was zero. Not what I was expecting from the way it was described in the manual! Also, there doesn't appear to be any way to instantly instantiate selected bits based on the location of the player, so there is the risk that after the map loads the player could see some of the later instantiated items pop into view.

    The practical upshot being that MegaScatter didn't help. But, I knew that spreading the creation of the scene objects over a short period of time had to be the way to go, so I set about creating my own scattering system. With a bit of experimentation I finally worked out a method that quickly and easily allows me to create and maintain scene objects in the editor, which aren't saved with the scene, but are instantiated at runtime, without any of the problems outlined above.

    In my next post I'll describe how this works. But for now here's some screenshots of some work I've been doing on one of the maps. (Because of variations in monitors some forum images as posted may be too dark/bright, but the game has settings to compensate for this).

    Before 1.png After 1.png Before 3.png After 3.png
     
    Last edited: Oct 31, 2020
    Kurt-Dekker likes this.
  16. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    So following on from my last post, here's a bit more detail about how I fixed the slow scene loading problem.

    The first thing I had to do was change the approach I was using to design the map layouts, which up until then had consisted of a single scene for each map that contained everything that went to make up the contents of that area.

    Instead of that I split the map design into two scenes, the first scene containing the terrain and anything that needs to be instantiated at the same time as the map loads, and then a second scene that contains all the actual geometry, buildings, vegetation, rocks, props etc. etc.

    I then made a couple of utility scripts that enable me to, at the click of a button, generate assets that contain instantiation data for all the objects in the geometry scene, that the main scene can use at runtime to instantiate everything not included in the main scene.

    Consequently, at runtime, I now only load the first of the two scenes for the map, which has very little in it, which loads quickly, and then another utility script instantiates all of the missing geometry over the course of a number of frames.

    A couple of advantages that my home grown solution gives me is that it allows instant instantiation of geometry that is within a certain distance of the player when the map is loaded, so that the map being 'built' isn't visible to the player. But, possibly more importantly, it enabled me to easily implement a system that allows for a reduction in map detail to help the frame rate on lower specification machines, by selectively only instantiating a certain percentage of the scene geometry. Important things like buildings and such can be flagged to always instantiate.

    I adapted the same process to handle spawning the mobs in a similar way, which was the final piece of the puzzle that was the scene loading problem.

    So I've now got a nice workflow that allows for easy design and alteration of the maps and results in much faster load times, a large map now takes about 5 seconds to load, and that's including the fade-out and fade-in, which feels much more acceptable.
     
  17. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    As well as sorting out the scene loading issue, I've been working on a new area and quest line which takes place in Emerald Hills.

    Nestled deep in the heart of Emerald Hills is the Temple Of Althraxia.
    Recently discovered after lying hidden and abandoned for thousands of years, it is protected by the re-animated remains of the warriors that used to guard it.
    Legends tell of fabulous treasures being hidden in the depths of the temple catacombs, but knowing what also awaits unwary explorers within, will anyone dare to enter?

    Here's a few screenshots, hope you like them.
    Temple Of Althraxia 1.jpg Temple Of Althraxia 2.jpg Temple Of Althraxia 3.jpg Temple Of Althraxia 4.jpg
     
  18. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    More screenshots of the Temple Of Althraxia

    Temple Of Althraxia 5.jpg Temple Of Althraxia 6.jpg Temple Of Althraxia 7.jpg
     
  19. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    Another progress update...

    I've teamed up with Reed Means Music to start adding a soundtrack to the game, with different themes for all the maps and buildings. Really happy with the results, the music definitely adds to the atmosphere of the game.

    I've also started adding ambient sounds and other sound effects. Still a lot of work to do on that front, but it's coming along nicely.

    I'm currently putting together a video showcasing this, which I hope to have ready sometime in the next few days.

    On a slightly different note, I've continued working on optimizing the network side of things and that also seems to be looking pretty good. Here's the Photon Dashboard analysis of a few hours of testing from yesterday.

    Network Stats.png
    Not a big test by any means with a max of 7 CCU. But with a maximum of 3 msg/s per room and 0.1kb total bandwith over the course of a few hours it's looking like it should be okay for the new target of being able to support 50 users per room that I've set myself.

    I still haven't tested it with more than 20 CCU, so I'm still not entirely certain how exponential the rise in msg/s will be once I get more players connected to the same room instance. But unless absolutely everyone congregates in a very small area and is constantly moving around, then I'm pretty sure the interest management system will keep the networking load manageable.

    Also, following on from my previous posts regarding map loading times, I've got the loading time (including fading in/out) down to 3 seconds irrespective of the size of the map, which I reckon is probably about as good as it'll go. The incremental building of the map geometry caused me a few headaches with remote character avatars and mobs spawning before they had anything to stand on sometimes, but I managed to sort that out in the end.

    As usual, any comments and/or suggestions are most welcome! :)
     
  20. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    Hi all, here's a link to a You Tube video showcasing the current progress of the combat, party and questing elements of Kingdom of Galanor, the game I'm currently developing using Unity.


    I recently teamed up with Reed Means Music for the in game music which has now been added to some of the maps and I've also started adding sound effects and ambient sounds.

    There will be different music tracks for each map and building type, but all following the same underlying theme/style.

    As usual any and all comments, suggestions and general feedback are most welcome
     
  21. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    I've engaged the services of a character modelling studio to have the main characters remodelled so that they start off wearing no equipment rather than having their armour/clothing as part of the character mesh as is currently the case. I'm also having made various armour/equipment sets for them to wear.

    I've implemented a system that visually represents armour items on the character as they are equipped now, which will give better feedback as equipment items are equipped and upgraded and lead to a greater variation in the look of each character class (once I've got more equipment sets added to the game).

    Also, hair and beards are separate models too now, which will allow for further customization of the character appearance, as will the addition of different skin tones and face designs which is planned for a later date. I'm also looking at implementing a way to allow basic customization of the body shape for each class to add further variety.

    Here's a short video showing it in action.
     
  22. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    Just over a month since my last update, how time flies!

    I've finally finished the Temple Of Althraxia map, quests and boss fights. It took me a while longer than I hoped, but the quest story involving it is fairly complex, consisting of somewhere in the region of 20 separate quests in total.

    What also slowed down the progress was the fact that I needed to develop some completely new quest mechanics while I was working on this area to enable me to construct the quest line how I wanted.

    Following on from my previous post, I've also continued working on the equipment system. I abandoned my original approach, which was to have a semi naked character body and then have armour pieces that fitted over it due to the amount of issues I encountered with parts of the body clipping through the armour when animated. Whether or not this is an inherent problem with this approach or was due to poor setup of the bone weights on the armour parts I'm not entirely sure about, but I was wasting too much time on it as it was.

    Also, the animation studio I was working with didn't seem to be able to hit quite the right mark with the texturing style I was after, so with both those problems I started looking into other options.

    After some research into how others approached this, I found that World Of Warcraft characters models are put together in a modular way and then the textures are applied to the character afterwards. So I decided to use the same approach. I already had an asset that took this approach, however I had previously decided not to use it because it worked by having all the parts contained on a single character and disabling certain bits to achieve the look required. This felt kind of inefficient to me, especially considering how much equipment will eventually be included in the game, but mainly because as it was I couldn't adapt it to work in a similar fashion to the World Of Warcraft method.

    So, it was time to download Blender and get on YouTube to watch some tutorials in the hope that I might be able to do something about it myself.

    As it turned out, it didn't take me too long to work out how to import the modular character .fbx file into Blender and export each armour piece separately (with its rig), which was the first step, which meant I now had all the separate parts required to build up a complete character at runtime.

    Secondly, I adapted this to set up a system where the character can be assembled at runtime and all the bone weights for the separate parts are copied to the main part, so that they will all animate correctly using a single animator controller.

    The final step was to work out how to do the texturing. As it stood, all the parts were textured from a single atlas, which was fine except that as the texture atlas was already full, there was no room to add the textures for new parts, meaning that I would end up with multiple textures being used to draw each character depending on what they had equipped.

    What I came up with was a system whereby each armour part has its own 512x512 texture, and the character has a single material with a blank 2048x2048 texture. I worked out how to remap the UVs for the armour parts, so that each particular type (head, chest, gloves, shoes, etc) map to a corresponding 512x512 section of the 2048x2048 character texture and as each item is equipped it copies its texture to its section of the character atlas.

    This gives me complete flexibility for adding new items to the game as well as always only using a single material for each character regardless of what they are wearing.

    One caveat with the stitching method I'm using at the moment is that each equipment item is still a separate child gameobject once combined with the main character, which I believe results in a draw call for each piece as skinned mesh renderers aren't currently batched. If this eventually turns out to be a performance issue I'll look into actually combining the meshes, but at the moment it isn't a concern.
     
  23. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    Here's a few pictures showing how some of the characters look wearing different equipment. Appearance 1.png Appearance 2.png Appearance 3.png Appearance 4.png Appearance 6.png
     
  24. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    Here's a couple of screenshots from part of Shadow Boulder Ridge, the area of Emerald hills where the next major quest line will take place. I've only been working on this part for 3-4 days so it's still very early days.

    Shadow Boulder Ridge 1.png Shadow Boulder Ridge 2.png
     
  25. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    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/

    Please be aware that KoG is still very early on in development, consequently many of the intended features are incomplete or missing altogether and there isn't very much in the way of in-game tutorial at the moment (Basic instructions will be uploaded to the community hub in soon).

    However, there is still plenty to do, with 4 character classes to choose from and somewhere in the region of 200 quests and character content that will take you to around level 25. Also, most of the crafting and profession system is in place.

    This testing phase is primarily to test the networking performance and multiplayer interaction.

    At the moment the only input method is keyboard/mouse. Game controller support will be added at a later date.

    Hope you enjoy the test and please let us have your comments and suggestions and bug reports.
     
  26. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    Nestled in the foothills of the Greymist Mountains can be found Elendor, the capital city of Galanor.

    A bustling hub of trade and commerce, the city of Elendor is one of the most important places in Galanor and would be heroes will find they spend a lot of time there working, training and replenishing supplies.

    Still in development, here are some screenshots of its progress so far. All comments, criticisms and suggestions are welcome.

    Want to join the public play test? You can do so here for free https://store.steampowered.com/.../The_Kingdom_of_Galanor/

    Elendor 1.png

    Elendor 2.png

    Elendor 3.png
     
    guicamarotto likes this.
  27. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    It's been quite a while since I posted any progress updates for KoG, but I have been working on it a lot in the meantime.

    The Steam play test highlighted a number of areas that needed work, and I decided to redesign some of the core components of the game from the ground up to address the issues.

    That work is going well, and the end result will be worth the extra time and effort. I'll periodically post updates here as progress continues.

    As a side project, I'm considering releasing some of the editor tools I've made that have helped me with my workflow for KoG, you can check it out here. I'd be interested to find out if they sound like they might be useful.
     
  28. Enzo36t

    Enzo36t

    Joined:
    Aug 30, 2020
    Posts:
    63
    This looks very neat and for Android, that's amazing. :D
     
    Munchy2007 likes this.
  29. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    Thanks very much. But it isn't for Android it's a PC game :)