Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

uMMORPG Official Thread

Discussion in 'Assets and Asset Store' started by mischa2k, Dec 29, 2015.

  1. cioa00

    cioa00

    Joined:
    May 31, 2016
    Posts:
    203
    That error is if im not wrong a limitation from UNET side, at least at the moment.
     
  2. Folei

    Folei

    Joined:
    Mar 13, 2016
    Posts:
    4
    Yes, I am the same feeling. In order to avoid this limitation due to the number of attributes, I will create a list (on the same model that the item management functionnalities).
     
  3. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    What do you mean with Hack and Slash combat? What's missing?
    WASD movement will be in V1.24. I am still waiting for V1.23 to be accepted.

    Perhaps try and reach out to the UNET developers and let them know that this limit is too small. Perhaps you can find something about that on the UNET forums, maybe it was addressed by a developer already.

    Other than that, you can put your attributes into a separate script. Kinda ugly, but you don't really have another choice.
     
  4. MHolmstrom

    MHolmstrom

    Joined:
    Aug 16, 2012
    Posts:
    115
    I can't find the section that handles the attack state so I can add a random.range to the attacks, anyone?

    @vis2k The hack and slash combat is where you don't require a target while left mouse button is down you can attack without the conditions and uses some sort of collider detector to figgure you if you hit the triggerbox then apply damage and so on. Feels like it should be easy to add but I'm kinda lost in the code.
     
    CrandellWS likes this.
  5. joncrzo

    joncrzo

    Joined:
    Sep 26, 2015
    Posts:
    30
    Unfortunately that's still present.

    http://blogs.unity3d.com/2014/05/29/unet-syncvar/
     
  6. Folei

    Folei

    Joined:
    Mar 13, 2016
    Posts:
    4
    I had find a ulgy workaround. But I am quite surprised that nobody notice it and alert you about this point. With the current "standard code" of ummorpg, you can "only" add 3 new attributes. Whatever, with or without this limitation, it's still a nice asset ! :) Thanks for your support.
     
  7. JBR-games

    JBR-games

    Joined:
    Sep 26, 2012
    Posts:
    708
    I was wondering if anyone had an ideas how to make looting a bit different. I am a lazy looter. i do not want to have to click on each enemy for a loot window and then have to click on each item to get it. So i think adding a (loot all) button is easy enough to do but what i really want is all the loot to just be added to a general loot panel that i do not have to check every kill. So i could check my loot after killing say 5 monsters.
     
  8. JBR-games

    JBR-games

    Joined:
    Sep 26, 2012
    Posts:
    708
    Its been a known issue unfortunately

    So here is how i did a work around that gives the defense & Attack 3 seperate Attack types (melee , ranged , magic) . Please Note that this is a work in progress and that it still may have some bugs. Redo Defense & Damage > player.cs

    Code (CSharp):
    1.  
    2. [Header("Defense")]
    3.     [SyncVar, SerializeField] int baseDefense = 1;
    4.     private int equipBonus;
    5.     private int buffBonus;
    6.     //0  is melee
    7.     //1  is ranged
    8.     //2  is magic
    9.     public override int defense {
    10.         get {
    11.             var entity = this.gameObject.GetComponent<Entity>();
    12.             if (entity.defenceTypes == 0)
    13.             {
    14.                 baseDefense = strength + stamina;
    15.                 // calculate equipment bonus
    16.                  equipBonus = (from item in equipment
    17.                                   where item.valid
    18.                                   select item.equipDefenseBonus).Sum();
    19.  
    20.                 // calculate buff bonus
    21.                  buffBonus = (from skill in skills
    22.                                  where skill.BuffTimeRemaining() > 0
    23.                                  select skill.buffsDefense).Sum();
    24.  
    25.                 // return base + equip + buffs
    26.                 Debug.Log("Defence calculated at " + baseDefense);
    27.    
    28.             }
    29.            if (entity.defenceTypes == 1)
    30.                 {
    31.                 baseDefense = stealth + agility;
    32.                 // calculate equipment bonus
    33.                 equipBonus = (from item in equipment
    34.                                       where item.valid
    35.                                       select item.equipDefenseBonus).Sum();
    36.  
    37.                     // calculate buff bonus
    38.                      buffBonus = (from skill in skills
    39.                                      where skill.BuffTimeRemaining() > 0
    40.                                      select skill.buffsDefense).Sum();
    41.  
    42.                     // return base + equip + buffs
    43.                     Debug.Log("Defence calculated at " + baseDefense);
    44.  
    45.                 }
    46.              if (entity.defenceTypes == 2)
    47.                 {
    48.                 baseDefense = mind + intelligence;
    49.                 // calculate equipment bonus
    50.                 equipBonus = (from item in equipment
    51.                                       where item.valid
    52.                                       select item.equipDefenseBonus).Sum();
    53.  
    54.                     // calculate buff bonus
    55.                      buffBonus = (from skill in skills
    56.                                      where skill.BuffTimeRemaining() > 0
    57.                                      select skill.buffsDefense).Sum();
    58.  
    59.                     // return base + equip + buffs
    60.                     Debug.Log("Defence calculated at " + baseDefense);
    61.                 }
    62.          
    63.             return baseDefense + equipBonus + buffBonus;
    64.         }
    65.      
    66.     }
    67.  
    new attributes
    Code (CSharp):
    1.   [Header("Attributes")]
    2.     [SyncVar,SerializeField] public int strength = 0;
    3.     [SerializeField] public int intelligence = 0;
    4. //added new  player stats***********************************************************************************************
    5.     [SyncVar,SerializeField] public int mind = 0;
    6.     [SyncVar,SerializeField] public int stamina = 0;
    7.     [SyncVar,SerializeField] public int agility = 0;
    8.     [SyncVar,SerializeField] public int stealth = 0;
    9. //**************************************************************************************************************************
    10.  
    in Entity.cs added
    Code (CSharp):
    1. //added*****Defence Types******Attack types*******************************************************************
    2. //0  is melee
    3. //1  is ranged
    4. //2  is magic
    5.     public int defenceTypes;
    6.     public int attackTypes;
    7. //***********************************************************************************************************
    this required an extra variable to be sent when damage is done to all scripts that send the dealDamageAt()
    modify Entity.cs as shown
    Code (CSharp):
    1.   // deal damage at another entity
    2.     // (can be overwritten for players etc. that need custom functionality)
    3.     [Server]
    4.     public virtual void DealDamageAt(Entity entity, int n, int type) {
    5.         // subtract defense (but leave at least 1 damage, otherwise it may be
    6.         // frustrating for weaker players)
    7.         // [dont deal any damage if invincible]
    8.         entity.defenceTypes = type;
    when attacking ....
    Code (CSharp):
    1.                     var attacktype = skill.skillAttackType;
    2.                     var entity = this.gameObject.GetComponent<Entity>();
    3.                     entity.attackTypes = attacktype;
    4.   DealDamageAt(target, damage + skill.damage, attacktype);
    Now you would modify the damage section of player.cs and similar to how Defense was already done, so that you would have different attack powers depending on attack type used. This will require a fair amount of reworking misc scripts including adding attacktypes to skills and items.
     
    Last edited: Jun 12, 2016
  9. danielnetzer

    danielnetzer

    Joined:
    Jan 5, 2016
    Posts:
    29
    I'd say what you realy need to implement is a Options UI which is where you can set game options such as graphics, key binds (I -> Inventory as default for example and the option to change it) and game Option such as Auto Loot, keep in mind it will add lots of complexity to the game if done badly.

    to actually implement auto loot you just need to add the loot to your char inventory when the monster dies instead of spawning it inside a Monster Loot Panel, then again it'll require checks to such as Inventory not full and similar stuff.
     
  10. JBR-games

    JBR-games

    Joined:
    Sep 26, 2012
    Posts:
    708
    What actually spawns the loot panel? i see in the monster.cs where it sets the loot. But i dont know what actually sets loot in popup and sets it active. Im guessing its in UIrefresh.cs. i think my issues is i dont understand synclists very well.

    So i do not want loot straight to my inventory but rather a loot panel that accumulates loot on every kill and then allows me to loot when i feel like it... Lol any ideas on doing that?

    Edit.. Ok it was late when i was kicking this idea around. After reading throught the code again its not that complicated.... The popup window doesnt hold the values but just displays the loot on the monster. So would it be possible to simply move the lootitems sync list to an empty gameobject and just keep adding items from the monster as it dies to this object ?
     
    Last edited: Jun 12, 2016
  11. danielnetzer

    danielnetzer

    Joined:
    Jan 5, 2016
    Posts:
    29
    no reason to instantiate more game objects as this will consume space and time, keep it simple in the code itself. but again I don't understand what you're trying to achieve, are you talking about a Stackable loot panel? so if you kill a large group of monsters for example it will show all loot from all those monsters?
     
  12. JBR-games

    JBR-games

    Joined:
    Sep 26, 2012
    Posts:
    708
    yes
     
  13. danielnetzer

    danielnetzer

    Joined:
    Jan 5, 2016
    Posts:
    29
    well you need to add some sort of a script to the Player Observer Area that will detect all dropped loot objects(UI objects) and put them all in one Ui loot panel. good luck ;)
     
  14. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Entity.DealDamageAt (and Player.DealDamageAt).

    It's a UNET limitation, I can't do anything to remove that. We have to notify the UNET developers about this, so that we can add more SyncVars to our scripts.

    I usually avoid doing that, because we already get that for free when starting Unity builds with the settings launcher. Also it's one of those simple things that everyone can add one their own with some coffee and a few hours of time. As you said, it will make uMMORPG more complex for everyone, without really solving any MMORPG specific problems.
    Please don't be discourage when I decline so many features, but as I said before: what I don't put into uMMORPG is as important as what I do put into it.

    The loot panel is shown in the Player.SelectionHandling function when the player clicks a monster that has loot.

    About your loot idea: should be doable by modifying the UIRefresh script to show loot from all observers (see NetworkBehaviour documentation).
     
  15. danielnetzer

    danielnetzer

    Joined:
    Jan 5, 2016
    Posts:
    29
    oh its more then ok, I dont expect you to implement a fully ready for market product, its a basic great asset that we can learn a lot, I'm waiting for the 1.23V with the AoE to come out and then ill purchase it and work from there. most of the things i'm saying is just ideas for other people how to implement stuff, not a wishlist.
    the only thing on my wishlist regarding this amazing asset is a Party system of some sort even even the most basic, something we can try and upgrade from there.
     
    mischa2k likes this.
  16. JBR-games

    JBR-games

    Joined:
    Sep 26, 2012
    Posts:
    708
    I agree keeping it simple makes the system much easier to understand and then customize as we see fit and for the most part i feel it is pretty easy to add custom elements.

    That being said, simple CAN NOT justify losing key features that all mmorpg's should have, party system im looking at you ;) no pressure... Lol

    Thanks for the info on loot panel. I need to do some research on network behavior...

    Also would it be possible to have all attributes as an array or SyncList since we are so limited with syncvars?
    like
    Code (CSharp):
    1.   public SyncListInt main_Attributes = new SyncListInt();
    Thanks
     
    Last edited: Jun 13, 2016
  17. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    It would be possible as a workaround until that SyncVar limit is increased. It would break things for everyone else though, so yet again the best solution is probably to just wait for UNET to resolve the issue again.
     
  18. jagatai33

    jagatai33

    Joined:
    Feb 2, 2016
    Posts:
    165
    Agreed, for starters im using the player sending the invite as the party leader after a quick check to make sure player initiator and target are not already in a party, in UIRefresh i make a quick check to see if the party group count is over 0 if so then from my SyncListStruct i pull the entity with getcomponent for which i use HPPercent() to update each player HP bar during that check i make sure with proxchecker that isHidden() is false otherwise grey out players bar to show they are out of range.

    My problem is my struct (the bug you mentioned) even though i called it BuggyParty.cs it still not syncing correctly with players, ill put up my code once i get it all in place and cleaned up.
     
  19. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    You have to try all kinds of names. Some work, some don't. The 'Buggy' prefix was just a coincidence.
     
  20. danielnetzer

    danielnetzer

    Joined:
    Jan 5, 2016
    Posts:
    29
    well seems like V1.23 is on the asset store, I was wondering if its possible to add some sort of an AoE skill to the WEbGL so we can see it in action?
     
  21. jagatai33

    jagatai33

    Joined:
    Feb 2, 2016
    Posts:
    165
    Use the Warriors Strong Hit
     
  22. danielnetzer

    danielnetzer

    Joined:
    Jan 5, 2016
    Posts:
    29
    I dont have this asset yet, I was waiting for this release. can you use the warrior class on the WebGL Demo?

    Edit: no you cant, but I trust you if you say its working properly.
     
    Last edited: Jun 13, 2016
  23. jagatai33

    jagatai33

    Joined:
    Feb 2, 2016
    Posts:
    165
    @vis2k

    quick question (im having one of those days!)

    Where does the client load the scene?, i was looking in NetworkManager OnClientConnect is that where i can use SceneManager to load the scene before ClientScene.Ready() is called?

    thanks,
    -J
     
  24. joncrzo

    joncrzo

    Joined:
    Sep 26, 2015
    Posts:
    30
    I don't think it is working properly, whenever I have a group of skeletons attacking me and I use the strong hit, it damages the skeleton I have selected and attacking, but the others around me do not get any damage.

    Unless I am missing something.. I see no aoe effects either.

    I do love that after looting the monster, the loot window doesnt open anymore.. love it!
     
    Last edited: Jun 13, 2016
  25. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Update: V1.23 is now on the Asset Store! Changes can be seen in the first post.
    Can do that tomorrow if you still need it (it's midnight here).

    There is only the world scene. And it's the default scene, so no scene is actually loaded anywhere.

    What's the aoeRadius on your Strong Hit skill (see ScriptableObjects folder). Also did you try to set it higher? And did you try a fresh project?
     
  26. cioa00

    cioa00

    Joined:
    May 31, 2016
    Posts:
    203
    As far i`ve noticed there isin't any effect because you need to replace animation with your own animation for that case. And AoE is working as after i gathered skeletons around my character and when i attacked them with strong hit skill i saw floating numbers over thier heads. You might want to try increase aoe radius from 7 to 10.

     
    Last edited: Jun 14, 2016
    mischa2k likes this.
  27. joncrzo

    joncrzo

    Joined:
    Sep 26, 2015
    Posts:
    30
    I see the floating numbers, but have you clicked them? Their health bars are full.
     
  28. cioa00

    cioa00

    Joined:
    May 31, 2016
    Posts:
    203
    I haven't check that, but i saw that enemies died after 3rd-5th attack. I`ll check that whenever i get the chance, but i guess someone else could try check that in meantime their self. Just attack once and click enemies to see if their hp has been lowered.

    Update: I managed to check that now and after aoe skill attack i`ve checked mobs hp bar and it was lower, so it`s working.
     
    Last edited: Jun 14, 2016
  29. danielnetzer

    danielnetzer

    Joined:
    Jan 5, 2016
    Posts:
    29
    another question I have regarding this asset is how compatible it is with the Gaia asset, since the player is using the Mesh to navigate and the Gaia is generating Terrain with colliders, how will it work?
     
  30. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    uMMORPG uses Unity's Navigation system. So anything that you can bake a Navmesh for will do.
     
  31. danielnetzer

    danielnetzer

    Joined:
    Jan 5, 2016
    Posts:
    29
    ok, got a response from Gaia creator, shouldent be any problem to bake Navemesh on top of the terrain. this should simplify things very much to create 1 giant open world game with uMMORPG without the need to create further scenes (besides the offline login/registration scene obviously). keep up the good work, going to purchase uMMORPG right away, btw on Gaia 2.0 there will be an option to create those terrains on the fly so it will save tons of CPU even though that the uNET system only shows objects that in the player proximity checker, maybe to randomize dungeon and instances.
     
  32. jagatai33

    jagatai33

    Joined:
    Feb 2, 2016
    Posts:
    165
    i use Gaia and it works great!, havent had any issues. Just keep in mind depending on the processing power of your development box some of those large scenes you make with Gaia can take 1+ hrs to bake with navmesh (but that has nothing to do with uMMORPG).
     
  33. cioa00

    cioa00

    Joined:
    May 31, 2016
    Posts:
    203
    Even build-in terrain with a lot stuff took few hours. Sadly unity crashed after 6h baking process was done.
    I haven't tried Gaia yet, but i might try that out too. Thank you guys for pointing out that it`s working fine.
     
  34. danielnetzer

    danielnetzer

    Joined:
    Jan 5, 2016
    Posts:
    29
    well just purchased both uMMORPG and Gaia, will write a review on them after a few hours of use.
    going to noobtuts.com asap to read the beginner guides all over again.
    fits me to buy this at the busiest time of the year for me (2nd year exams for my Bsc on computer science).

    EDIT : after an hour playing a bit on the current v1.23 release, I have to say it looks pretty good with some small glitches, when I move around with the player in an open space it runs super smooth, once I enter the starting area with the skeletons and the trees everything seem to be a bit glitchy and theres some sort of a delay for example when I click on the floor to move to Pos x, and the char moves only after 1 second or so. I was running the unity Editor as the "Dedicated Server" and the .exe as the player.
     
    Last edited: Jun 14, 2016
  35. jagatai33

    jagatai33

    Joined:
    Feb 2, 2016
    Posts:
    165
    yeah, its the rendering of those tree's especially on lower end gfx cards :(

    ** not related to uMMORPG, its just Unity rendering. remove the tree's, also something to note the tree's Gaia uses are rendering friendly.
     
    Last edited: Jun 14, 2016
  36. danielnetzer

    danielnetzer

    Joined:
    Jan 5, 2016
    Posts:
    29
    just about to make my way through a simple Gaia terrain and then add uMMORPG on top of it, I noticed that when I run it as adviced in the documentation in noobtuts.com its working fine, so i'm assuming the dedicated server option is explicit for linux headless server and thats why its causing problem, jagatai have you ever tried to test the limits of uMMORPG as in connected clients and AI's?
     
  37. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    As jagatai mentioned, try disabling the trees or set graphics settings to something lower. I simply didn't buy any 3D model trees yet, hence why I used Unity's speedtree, which slows things down a lot.
     
  38. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Progress Info: V1.24 was submitted for review. Changes can be seen in the first post (WSAD movement etc.).
     
    JBR-games likes this.
  39. jagatai33

    jagatai33

    Joined:
    Feb 2, 2016
    Posts:
    165
    YAY! thank you vis2k
     
  40. jagatai33

    jagatai33

    Joined:
    Feb 2, 2016
    Posts:
    165
    I purposely use an old junky Duo Core on Ubuntu 14.x and with roughly 400+ AI's and between family and friends managed to get about 16 clients connected, all in all with server CPU at 112% the game ran smoothly everyone was able to kill the AI's and kill each other (LOL have to love PvP). vis2k has also made some nice optimizations server side so unnecessary updates do not occur on AI's that have no observers (i.e. no players around) which if i remember right gained a notable % in CPU performance.

    uMMORPG is built on UNET which is still in "strong" development and vis2k can correct me if im wrong but in the later phases of UNET the platform will be able to easily scale, from one of the Unity developer conference videos i believe they mentioned on a UNET rely server 10k CCU was achievable!

    All in all and without sounding like a fanboy, i personally like how uMMORPG is being developed (i have tried just about every platform out there from RealmCrafter, Esenthel, MMO Kit, Torque MMO Kit and almost every notable asset on Unity including Atavism and uMMORPG continues to remain my goto!). The C# code is very clean well documented and relatively easy to follow. The hardest core components for MMO's are all native to Unity3d + UNET which removes having to handle things like Synchronization, Movement, Pathing and Rendering not to mention multi-platform, dont mistaken me like "any" project some programming knowledge is required, but the fact that its all native Unity3d C# simplifies a lot of the mundane tasks and features which otherwise would have to be coded from scratch.

    Hope that helps.
    -J
     
  41. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    A few words about F#:
    First of all, if the day comes then I'll probably offer a C# and a F# version of uMMORPG, so no one has to be scared.

    I can hardly describe how incredible it would be to have uMMORPG available in a functional programming language. The impact would be comparable to the switch from the old networking to UNET, if not more. This is a huge feature that would make our lives significantly easier. Think about having only 2000 lines of elegant, easy to maintain code. We have to do everything that we can to keep our MMORPG project simple, so that a single programmer can handle it all. This is why we need F# so desperately.

    To get people excited, here are a few links about how people started to use functional programming languages to solve hard problems:
    Paul Graham - Beating the Averages
    John Carmack at Quakecon, talking about Functional Programming

    You can vote on F# support for Unity here: https://feedback.unity3d.com/suggestions/f-support

    I built a F# Editor plugin called "F# kit" for myself to learn more about the language and translate a few uMMORPG scripts to F#. The plugin automatically finds and compiles all F# scripts in your project directory and you can put them onto GameObjects as usual. The good news is that I submitted it to the Asset Store, so it will be available for everyone very soon!

    Here are some examples from Utils.cs translated to F#. Note that there isn't even any functional programming in it just yet, it's merely the more elegant syntax that can be seen here:
    aaaaaaaaaaaa.png

    Here are a few unrelated syntax examples that show the beauty of F#:
    Screenshot at Jun 14 22-08-09.png
    Note how simple it is to create lists and arrays.

    I am glad that you enjoy uMMORPG, thanks!
     
    Last edited: Jun 15, 2016
    tequyla and dhogan like this.
  42. danielnetzer

    danielnetzer

    Joined:
    Jan 5, 2016
    Posts:
    29
    hey Vis2k, I noticed the depcrecated method of Application.loadedScene...
    is this - SceneManager.GetActiveScene().ToString(); the right way to fix it?
     
  43. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    I use SceneManager.GetActiveScene().name in V1.24.
     
  44. danielnetzer

    danielnetzer

    Joined:
    Jan 5, 2016
    Posts:
    29
    thanks, changed that.
     
  45. JBR-games

    JBR-games

    Joined:
    Sep 26, 2012
    Posts:
    708
    When the players state goes to "Casting" . Where in code does the animation for the current skill get called?
     
  46. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    LateUpdate passes parameters to Mecanim. The animation controller (state machine) does the rest.
     
  47. JBR-games

    JBR-games

    Joined:
    Sep 26, 2012
    Posts:
    708
    Thanks. So i noticed that the attack animation gets called at nearly the same time as the damage is calculated. So if the attack animation is long the skeletons might fall over dead before the main attack blow has even happened. Have you looked into this much ? A temporary work around i did was to use a corutine to delay the damage function some predetermined amount of time . But im sure @vis2k Or others might have a better idea. Ideally im thinking something that looks at the animation clip to be played length. And sets a delay so damage is always done at/near the end of the clip, maybe? Thought i read somewhere you could check the current clip completion?

    Code (CSharp):
    1. yield return new WaitForSeconds(anim.clip.length);
     
    Last edited: Jun 15, 2016
  48. danielnetzer

    danielnetzer

    Joined:
    Jan 5, 2016
    Posts:
    29
    you can just play with the mecanim animator instead of using a coroutine/yield. (i'm pretty sure this small hack is pricey)
     
  49. JBR-games

    JBR-games

    Joined:
    Sep 26, 2012
    Posts:
    708
    Ahh.. So im guessing delay the death animation..??? Still have the issue of getting timing correct vs. Which animation is played. Since they are 2 different Animators.(attacking animation vs. Dieing/taking hit animation).
    Maybe one could make all animations take the same amount of time to fix this.
    Has anybody else address this issue yet ?
     
  50. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Did you modify anything? By default it works like this:
    - player starts casting the skill, in the same time the animation begins
    - player casts the skill for exactly the animation time
    - player deals damage, animation finishes at the same time

    I just tried it again, and it still works like that. Perhaps you interpreted the damage popup from your first attack as the damage popup for your second attack? Because the second attack starts around the time that the first damage popup is shown.