HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Basic Game Model in Scripting Language

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
scriptinglanguagegamemodelbasic

Problem

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:advanceT

Solution

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

Code Snippets

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
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
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

Context

StackExchange Code Review Q#60430, answer score: 3

Revisions (0)

No revisions yet.