All object instances behave like one instance

schnico
New member
 
Posts: 6
Joined: Fri Jan 08, 2016 21:13
In-game: schnico

All object instances behave like one instance

by schnico » Sun Feb 21, 2016 13:15

Hi folks,

it's me and my boat mod (forked of PilzAdams boat) again. Feel sorry about the confusing subject, but I didn't know, how to discribe the problem.
In short: if I enter one boat and move or rotate it ingame, the other boats do exactly the same. I know HOW this happened, but not WHY.

I did the following: The original mod saved the driver inside the "driver" property.
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local boat = {
   driver = nil,
}


My boat shall handle more players per boat (one driver and more passengers). So I handle all players inside a property called "seats":
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local boat = {
        seats = {       -- first Seat is always driver seat
                [1] = {
                        pos={x = 0, y = 20, z = 20},
                        player=nil,
                    },
                [2] = {
                        pos={x = 100, y = 20, z = 10},
                        player=nil,
                },
                [3] = {
                        pos={x = 0, y = 20, z = -10},
                        player=nil,
                    },
                [4] = {
                        pos={x = 0, y = 20, z = -20},
                        player=nil,
                    },
        },
       
}

The "driver" property will be dropped, because I can get the driver from the seats table

in the boat.onstep() the boat gets the player control. Here the "error" occurs:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
function boat.on_step(self, dtime)
   self.v = get_v(self.object:getvelocity()) * get_sign(self.v)
        local Driver = self.driver
        --local Driver = self.seats[1].player
   if Driver then
      local ctrl = Driver:get_player_control()
      local yaw = self.object:getyaw()
      if ctrl.up then
         self.v = self.v + 0.1
      elseif ctrl.down then
         self.v = self.v - 0.1
      end
   end
end

If I'm using self.driver (I still kept it for debugging) everything is working normal.
But if I'm using self.seats[1].player every boat behaves like one boat: if I rotate one boat left, all boats rotates left and if I accelerate one boat, all boats accelerate.

So I did print(self) when I attaches to the boat to get the table ID of the object.
If I'm using self.driver and enter different boats I got different table ids. And if I'm using self.seats[1].player and enter different boats, I got the same ID for all boats.

Can you explain me why that happens? Thank you really much! :)
 

User avatar
qwertymine3
Member
 
Posts: 194
Joined: Wed Jun 03, 2015 14:33
GitHub: Qwertymine
In-game: qwertymine3

Re: All object instances behave like one instance

by qwertymine3 » Sun Feb 21, 2016 15:35

schnico wrote:My boat shall handle more players per boat (one driver and more passengers). So I handle all players inside a property called "seats":
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local boat = {
        seats = {       -- first Seat is always driver seat
                [1] = {
                        pos={x = 0, y = 20, z = 20},
                        player=nil,
                    },
                [2] = {
                        pos={x = 100, y = 20, z = 10},
                        player=nil,
                },
                [3] = {
                        pos={x = 0, y = 20, z = -10},
                        player=nil,
                    },
                [4] = {
                        pos={x = 0, y = 20, z = -20},
                        player=nil,
                    },
        },
       
}

The "driver" property will be dropped, because I can get the driver from the seats table


In lua tables are objects - i.e. accessed by references.

When you register the boat, minetest stores your definition in a table of all definitions, to be used when you create a new boat.

When minetest creates an instance of your boat in-game, it applies your definition as a meta-table to the table of this new instance.
This is a slightly advanced lua concept, but in this case basically means - if a variable does not exist in this table and someone tries to access it, look in the meta-table for it.

Since the meta-table is the same for all the boats, and tables are a reference type, this means that all of your boats have a reference to the same table.

You will have to create a new table for each boat you create (and new tables for each player and each pos they are at) to avoid this issue. (This can be done in the on_activate method).
With your current layout I would suggest looking into how to perform deep table copying in lua.

Feel free to ask if you have any further questions
Avatar by :devnko-ennekappao:
 


Return to Modding Discussion

Who is online

Users browsing this forum: No registered users and 14 guests

cron