Search Unity

[RELEASED] Turn Based Strategy Framework

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

  1. Neil2TheKing

    Neil2TheKing

    Joined:
    Sep 14, 2017
    Posts:
    15
    I recommend adding an option for online multiplayer in the grid helper similar to the 2D vs 3D option. Essentially let users decide they are creating a scene for online multiplayer and have the grid helper load in the online components as appropriate. Online multiplayer requires you to load in Players differently from normal. If the Grid Helper did this for you it would prevent little mistakes along the way. Online multiplayer also requires you to modify the CellGrid.CellClicked method to function correctly, so the grid helper would need to modify the CellGrid instantiation as well.

    I also recommend including a simple Main Menu Scene with the framework to streamline setting up the online networking. I'm thinking having a main menu scene for the demo with four menu options; the first three take you to the three current demo scenes while the fourth takes you to the online multiplayer matchmaking scene, and you could have all the necessary code for online prewired into the menu.

    This should get online multiplayer working for the framework mostly out of the box. Note that users will still need to create their own Photon account and adjust a couple settings within the Photon package to get everything working properly. I'll see if I can implement some of my code into an unmodified TBS Framework script to enable online multiplayer. I have some deadlines to meet these next couple weeks so it may take a while. I will come back with a status update in July. I'll aim to have a Main Menu scene set up for you with the online functionality implemented and I will aim to have a functioning online multiplayer game scene implemented to give you a baseline for grid helper automation.
     
    michal-zetkowski likes this.
  2. jcjc2k10

    jcjc2k10

    Joined:
    May 2, 2017
    Posts:
    2
    Omg thank you so much for the swift reply.. that solved it for me!
     
    michal-zetkowski likes this.
  3. Liberation85

    Liberation85

    Joined:
    Apr 16, 2019
    Posts:
    65
    Been making alot of progress on my game, so I thought I would share a screenshot :)


    upload_2021-7-1_22-27-26.png
     
  4. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Sure, keep it coming :) Looking good
     
    Liberation85 likes this.
  5. DhiaSendi

    DhiaSendi

    Joined:
    May 16, 2018
    Posts:
    43
    Hey Michal,
    thank you for this amazing and powerful tool !
    I have a question, we are working on a game where you are playing in FPS mode and whenever a fight triggered it turns to a top down turn based combat ,so the grid have to be generated at runtime in order to take advantage of specific places (for example cities is better than mountain in term of bonus )
    is it possible to generate whenever a fight is triggered ?
    Thanks !
     
  6. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Hey, sounds fun, can you post some screenshots sometime in the future? :)

    This is not currently supported in the framework, but this is kind of how I generated maps in "alpha" version of the project when I didn't know how editor scripting worked

    I would approach reproducing this feature this way:
    1. Take any of the generators from TBS Framework\Editor\GridGenerators
    2. Reuse GenerateGrid method as Start method (disregard return value) - this will make the script generate map on runtime. Also, make sure that newly generated cells are children to CellGrid game object.
    3. Lastly, CellGrid needs the map to be genrated before it's Start method is triggered. I would disable CellGrid gameobject in the editor and re-enable it in grid generator script, at the end of it's Start method
    When you get it to work you will need to implement the actual grid generator script for your game.

    Hope it's not too complicated, let me know if you have any issues.
     
  7. Untrustedlife

    Untrustedlife

    Joined:
    Apr 21, 2020
    Posts:
    78
    Here's a trailer for my game made with help with this asset, Steam.Store page will be visible soonly.
     
    michal-zetkowski likes this.
  8. unity_sFtLukWoBQ7vWA

    unity_sFtLukWoBQ7vWA

    Joined:
    Feb 15, 2020
    Posts:
    2
    Hello, I am having an issue that I can't figure out. I am using the project that was provided with the burgundy colored land & scouts/wizards/knight.

    I have implemented 2 things so far:
    1. You can only action 1 unit per turn
    2. An undo button if you change your mind which unit you want to action
    Everything works fine EXCEPT that if you use all your movement points, the unit receives UnitStateMarkedAsFinished and changes color. I've tried everything to try to change the unit state so that it changes color back. I checked if the switch for MarkedAsFinished is running before & after but its only running once. I'm resetting the movement points and running Debug.Log immediately after, but it seems to be ignoring the new SetState call.

    Unit.cs
    public virtual void UndoMove(Cell destinationCell)
    {
    MovementPoints = TotalMovementPoints; //resetting the movement points back to original value


    Cell.IsTaken = false;
    Cell.CurrentUnit = null;
    Cell = destinationCell;
    destinationCell.IsTaken = true;
    destinationCell.CurrentUnit = this;

    transform.position = destinationCell.transform.position;

    SetState(new UnitStateMarkedAsFriendly(this)); //this is seemingly being ignored???, I also tried a few other things like UnitDeselected();

    Debug.Log(this.UnitState); //in the case that Move caused complete depletion of MovementPoints, this will continue to show UnitStateMarkedAsFinished despite the line immediately before this
    }
     
  9. unity_sFtLukWoBQ7vWA

    unity_sFtLukWoBQ7vWA

    Joined:
    Feb 15, 2020
    Posts:
    2
    LMAO... I just noticed an if statement in UnitStateMarkedAsFinished and was like UnitStateNormal huh? Check it out and my answer was there: "Purpose of this class is to prevent units from changing appearance from "finished" to anything other than "normal". Ok... I got this :D
     
  10. pzolla

    pzolla

    Joined:
    Apr 21, 2020
    Posts:
    19
    Michal:

    Can you provide any insight into whether a 'fall release' of your framework improvements is still on track. Trying to weigh doing some work with TBS Framework now or wait? Not looking for # of days but something like '6-8 weeks' or 'many months'.

    Sorry to be a bother, I know these timing questions can be problematic.
     
  11. Untrustedlife

    Untrustedlife

    Joined:
    Apr 21, 2020
    Posts:
    78
  12. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Hey, sorry for delayed replies, I've been traveling.

    @unity_sFtLukWoBQ7vWA Glad you worked it out, feel free to contact me if you have more questions

    @Untrustedlife I was just about to ask if you don't mind me adding it to asset description, I'll definitely do it :) Good to see another game made with the framework, let me know if you need anything

    @pzolla The plan still stands, In my opinion you should wait. If you want to discuss it in more details, contact me by email
     
  13. Megalogue1

    Megalogue1

    Joined:
    Dec 17, 2020
    Posts:
    134
    Hey, I recently purchased TBS, and it shows a lot of promise for one of my projects!

    Two questions so far:
    1. Is there a built-in way to get the neighbor of a given hexagon cell in a given direction? For example, getting only the hex to the "northeast" of a given cell.
    2. Is there a built-in way to get a reference to a the grid cell with a given set of offset coordinates? For example:
      public Cell GetCellAt(Vector2 offsetCoords)
      I would rather not iterate through every child of CellGrid every time I want to do this, and I would also prefer not to use LINQ.
    Thanks for being a responsive dev. :)
     
  14. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    @Megalogue1 Hey, good luck with your project :) This is not built-in, but let's see if we can do something about it:
    1. In your class derieved from Hexagon add a dictionary that will map Direction to neighbour (you probably want an enum for Direction). You can initialize the dictionary in overwritten GetNeigbours method. Make sure to call base.GetNeighbours first and then you can acces Cell.neighbours field and assign cells to directions in the dictionary.
    2. Cells are stored in CellGrid.Cells as a list, you'll need to represent the grid as a 2D array. You can do it in CellGrid.Initialize method. Keep in mind that some cells can have negative offset coords, so you'll need to account for that. Alternatively you can use dictionary instead of array, this way you won't have to deal with negative coords, but you loose the ability to quickly access cells in given distance and direction (in case of an array it would be just a matter of operating on indices)
     
    Megalogue1 likes this.
  15. Megalogue1

    Megalogue1

    Joined:
    Dec 17, 2020
    Posts:
    134
    Thanks for the tips. I've made some good progress on implementing those functions myself.

    How about adding delays during certain parts of a turn? For example, if I want custom unit animations to play at certain times (such as when a unit is attacking or gathering resources), I want the game to wait to progress until those animations are over. For human players, this could be as simple as blocking clicks for a certain time period, but that doesn't work for AI players.

    EDIT: I would also like to allow players to add units to the board during their turn. What's the correct way to go about this? So far, all I've been able to find in the documentation is how to add units using the Grid Helper, not how to do it in-game. I've tried it myself and gotten errors from TBS functions that I don't fully understand.
     
    Last edited: Aug 22, 2021
  16. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Regarding delays for the AI, you can add them in NaiveAIPlayer script in Play method. This method is a coroutine, you can find information on how to "freeze" a coroutine on the Internet (basically use "yield return new WaitForSeconds(x)"). The script is a bit convoluted and I will be replacing it in the new version, you can read about the upcoming changes a couple of pages back.

    To spawn units on runtime, instantiate the unit prefab, assign its player number, cell and position and pass the new unit transform component to CellGrid.AddUnit method. Check out previous pages of this thread, there are more posts about it with some sample code.
     
    Megalogue1 likes this.
  17. Megalogue1

    Megalogue1

    Joined:
    Dec 17, 2020
    Posts:
    134
    Ah, I had done everything for the unit placement except assigning the cell. Works perfectly now!

    I've been putting off learning with coroutines for as long as possible...I don't fully understand them, and as a beginner, they feel too close to multithreading for comfort. I'll see what I can do, though, and post my modifications if they're not working right.
     
    Last edited: Aug 23, 2021
    michal-zetkowski likes this.
  18. beavisCZ

    beavisCZ

    Joined:
    Sep 13, 2018
    Posts:
    1
    Hello Michal, it will be as free update to current users or it will be whole new asset sold on store? I considering your current asset so it is important for me....
     
  19. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    @beavisCZ Hey, it will be a normal, free update to Turn Based Strategy Framework project, all current and future users will get it with no additional fees :) BTW, if anyone is wondering, Autumn release date still stands :)
     
  20. MisterSpinalzo

    MisterSpinalzo

    Joined:
    Sep 15, 2021
    Posts:
    8
    Greetings all,

    First off, I've just now purchased this, and thank you, Michal, for all your hard work. This will save me hundreds of hours of work. I'm working on porting a tabletop game that is somewhat of a cross between D&D (of course) and Pathfinder. I will have many questions. So, thank you in advance.

    One observation that I have even before getting started is this: It looks like, by reading this thread, that line of sight mechanics is not part of this framework, but should be easy to build in. I'm looking forward to getting off and running.

    Cheers,
    Mr. Spinalzo
    Game Engineer, Blight
     
  21. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    This is correct, line of sight is not included, but should be relatively easy to add. Feel free to ask me if you have any issues :)
     
    MisterSpinalzo likes this.
  22. fluxtheory

    fluxtheory

    Joined:
    Aug 20, 2021
    Posts:
    6
    Hi Michal, just wondering if you have any familiarity with TopDown Engine? Would any features be duplicate (such as procedural map generation)/conflict with that particular asset?

    Also are there any plans to implement a layer-sorting system like in the native Tilemap Renderer?
     
    Last edited: Sep 19, 2021
  23. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Hey, sorry but I never used TopDown Engine.

    I never considered implementing layer sorting, would you mind describing what would be the benefits?
     
  24. fluxtheory

    fluxtheory

    Joined:
    Aug 20, 2021
    Posts:
    6
    I've only been playing around with TBSF for a few hours so forgive me if my assumptions are incorrect. I've noticed all your demos are set at the "strategic" level where the action is zoomed out so only a dozen or two prefab tiles are needed to fully populate the scene. Water tiles, road tiles, grass tiles, city tiles, stuff like that. However this approach makes it difficult to stage more close-up engagements where the environment might be a bit more varied.

    Say, the skirmishes in my game are at the level of a bar fight. I have a stool object sprite that I want present in multiple scenes, one in a building with dirt floors, one in a building with wooden floors and one with a building with adobe floors. In the native tilemap system, i dont need to worry about what type of surface I am putting my stool down on, I simply have a separate layer called props that stores all the furniture and it doesnt care what layers are underneath it. But in TBSF I absolutely do need to care, because my tile palette are the cell prefabs. Which means for my particular example, I would need a cell prefab for adobe floor w/ stool + dirt floor w/ stool + wooden floor w/ stool. Multiply this across possibly hundreds of props and we're looking at a lot of potential extra work. A layer system (or actually even just try and integrate the tilemap would do) like the native tilemap would solve a lot of this.

    Correct me if my understanding is incorrect.
     
    Last edited: Sep 22, 2021
  25. MisterSpinalzo

    MisterSpinalzo

    Joined:
    Sep 15, 2021
    Posts:
    8
    I am missing something very basic in the tutorial. I am creating obstacles. The tutorial says to duplicate the cell prefab. I've done that. Then create a new cube, apply the black material. All good. Then "attach" the new cube to the cell prefab duplicate. I cannot replicate your RockSquare prefab by doing this. So, I applied the black material to the duplicate cell prefab. When using the cell painter, it will place the object once, then color consecutive cells rather than place another.

    When I use your RockSquare prefab, it works as expected. I am not understanding how the cube with black material gets attached to the cell prefab duplicate. I do not get the thumbnail to show at two cubes. One at a scale of 1 (prefab) and one at a scale of 0.8 (black cube).

    I apologize for my noobness.
     
  26. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Hey, sorry for the delay. It is supposed to be like this:
    • duplicate the prefab
    • create a new cube
    • apply the black material to the new cube
    • attach the new cube to duplicated prefab and manually change it's position and scale to fit on top of the prefab
    • save the new prefab
    Does that make sense?
     
  27. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Hey, sorry for the delay. I think I get it and you are correct. Just to be sure we're on the same page, could you post some sample screenshots?

    I'm not really familiar with Unity tilemap system. I guess I should look into it, it would be nice to use built-in tools. On the other hand, it wouldn't work for 3D maps, I would need to support 2 separate workflows.

    Finally, I might be totally wrong, but wouldn't tiles with transparent background solve the issue?
     
  28. MisterSpinalzo

    MisterSpinalzo

    Joined:
    Sep 15, 2021
    Posts:
    8
    Yes. Thank you, Michal. I figured out how to do it by deconstructing your RockSquare prefab. I appreciate your patience. I'm playing with the unit and grid painter, at the moment. There are some nuances that I'm trying to figure out.

    Overall, having fun. Cheers.
     
    michal-zetkowski likes this.
  29. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
  30. fluxtheory

    fluxtheory

    Joined:
    Aug 20, 2021
    Posts:
    6
    Hi Michal,

    I'm using your modified RectangularSquareGridGenerator to generate my isometric scene but I'm not sure why but the tilepainter is broken. The red tile painter cursor does not appear and no new tiles can be drawn onto the generated scene. Ive dragged the barrel manually into the scene for now as an example. Using my barrel prefab with transparent background looks promising but as you can see without a layer system its slipping under the terrain

    Untitled.png
     

    Attached Files:

    Last edited: Sep 26, 2021
  31. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    @fluxtheory Can you show me your cell prefab? Do you have a 2d collider attached to it?
     
  32. fluxtheory

    fluxtheory

    Joined:
    Aug 20, 2021
    Posts:
    6
    The documentation said to use a Box Collider 2D. I'm using a tilemap collider 2D, is that ok?

    upload_2021-9-28_19-6-31.png
     
  33. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Hmm, this shouldn't matter, any collider is fine. Unless there are some quirks to the tilemap collider that I'm not aware of. Would you mind exporting your project and sending it to me at crookedhead@outlook.com?
     
  34. fluxtheory

    fluxtheory

    Joined:
    Aug 20, 2021
    Posts:
    6
    Sent!
     
  35. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Hey, I rebuilt one of the demo scenes to showcase changes coming in the update. New features in the level include structure-capturing mechanism and deployment of new units during gameplay - both made possible thanks to the new Ability System. Reworked AI System made it easy to program AI Players to use the abilities. Finally, the level incorporates a custom game ending condition - capturing enemy HQ.

    I was hoping to deliver in this update demo scenes that are far superior to the current ones in terms of production quality. Unfortunately this is beyond my reach at the moment. I'll focus on updating current scenes with some custom abilities, so it is easier for you to create your own. Also, I'm working on a new level inspired by Heroes Of Might and Magic that I'm already quite happy with.

    Let me know how you like the updated scene :) - https://crookedhead.itch.io/v21-demo-scene-1
     
  36. unity_pFb9mvTB5gzvDA

    unity_pFb9mvTB5gzvDA

    Joined:
    May 22, 2018
    Posts:
    3
    I wanted my cavalry units to get an extra 2 to their attack factor if they moved the turn. but every time I try to override anything team 2's units disappear after moving. they still exits they just become invisible. this is my currant attempt:

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using TbsFramework.Cells;
    3. using TbsFramework.Units;
    4. using UnityEngine;
    5.  
    6. namespace TbsFramework.Tutorial
    7. {
    8.     public class CavalryUnit : Unit
    9.     {
    10.         public Color LeadingColor;
    11.         private bool moved = false;
    12.         public override void Initialize()
    13.         {
    14.             base.Initialize();
    15.             transform.localPosition += new Vector3(0, 0, -1);
    16.             //GetComponent<Renderer>().material.color = LeadingColor;
    17.         }
    18.        
    19.         private void Update()
    20.         {
    21.             if(IsMoving)
    22.             {
    23.                 moved = true;
    24.                 AttackFactor += 2;
    25.             }
    26.            
    27.         }
    28.         public override void MarkAsAttacking(Unit other)
    29.         {
    30.         }
    31.  
    32.         public override void MarkAsDefending(Unit other)
    33.         {
    34.         }
    35.  
    36.         public override void MarkAsDestroyed()
    37.         {
    38.         }
    39.  
    40.         public override void MarkAsFinished()
    41.         {
    42.         }
    43.  
    44.         public override void MarkAsFriendly()
    45.         {
    46.             GetComponent<Renderer>().material.color = LeadingColor + new Color(0.8f, 1, 0.8f);
    47.         }
    48.  
    49.         public override void MarkAsReachableEnemy()
    50.         {
    51.             GetComponent<Renderer>().material.color = LeadingColor + Color.red;
    52.         }
    53.  
    54.         public override void MarkAsSelected()
    55.         {
    56.             GetComponent<Renderer>().material.color = LeadingColor + Color.green;
    57.         }
    58.  
    59.         public override void UnMark()
    60.         {
    61.             //GetComponent<Renderer>().material.color = LeadingColor;
    62.         }
    63.         public override void OnTurnEnd()
    64.         {
    65.             base.OnTurnEnd();
    66.             if(moved==true)
    67.             {
    68.                 AttackFactor -= 2;
    69.                 moved = false;
    70.             }
    71.         }
    72.     }
    73. }
     
  37. MisterSpinalzo

    MisterSpinalzo

    Joined:
    Sep 15, 2021
    Posts:
    8
    Great work. Looking forward to the update. Some of these new mechanics will help me quite a bit.
     
    michal-zetkowski likes this.
  38. MisterSpinalzo

    MisterSpinalzo

    Joined:
    Sep 15, 2021
    Posts:
    8
    Has anyone else had this happen?

    When using the unit painter:
    - Place some units for player 0
    - Exit unit painter
    - Change unit prefab to player 1 unit
    - Enter unit painter
    - Cannot place units, no cursor

    This may be by design, but after placing a cell with the cell painter, it cannot be changed using the painter. For instance if you want to rearrange cells after painting, you must clear the scene, recreate the grid and paint the cells. Deleted cells cannot be repainted. If this is the expected behavior, I'm good with it.
     

    Attached Files:

  39. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Tile and Unit painters act up sometimes. Unity editor scripting is poorly documented (at least it was at the time when I programmed it), so there was a lot trial and error. I recreated your scenario, and actually got the same result (maybe it's a good lead to investigate further?). Toggling the painter on and off a few times fixed it. BTW, you don't need to change player number on the prefab, you can do it directly in Unit Painter :)

    Regarding cells, they can be painter over again and again. If you delete a cell, then no, it can't be painted over any more (you can deactivate the game object instead of deleting the cell). If you decide that you need a bigger map, then you need to generate it again. Technically, you could just copy cells and manually set their OffsetCoords, but that would be tedious and there is no tool in the framework that would facilitate this process (maybe someday :) )
     
    MisterSpinalzo likes this.
  40. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Hey, your approach is totally fine. There is no need to use Update method though, you can put that code in OnMoveFinished method. As to why it would cause other team units to disappear, I have no idea. Could you export your project and send it to me by email at crookedhead@outlook.com?
     
  41. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    If anyone is interested, the issue was the tilemap collider after all.
     
  42. MisterSpinalzo

    MisterSpinalzo

    Joined:
    Sep 15, 2021
    Posts:
    8
    Thank you again for your prompt attention.

    I have not been able to paint over tiles that are already painted. No cursor appears.
     
  43. fluxtheory

    fluxtheory

    Joined:
    Aug 20, 2021
    Posts:
    6
    Thanks for the quick turnaround. I finally had time to play around with it again and as you probably already know via the screenshots you sent back in your email - without a layering system, environmental props will replace the terrain tile it is sitting on. Let me know if you have plans to expand TBSF in this direction.
     
  44. unity_pFb9mvTB5gzvDA

    unity_pFb9mvTB5gzvDA

    Joined:
    May 22, 2018
    Posts:
    3
    I fixed my cavalry issue. just deleted the update function.
     
  45. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    So the cursor appears for initial cells, but not for the ones that were painted, right? Do you have collider on the cell that you painted with? If so, please export your project and send it to me by email.
     
  46. Liberation85

    Liberation85

    Joined:
    Apr 16, 2019
    Posts:
    65
    Regarding the tile painter, I have to disable my hud stuff, since I work in 2d mode and the hud panel covers some of the map, I guess the raycast to the colliders gets blocked? Dunno, but that is the only issue I get.
     
  47. Liberation85

    Liberation85

    Joined:
    Apr 16, 2019
    Posts:
    65
    @michal-zetkowski

    Got a question for you, I'm trying to slow the AI player turn down a bit, as it stands the AI blazes through its units pretty quick. I've experimenting with yield return new WaitForSeconds(1); in various places throughout the for loop in native AI, but it doesn't seem to make much difference.

    Any thoughts on this?
     
  48. MisterSpinalzo

    MisterSpinalzo

    Joined:
    Sep 15, 2021
    Posts:
    8
    Sorry. I've been away from it this last week.

    I will check it out and post a response.

    Thanks.
     
  49. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Hey, in NaiveAiPlayer line 38 there is a loop that iterates over all units. Putting yield return new WaitForSeconds(1); worked for me.
     
  50. Liberation85

    Liberation85

    Joined:
    Apr 16, 2019
    Posts:
    65
    Cheers mate, that worked well.

    upload_2021-10-10_16-1-11.png

    New screenshot of my latest endeavour, using a line render to mark out the player route. Took me a while to suss this one out, but it was an enjoyable learning experience.