I currently make a top down game that has a circle player that eats circle food. I made a score label that says how many I've eaten. Sometimes the circle eats more than 1 food at the same time and the game addresses it as one.
player.gd

extends CharacterBody2D

@onready var you_died = $YouDied
@onready var score = $CanvasLayer/Score
@onready var player = $"."

const weight = 0.2
const SPEED = 450
var kills = 0

func _physics_process(delta):
	var input_direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	velocity = input_direction * SPEED 
	move_and_slide()


func _on_area_2d_body_entered(body):
	var player_scale = player.scale.x
	var food_scale = body.scale.x
	print("[Player]:Body name : ",body.name)
	print("[Player]: " + str(food_scale) + " " + str(player_scale))
	if food_scale > player_scale:
		print("[Player]:Died...")
	else: 
		kills += 1
		print("Check kills:",kills)
		score.text = str(kills)
		scale.x += weight
		scale.y += weight

food.gd

extends CharacterBody2D

const SPEED = 60
var rng = RandomNumberGenerator.new()

var food_scale
#behaviour of food
var direction_x
var direction_y
var weight = 0.2
@onready var timer = $Timer

func _ready():
	var scale_choice = rng.randi_range(0,4)
	scale.x = (scale_choice * weight) + 1
	scale.y = (scale_choice * weight) + 1
	food_scale = scale.x
	
# Called every frame. 'delta' is the elapsed time since the previous frame.

func _physics_process(delta):
	var input_direction = Vector2(rng.randi_range(-1,1), rng.randi_range(-1,1))
	velocity = input_direction * SPEED 
	move_and_slide()
	
@onready var player = $"../../Player"
func _on_area_2d_area_entered(area):
	var player_scale = player.scale.x
	print("[Food]:Player : " + str(player_scale) + " Food : " + str(food_scale) + "!")
	if player_scale < food_scale:
		print("[Food]:Player Got Killed")
		get_tree().reload_current_scene()
	else:
		queue_free()

I think the problem has to do with the fact that the signal is area_2d enter. Any help?

Here is the project :

no-tutorial.zip
2MB

    GameDevWannaBe you made me worry and doubt myself for a second there, had to go and create a project just to test this.
    the problem is with your code, godot collisions work correctly when 2 or more nodes collide with both on_area_entered and on_body_entered in godot 4.2.2:

    your collisions should be handled from ONE SIDE ONLY.
    either put the on area entered on the player or on the coin, NOT BOTH.
    if you are trying to do a cell simulator, then put the same code in both objects.

    func _on_area_2d_body_entered(body):
    	var player_scale = player.scale.x
    	var food_scale = body.scale.x
    	print("[Player]:Body name : ",body.name)
    	print("[Player]: " + str(food_scale) + " " + str(player_scale))
    	if food_scale > player_scale:#< ----- HERE'S YOUR PROBLEM
    		print("[Player]:Died...")
    	else: 
    		kills += 1
    		print("Check kills:",kills)
    		score.text = str(kills)
    		scale.x += weight
    		scale.y += weight

    in here you are testing player size against coin size to determine if something will happen. use a different system, create a variable in player to handle this. when two collisions happen at the same frame, it might be waiting for the frame to end to update physics.

    func _on_area_2d_area_entered(area):
    	var player_scale = player.scale.x
    	print("[Food]:Player : " + str(player_scale) + " Food : " + str(food_scale) + "!")
    	if player_scale < food_scale:
    		print("[Food]:Player Got Killed")
    		get_tree().reload_current_scene()
    	else:
    		queue_free()

    in here the coin is killing itself after doing the same test.

    there should only be ONE on_body_entered in player to handle everything:

    
    var player_scale : float = 1.0
    
    func _ready():
    	player_scale = player.scale.x
    
    func _physics_process(delta):
    	player.scale = Vector2(player_scale, player_scale)
    
    func _on_area_2d_body_entered(body):
    	var food_scale = body.scale.x
    	print("[Player]:Body name : ",body.name)
    	print("[Player]: " + str(food_scale) + " " + str(player_scale))
    	if food_scale > player_scale:
    		print("[Player]:Died...")
    		get_tree().reload_current_scene()
    	else: 
    		kills += 1
    		print("Check kills:",kills)
    		score.text = str(kills)
    		player_scale += weight
    		body.queue_free()

    Thanks for the answer but I am a bit confused. You advice me that the game's collisions should be handled from one side (player or food) but in the next line you advice me to put the same code in both objects. Isn't the second statement being dealt by both?

      GameDevWannaBe there is no contradiction.
      if it's any type of game, handle collision from one side only, destroy the collided object from the function called by the signal
      if it's a cell simulator, do the same, but put the same code on all "cells". when a cell collides with another it test if it's bigger, and then destroys the smaller cell, otherwise nothing happens.

      what you are trying to do doesn't look like a cell simulator.

      I moved everything to the food section and it works perfectly. Searched the term "Cell Simulator" and that not exactly the game I want to achieve. I just want a player to eat food and get bigger, no interaction between the "cells". Also I created a static variable inside the food.gd to handle the kills. Thanks again!