luaroblox

In Lua Roblox API, when using Roblox Lua API Objects and performing conceptually similar arithmetic, why does 1 expression yield false & 1 yield true?


Context:

There are two equivalence comparison expressions below. Both expressions are very similar. Both the left side and right side of all four arguments yield the same value in the output box, but the difference across the expressions (which I found) are the types of the objects being compared (as left-side and right-side arguments). So, then one expression yields a boolean value of "true" with respect to the equivalence operation and the second expression yields a boolean value of "false" with respect to the equivilance operaetion, though in both expressions, the individual output values (on the output box) are the same, and the types are the same within that expression. (I.e., each expression I am trying to yield a true value, but only one comes out as true).

Question

Why does one expression (with objects of type "string") yield "true" and the other expression (with objects of type "Instance") yield "false"?

Code:

--In context of these following 2 function in the following 2 lines:
    box.Touched:Connect(onTouchedDebounced)
    function onTouchedObject(otherObjectPart)

--consider the following code:


--After declaring objects to be compared below in the following 3 lines:    
     local otherObjectPartsParent=otherObjectPart.Parent;
     local resultFromGetPlayerFromCharacterFunction = game.Players:GetPlayerFromCharacter(otherObjectPartsParent);

--Here I want to say:
--ActiveUserPlayerName == ActiveUserPlayerName is true
--Where: (#1): Object1 = "ActiveUserPlayerName";
--Where: (#2): Object2 = "ActiveUserPlayerName";
--Where: (#3): Left_Side_Arguement = ActiveUserPlayerName of type Instance
--Where: (#4): Right_Side_Argument = ActiveUserPlayerName of type Instance
    print ("resultsFromGetPlayerFromCharacterFunction: ", resultFromGetPlayerFromCharacterFunction); --OUTPUT: ActiveUserPlayerName
    print ("otherObjectPartsParent.Name: ", otherObjectPartsParent); --OUTPUT: ActiveUserPlayerName
    print ("typeof(resultsFromGetPlayerFromCharacterFunction): ", typeof(resultFromGetPlayerFromCharacterFunction)); --OUTPUT: Instance
    print ("typeof(otherObjectPartsParent): ", typeof(otherObjectPartsParent)); --OUTPUT: Instance
    print ("resultFromGetPlayerFromCharacterFunction == otherObjectPartsParent is: ", resultFromGetPlayerFromCharacterFunction == otherObjectPartsParent); --OUTPUT: False


--Here I want to say:
--ActiveUserPlayerName == ActiveUserPlayerName is true
--Where: (#1): Object1 = "ActiveUserPlayerName";
--Where: (#2): Object2 = "ActiveUserPlayerName";
--Where: (#3): Left_Side_Arguement = ActiveUserPlayerName of type string
--Where: (#4): Right_Side_Argument = ActiveUserPlayerName of type string
    print ("resultsFromGetPlayerFromCharacterFunction.DisplayName: ", resultFromGetPlayerFromCharacterFunction.DisplayName); --OUTPUT: ActiveUserPlayerName
    print ("otherObjectPartsParent.Name: ", otherObjectPartsParent.Name); --OUTPUT: ActiveUserPlayerName
    print ("typeof(resultsFromGetPlayerFromCharacterFunction.DsplayName): ", typeof(resultFromGetPlayerFromCharacterFunction.DsplayName)); --OUTPUT: string(*corrected)
    print ("typeof(otherObjectPartsParent.Name): ", typeof(otherObjectPartsParent.Name)); --OUTPUT: string (*corrected)
    print ("resultFromGetPlayerFromCharacterFunction.DisplayName == otherObjectPartsParent.Name is: ", resultFromGetPlayerFromCharacterFunction.DisplayName == otherObjectPartsParent.Name); --OUTPUT: True

Solution

  • Your variable names make this very hard to read. But by renaming otherObjectPartsParent to character and resultFromGetPlayerFromCharacterFunction to player, it makes a lot more sense what's happening.

    local character = otherObjectPart.Parent;
    local player = game.Players:GetPlayerFromCharacter(character);
    
    print ("player : ", player); --OUTPUT: ActiveUserPlayerName (a tostring'd version of the Player object)
    print ("character.Name: ", character.Name); --OUTPUT: ActiveUserPlayerName
    print ("typeof(player): ", typeof(player)); --OUTPUT: Instance (of class Player)
    print ("typeof(character): ", typeof(character)); --OUTPUT: Instance (of class Model)
    print ("player == character is: ", player == character); --OUTPUT: False (pointer comparison, these are two different objects)
    
    print ("player.DisplayName: ", player.DisplayName); --OUTPUT: ActiveUserPlayerName
    print ("character.Name: ", character.Name); --OUTPUT: ActiveUserPlayerName
    print ("typeof(player.DisplayName): ", typeof(player.DisplayName)); --OUTPUT: Instance (this looks wrong, this should be a string)
    print ("typeof(character.Name): ", typeof(character.Name)); --OUTPUT: Instance (this also looks wrong, this should be a string)
    print ("player.DisplayName == character.Name is: ", player.DisplayName == character.Name); --OUTPUT: True (string comparison, this should be correct)
    

    At the end of the day, you are comparing two different objects. When someone joins the game, their Player is added to the Players service, and their Character is added to the Workspace.

    The Player and Character have the same names, but one represents who they are on Roblox and the other is their physical representation in the game.

    And when it comes to comparisons, it matters what kinds of types you are comparing. Lua primitives like bools, ints, strings, and nil will compare by value. Tables and userdata objects will compare by pointer reference. So when it comes to Roblox lua, you need to pay attention to the object types you're dealing with. Instances are userdata under the hood so just because two objects have the same name, they won't always be equal.