Design Talks - Your Game Module

@sporkfin,

You might like this:

function switch(n, ...) for \_,v in ipairs {...} do if v[1] == n or v[1] == nil then return v[2]() end end end function case(n,f) return {n,f} end function default(f) return {nil,f} end local test = 2 switch( test, case( 1, function() print("one") end), case( 2, function() print("two") end), case( 3, function() print("three") end), default( function() print("default") end) )

@RG Yes I like!  Thanks also to @davebollinger!  Your two great minds where thinking alike  :wink:

@remiduchalard  No, I don’t think physics will be useful for your app.  I was just stating that using physics makes my apps smaller but your app wouldn’t really make sense with physics.

@sporkfin Thank you for your analyse

Have you in all your apps a module to manage timer, transition and enterframe listener to put them in pause, resume, cancel…

To manage them with tag like for transition?

@remiduchalard  Yes, I keep master lists of all transitions, objects, and timers in my “master module” - mentioned in my first post in this discussion.  I also associate the timers and transitions with their related objects so if their object dies the timers and transitions will be removed from the master list.

[lua]

– the death of an object removes all of it associations including timers and transitions before the object is cleared

function mt:death(o)

if (o and o ~= nil) then

     if o.shaderInfo  then mt.shader.removeObject(o) end

     if o.timer then mt:clearTimer(o.timer)  end

     if o.timer2  then mt:clearTimer(o.timer2)  end

     if o.shadowList  then mt:clearFromTable(o.shadowList, o) end

     if o.myTable then mt:clearFromTable(o.myTable, o) end – object list “sphere”, “egg”, “worm” etc.

     if o.trans then mt:clearTrans(o.trans) end

     if o.eye then mt:clearObject(o.eye)      end

     if o.shadow then mt:clearObject(o.shadow) end

     if o.ripple then mt:clearObject(o.ripple) end

     if o.ripple2 then mt:clearObject(o.ripple2) end

     mt:clearObject(o)  end

end

[/lua]

Hi! I definitely use a game module. In fact, I use TONS of modules. Typically I will have a “gameEngine” module, containing an “enemiesManager” module, containing for example an “alienShip” module, containing an “alienShipBulletManager” module, containing an “alienShipBullet” module. It sounds very cumbersome and complicated, but the reality is the opposite: yes, it means you get lots of modules, but each modules has a clean, simple, welldefined and easy to understand (and debug) job.

I also have a really handy parent/child setup for these, which helps me speed up my coding tremendously. Handy meaning consistent and easy to read.

Also of note, I actually have an appEngine module called from main.lua that creates the game in it’s own module and displayGroup, so in essence I can have multiple instances of my game running in one app, side by side and scaled / rotated differently.

So, as far as I’m concerned, you can’t have enough hierarchical levels in your modules and displayGroups!

you use:

if (o and o ~= nil) then

you can use:

if o then

with the same result as yours…

your statement

 if o.shaderInfo then mt.shader.removeObject(o) end 

Usualy, I create the if statement to check if the argument is valid or not inside the function not outside.

why?

because in your case…if in other parts of your code you call more times this function, you will need to create an “if” in all of them.

in my case, I only need to create 1 time…inside the function.

you have this problem here:

if o.timer then mt:clearTimer(o.timer) end if o.timer2 then mt:clearTimer(o.timer2) end

since you don’t have any object check inside your function you had to create the if 2 times to check if the object exists before going to the function…

regards,

Carlos.

I don’t create games…but I do create business apps.

Usualy I create functions that I know I will use it in other apps or more than 1 time in the same app. self-contained modules.

in my last projects, I studied all buttons, shadows, menus from material design website. tried to mimic their results.

my UI.lua file has this functions:

-- topBar -- testNetworkConnection -- urlEncode -- networkRequestImages -- networkRequest -- endTransitions -- dbCopy -- divider -- changeState -- background -- backgroundStatusBar -- addCircleShadow -- circle shadow -- createShadow -- rectangle shadow -- bottomShadow -- line shadow -- checkBox -- switchButton -- tooltips -- toolbar -- menuTreeItems (use bottomNavigation) -- menuFourFiveItems (use bottomNavigation) -- bottomNavigation (use this function instead menuTreeItems or menuFourFiveItems) -- listStyleSheet -- actionButtonSpeedDial (revise code) -- actionButtonMenu (revise code) -- actionButtonChange (revise code) -- actionButton -- button -- unselectButton -- used for Button -- selectButton -- used for Button -- disableButton -- used for Button -- changeButtonState -- used for Button -- changeButtonColors -- used for Button -- enableButton -- used for Button -- dialogBox -- dialogBoxLogin -- dropdownButton -- card -- cardBlock -- cardBlockLinks -- cardContentImage -- cardContentImageAvatar -- cardBlockLinks3x -- chip -- gridList -- list -- menu -- slider -- sliderEditable -- sliderAnimated -- snackbar -- subHeader -- tabs -- use only with 3 or less elements -- tabsScroll -- use for any number of elements (if you have more than 3 is recomended using center=false) -- newTextField -- focusNewTextField -- used on newTextField -- unfocusNewTextField -- used on newTextField -- resetNewTextField -- used on newTextField -- createBackgroundFields -- used on newTextField -- showErrorMessage -- used on newTextField -- utf8\_decode -- utf8\_encode -- newCalendar -- get\_year\_month\_day -- get\_days\_in\_month -- get\_day\_of\_week\_alternative -- get\_day\_of\_week -- get\_month -- get\_day\_week\_month\_day -- get\_date\_parts\_alternative -- get\_date\_parts -- maxWidth -- maxChars -- limitString -- splitString -- addTouch -- return self if return\_self=true -- fileExist -- menuScrollNew -- slideRotate -- removeMost

right now its a mess and I need to remove some of this functions to different files…not related to UI…this all functions are about 16k lines…all functions have an example how to use them so I can remember later the code needed to execute them properly so the real code is less than this.

with the help of this file. usually, my scenes are about 200 to 300 lines. oh, I use my own code to create/remove scenes it’s about 40 lines to take care of any transition from 1 scene to another…100 lines to remove any scene…

@carloscosta, very true regarding the double check for “o”. 

This is my “working code” so it’s not optimized and has a lot of artifacts and stand-ins from cobbling together various methods, structures and ideas - some more refined that others.  As for the extra “o” check, sometimes I add a property to the second “o” to add an on-the-fly filter for the objects I’m asking to “die”  see below

[lua]

  1. if (o and o ~= nil) then
  2. – o~= nil is a stand in for testing other properties. While in development I sometimes find in useful to drop in a test another property on the fly like:
  3. if (o and o.x ~= nil) then – sometimes I need to sort objects that way so only some “die”

[/lua]

Also, very true about the double checking for valid arguments.  In an earlier version of the “death” function, all of the instructions were contained in the initial “if” statements.  At some point, I extracted the instruction sets into their own functions (with their own checks) and added a reference without deleting the initial if/then check for valid arguments - so yes, very unnecessary redundancies for now.  This will definitely be refined in a future code revision.  Although now it’s bugging me so I think I’ll do it tonight  :wink:

Carlos, it looks like you are using a database.  What is your preferred method for database integration.  Have you tried / do you use Coronium Core?  It’s worked really well for me.

Only a true coder will do it now rather than defer to another time!  

But that “true coder” should really release something  :wink:

@sporkfin, i’m using a shared hosting plan(reducing costs to min), databases are created in mysql.  database normalization usually is at least 3NF.

To get data from the database to my apps I use webservices created in PHP with prepared statements and some encryption when needed. The best part is after they are created are very easy to use in other apps. most of the changes are the SQL queries, nothing more. 100% of my apps I use local and/or remote databases.

Coronium Core looks fantastic and pretty easy to use, but the running costs of cloud services usually are a bit higher than a shared hosting plan that’s the only reason we went for this approach. Righ now I’m testing Coronium Ace and its really fantastic. in less than a day, learning and creating a small app, i was able to create a small chat app (if i can call it that).

@SGS, working on it bro!   :smiley:

@carloscosta, I’m using digital ocean for $5/month and it easily scales up to meet demand.  With all the cloud server competition and, of course, tech progress in general, DB’s much cheaper than a few years back.

By the way, my new “death” code looks like it got a makeover on a realty TV show for coders   :stuck_out_tongue:

@sporkfin, with $5/month with your plan what can you do or have?

we where paying about 100€/year. we just upgrade our package to a 400 € plan but we only paid half for 2 years (we will negociate the price when the contract is over again). right now we have more than 15 databases. 10 websites some backoffices, “unlimited bandwidth”, “unlimited space”.

By the way, my new “death” code looks like it got a makeover on a realty TV show for coders    :stuck_out_tongue:

LOL. show us :slight_smile:

@sporkfin glad to hear!   Do checkout one.com I was using them until I became a pain and was maxing out their servers (going dedicated was expensive but refreshing).  Their basic hosting is seriously cheap!  I was running 500,000 users on like $100 a year.

I now have dedicated servers for my games at around $100 a month with full redundancy, node replication, unlimited dbs, unlimited traffic, etc.

@sporkfin, i notice that you call a function more than 1 time to clean the same type of object.

what i do is:

i put all timers in a table called timers

i put all transitions in a table called trans

i put all objects in group, or subgroups when needed.

to remove them is less code, easier to debug and prevent errors.

you just need a for i=#timers, -1 do…code inside to remove…end

all timers removed…same for the others.

to remove a scene i only use 1 line: ui.removeMost(masterGroup)

@carloscosta, Yes I do have master lists for all of those and one line control for pausing, resuming, cleansing timers and transitions, and scrubbing entire scenes.  For instance, ui:skillScene() - removes all of the above

The code above was originally referenced as an example of how I cleanse one object when it dies and remove it’s reference from master lists.  The code was an excerpt from a larger section of even crazier code.  I chose to share the snippet I did because it’s the most human readable in that it uses simple names instead of abbreviations from my imagination.  The objects might be the same type, but they have many other objects and events associated with them that also have to be cleansed so it’s not just a simple timer removal until the very last step.

In my world, each object has it’s own AI loop which interacts with other objects and AI loops and physics and timers with delays so when an object dies it might be interacting with a dozen other objects and be in the middle of multiple physics events.  It might also be under the influence of several timers with delays.  Each one of the attributes of the object that dies might be having interactions with other attributes of other objects.  If one object dies and another object is still “thinking” of any aspect of it, I get crashes and memory leaks, so I’m constantly making checks, scrubbing an cleansing hundreds of objects.

I also have to track whether an object is alive so I don’t try to kill it twice.   If an object is dying slowly from say hunger and poison and then something else kills it right before it was going to die, I might end up in a situation where one object dies 3 times in the same millisecond while it’s also interacting with delayed timers.  Actually, before I can even call the “death” function I have to run a “pre-Death” function to unlink the object from other objects and events (basically, tell everyone else to ignore the object). Thus, my code ends up with a lot of redundancies to guard against unanticipated and novels events.  The creatures I’ve been describing don’t move along a path or a grid, in fact, the whole system is very open ended and unpredictable which means - yes, even more if/then checks - so many that they may not even seem abnormal until someone points them out to me  :wink:

Eventually, I circle through the code and cull as many conditional statements as possible - and then I think of another AI enhancement and they return!

@SGS

With numbers like that, I can see how one.com would be appealing with their unlimited bandwidth.

Here’s what the Digital Ocean prices look like.   I still have shared server space on pair.com from back when I was a web designer /developer.  I have found both Digital Ocean and pair.com to have excellent customer service which I prioritize as I don’t get all geeked out happy about server-side work and will pay a premium to not have to worry about it.  That might change when I’ve got hundreds of thousands of users. . . like some people!