Search Unity

The Lockstep Framework

Discussion in 'Multiplayer' started by jpthek9, Apr 14, 2015.

  1. KHRZ

    KHRZ

    Joined:
    Mar 2, 2013
    Posts:
    56
    I used raycast for selection so far, but the lockstep framework has some selection system too. Input stuff used to generate a command doesn't require sync, just don't do like me and spawn/discard a building for the player choosing where to build and have the temporary building assigned a unique ID only for him...
     
    jpthek9 likes this.
  2. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    No problem; glad to answer your questions:
    1. Networking is abstracted away from the core framework so you can implement what you need with UNET, Forge, Photon, etc.. Personally, I use Forge and've implemented it in a separate repo: https://github.com/SnpM/ForgeNetworkHelper. You'll have to override GameManager.MainNetworkHelper to return an instance of the NetworkHelper you want to use.

    2. Exactly. Animations are client side. There are several events you can hook onto for certain Abilities that can be rigged up to your animation system.

    3. Selections are actually client side. They're sent through Commands which are synchronized for all players. I don't recommend extensively using Unity colliders, however, because they're expensive without Rigidbodies and RB's would add a lot of overhead for it not to be worth it. In LSF, there's a system set up in SelectionManager that handles the selection calculations.
     
    Velo222 and reese01 like this.
  3. Velo222

    Velo222

    Joined:
    Apr 29, 2012
    Posts:
    1,437
    Thank you. When I'm feeling ambitious enough, I'll give it a shot. :)
     
  4. Velo222

    Velo222

    Joined:
    Apr 29, 2012
    Posts:
    1,437
    Hey Jpthek,

    I downloaded the framework and when I first imported it into my project, I get this error: "The type or namespace name `GridSettings' could not be found. Are you missing a using directive or an assembly reference?".

    Is there a script or something I'm missing?
     
  5. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    GridSettings was something I was playing with very recently but it looks like it didn't get tracked. I just added it to the repo so the most recent version should be free from that error.

    By the way, there're lots of features that I haven't documented or demonstrated yet. If you're curious about any specific parts or functionality, shout it out and I'll try to explain it.

    Eventually, I plan to compile all the FAQ topics into one scene or a collection of scenes for easy reference.
     
  6. Velo222

    Velo222

    Joined:
    Apr 29, 2012
    Posts:
    1,437
    Sounds good. Thanks for that. I'm sure I'll have more questions as I dig into it. Mainly because I'm so new to both a lockstep framework as well as networking in general. I have so much to learn in those areas -- but I'm looking forward to the challenge.
     
    jpthek9 likes this.
  7. Velo222

    Velo222

    Joined:
    Apr 29, 2012
    Posts:
    1,437
    Hey jpthek,

    I have downloaded and "installed" the framework into my game directory. Now I'm playing your example scene, but I'm getting a few errors, so I was wondering if you could help me with them.

    The first one is:
    Code (CSharp):
    1. NullReferenceException: No LockstepFrameworkSettings detected. Make sure there is one in the root directory of a Resources folder
    2. Lockstep.LSFSettingsManager..cctor () (at Assets/Lockstep Framework/Settings/LSFSettingsManager.cs:29)
    I looked at that script, and it looks like it is trying to load "LSFSettings settings = Resources.Load<LSFSettings> (SETTINGS_NAME);". I tried placing the LSFSettings script in my Resources folder, but that didn't work. I think maybe it needs to be some sort of asset, but I'm not sure how to do that.

    I guess I'll leave you with just that first question, and see if I can resolve that, if it fixes some of the other errors I'm getting. They might all be linked.

    Also, is there a way to PM you? If you don't accept PM's that's okay, but I just wanted to check. I might have a lot of questions (at least initially) and I don't want to clutter up this forum thread with all of them. But I will if I have to ;)

    Thanks.
     
  8. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Yeah, make sure you press control - shift - L and load the example database at Lockstep-Framework/Example/ExampleDatabase.

    I'm checking my account settings... seeing if I can allow PMs.
     
  9. Velo222

    Velo222

    Joined:
    Apr 29, 2012
    Posts:
    1,437
    Interesting. I actually did that before you posted, and it didn't work. But then when I just tried it now, it did work. I guess I just had to exit and re-open Unity for some reason.

    Anyways, it works now. :)
     
    jpthek9 likes this.
  10. KHRZ

    KHRZ

    Joined:
    Mar 2, 2013
    Posts:
    56
    Having some problems with pathfinding corner cutting around square bodies. I tried doing a check in the astar part where it checks the 8 neighbor nodes and skip those unwalkable, and also skip diagonal nodes if one if neighbours between them are unwalkable, but it didn't seem to have an effect. Are units still cutting too close to corners? I currently have 2 grid node tile per square which may be an issue having them cut closer to the corner (it was supposed to help actually though, I was thinking of blocking an extra tile out of the building but this would close narrow paths between buildings completely off). I am thinking maybe of implementing a rounded rectangle body shape (2rectangles + 4 circles) but maybe it will just be glitchy. Just curious if you are using rectangle hitboxes and it works for your units to walk around them? Currently my unit's diameter is 70% of the tile width.

    Also I tried writing some temporary deactivation function for agents, seems the only one there was permanent. I need to deactivate them while entering buildings (or potentially just the body/visual if I want them to still shoot out of the building or something). However seems to be an error after I removed them afterwards with going out of partition bounds (deactivation doesn't work fine if you split it in 2 parts?) I was thinking instead of deactivating them I could just move them all somewhere out of the way, but there's also an issue I'm having with the interpolation between movement causing the agents to slide instead of instantly moving which I wouldn't want in this case... so yeah I am creating too much mess when I try to add features:/
     
  11. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    You can use LSBody.GetCoveredSnappedPositions (FixedMath.One, output) to get the ideal collection of nodes that the object covers. For best results, position buildings with odd diameters on whole positions i.e. (0,0) and even diameters on half positions i.e. (.5,.5). GetCoveredSnappedPositions rounds the boundaries up so the worst that can happen is blocking off a bit more space than necessary.

    Note that the pathfinding algorithm assumes if a node is unwalkable, a 1x1 square cannot be placed on the node without touching any obstacles.

    Regarding temporary deactivation of agents, that's what I was thinking too. Currently the deactivation system pools the unit and resets it upon next use. Temporary deactivation would be very useful though, for a lot of cases in addition to yours. It'd take significant refactoring but I'm definitely looking into it in the future.
     
  12. KHRZ

    KHRZ

    Joined:
    Mar 2, 2013
    Posts:
    56
    Just a heads up. Something I am considering implementing is flow fields, as seen here:
    https://howtorts.github.io/2014/01/30/Flow-Fields-LOS.html

    Now you don't need the flow field however for the units to make it around the corners, all you need is to make sure your center has passed the corner before deciding to turn (if another unit pushes you back though you must reset your walk progress). Still units may waste some time clinging against the wall, but it's much better than getting stuck. So unless it's performance heavy to check whether you are at a corner, it's an easy fix.
     
  13. Velo222

    Velo222

    Joined:
    Apr 29, 2012
    Posts:
    1,437
    And that flow field algorithm is deterministic KHRZ? With Jpthek's included pathfinding, how do I make an object an obstacle for units to avoid or go around (i.e. is there some script/component I put on the obstacle for units to avoid)?

    I was considering using Aron Granberg's A* pathfinding for my pathfinding (since I'm very familiar with it), and from what I understand it is essentially deterministic.....but I'm not sure and havn't tested it.

    Right now, I'm simply looking for a good pathfinder where I can place buildings and have units avoid them with relatively decent results -- but I have not seen what Jpthek's pathfinder can do yet.
     
  14. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Give the new Blocker script a shot. The mapping works well (always rounds up for half position boundaries) and I haven't had any corner cutting problems with it. It's an EnvironmentObject so make sure there's an EnvironmentHelper attached to the Manager and that the object EnvironmentHelper tracks has a DefaultEnvironmentSaver on it which'll save all EnvironmentObjects in the scene.

    BlockerTestScene shows the Blocker in action, as well as a few units to test the pathfinding with. A dynamic blocker is in the works; it'll function similarly to the environment Blocker but will update the grid mapping when the object moves.

    I'll look into flow field pathfinding. It might be just what LSF needs for intelligence, fluid agent movement. One problem I think that might arise from FFP is that every node needs to generate a direction and value for each active destination which might be a problem both performance and memory wise for an RTS games that requires making many new destinations. Still, the costs might compare well with the current costs of generating a path for every unit individually.
     
    Last edited: Dec 22, 2015
  15. KHRZ

    KHRZ

    Joined:
    Mar 2, 2013
    Posts:
    56
    That is is my thinking as well, while flow fields will be overkill for a single unit, the issue will be when 100+ units are commanded at the same time anyway. And an advantage is that the unit won't need a new path when it gets pushed out of their paths. I've been looking at StarCraft 2 pathfinding a lot (they use flow fields) and it seems they have their performance issues, for example on a big maze map units won't have their full path calculated for a long trip, they may end up in a local blind way, and when you command a unit to follow another, which is far away, it will not update to see that the unit has moved away before it arrives. There is probably some way the path finding is aborted if it is found to take too long (which must happen deterministically, so you would have to consider if the slowest PC would stutter with a long path finding time). My worry here is that SC II is written so efficiently that trying to be as capable as it won't work out well. There is always the option to let the unit start moving in the straight direction and then have it turned after a time for the flow field to be calculated, so most of the time it will just start to move in the correct direction right away.
     
  16. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    That last solution where units don't find the path right away is actually used. I've been thinking about making groups be able to use a single path, but still brainstorming about that.

    Regarding the comparison to SC2, I think LSF's pathfinding can hold its own. The algorithm takes only fractions of a second to complete so a couple hundreds pathing units won't be a big problem performance-wise.
     
  17. Superjayjay

    Superjayjay

    Joined:
    Mar 28, 2013
    Posts:
    69
    Just wanted to say this looks like something Unity is sorely lacking. I haven't played around with it yet, but this is looking super promising:)
     
    jpthek9 likes this.
  18. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Lots on the way :D

    I'm working on an FPS right now so LS is being expanded for games of that genre as well.
     
    Superjayjay likes this.
  19. KHRZ

    KHRZ

    Joined:
    Mar 2, 2013
    Posts:
    56
    Something I noticed in StarCraft 2. I think every single building with rectangle hitbox is 45 degrees off, which would fix the corner issue probably. It seems their units moves their radius distance away from the corners anyway but maybe it's part of the trick to avoid issues.
     
  20. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Oh yeah, that is interesting. I think for LS, the problem was solved for the most part by rounding up grid mapping.
     
  21. Superjayjay

    Superjayjay

    Joined:
    Mar 28, 2013
    Posts:
    69
    Awesome :D
     
    jpthek9 likes this.
  22. KHRZ

    KHRZ

    Joined:
    Mar 2, 2013
    Posts:
    56
    Reporting this since I'm having trouble locating my glitch. So I have some rocks with circle bodies (picture), when I remove my rocks their bodies dissapear, so the unit can walk where the rock was. However, sometimes (about 20% of the time), the circle hitbox of the rock is not gone, despite it not showing up in the gizmo drawing (unit in picture must walk around the circle). Since the glitch is irregular, it is hard track down, but seeing as no hitbox is drawn, maybe the error is that the hitbox is only stuck in the physics engine? (The rock does not have an LSAgent, only an LSBody, which I call Deactivate() on. )



    Edit: So it appears every rock hitbox is still there, but will collide with only one of the moving units. So there's some shenanigans going on with regards to unit IDs/collision pairs I think.
     
    Last edited: Jan 18, 2016
  23. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    That is strange. If the rock model is childed to an LSBody handler, are you deleting the root object? Sometimes in Unity, I click on the model and forget to navigate to the root object with the LSBody component.
     
  24. KHRZ

    KHRZ

    Joined:
    Mar 2, 2013
    Posts:
    56
    I've found the reproducible cause of the bug. So the hitbox works for all units that have not collided with it. If I let all my units collide with it before removing it, none will collide. But if some haven't collided with it, they will still collide after it is removed. It makes sense with GetCollisionPair, which will look for an existing pair, which will be deactivated, otherwise add a new pair. So apparently, units are still able to collide with the deactivated body. I am not using an LSBody handler, I am just attaching it myself to a gameobject. Is this a requirement?

    I haven't looked into the partitioning, but didn't see anything in body.deactivate that removes it from the partitioning system. This is where the body still works at least.
     
  25. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Yeah, LSBodies I have to be initialized and added to a list in PhysicsManager (in a deterministic order) to be simulated deterministically. Add EnvironmentSaverHelper to the same GameObject as the GameManager script and reference the object you want to store the scene's data in, in the "Saver" field of EnvironmentSaverHelper (it can be the same GO). On the saver object, add DefaultSaver then click "Scan And Save" on EnvironmentSaverHelper in the inspector which'll save all bodies' positions and rotations in the scene, as well as initialize them when the simulation starts.
     
  26. KHRZ

    KHRZ

    Joined:
    Mar 2, 2013
    Posts:
    56
    Maybe I wasn't clear here, as I discovered I did not have an issue with determinism (the 20% chance was that I had made the bodies collide before so their collision pair would be deactivated.) The issue I found is that while LSBodies are inserted to Partition in their initialization with Partition.PartitionObject(), they are not removed from Partition with their deactivate function/ PhysicsManager.Dessimilate. The only function that removes LSBodies from Partition is Partition.UpdateObject(), which is only run during earlySimulate, and places the bodies back in their current node. There didn't seem to be anything permanently removing the body from Partition, so I made a function that just removed the body on LSBody.deactivate, and my bug was solved.

    Edit: I see you added a Partition.RemoveNode later (I have a version from last month). Didn't see it being run in PhysicsManager.Dessimilate though.
     
    Last edited: Jan 25, 2016
  27. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Good catch! I added something in Deactivate with the recent update to remove the body from the partition in Deactivate.
     
  28. KHRZ

    KHRZ

    Joined:
    Mar 2, 2013
    Posts:
    56
    So we have gotten some funding for our game, not big money yet, but basically the support is so that we may impress some people that can give us bigger money, so potentially we can work full time (currently it's just me programming while doing a master degree)

    This would start earliest in the summer. So If we have some real effort, we would make many typical RTS features like upgrade system, fog of war, some enemy AI behavior (our AI will not build bases, just send units to attack). But will need attack move/patrol etc. So obviously since we are using Lockstep Framework we will try to fit it together with it (currently I only made features that operate "next to" Lockstep framework.) So maybe we can contribute some to have it included in Lockstep framework?

    So my question is, do you have any thoughts/recommendations/plans for more RTS features? For example, we have tried a bit of a buff system where you have a list of buffs, so potentially an upgrade system could just put upgrades as permanent buffs. But again a full upgrade/buff system should maybe be incorporated a bit into each ability (I saw the move ability have some modifiers you can set for example). I was wondering also did you read about making RTS games somewhere (book/webpage)?
     
    reese01 likes this.
  29. Avinash-pdy

    Avinash-pdy

    Joined:
    Mar 4, 2013
    Posts:
    28
    Hi,

    I previously tried DPhysics. Currently i pulled latest LockStepFramework. I opened Example Scene and setup the Database. When i run. Nothing happens. I just see two red blocks (TestAgents). I click on them nothing happens. I am starting to work on a Tower Defence game and was hoping to use LockStepFramework.What i need is a grid. There will be towers of two opponents on each side. They will spawn units which move towards other players tower. Can you please guide me to how i can setup a simple grid and units. I can see documentation will be coming after its core features are done. But if i get a head start i can figure it out. Thanks
     
    Last edited: Feb 29, 2016
  30. KHRZ

    KHRZ

    Joined:
    Mar 2, 2013
    Posts:
    56
    For me there have been little errors occurring around my project, although the example scene worked fine for me. I have the pathfinding working, I have not gotten going with the database though. Attach LSbodies/LSAgents/LSMove/LSTurn to you stuff and set up in the code:

    body = GetComponent<LSBody> ();
    body.Shape = ColliderType.AABox;
    body.Reset ();
    body.CanSetVisualPosition = true;

    body.HalfWidth = FixedMath.One;
    body.HalfHeight = FixedMath.One;
    body.Radius = FixedMath.One;
    body.Immovable = true;

    Note: many of these properties are private, I just switched them to public for now. Wouldn't be neccesary if you had the database working, but I have some errors with the database so I avoid it for now.

    To make pathfinding work, I had to set CanPathfind = true at the end of OnSetup in Move class (seems it should be true already, but for some reason isn't), and initialize GridManager:


    GridManager.Settings = new GridSettings(NodeCount,NodeCount,OffsetX,OffsetY,true);
    GridManager.Initialize ();
    Block node:
    GridManager.GetNode (i, j).Unwalkable = true; // I changed this to public for simplicity

    This is a quick fix at least. Probably I forgot some details also, whenever I had an error message from Lockstep I either fixed it or disabled the issue. So while it works I doubt you'll get it going in a few minutes (I have spent many hours total to understand it).
     
  31. KHRZ

    KHRZ

    Joined:
    Mar 2, 2013
    Posts:
    56
    Not to pile on too many questions. But LSAgent is the main class that all abilities rely on to attack etc. They are a bit heavy as long they include all their stuff (abilities/simulate function being run). So for our game with possibly 20000+ objects that are passive and should have minimal stuff on them, LSAgent may be a bit too much. I am guessing if it is disabled/placed in a list that is not iterated when simulating, it may be OK. After all "agent" implies it's supposed to do stuff on it's own. They may still have a body for hitbox, and needing to take damage, but without moving around. I know the indexing system for units in the list is based on ID, so having them not being iterated would take some change. One thing is that you won't select and command these passive things, so they don't need the same ID list when sending commands, they could have a separate ID range. This would support the additional objects without increasing index size. There are probably many RTS games with trees/cave rocks that could use it.

    Here's what happens in a couple of minutes when I have (I think 5-10k) LSAgents with immovable bodies: (Edit: After I fixed an issue, the problem is not as bad it seems).


    PS: In LSBody.Deactivate(), when calling Partition.UpdateObject, objects that hasn't moved, where PastGridX/YMin/Max == GridX/YMin/Max, are not removed from the partition so the body is still collided with.
     
    Last edited: Apr 4, 2016
  32. KHRZ

    KHRZ

    Joined:
    Mar 2, 2013
    Posts:
    56
    Hm jpthek's been missing from the topic for a while. Anyway, I thought I'd give an update on the game I'm working on. Still no big money, so it's going slowly for now. Lacking a bit on the game designer/programming/art side due to this, but our PR guys are hard at work, and you can read something about it here: http://www.dwarfheim.com/home
     
  33. DearTao

    DearTao

    Joined:
    Jan 11, 2013
    Posts:
    1
    I download this demo from github,but cant run,i use unity 5.3.5, i can open the scene ,but all componts refrence missing
     
  34. Zelfire

    Zelfire

    Joined:
    Aug 31, 2015
    Posts:
    3
    I honestly don't know what I would do without this framework, I was about to go learn about fixed point maths and stumbled upon this gem. I'm a total newby as I'm in a completely different field of work with just a passion for games, making my first game/program so it looks really complex to understand this framework. I've been studying the LSF for many days now and still not able to get a working path-finding agent, but I'm learning many new things in the process, like how events work etc. I can't thank jpthek enough for making this freely available after spending god know how many hours on it... and thank you KHRZ for your contribution.
     
  35. FuzzyShan

    FuzzyShan

    Joined:
    Jul 30, 2012
    Posts:
    182
    can you emulate all the PhysX configurable joints into this engine?
     
  36. Jos-Yule

    Jos-Yule

    Joined:
    Sep 17, 2012
    Posts:
    292
    @FuzzyShan i'm sure if you download the code and take a look you could if you worked at it enough.
     
  37. imgodot

    imgodot

    Joined:
    Nov 29, 2013
    Posts:
    212
    If lockstep is needed, you might take a look at Photon TrueSync.
    It is lockstep and it has it's own deterministic physics engines for 2D and 3D.
    I've only looked at the samples a little, but it may be useful to someone.
     
  38. Zelfire

    Zelfire

    Joined:
    Aug 31, 2015
    Posts:
    3
    Can someone correct me if I'm wrong. But in the GridManager script I think the GetGridIndex should read
    public static int GetGridIndex (int xGrid, int yGrid)
    {
    return (Width - xGrid - 1) * Height + (Height - yGrid-1);
    }
    instead of
    public static int GetGridIndex (int xGrid, int yGrid)
    {
    return xGrid * Height + yGrid;
    }
    Took me a long while to find out why the grid was all flipped when doing the playback. This caused the playback to go OOS. That line of code fixes it for me, got there by trial and error. Managed to get pathfinding to work just fine now, I mean with obstacles in the way. I'm trying to figure out how to add buildlings now.
     
  39. Zelfire

    Zelfire

    Joined:
    Aug 31, 2015
    Posts:
    3
    The only way to get 2000+ bodies with a decent frame rate (default yields 0.5 ish frame rate for me) is to really lower the simulations calls/sec which means they dont pathfind well at all or move in weird manners, basically resorting to one physics simulation frame every 1-3 seconds which is bad :(. Is there anyway to make this framework efficient for large numbers? I know KHRZ mentioned it in earlier posts but I've got no idea how to go about this atm.

    EDIT: Nevermind, engine is actually pretty efficient if you don't spawn all units on one spot, means less collision checks. Unit range plays a role too apparently. Getting around 60 fps with 1000 ish units.
     
    Last edited: Jan 24, 2017
  40. KHRZ

    KHRZ

    Joined:
    Mar 2, 2013
    Posts:
    56
    Quick update on my game: Still going slow. But for the physics performance: I plan to fix it for static objects (have 20000+ of them). Currently physics collision loops through all pairs in a partition. I plan to make a separate array for static hitboxes, so it only needs to iterate through moveable hitbox array against itself and the static hitbox array. Currently have 86% CPU usage from the PhysicsManager.
     
  41. KHRZ

    KHRZ

    Joined:
    Mar 2, 2013
    Posts:
    56
    Last update from me: So the game I've been working on has finally gotten some investments (~$250 000). The game is dwarfheim.com, a coop RTS game with 4v4 players, where each player on the team does a different role (building the base, mining a dungeon, leading the army, doing diplomacy/trade). It could be the biggest game using Lockstep Framework so far. (I wrote quite a bit of engine first though before Lockstep Framework was released, and sort of mashed them together).

    Personally though I have quit the project, as I want to focus more on artificial intelligence research. So we'll just have to wait and see what they'll be able to do.
     
  42. II_Spoon_II

    II_Spoon_II

    Joined:
    Jun 16, 2018
    Posts:
    180
    Is it beginner friendly? or needs some netwroking experience? @jpthek9
     
  43. KHRZ

    KHRZ

    Joined:
    Mar 2, 2013
    Posts:
    56
    I used the DarkRift plugin (had to write half myself), was pretty simple even when I had no network experience (except university course). All you write is how to respond to messages/command IDs and whatever you send for each frame, and I wrote a votekick menu that appears when a player lags too long (others should be forced to wait after some time of disconnect, or he is screwed by losing out on the game).

    Now bit of a lame update on the DwarfHeim RTS: The new guys they hired had the idea to go for an authorative server. (Instead of Lockstep Framework). I don't think their reasons were that great (wanting to use more of the Unity Editor and 3rd party libraries, some desync bug they were too lazy to fix), since you can still do that with Lockstep Framework, (most stuff like graphics/input handling doesn't need to be part of the deterministic sync).

    They plan release in December 2019... we'll see about that.