what's the best way to handle every tile's interactions data.

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By IHate

I’m trying to implement interactions between tiles but I’m not quite sure how to handle the data.

Every tile have very specific interactions with other tiles that no other tile shares.

Right now I have a resource shared among all the tiles with the basic information every tile needs. I load all the resources into an Array and every resource index matches their tile_id.

And now I’m thinking how to add these very specific behaviours and conditions for every tile.

Should I add a variable for every resource in which I add a script with that tile’s specific behaviour? Is there a problem having multiple small scripts loaded all at once? Should these scripts be resources too because they are reference-counted?

Edit: The game is turn based so this conditions only need to be tested once per turn.

If anyone knows of a better way of handling the data for the tiles please let me know.

This seems like a problem that would end up like yandere dev’s code if not dealt properly, if i were to do something like this i’d use a switch statement but gdscript doesnt have that and using multiple if else statements would really affect performance So i dont really have an answer

Kurotsuki | 2021-03-13 07:37

Godot has the switch statement, it’s called a match if I remember correctly. What is that yandere?

estebanmolca | 2021-03-13 08:41

Table of Contents · Game Programming Patterns

estebanmolca | 2021-03-13 08:54

Just as estebanmoica said Godot has match and I use it sometimes for example to check the type of tile and other things the godot documentation says its even has extra functionality over switches match doc:

match card_type:

	TYPE.PATH:
		path_tiles.append(mouse_tile)
		continue

	TYPE.ACTIVATION:
		is_spell = true
		removed_tile_id = map.get_cellv(mouse_tile)

		if path_tiles.has(mouse_tile):
			map.set_cellv(mouse_tile,0)
		else:
			map.set_cellv(mouse_tile,-1)

		for dir in DIRECTIONS:
			var neighbor_id = map.get_cellv(mouse_tile+dir)

			if DB_tiles[neighbor_id] == null:
				continue

			elif neighbor_id != DBase.TILES.PATH && DB_tiles[neighbor_id].adjacent_effect:
				adjacent_tile_effect("Remove",removed_tile_id,neighbor_id)

	_:
		if !is_spell:
			map.set_cellv(mouse_tile,card_tile_id)

IHate | 2021-03-13 09:29

Thanks for the link it has a lot of concepts I didn’t know about

IHate | 2021-03-13 10:57

:bust_in_silhouette: Reply From: Inces

Will this interactions be processed all at once, like in ready() or process(), or will it be like the turn game where You could check these interactions for one tile at a time ? Please tell us something more about Your project, maybe we could figure something out.

You are right, the checks wouldn’t be every tick and would only happen once the player uses the tiles that are like resources so you can’t spam them freely. Its more of a turn based thing the tiles don’t do anything until the next turn others require more turns.

IHate | 2021-03-13 09:22

:bust_in_silhouette: Reply From: IHate

I think I got it. What I’m going to do is to have every behaviour be its own script and load them in the Tiles base resource that use them. Then I would have an array of strings with the name of every script and this name would be the same as the name of its function. Every time I put a tile or remove it I would call for the check_behaviours function of every tile that may be affected

extends Resource
class_name Tiles

export (Array,Resource) var Behaviours
var function_names :PoolStringArray = ["foo1","foo2", ...]

func load_behaviour_scripts():
  for x in Behaviours.size():
    var script = Behaviour[x]
    Behaviour[x] = [script,script.new()]  #or use another array to save the loaded scripts

func check_behaviours([param]:Array):
   for x in Behaviours.size():
     var script = Behaviour[x][0]
     var usable_script = Behaviour[x][1]
     for function in  function_names:
       if script == load("path_to_behaviours_folder/"+ function+".gd"):
         usable_script .call(function,[param])

Once I’m done implementing it I’ll update the post

:bust_in_silhouette: Reply From: Inces

I still can’t really imagine complexity of these tile bahaviors, but I feel that creating separate script for all of them would be overdoing it. They are tiles in the end, they can’t really have complicated bahaviours, I suspect they will be all about influencing some calculations .
Since it is a turn game, can’t You implement a scripted Node under actor object, that would be responsible for getting surrounding tiles and calculating their interactions after every move ? Also instead of large if/match statement code You maybe would be able to handle all interactions in this one script via JSON sheet ?

its not complicated is just a lot of if statements.

is this tile under this other specific tile? is the specific tile 3 tiles away? is this tile surrounded? is this tile surrounded by 2 rings of tiles? do something specific depending on the tiles surrounding if they are different between then do another thing, etc.

I haven’t designed all the tiles and their behaviours but I want to have a system that allows for as much freedom as possible when it comes to add new behaviours to tiles.

With the separated scripts I would only call the functions that the tile resource has and that function would check only the requirements for that specific behaviour. So every tile would only need to check one or two if statements per behaviour and skip all the others.

How would that pipeline look with the json? Won’t you have to check for every behaviour condition even if the tile only have 1 behaviour or do you mean every tile would have its own json? I think you can do if statements in xml but json doesn’t have that what would the json file be?

IHate | 2021-03-13 12:31

I see, loop hero stuff :slight_smile:

Yeah, this kind of elastic interactions are not suited for JSON, i was thinking of table json sheet where tiles would be on x and y of a table and cells would contain keywords for calling interaction functions, but that would only work for simple tile vs 1 neighbour bahaviour.

So You are right, multiple scripts seem like only option. You will just put repetitive checks in their parent class.

Inces | 2021-03-13 13:02

Yes I started this project as a loop hero clone because it seemed like a really simple game I could imitate for practice but now the project is growing in complexity even changing core mechanics but I liked the idea of using tiles as resources. If I was to copy everything in loop hero even if is not a good habit I could just hardcode the tiles there’s not that many interactions.

IHate | 2021-03-13 13:27