Search Unity

[RELEASED] Turn Based Strategy Framework

Discussion in 'Assets and Asset Store' started by michal-zetkowski, Jul 2, 2019.

  1. dbugger

    dbugger

    Joined:
    Jan 10, 2013
    Posts:
    55
    I don't think that you would need to close it. I also have some packages in the asset store, and I maintain both a Unity thread and a Discord server. Usually the threads are very useful for small questions that need not a lot of discussion, but when there is a lot of back-and-forth, Discord is MUCH MUCH better. I would definitely recommend you opening a server. It will help you also create a closer bond with your audience. If you wish some help, feel free to personally contact me and we could discuss it a little more inside my own server.

    Thanks, for the answer about auto-selecting. I will take a look at it.
     
    Last edited: Jan 29, 2022
    michal-zetkowski likes this.
  2. dbugger

    dbugger

    Joined:
    Jan 10, 2013
    Posts:
    55
    Another question:

    I am trying to create a system like FF tactics, where a menu comes up, when the turn of a character comes.



    I am having trouble doing it with the current Ability system that is implemented. With this method, the abilities seem to be running all at the same time concurrently (attack, move, magic, etc...). But i need that each ability activates only after the proper action has been called. Now I have made a "ActionMenuAbility" to show up the menu, but I have no idea how can I do to activate each ability, corresponding to the action selected.

    Any suggestion?
     
  3. Liberation85

    Liberation85

    Joined:
    Apr 16, 2019
    Posts:
    65
    A discord would be sound.

    You could build a small community of budding indie devs, all of which would share info, tips and tricks, and feedback with one another

    But keep the thread, just make sure the discord link is posted up.
     
    michal-zetkowski and dbugger like this.
  4. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Sorry for the delay. Actually, I think I've got just what you need. The idea is to have an ability that lets you select other abilities. The ability will take a list of abilities as a parameter and create a button for activating each ability when the unit is selected. You can check it out in SpellcastingAbility in Example5. I also attach a more generic implementation. Let me know what you think about this solution, I'll be interested to hear your opinion.

    Regarding Discord, I think I'll set it up since people seem to like the idea :)
     

    Attached Files:

  5. dbugger

    dbugger

    Joined:
    Jan 10, 2013
    Posts:
    55
    Well, sadly I had to do a lot of UGLY things, to get my code working. Duplicating many files that you already had, because of one very unfortunate detail. In the class Unit, GetAvailableDestinations is NOT virtual. This is unfortunate because in my game, the cost of moving to a cell is not only measured by the "movement cost" of that tile, but other factors as well. I had to build a custom GetAdvancedAvailableDestinations inside my CustomUnit, which in turn took me to remake MovementAbility. Really a tragedy! I recommend making GetAvailableDestinations virtual immediately!

    The other HUGE problem was this, inside Unit.cs

    Code (CSharp):
    1.  
    2. public event EventHandler<MovementEventArgs> UnitMoved;
    3.  
    4. public virtual void Move(Cell destinationCell, List<Cell> path)
    5. {
    6.    // ...
    7.     UnitMoved?.Invoke(this, new MovementEventArgs(Cell, destinationCell, path, this));
    8. }
    9.  
    This method is virtual, so it can be overriden. But UnitMoved is an event, which means that even if I override "Move", I will not be able to call "UnitMoved?.Invoke", since events are only allowed to be invoked in the class where they were declared. Which forced me to modify Unit.cs and I dont have to explain why this is dangerous, right? I do not "own" that file, it belongs to the package, and if I make an update, the code will break. I was forced to add this:

    Code (CSharp):
    1. protected void InvokeUnitMoved(MovementEventArgs args) => UnitMoved?.Invoke(this, args);
     
  6. pzolla

    pzolla

    Joined:
    Apr 21, 2020
    Posts:
    19
    I second this request. I have yet to delve into the new update, but I ran into this prior. Any ability to allow for modifications that won't be overwritten by an update would be great.
     
  7. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    @dbugger @pzolla, take a look at Unit.GetGraphEdges, you might find it useful and it is virtual.

    @dbugger, you are right that it doesn't make sense that Move is virtual and base implementation invokes an event
     
  8. dbugger

    dbugger

    Joined:
    Jan 10, 2013
    Posts:
    55
    It is not enough. Because you are still doing this in GetAvailableDestinations.

    upload_2022-1-24_21-48-32.png

    Which means that you are still assuming the cost of the move is base on the sum of the value of the tiles. This is not necessarily so.
     
  9. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    @dbugger Right... Seems to me like I could fix it by using cost calculated in GetGraphEdges instead of cell.MovementCost.
     
  10. dbugger

    dbugger

    Joined:
    Jan 10, 2013
    Posts:
    55
    You are still assuming that there are no external factors that might change the pathCost. Imagine if someone wants to make it slower to move through tiles, that are adjacent to other units. This is just an example.

    You should not complicate yourself more than necessary, and make the method virtual. Then each developer can handle the issue by themselves.
     
    michal-zetkowski likes this.
  11. DavidBaughan

    DavidBaughan

    Joined:
    Apr 24, 2021
    Posts:
    5
    So i picked this system up recently and have spent a bit over a week trying to get to grips with it.

    I have just solved a very basic error that has been driving me mad for days now. No matter what i did the game was crashing whenever i tried to click on a unit. I just realised that the reason why was that I had added the units to the scene directly instead of using the unit painter.

    From a new user point of view i think it would be very helpful to have a note in the documentation saying that the unit painter needs to be used to prevent errors. I was pulling my hair out trying everything i could think of to see what was different between my scene and the example ones.
     
  12. dbugger

    dbugger

    Joined:
    Jan 10, 2013
    Posts:
    55
    I would be interested in finding out what exactly is the difference between the units added with the painter, as opposed to those added manually.
     
  13. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Sorry to hear that :(. Unit Painter sets a reference to a cell that the unit is occupying. The reference is required for pathfinding, determining if unit can be attacked etc. If you add the unit manually, the reference will be null.

    Let me know if you have other issues.
     
  14. dbugger

    dbugger

    Joined:
    Jan 10, 2013
    Posts:
    55
    I noticed that the CellGrid auto-starts the game by itself.

    upload_2022-1-29_15-0-9.png

    I would like the game to start manually (for instance, pressing a button). I thought of having the CellGrid disabled, to avoid this method running automatically, but I also wanted "Initialize" to run before that. These 2 calls seem to be bound programmatically, and I cannot call initialize manually, since it is private.

    Any recommendation on how to do this?
     

    Attached Files:

  15. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Hmm, I don't see a solution to do it without modifying the existing code. Gonna have to rework Start / Initialize / StartGame methods. Again, the problem is a combination of events / private / non-virtual methods.

    The most obvious dirty solution that comes to mind is to change Start method name to something else so it is not called by Unity, Invoke it by clicking a button And add another method for your initialization.
     
  16. dbugger

    dbugger

    Joined:
    Jan 10, 2013
    Posts:
    55
    My recommendation:
    - Wrap the events with function/properties/Unityevents, and make them protected
    - Extract the code in "Start" to its own method, and set it as protected
    - Add booleans "Initialize on Start" and "Begin game on Start" that check if you should run "Initialize" and "StartGame".

    Doing this, you should avoid breaking the existing APIs
     
    michal-zetkowski likes this.
  17. ThePortOfRiches

    ThePortOfRiches

    Joined:
    May 25, 2013
    Posts:
    4
    Has anyone figured out a solution to animating the pawn/character? I wanted to include animations for idle, movement, death and attack on my 3D characters. I already have the characters and animations I need; and can figure out the class types from the examples.

    I'm just new to scripting this all together.

    I purchased TBSF back in 2018 and just now dusted it off to see what I can do with it for my own personal game.
     
  18. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Hey, you can trigger the animations in Unit.UnMark (idle animation), Unit.MarkAsDestroyed and Unit.MarkAsAttacking. There is no dedicated method for triggering move animation. You can trigger it instead in overriden Unit.Move method (don't forget to call the base method) and turn it off in OnMoveFinished.
     
    ThePortOfRiches likes this.
  19. ThePortOfRiches

    ThePortOfRiches

    Joined:
    May 25, 2013
    Posts:
    4
    Quick response time, thanks. I'll see what I can do.
     
    michal-zetkowski likes this.
  20. ThePortOfRiches

    ThePortOfRiches

    Joined:
    May 25, 2013
    Posts:
    4
    Quick question: Do I setup my own script, or modify an existing unit script?
     
  21. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    You should create your own script that will inherit from Unit class. In the script you override appropriate methods :) Let me know how it goes. Also, there is a chapter about customizing unit methods in the documentation, you might find it useful.
     
    ThePortOfRiches likes this.
  22. Deleted User

    Deleted User

    Guest

    Thanks for the great job!
    Sorry for my poor English!
    I had worked on this framework for couple of days. But still cannot make my code works. What I want is something like FE or



    1. Select some unit and show the movable area.
    2. Click somewhere to move or click the unit again.
    3. Show the ability menu.
    4. Click attack/finish/skill/item button.
    5. Finish the chosen action.

    I had read the code in AbilitySelection.txt but it's a little different with my game.
    The point which I think is the most important is HOW TO run the abilities one by one, instead of calling them by the same time through Display method.
    By the way, it seems that FE is a very famous game, why TBS did not implement the operation style like FE?
     
  23. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Hey, thanks, I'm happy to hear that you find it useful :) Your english is totally understandable, don't worry about it.

    Take a look at Example5. In the scene there is a hero unit that can cast spells. When you click on the hero during gameplay, a spellbook appears. The spellbook is basically a skill menu, and individual spells are separate abilities.

    The idea is simple:
    1. Have an ability that lets you select different abilities.
    2. In Display method show some kind of menu and assign different abilities to different buttons
    3. Technically speaking, to select an ability use the following code:
    Code (CSharp):
    1. cellGrid.CellGridState = new CellGridStateAbilitySelected(cellGrid, UnitReference, selectedAbility);
    Let me know if you have more questions
     
  24. Deleted User

    Deleted User

    Guest

    Thanks very much for your reply!

    I will read the code in Example5 again later. Your advices are very useful. But I got some more questions today.

    I want to show the menu AFTER I moved some unit or click it twice, but I don't understand the code in CellGridStateAbilitySelected::OnStateEnter. I think the unit will be in state of selected when I clicked but it automatically transform to UnitStateNormal, is it right? If so, how can I know when the unit had been selected and ready for the second click.

    I also modified the code about the movable area, implemented some features like the game I mentioned in the earlier post. When the turn ended, the cells which near an enemy will set a boolean value named EnemyNearby to true. Then the MovementCost in the cells will increment by 1.

    It's working in my game, hopes it's useful for others too. Thanks for the clearly and useful code, it's very easy to understand.

    Code (CSharp):
    1.  
    2. CellGrid.cs
    3. private void SetMovementCosts()
    4.         {
    5.             SetCellsCost(Units, false);
    6.             SetCellsCost(GetEnemyUnits(CurrentPlayer), true);
    7.         }
    8.         private void SetCellsCost(List<Unit> units, bool flag)
    9.         {
    10.             foreach (var unit in units)
    11.             {
    12.                 var cells = unit.Cell.GetNeighbours(Cells);
    13.                 foreach (var cell in cells)
    14.                 {
    15.                     cell.NearEnemy = flag;
    16.                 }
    17.             }
    18.          
    19.         }
    20.  
    21. Cell.cs
    22. public float MovementCost
    23.         {
    24.             set
    25.             {
    26.                 MovementCostOrigin = value;
    27.             }
    28.             get => EnemyNearby ? MovementCostOrigin + 1 : MovementCostOrigin;
    29.         }
    30.  
     
  25. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    This looks good, nice to see that you're getting new features implemented :)

    Regarding your current issue. First of all, you should not bother with UnitState classes. Their purpose it to make Unit.MarksAsFinished, Unit.MarkAsFriendly and Unit.MarkAsSelected work correctly. Besides, there is a smal bug in the code fragment that you are reffering to, found by @dbugger. It will be fixed soon, but you don't need to worry about it anyway.

    Lets consider first how to make the menu appear AFTER the unit moved. Basically speaking, you want to have a unit with just MoveAbility activated by default and "SkillMenuAbility" activated when MoveAbility executes. I assume that you have "SkillMenuAbility" implemented. The steps are as follows:
    1. Make a custom ability script that will inherit from MoveAbility, lets call it CustomMoveAbility
    2. In the new script add a "public Ability AbilityToActivate" field
    3. Override OnCellClicked method with the following code
      Code (CSharp):
      1. public override void OnCellClicked(Cell cell, CellGrid cellGrid)
      2.         {
      3.             if (availableDestinations.Contains(cell))
      4.             {
      5.                 Destination = cell;
      6.                 Execute(cellGrid, _ => { }, _ => cellGrid.CellGridState = new CellGridStateAbilitySelected(cellGrid, UnitReference, abilityToActivate));
      7.             }
      8.             else
      9.             {
      10.                 cellGrid.CellGridState = new CellGridStateWaitingForInput(cellGrid);
      11.             }
      12.         }
    4. Have only CustomMoveAbility attached directly to your unit gameobject. This will make CustomMoveAbility activate by default
    5. Have SkillMenuAbility attached to some child object of Unit, so it won't get automatically activated. Assign the SkillMenuAbility to AbilityToActivate field of your CustomMoveAbility
    What happens here is that we use Execute instead of HumanExecute method to run the move action. Execute method takes two additional parameters, preAction and postAction, invoked before and after the ability is executed. In our case preAction is empty and in postAction we select SkillMenuAbility.

    Let me think a bit about doing the same on double click, can't come up with anything from the top of my head.
     
  26. guicamarotto

    guicamarotto

    Joined:
    Jun 23, 2020
    Posts:
    25
    Hi, nice work with this framework, I am wondering to buy it, but want to know first if you have a documentation, or a how-to-use material, tutorial videos. other thing I would like to know, I was developing a turn base game by my self, but I was doing with isometric camera and 3d assets, do you think your framework can reproduce this?

    my current project:
     

    Attached Files:

  27. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Hey, this actually looks like made with TBS Framework, I'm sure you'll be able to reproduce it. There is a documentation that you can check out before buing, the link is below. Sadly, no video tutorials as of now. Other than that there is this forum thread and you can always reach out for help by email. Discord server is planned to start soon.

    Let me know if you have more questions

    https://drive.google.com/file/d/1Q-oc3MIaWg1B4kD3Z99gIFDKfEKGxft8/view
     
    guicamarotto likes this.
  28. guicamarotto

    guicamarotto

    Joined:
    Jun 23, 2020
    Posts:
    25
    Nice!! thx a lot! already bought!
     
    michal-zetkowski likes this.
  29. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Feel free to reach out with any issues
     
    guicamarotto likes this.
  30. mebaucco

    mebaucco

    Joined:
    Mar 6, 2018
    Posts:
    5
    Hello,

    I'm looking for a way to jumpstart my hobby project and your system caught my eye. I am wanting to make a simple space 4X where I have a galaxy map for movement and then battles are fought in a separate map. I think this system would be great for the battle part of the game, but I'm wondering if I can make my galaxy map big enough using this system, given that no combat would happen on it and most of the hexes would be empty.

    I'm also wondering if a player could "build" custom units. For instance they may want to add different armor, weapons or special effect modules to a ship. I know this isn't available out of the box, but how hard would it be to implement something like this?

    Thanks in advance for any information you can give!
     
  31. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Hey, so you're planning to use the framework just for the battle part, right? How big are the maps you're thinking of? I assume you want the maps to be "3D" since the game takes place in space. This is not included out-of-the-box but is easy to add.

    Spawning custom units on runtime is supported. Just create some kind of in-game unit editor and you're good to use them.
     
  32. mebaucco

    mebaucco

    Joined:
    Mar 6, 2018
    Posts:
    5
    I wouldn't mind using the framework for the big map if I can get away with it since that would save time, but I am guessing it would be too big. I woud love to be wrong though!
     
  33. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Well, the problem is that in the Framework each cell is a separate object. So if you wanted a 1000 x 1000 x 1000 map, that alone is 1bln objects. I guess this would require some specific optimizations. But if you scaled it down a bit, then who knows?
     
  34. mebaucco

    mebaucco

    Joined:
    Mar 6, 2018
    Posts:
    5
    Thanks for the information! The galaxy map will be 2D but that would still be a lot of objects, even if most of them don't "do" much. Maybe I will try 250 x250 and see what happens, that is still a ton of space. If it doesn't work I will just go with something home made.
     
    michal-zetkowski likes this.
  35. Deleted User

    Deleted User

    Guest

    @michal-zetkowski
    Hi! Have you got some ideas about my questions? I will try to add a state variable to distinguish whether the unit was chosen. But I think you may get some solutions much better.
     
  36. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Right, sorry. BTW, did you manage to implement showing the skill menu after unit moved?

    Regarding detecting the double-click, I think you should utilize OnMouseDown method of Unit. I see two options:
    1. Override the OnMouseDown method in your Unit subclass (don't forget to call base method). In the method you'll set up a flag (like "isClickedOnce") and save the event time. When the method runs the second time, check if the flag is set and the time is lower than some deltaTime. Once you detect the second click, simply set CellGrid.CellGridState like before
    2. OnMouseDown in base Unit class invokes UnitClicked event. You can subscribe to the event in some external script. In the handler method you do more or more or less the same as in overriden OnMouseDown method from the previous point. You'll just have to keep track of the unit that was clicked also
    I like the second point better, because it feels cleaner, but either should work. Let me know if it worked out, sorry for the delay.
     
  37. Deleted User

    Deleted User

    Guest

    You don't have to apologize. I just wondering to get some better advices. Thanks for your reply, and these days I became more familiar with this framework and ready to make more features. I got more confidence to working with it. Thanks for the great job! Really appreciated. I had make a small demo for TBS game before, but I need months to finish it without your framework.
     
    michal-zetkowski likes this.
  38. Deleted User

    Deleted User

    Guest

    The answer to the question about clicking one unit twice can be very simple. It's just in OnUnitClicked method in Ability file. The first click will call the Display method in the Ability file, and the second click will call OnUnitClicked. The only thing to do is to check whether the clicked unit is the current unit. These contents can be found in the document.


    Code (CSharp):
    1.  
    2. public override void OnUnitClicked(Unit unit, CellGrid cellGrid)
    3.     {
    4.         if (!CanPerform(cellGrid)) return;
    5.      
    6.         if (unit == UnitReference)// This is the key.
    7.         {
    8.             cellGrid.CellGridState = new CellGridStateAbilitySelected(cellGrid, unit, menuAbility);
    9.         }
    10.         else if (cellGrid.GetCurrentPlayerUnits().Contains(unit))
    11.         {
    12.             cellGrid.CellGridState = new CellGridStateAbilitySelected(cellGrid, unit, unit.GetComponents<Ability>().ToList());
    13.         }
    14.     }
     
    michal-zetkowski likes this.
  39. Deleted User

    Deleted User

    Guest

    To cancel some action, you can try to use the code:

    Code (CSharp):
    1.  
    2. public override void Cancel(CellGrid cellGrid)
    3.     {
    4.         cellGrid.CellGridState = new CellGridStateAbilitySelected(cellGrid, UnitReference, lastAbility);
    5.     }
    6.  
    I add a virtual method Cancel in Ability.cs. Ugly but useful.
    LastAbility is the last ability you had used.

    You also need to add the code in CellGridStateAbilitySelected.cs

    Code (CSharp):
    1. public override void OnCancel(CellGrid cellGrid)
    2.         {
    3.             base.OnCancel(cellGrid);
    4.             if (_abilities.Count == 1)
    5.             {
    6.                 _abilities[0].Cancel(cellGrid);
    7.             }
    8.         }
    Then you can call cellGrid.OnCancel() to cancel current action.
     
    michal-zetkowski likes this.
  40. evanec

    evanec

    Joined:
    May 2, 2017
    Posts:
    2
    Is networking planned to be added to the framework?
     
  41. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Hey, networking will be added at some point, but no specific plans are made at this point and no work is being done in this regard.
     
  42. guicamarotto

    guicamarotto

    Joined:
    Jun 23, 2020
    Posts:
    25
    Hello. do you have any channel with tutorial videos? I am trying to use the framework, but have some issues like this, when test play the units doesn't appear.

    upload_2022-2-11_12-10-55.png

    upload_2022-2-11_12-12-2.png
     
  43. ouraf

    ouraf

    Joined:
    Sep 4, 2019
    Posts:
    18

    Is it possible for, in a future version, add a null check on the prefab if the required fields are empty? it should prevent the game from compiling if i recall C# rules correctly.
     
  44. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Hey, sorry but there are no video tutorials currently. Units get snapped to their cell position, your prefab should account for this by having its model offset by cell's height. Take a look how it is set up in tutorial scene - unit model is a child of unit gameobject and it is moved by 0.9 units on Y axis
     

    Attached Files:

    guicamarotto likes this.
  45. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Yes, I could add a warning.
     
  46. Thundar

    Thundar

    Joined:
    Nov 16, 2012
    Posts:
    6
    upload_2022-2-13_11-21-21.png

    Thanks for the 2.1 update, spent the last week rewriting my project to use inheritance instead of directly editing scripts so I can more easily make use of some of the new features and it's been a big improvement.

    Ran into an issue with the ability system however. As I was editing the act coroutine to sync with animations I noticed a strange bug where the AI will attack the first turn, skip the second turn and then attack again in the third turn.

    Narrowed down the problem to the simple version in the screenshot, if there's a wait period before the attack handler it reproduces the bug. Been struggling to figure out why this happens and how to fix it, not sure if the issue is with the ability system, the AI system or maybe a combination.

    Any ideas on how to fix this? Perhaps a workaround or a better place to add animation delays.
     
  47. Thundar

    Thundar

    Joined:
    Nov 16, 2012
    Posts:
    6
    upload_2022-2-13_21-7-42.png

    Think I finally discovered the source of the problem after lots of digging, the way the Execute() method inside AttackAIAction.cs is structured can cause the CleanUp() method to fire before the attack happens if there's a delay before the attack is handled. This breaks the AI and makes it skip the turn after attacking.

    Replacing the commented lines with the new yield return guarantees that the Cleanup() always fires after. Not the most elegant solution but the best I could come up with.
     
    michal-zetkowski likes this.
  48. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Ah, you might be right! Strange it never happened to me while testing... Your solution is perfectly fine. HumanExecute / AIExecute methods were supposed to be helper methods, so users don't need to remember to run Ability.Act with StartCoroutine, but it seems it's not gonna work... Sorry for your trouble

    Do you have any other insights about the new update? Let me know if you have more issues
     
  49. Thundar

    Thundar

    Joined:
    Nov 16, 2012
    Posts:
    6
    Thanks for the reply and no worries, this framework is the only reason I've been able to get this far in the first place!

    upload_2022-2-13_22-6-11.png

    Not actually sure if it's the CleanUp() method that's responsible for the bug I had but all the code below is subject to the same coroutine timing problem, the helper methods are nice but I suppose they can break the coroutine chain and thus the execution timing.

    So far the new update looks really good and I plan on digging into the turn resolver and ability system over the next few weeks, will be sure let you know if I run into any issues.
     
    michal-zetkowski likes this.
  50. dbugger

    dbugger

    Joined:
    Jan 10, 2013
    Posts:
    55
    I am not sure if this was already asked. Is there a way to create grids programatically?