10
\$\begingroup\$

I've been working with Lua for a little bit, and I have finally come up with some code that can be extended to create the core of a game model. I come from an object oriented background, so working with Lua is very different for me.

The purpose of this code would be to create the game model for a game with Lua. Another programming language would load the scripts and then make the calls to create the Game object and to advance the turns. Any information resulting from a game turn could be passed back to the rendering in the proper programming language.

I would love to hear about any aspect of this code, but I am new to Lua syntax so I am sure I am making rookie mistakes.

Game.lua

--This syntax loads other scripts, such as Player.lua
local player = require "Player"
local Game = {} -- the table representing the class, which will double as the metatable for the instances
Game.__index = Game -- failed table lookups on the instances should fallback to the class table, to get methods
-- syntax equivalent to "MyClass.new = function..."
function Game.new()
 local self = setmetatable({}, Game)
 self.players = {}
 self.currentTurn = 0
 return self
end
--Adding players to the game
function Game.addPlayers(self, numPlayers)
 --i has to be set to 1 for it to work properly
 for i = 1, numPlayers, 1 do
 self:addPlayer()
 end
end
function Game.addPlayer(self)
 table.insert(self.players, player.new(6))
end
--Advancing and reporting the game turns
function Game.advanceTurn(self)
 self.currentTurn = self.currentTurn + 1
end
function Game.getTurnNumber(self)
 return self.currentTurn
end
--test function to access player data
function Game.reportPlayers(self)
 for key,value in pairs(self.players) do
 print(key)
 end
end
--create the game "instance"
local game = Game.new()
game:addPlayers(2)
--these types of commands would be sent to Lua by a proper programming language
game:advanceTurn()
print(game:getTurnNumber())
game:advanceTurn()
print(game:getTurnNumber())
game:reportPlayers()

Player.lua

Player = {} -- the table representing the class, which will double as the metatable for the instances
Player.__index = Player -- failed table lookups on the instances should fallback to the class table, to get methods
-- syntax equivalent to "MyClass.new = function..."
function Player.new(startingHandSize)
 local self = setmetatable({}, Player)
 self.handSize = startingHandSize
 print(self.handSize)
 return self
end
function Player.set_handSize(self, newHandSize)
 self.handSize = newHandSize
end
function Player.get_handSize(self)
 return self.handSize
end
return Player
asked Aug 18, 2014 at 23:03
\$\endgroup\$
3
  • \$\begingroup\$ I am not sure I understand what happens when self.currentTurn exceeds self.numPlayers. And while we are here, what is the significance of 6 in game.addPlayer? Are you having some specific game in mind? \$\endgroup\$ Commented Aug 19, 2014 at 0:17
  • \$\begingroup\$ No specific game in mind, no. The 6 is the number of starting cards (sorry should have had a comment or variable to indicate that). Nothing intentional happens if self.currentTurn exceeds self.numPlayers so I did not mean to give that impression. If something is happening, it is not supposed to be. The calls at the bottom of the Game.lua script are just examples of the types of calls that will be made when the game is fleshed out. \$\endgroup\$ Commented Aug 19, 2014 at 0:23
  • \$\begingroup\$ Why I was asking about a specific game - I know just one card game with an initial hand size of 6 (and its variants which do not fit a round robin turn model). \$\endgroup\$ Commented Aug 19, 2014 at 0:45

1 Answer 1

3
\$\begingroup\$

I don't notice any major issues with your code.

  • Use _name naming for private variables, since everything is global (and thus, accessible) by default in lua. You can use the normal variable name for getters and setters.
  • You can modify the getter (get_handSize) and setter (set_handSize) a little as functions in lua don't need the parameters:

    function Player.new( startingHandSize )
     local self = setmetatable( {}, Player )
     self._handSize = startingHandSize
     return self
    end
    function Player:handSize( newHandSize )
     if not newHandSize then return self._handSize end
     self._handSize = newHandSize
    end
    

    You can now simply use player:handSize() or player:handSize(n) for getting and setting the private variable.

  • Since you are simply inserting new players to self.players table, you can iterate using ipairs to list them sequentially (depends on your game design).
  • You can save a little disk space by using the oop approach of defining functions instead of passing self every time.

That much was a basic approach to oop in lua. Now, extending the concept, you can use closures for proper private variables.

function Player.new( startingHandSize )
 local self = setmetatable( {}, Player )
 local h = (function()
 local _handSize = startingHandSize
 return function( self, newHandSize )
 if not newHandSize then return _handSize end
 _handSize = newHandSize
 end
 end)()
 self.handSize = h -- self._handSize will always be nil
 return self
end

and in a similar fashion:

function Game.new()
 local self = setmetatable({}, Game)
 local c, a = (function()
 local _turn = 0
 return function( self )
 return _turn
 end, function( self )
 _turn = _turn + 1
 end
 end)()
 self.getTurnNumber, self.advanceTurn = c, a -- self.currentTurn will always be nil
 return self
end
answered Aug 19, 2014 at 12:33
\$\endgroup\$
1
  • \$\begingroup\$ I appreciate the feedback! Do you think that private variables are better than relying on block scoping to limit their scope? I am unsure on this. \$\endgroup\$ Commented Aug 21, 2014 at 4:52

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.