#BoredGameClub

47 messages · Page 1 of 1 (latest)

lyric narwhal
#

This game is so far out in the making, but I really wanted to try to capture my progress as I slowly etch away at it. My code is ugly, my art is bad, and my scope (presently) is small. In the end, this will be a combination of Slay the Spire and Gloomhaven. This will result in a deck building turn based tactics rogue-like. All art is placeholder and there is no hero, enemy, or card data that is relevant at this time.

Overall, I'm very happy with my progress so far. I don't feel I've gotten stuck on anything for too long. The community has largely been extremely welcoming and helpful. I have only been using Godot since roughly Christmas of 2023 (but I didnt really start to do things then, just created the project)

#

Initially, I created tiles by drawing them directly onto a TileMap, but (as far as I'm aware) that resulted in a static TileMap per scene that I set up. The gameboard generation expanded into a more refined (but still likely flawed) function that maintained the custom data input into the tilesets (thank you @uncut garnet) and allowed for me to track which unit is standing where. Further implementation is needed to make it so that I can generate tiles in a more refined way than an entirely random identity.

#

I also found a way to successfully futureproof (to my best knowledge) my placement of units as well as my loading of unit data. The unit data is is stored in a dictionary of units, maintaining all custom data in the same way that the tiles do

#

Handling movement has been an issue, largely because the sprite2d is being placed globally but I'm trying to reference their position local to the gameboard coordinates. As of right now, this is my progress in making units move across the tilemap. I believe the check for whether or not a unit is occupying a tile is now completed, but I left the note there so that I can make sure in additional testing.

#

I do have to watch how fast I click when selecting and moving units. As of right now, I can move a unit mulitple times if I'm clicking too quickly which is a major issue. I will figure that out at a later date. I am presently handling "left_click" all in one input map function, though that may come to bite me on the ass in future implementation of left click when I go to select cards, who knows

#

Units and cards are .tres that are called upon in almost the same way (thanks @frank tartan, shoutout @copper agate). unfortunately I forgot the person who helped me with the initial initialization of the units. If you find this, thank you! The recommendation was that the unit resides within its own scene.

broken ember
#

Love your art style doggolaugh

lyric narwhal
lyric narwhal
#

I have done some major cleanup to the utter mess that was the input events and have implemented both the check for if the tile is occupied as well as added temporary attack functionality

lyric narwhal
#

update 1: my friend did some art to use within the project

#

update2: I refactored how the tile information is generated and stored. Rather than loading up a dictionary with the information and using tilesets on the tile map I now have packed scenes that create the tiles and units. This should be more clean going into the future, and has also been done to the unit generation, which is also packed scenes. The tilemap "Gameboard" is still serving as the central location in which the all of the location based events are handled, and is really only being used to map x,y to a position in game space that I dont have to compute or use tile-sized numbers.

#

there feels like there is still "too many" instances in which I am using map_to_local, but as of right now the changes all work and I can return to range finding problems. As of right now, when a unit is selected to move/attack it does not care how far away the move or attack target is. Someone in the discord told me about raycasting and that I should probably use that for determining the neighbors of tiles or something like that - I don't know yet, I've barely looked into it. I also know that I need to implement a* to assist with this implementation.

#

I also think that it may be possible to use raycasting rather than signals to collect mouseclicks, which may result in an easier time keeping track of who is where. the attached is the present selection and moving functions

lyric narwhal
#

implemented astar connections with my ugliest function to date! We instantiate an area2d and move it around to each of the tiles that is created, check its neighbors, connect its neighbors, and then move it to the next tile.

lyric narwhal
#

astar path finding is working, but I have yet to implement range finding. Units can still move across the entire map when asked to move. Pathing around units is occupied by performing set_point_disabled when a unit enters/exits a hex. This results in an inability to move through allied units, which may need to be allowed for better gameplay feel. I also realized that finding an attack range is different than determining movement, so I've made a separate AStar2D to handle range finding (which doubles as flying movement). This may be improper implementation.

lyric narwhal
#

I'm also unsure of how to create indication of movement range. My initial thoughts have been to do something like:

var available_moves = []
movementspeed = x
start = astar_walk.get_point_connections(starting_point_index)
for connections in start:
get move distance to connections

if move_distance_to_connections - x < = x
add to available_moves

if x > 0, add tiles to...start? Need to check based off of the new tiles to see if move cost < movement available

This is complicated for me 😦

white delta
#

Hello, maybe in the weekend I can join in and brainstrom your problem

lyric narwhal
white delta
#

Look, here is my idea as far as I've understood your intention. So, let's start with an inefficient approach to the problem: every tile has a 6 neighbour tile (because you have 6 edges) so you'll need 6 raycasts to collect the neighbour tiles. If a movement greater than 1 is applied you'll want the you'd want to do more iterations of the same thing. So this will have a great impact on computing power.
Now that we understand the limitations of the inefficient method we can come up with a more efficient way of calculating.

#

The way that I'm talking about is very similar to a linked list method. You'll have to basically, on map creation, do the raycasts once for every tile on the board and cache the neighbours for every tile. This also allows you to think if a neighbouring tile is considered a valid neighbour in the sense that perhaps not every tile is visitable.
Now, this has a greater computing impact on start, but this is highly acceptable since every other game has a loading screen and this complex calculus can be hidden with it. For a map with 100 tiles there will be 100 x 6 raycasts, but there will not be 600 neighbours, since tiles on the margin on the map will only have 3 neighbours.

#

As far as I've seen your map is not that big, but if this method is required to function on bigger maps you can always multithread to make it faster. For under 100 tiles it will be really fast since today's processing power is higher than you think.

white delta
#

There you go. You have your answer. Easy and fast method to calculate the cached neighbours.
Now, you were asking about the movement method in order to make a unit move one or more tiles. This can be achieved by going through the cached list of neighbours starting from the chosen tile of the current unit. This will also allow you to add an effect/shader on all possible tiles that your current unit can go to.
You'll need to store the information in a map/dictionary with a reference to the tile and the movement cost to go to that tile(movement cost representing the steps required to arrive there). Once the player chooses the desired tile, you'll need to check if that tile is in the dictionary and get the shortest path possible.
You can also have custom conditions, maybe some paths are blocked by enemies so there are not valid paths, then there will not be added to the dictionary, but kept in a separated dictionary in order to justify to the player with a message that the desired movement is not possible because the path is blocked.

#

What if the game has a flying mechanic, where it can basically skip across the map. That is doable, and you'll basically have to move the player to the chosen "fly tile" if the tile is not occupied and ignore checking if there is a path.

white delta
#

Hopefully the informations are enough and clear. Sorry for the long post.
Let me know if there is something that is not clear.
Some final words regarding the performance of the method, in depth, per turn: Since there can only be a maximum of 6 neighbouring tiles and every tile has a cached list we can see this method is ram memory dependent, meaning faster memory access will give faster results (aka the faster the RAM of the computer and the more processor cache the better). Because of this, hiccups on the start of turn can be present, but I think this only affects really old PCs on high movement steps( 100 + ). For 60 fps this is totally acceptable.
More, cached lists can be stored in the saved file in order to optimize the loading of saved games since this information will not change at all during the game.

white delta
#
  • I feel the need to justify acceptable performance: when I'm saying acceptable performance it means doing this method of caching tiles AND also all the logic running in the game that can also be somewhat complex
lyric narwhal
#

So the tiles themselves already have gathered their neighbor by moving a single area2d around gathering neighbors (see lines 79-100). The output of the calculation is being done already behind the scenes within Godots built in AStar2D function, and I have tested to make sure that the units are automatically selecting the "shortest" path. The units themselves move as expected, they just have no check at all as to how much he unit should be able to move. I need to know the function that can show the math. I thought it would be _compute_cost() but that does not work

#

As a secondary thing, not only do I want to check to make sure the unit moves the appropriate distance, I would like to check for all available moves and highlight the tiles that can be moved to

broken ember
# lyric narwhal As a secondary thing, not only do I want to check to make sure the unit moves th...

are you looking for something like the fire emblem games? If so I just implemented something similar here: #1191318550376366151 message. I implemented it using multiple iteration of BFS because of multiple range indicators (movement, attack, etc.). To be able to do it for weighted graphs, I would switch to dijkstra's instead of plain BFS, but the idea is similar. If you are interested, I can elaborate

lyric narwhal
#

Update:
Units now properly have checking for movement before just teleporting across the world regardless of how far it is
Units now properly check if they are in range before performing an attack

Next Steps:
Create a turn handler, only allow for inputs during player turn.
Create end turn button to begin enemy turn
Make enemies do stuff

lyric narwhal
broken ember
#

Thanks for offering but I do prefer doing it on my own pace. When I can write code is very unpredictable so it would be hard for me to cooperate with you on this project. I just modified the normal BFS code to color/label the explored nodes. For example, I firstrun BFS with the movement range, then label all the explored nodes as "move" in a dictionary. Then I run another BFS with this information for the attack range, and the starting points of the second BFS are the "frontier" (the outer most nodes explored in the first BFS). That's the rough idea.

lyric narwhal
#

Enemies now target a random hero and can perform a move and attack. Pathfinding works entirely as far as I can tell. What I would like to do now is have the enemies perform their turns a little differently. My plan is to handle enemy turns in the same way that enemies are handled in Into the Breach, which is

Game starts
Enemies move, project their attacks (Show the player what theyre doing, attacking, healing, spawning an enemy w/e)
Player takes their turn
Enemy performs attack
Enemies move -> repeat

This will cause the attack to be delayed until the next turn rather than what it is now, which is to attack immediately after moving.

#

Work has also begun on content for some initial cards to be played, they are presently located on a google sheet not within Godot. I look forward to implementing these and making a sufficient card generator to be accessed routinely. I know that I need an AoE helper similar to the one created in this video
https://www.youtube.com/watch?v=R-piBRCmw4Q

lyric narwhal
#

The next implementation is going to be a more effective targeting of the heroes. I'd prefer that they don't just wander aimlessly back and forth in the event that the player separates their heroes on the map

lyric narwhal
#

Targeting the heroes now has target checking. Right now, it checks for the closest, farthest, or picks random based on the string passed into the function. This can be passed within the logic of which action the enemy selects later. I still dont have a way to project the enemy actions at this time, nor do I think I know what that implementation would really look like. I'm starting to think we might just show the player the move, target, and action...Not sure.

lyric narwhal
#

Refactoring complete, units are now children of their tile, which makes targeting in future events easier

lyric narwhal
#

I have hit a major snag in the implementation of cards

Due to their dynamic nature in terms of number of actions they perform, order of actions they perform, and power of actions they perform...as well as the variety of actions I am not able to just load a basic tres as I already knew how to do and had done with the unit.

My intial thought is to make something as drawn here, where the tres would be loaded with the actions that can be performed by the card, and when the dropdown selects the action type it prompts for all related information to be stored into the card.

From there, the implementation is simple. For action in actions: do actions. that is to say call the function that does the attack, move, whatever other action

The issue is coming in generating the cards themselves and loading up the variables in a way that is easy, clean, and repeatable. This is very important to get right in order to not have to conduct a significant amount of improvement at a later date.

lyric narwhal
#

I've delved into the world of _get_property_list() and attempted to build it....I'm moving along but it's still not working 🙃 the associated fields do not allow me to change them yet

lyric narwhal
#

I got things working, but only in part. The script I wrote to do this only allows for one action. The fields are working as intended, but I do not have a clean way to add additional actions within the script at this time without repeating roughly 100 lines of code. This is also an issue, as if any action is added to the list I would have to add it into each action.

I may just do that for now, and then revisit this at a later date once some of the prototyping of this game is completed.

lyric narwhal
#

Card generation is hard. I almost regret making a card based game. Once the tres generator is created I can start working on actually creating the cards themselves. I am at a point where, as far as I can tell, the script I have written is properly getting the information but improperly setting the information OR improperly getting the information but properly setting the information.

#

the first value is changing correctly (the action type itself) but when I go to change the variables within the action it breaks down. It even gives "Set action_selection1" or "Set action1/armor" which are the proper variables that are being edited

#

This makes me believe that the _get function is the issue, since as far as I can tell the set function is reacting properly.

#

As far as I can tell, the keys within the dictionaries are not being checked by _get()

outer crane
#

ok but why did i have a hexagonal board game idea years ago with those colours

lyric narwhal
lyric narwhal
#

My git pushes (to share between my laptop and desktop) are beginning to have names like "send help" or "this is hard" for the bits of update that I've gotten in for the card generation. I'm looking forward to passing this hurdle, and I plan to make a small guide on how to do this, if I can. I'm not sure at this time that I will be able to accurately describe exactly what is taking place, but we'll see

lyric narwhal
#

Implementation of the cards has completed. I am able to make cards the way that I want with up to 10 (can include more, if it ever comes up) actions that are broken apart into Attack, Move, Defense, Heal, Card Effect, Crowd Control, and Status Effect. I've also fanned out the cards (poorly, but the functionality and numbers just needs some tweaking) in the player's hand. The hand / deck / discard pile will be done by reparenting the cards into their correct piles.