[SUPPORT] Advanced Turn Based Tile Toolkit

Hi awlamon, I actually gave an answer to a similar question a few days ago. Take a look at my response here and see if that answers your question.

Happy to hear you’re working on your project again, Haukifile. So with the action system you’ve got two different things happening. The server-side events that happen instantly and modify the underlying gameplay variables, and the client-side animating of actions that display to the player what happens and take as long time as needed to animate things.

The action system uses an array in BP_ActionManager called the action queue which sequentially plays the actions held in the array, removing them as they are completed. Therefore, if you enter the actions (throw grenade, explode grenade, move) in the correct sequence they should also play in the correct sequence. Check to see if they are in fact running in the correct order. Print to the log when the queue action macro for each of these three actions is called to control that they are called in the correct order.

If they are, make sure that they are not checked to be played with the previous action in the input of the queue action macro. If you call the explode grenade action after the move action, the action will explode at the beginning of movement, since they play at the same time, but the explosion presumably lasts a lot shorter than movement.

Lastly, ensure that your grenade throwing/exploding stuff is actually happening within an AnimateAction interface event. If you instead call these as normal within the same execution flow as the server side events they will happen instantly and not wait for any preceding actions.

Hope that helps you find the cause of the issue. Get back to me if it still doesn’t work.

Hey Mon, been looking over your latest version and seems the Grid Manager function for “Spawn Unit” isnt there anymore.
Do you still have functionality for adding units into the game as its running?

Thanks

Yeah, I moved that stuff over to the construction script of BP_Unit. You should now be able to spawn units using the regular UE4 SpawnActor node and the unit’s construction script will automatically add it to the grid (and to initiative if specified. Check the variables that are editable on spawn).

Hi !

I am looking forward to your next 1.9 release of this magnificent Toolkit.
I have some concerns to plan another migration of our project, because we are already spending a considerable effort to migrate to new version with Action System (but results are encouraging: the network seems now very stable).

Anyways, we are planning in the very next future to put something very big in the grid, like Dragons/Wyverns ecc.
So… we are very interested on having the Big Unit functionality fully working and out of experimental.

Do you think it will be a great effort to implement new functions without importing the whole ATBTT 1.9 version the day it will went out, or shall we try to use and fix the experimental version?
If so, do you think you can provide some support to us in order to use Big Units in the actual version without breaking everything?

PS. To solve the “Owns Unit” macro dilemma that I explained some page before, we made two additional variables on the PlayerController: RelativeToServerID and RelativeToServerFaction.
These new variables, that are set through a RPC from Server->Client (Replicated to Owning Client), allows us to recognize who is the player that actually owns the unit in the game, and what is its in-game faction (IE. for 2vs2 games).

The above will be crucial the day we will use a dedicated server instead of having a Client being Listen Server for the game.
I hope some people here will use what I’ve found so far to have a more controllable owns unit method :slight_smile:

Hey, it is safe to say that migrating to the next update will be much easier than for the last one. My previous update was a major refactoring of almost all parts of the toolkit, while in the next one it will mostly be about iterating on what I have. An exception is the ability system which is being reworked somewhat, but how the abilities themselves work will be mostly unaffected. It is mostly about moving a lot of stuff away from the player controller and into abilities and making them more generic and flexible as a result. The big unit stuff might also potentially see some significant changes, but I am pretty happy with what I already have, so most likely it will just be about cleaning up and expanding upon what I have. So if you use the big unit system already in place, converting should hopefully be pretty painless. When the time comes that I release the next update I’ll of course do my best to help people who struggle with this.

Thanks for sharing your approach to checking whether a blueprint is owned by a particular unit or PC. I feel my solution is pretty hacky so I intended to look into more elegant ways of solving this. Could you elaborate a bit on what you are doing? What type of variables are RelativeToServerID and RelativeToServerFaction and how are you using them in the macro? If this works better than what I already have I might consider adding it to the next update if you’re fine with that.

Working on implementing a way of showing tiles in move range similar to XCOM. Has been surprisingly challenging, but I’ve made pretty good progress today. Looks good at a distance, though corners look a bit wonky when looking too closely. If anyone here has a great understanding of spline tangents or have other ideas to smooth out those corners, please let me know.

Hey ,

Greetings ,

We’ve encountered following problem, maybe you can help us pinpoint its origin.

What we are trying to do - We have a small character (human figure) who gets into the mech (becoming a big character) and can go back and forth. We’ve put extra action point management on top (We have separate points for movements and attacks)

Mech is a child of BP_Unit with some extra variables. We initialize it when our human character is interacting with it. Initialization is done with basically doing “Remove Unit from game” function but in reverse.

It works fine in general. But now we are trying to add extra feature , when you are inside the mecha you go into a “planning” mode , so you could basically queue multiple actions per turn (like movement , attack etc as long as you have corresponding action points ) but make them play out only when you confirm the end of the turn and during this “planning mode” you get more like a preview rather than a normal “immediate” turn. (Before you confirm the turn you can undo those actions freely)
For this we were using your new feature for action queuing which seems like a good fit , we followed your youtube tutorial for it.

Problem we encounter is that when during this planning phase our Mecha unit’s custom variables are always being resetted to zero (we tried both changing/affecting those variables from viewport and inside class blueprint,still the same) with no reason. (We use realize movement function to handle cost management for actions) ; And we cant figure out why this is happening , it works normaly in immediate mode (without planning)

@RC_Malokai : Hi there! Looks like you’re doing some pretty ambitious stuff with the toolkit, and great that you got a lot of it working already. I’m a bit confused about the issue you’ve presented, though. Are all the blueprint graphs you pasted above from an ability blueprint? Is the problem that that you are trying to access values from the OwningUnit reference variable and having them return defaults? You said that you are using my action system, but I cannot really see where you are doing so in the blueprints you have pasted. In the last two screenshots are the correct values posted in one of them and the incorrect ones in the other, or what is going on here?

So yeah, I’m not completely sure I get this, sorry. Could you try to explain very clearly what you are doing in the case that works and the one that does not?

Hey ,

Thanks for the reply.
Well we try :smiley: We are actually trying to bring all those features within new refactored framework of your toolkit (so we could technically update it later easier , before we had fully custom solution which had custom “action system” which was working in parallel with toolkit and was really a performance drag)

As for the current problem :

Yes, its happening inside BP_Ability_Move

Yes but problem is that its not returning to default, its turning into zeroes. Even if we change default values. We also tried taking values from GameStateRef -> Owning unit as well.

If you look at the first screenshot you can see we are using Queue Action function. But its just a general idea on how we want to proceed with this feature further.

Well , i did expect this will be the case :smiley: I just had to give you a broader context so you can see what we are trying to do as well. :slight_smile:

Well, first of all I am using a different approach because the standard toolkit wants all units already in place in the Grid Manager with DefaultOwnerID already set, in my case the player selects his hero and his faction before entering in the game so the Grid in my case is empty.
After the initial spawn of starting units (only heroes), that is done on the Turn Manager on PlayerNotifyReady, I call a Server->Client RPC on the Player Controller that requested the initial spawn (I pass local player controller from the Camera BP to the Turn Manager) with, in input from server, an incrementing RelativeID for all players.
This basically means that every player knows his ID in the server point of view (ex. my ID is 2), and, because also every player knows the total players of the match, they “know” everyone in the game.
The same mechanism is for the faction. I put in every player controller a faction from the server relative point of view so that every player knows that there are many factions (player1,player2,player3,player4 are factions in my case) that should be considered as enemies.
In the case of Team vs Team, the factions names are team1p1 team1p2 team2p1 team2p2 ecc.
So, also in this case, every player controller can understand who are the enemies and who are the allies.

This is good also for the HUD programming: HUD exists only in the Client so these local information are very useful.

@RC_Malokai : Ok, so I’m trying to wrap my head around this. In the screenshots you pasted you are printing values from OwningUnit to the screen in screenshots 5 and 6. Are these the ones that are printing incorrect values? Do you run the exact same nodes for previewing the actions and for actually performing the actions? Have you checked that the value of OwningUnit is actually valid? Use the isValid node to test this out. If it is valid, make sure that the same actor ID is returned in all cases. Print the actor ID to the screen for both the place you got it working correctly and the place where it returns 0. Are you getting the same actor? When spawning new actors in UE4 you sometimes need to wait a tick or two before they become fully accessible to all nodes. Check if this could be the culprit in some of these cases and try testing with delay nodes to see if this changes anything. Those are the thoughts I have at the moment.

Ok, thanks for going in-depth. In my last update I focused on getting replication working well without spending too much time on stuff like how to assign units to specific clients etc. This is something I had planned to revisit soon and your solution seems like a reasonable approach. I likely won’t implement it exactly like you are doing, since I still want assignment of units to clients to be possible before runtime and also to keep factions and player controllers independent (so that a player can potentially control multiple factions), but the general idea of passing a RelativeID to players through the turn manager is something I might copy. I agree that accessing all of this stuff through the HUD is a real hassle at the moment, and something like what you suggest would be a major improvement in that regard. Thanks a lot for sharing!

This looks great as it’s something that I have had on my list for awhile, albeit lower priority than others. What is your spline point type set to? Linear?

Thanks, I think it is a promising start. The frame is actually not a continuous spline. That is something I tried to do for the longest time, but I was not able to do this in a performant way. The frame is actually made up of individual two-point spline meshes: long ones within the tiles and short ones connecting them. The tangents for each of these points are zeroed out, so in this case I might as well use simple, straight instanced static meshes. The spline points are set to linear, but that does not matter at the moment. The fact that the spline meshes are not informed by an underlying, connected spline should not be an issue in itself, but it does make it more difficult to figure out the appropriate tangents to get them to line up, which is what I’m currently struggling with.

Today’s work: Finally got big units working for hexagonal grids. The combination of hex grid math and the algorithms for making big unit walkability arrays was pretty tough to work with, but I got it done. The big unit implementation is pretty close to final now. There are some functions that can be made more “elegant”, but I think I’ve at least got it about as as performant as it is going to get.

Beware of the hexagonal thicc bois. Unless you’re on the other side of a wall without a huge gap, I guess.

Yes, to be more precise its more like this (see pic #1)

Yes.

ID is correct. Its valid. (see pic #2 and 3)

Thing is , that we don’t spawn units to do this.We add/remove from array & map. (see pic #4-5-6) , as i mentioned before we reversed the RemoveFromGame function.

@RC_Malokai : Ok, still not sure what is happening here, but here is something you can try to help you figure it out. For the variables you are changing that are reset, try setting one of them to replication OnRepNotify. Then in the OnRepNotify event add a branch that checks whether the value is true. If it is true add a print string (or any arbitrary node) where you add a break point. Run your game until you hit the break point, and then look at the call stack and step through the execution chain to find out exactly when the variable is reset. This should hopefully lead you to the cause of the variable resetting.

Hi. Units have “Initiative” attribute. I wonder if it would be hard to make that this value would not only decide who acts first but also how many times the unit would act before the next unit.
Like if one unit1 has initiative value of 0.21, unit2 of 0.51 so the action order would look like this:

Unit1 (0.21) -> Unit1 (0.42) -> Unit2 (0.51) -> Unit1 (0.63) and so on. It was in Heroes there units head "speed’ attributes and unit with speed 7 moved twice before unit with “speed” 15.

Hey SimBuz, that is actually pretty easy to do. Since the initiative order is informed by a simple array you can just increase the initiative value of the current unit at the end of its turn, loop through the initiative array until you find a unit with higher initiative and insert it at that index. I tried it out and it works great. Here are the precise steps:

  1. Add a new CurrentInitiative float variable to BP_Unit.

  2. Modify the SortUnitsInInitiativeOrder function in BP_TurnManager so that the units with the lowest initiative go first. Also set the CurrentInitiative value of each unit at the start of the game equal to its regular initiative value (this can be done anywhere, but I do it in the same function here):

https://i.imgur.com/XYr9R2f.png

  1. Override MoveActiveUnitInInitiative (also in BP_TurnManager), which is called at the end of a unit’s turn, so that its current initiative is increased by its initiative value and it is inserted at the index of the first unit we find with a higher initiative than this new value. If no such units are found add the unit to the end:

https://i.imgur.com/JiTHAGK.png

That is it, really. Have fun!

Note that this way of setting it up means that there will never really be a new “turn”, but initiative will increase constantly for all units until combat is over. If this is not desirable you can always add a check at the end of the turn to see if the initiative of the current unit will hit a certain threshold and if so reset the current initiative of all units.

Well we found where it happens , its part of our code here during the end turn(see attachment).

We cant figure out why we cant modify them both after its “reset” , it feels like we loose access to it after new turn starts.

Well, the active unit reference is set to blank as part of the EndTurn event. Could that be affecting things?

In other news I revisited the the FreeRoam ability today. I’ve set it up so that movement can be cancelled mid-movement to allow for non turn-based movement that still uses the grid for pathfinding. Check it out:

https://media.giphy.com/media/4SWpMJyMtKW74xt07P/giphy.gif

Also I’ve changed the macro I use within units and abilties to check whether the actor is owned by a specific player controller. I looked into the suggestion by @Wisdom- and did something similar. I’m using the unique player id contained within the player state and assign this to a replicated variable in all units based on which player is the owner. Since the player state ID is replicated to all clients and easily accessible from anywhere through the default UE4 singleton classes this works great and is much less hacky than my previous solutiuon. Like Wisdom’s solution this also makes it much easier to work with client-side objects like UI widgets when they need access to replicated actors.