Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat
Spine and Photon Multiplayer support in Gideros - Gideros Forum

Spine and Photon Multiplayer support in Gideros

Apollo14Apollo14 Member
edited November 14 in General questions
Hi guys!

IMO there're two critical things that are missing:
- Spine support (fully featured, with skins, etc.)
- Multiplayer support (Photon Cloud, it has become an industry standard)

'Serious' game developers can't use game engine if it doesn't fully support Spine, it's an industry standard, we can't avoid it. Multiplayer support is also pretty mandatory.

Currenly we have partially working p2p multiplayer support via Google Play Services, but there're few essential calls that are missing (for example 'leaveroom()'). And it's pretty painful to work with Google Play console, some time ago when I was testing p2p multiplayer, it took many days to make it work.
And Google's multiplayer doesn't work on iOS, that's an unsolvable problem.
We also have 'NoobHub' server, that is suitable only for card games or chess, where bad latency can be tolerated.
'Gideros Unite' is for local multiplayer only.

I'm in no way trying to blame maintainers, they did huge amount of work, it's a miracle how dramatically Gideros changed during last year, it's really miraculous. I'm subscribed to Corona&Defold updates, they didn't change as dramatically as Gideros, though they have full-time devteams hired.

Guys if somebody else here is missing Spine and Multiplayer, can we crowdfund it?


If not, personally I have only two options - stick to what I know and have already, and focus on releasing few simple games withot stuff that I was planning.
Another option is to join the flock - switch to Unity, not because I need their bells and whistles and crap asset store, but because it supports everything out of the box, all the game services, analytics, Spine, Photon, etc. Unity is a plague.
Or maybe check Cocos2d-x, if their C++ API is as scary as some people say.

Please tell what you think about it.
Thanks.
> Newcomers roadmap: from where to start learning Gideros
"What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
«1

Comments

  • I think someone has asked for more Spine API commands to be available, it's just that initially @hgy29 didn't know what users wanted.

    Photon Cloud is a good idea, their SDK appears to be available for all of our export types.

    Likes: Apollo14

    +1 -1 (+1 / -0 ) Share on Facebook
  • olegoleg Member
    @Apollo14 я 2 дні назад читав інтерв'ю. розробника 3dCoat -у нього спитали -"чому ви в 3dcoat -не зробите анімацію? цеж галузевий стандарт який є в усіх 3д редакторах"

    розробник відповів -ми не хочемо витрачати ресурси на функції де ми не є лідерами. 3dCoat -не повинен мати всі функції, ви повинні викоритовувати різні 3d редактори під свої потреби


    **
    якщо говорити про Gіderos - для мене не стоїть вибір gіderos чи Unity - я користуюся обома двигунами, і мені не потрібні однакові двиуни -gideros займає свою нішу, а unity - свою




    Likes: SinisterSoft

    +1 -1 (+1 / -0 ) Share on Facebook
  • I agree with @oleg . It is a double sided knife, there are somethings Gideros good at, there are somethings Gideros is bad at. In general friendly speaking pluses are more than the minuses for myself. But again this outcome can change according to your needs. There is no universal solution which fits all i guess. It is like a living organism, all programs are adapting to the new needs. Some are faster some are slower. As far as i can say Gideros has a significant fast adaptation process.

    Crowdfunding is also a good idea if the demand is high. So for this let us generate a user base how many people want to see Gideros supporting fully SPINE and PHOTON.
    I can vote + for both property.
  • Its hard to compare an SDK like Defold to Gideros because Defold is owned by King Games and they have literally millions of dollars to spend on making their SDK better, Gideros is on the other hand run by a handful of people with basically zero funding.

    As such you would expect other well funded SDK's to have a more full feature set but I do understand your frustration. I'd like to see a whole bunch of things in Gideros, like Multiplayer support, PathFinding, and a load of other things that I've squeeked on about on and off for ages.

    At the end of the day I (and everyone) can squeek for what they think Gideros needs but It's @hgy29 who is doing the heavy lifting so it is up to him what gets added. He has a f**king tough as job and he does this all for nothing.. whilst holding down a full time job of his own.. respect!

    For all its shortcomings, I still really think Gideros is the best 2D engine available. If there was some rich person or organization that could pump some funds into it so there could be rapid development and a proper road map.. it would really take off!

    Likes: SinisterSoft

    +1 -1 (+1 / -0 ) Share on Facebook
  • hgy29hgy29 Maintainer
    I didn't look at photon thing, can't tell about that one. Basically I don't use any existing gaming services: they are all inadequate in my opinion because each game need its own custom server side code at some point. I write all my gaming backends myself with Java+MongoDB and JSON-RPC interface. Yesterday I was telling myself that a generic version of my server could be hosted on gideros servers, but as I just said a generic version might be enough only for really simple games. Something to think about anyhow I think.

    For spine, gideros does have a complete support for it as long as you use the lua-based version. It is not as efficient as the native one, but you have access to all features.
  • Apollo14Apollo14 Member
    edited November 12
    Thanks! I totally forgot about spine-lua lib that has all the functionality.
    If there was some rich person or organization that could pump some funds into it so there could be rapid development and a proper road map
    That's exactly my desire :smiley: To have successful apps that'll generate really good income, and reinvest it into the engine.

    @hgy29 IMO custom servers are very expensive, cause they have to be located worldwide for good latency. At least in the NA, SA, EU, and two asian regions. None of them can be skipped, all are important markets.

    It is expensive to pay monthly rent for 5 servers and hire good backend specialist who'll setup them all.

    Even huge publishers choose Photon, though they have enough resources to have their own custom servers. What to say about indies.
    > Newcomers roadmap: from where to start learning Gideros
    "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
  • I think someone has asked for more Spine API commands to be available, it's just that initially @hgy29 didn't know what users wanted.

    Photon Cloud is a good idea, their SDK appears to be available for all of our export types.

    Let's find out how much gold is needed for Photon integration and how many people are willing to crowdfund?
    1. Apollo14
    > Newcomers roadmap: from where to start learning Gideros
    "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
  • I was wary of Photon at first because you have to search for prices - but the price for photon for 60 months is pretty good ($95 or something similar). But can you have more than one game on there for that?

    @PaulR was thinking about a plugin tutorial, maybe that would be a good one to do? ;)
  • Apollo14Apollo14 Member
    edited November 12
    @SinisterSoft it seems that their one-time plans are for one app only, and they have some other plans
    I guess game can be tested and soft-launched on a free plan, if metrics are good, then it's worth to get 'one-time' plan
    If I'd have to use their non-one-time plan, I'd prepare at least two multiplayer games to squeeze more from the plan. :D
    @PaulR was thinking about a plugin tutorial, maybe that would be a good one to do?<</p>
    that would be a great one to do!
    > Newcomers roadmap: from where to start learning Gideros
    "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
  • keszeghkeszegh Member
    edited November 12
    you should ask @hgy29 or anybody else capable (is there?) for how much they would add photon. then make a tentative kick-starter noting for whom it is worth how much to have photon addon. and if there is enough money tentatively then you can straight donate this to gideros and then it will be done without paying kickstarter the fee.
  • @hgy29.. 101% of the games we make here are simple games :D

    Likes: hgy29

    +1 -1 (+1 / -0 ) Share on Facebook
  • hgy29hgy29 Maintainer
    edited November 12
    antix said:

    @hgy29.. 101% of the games we make here are simple games :D

    i must be among the -1% that have needs that don’t fit in standards :smiley:

    Likes: antix

    +1 -1 (+1 / -0 ) Share on Facebook
  • PaulRPaulR Member, Maintainer
    I sent another email to Photon about splitting the Corona file into a generic interface and proprietary compiled code. I think that's a good idea for them (for business from users of other Lua engines that aren't Corona) and us.

    Re a tutorial, I think the tutorial needs to focused on building and interfacing with Gideros. Then that non-obvious knowledge can be applied to simple extensions to apps or more complicated plugins which uses general programming knowledge.

    Likes: Apollo14

    +1 -1 (+1 / -0 ) Share on Facebook
  • PaulR said:

    I sent another email to Photon about splitting the Corona file into a generic interface and proprietary compiled code. I think that's a good idea for them (for business from users of other Lua engines that aren't Corona) and us.

    They didn't agree to do it for Defold engine :/
    https://forum.photonengine.com/discussion/7976/lua-version-for-defold
    I guess they're afraid of hackers/cheaters?
    > Newcomers roadmap: from where to start learning Gideros
    "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
  • Likes: antix

    > Newcomers roadmap: from where to start learning Gideros
    "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
    +1 -1 (+1 / -0 ) Share on Facebook
  • Here is the photon.lua file converted from the bytecode that Corona use to the bytecode that Gideros uses:
    https://www.dropbox.com/s/0wyw3t6waxlu5uj/photon.lua?dl=0

    I tested it on the helloworld corona example. I had to add my app id, then comment out the bit at the bottom that hangs about.
    client:connectToRegionMaster("EU")
    client.logger:info("Start")
    --if display then
    --   client.logger:info("Start")
     --  timer.performWithDelay( 100, client, 0)
    --else
    --   while true do
     --      client:timer()
      --     socket.sleep(0.1)
    --    end
    --end
    I also added socket.lua to my project, don't know if it's needed or not. :)

    If anyone converts the Corona photonsdk examples then please send me a copy. :)

    Likes: Apollo14, PaulR

    +1 -1 (+2 / -0 ) Share on Facebook
  • SinisterSoftSinisterSoft Maintainer
    edited November 13
    Here is a replacement for the helloworld example, you need to add the socket.lua file to your project.
    local LoadBalancingClient
    local LoadBalancingConstants
    local tableutil
    local Logger
    local photon
     
    if pcall(require,"plugin.photon") then -- try to load Corona photon plugin
        print("Demo: main module:","Corona plugin used")
        photon = require "plugin.photon"    
        LoadBalancingClient = photon.loadbalancing.LoadBalancingClient
        LoadBalancingConstants = photon.loadbalancing.constants
        Logger = photon.common.Logger
        tableutil = photon.common.util.tableutil    
    else  -- or load photon.lua module
        print("Demo: main module:","Lua lib used")
        photon = require("photon")
        LoadBalancingClient = require("photon.loadbalancing.LoadBalancingClient")
        LoadBalancingConstants = require("photon.loadbalancing.constants")
        Logger = require("photon.common.Logger")
        tableutil = require("photon.common.util.tableutil")    
    end
     
    local appInfo = require("cloud-app-info")
     
    local EVENT_CODE = 101
    local MAX_SENDCOUNT = 100
     
    local client = LoadBalancingClient.new(appInfo.ServerAddress, appInfo.AppId, appInfo.AppVersion)
    -- client:setLogLevel(Logger.Level.DEBUG)
    local lastErrMess = ""
     
    function client:onOperationResponse(errorCode, errorMsg, code, content)
        print("debug","onOperationResponse", errorCode, errorMsg, code, tableutil.toStringReq(content))
        if errorCode ~= 0 then
            if code == LoadBalancingConstants.OperationCode.JoinRandomGame then  -- master random room fail - try create
                print("info","createRoom")
                self:createRoom("helloworld")
    		else 
    			print("error",errorCode, errorMsg)
            end
        end
    end
     
    function client:onStateChange(state)
        print("debug","Demo: onStateChange " .. state .. ": " .. tostring(LoadBalancingClient.StateToName(state)))
        if state == LoadBalancingClient.State.JoinedLobby then
            print("info","joinRandomRoom - 1")
            self:joinRandomRoom()
        end
    end
     
    function client:onError(errorCode, errorMsg)
        if errorCode == LoadBalancingClient.PeerErrorCode.MasterAuthenticationFailed then
            errorMsg = errorMsg .. " with appId = " .. self.appId .. "\nCheck app settings in cloud-app-info.lua"
        end
        print("error",errorCode, errorMsg)
        lastErrMess = errorMsg;
    end
     
    function client:onEvent(code, content, actorNr)
        print("debug","on event", code, tableutil.toStringReq(content))
        if code == EVENT_CODE then
            client.mReceiveCount = client.mReceiveCount + 1
            client.mLastReceiveEvent = content[2]
            if client.mReceiveCount == MAX_SENDCOUNT then
                self.mState = "Data Received"    
                client:disconnect();
            end
        end
    end
     
    local textObject=TextField.new(nil,"")
    textObject:setPosition(100,100)
    stage:addChild(textObject)
     
    client.mState = "Init"
    client.mLastSentEvent = ""
    client.mSendCount = 0
    client.mReceiveCount = 0
    client.mLastReceiveEvent= ""
    client.mRunning = true
     
     
    function client:update()
        self:sendData()
        self:service()
    end
     
    function client:sendData()
        if self:isJoinedToRoom() and self.mSendCount < MAX_SENDCOUNT then
            self.mState = "Data Sending"    
            local data = {}
            self.mLastSentEvent = "e" .. self.mSendCount
            data[2] = self.mLastSentEvent
            data[3] = string.rep("x", 160)
            self:raiseEvent(EVENT_CODE, data, { receivers = LoadBalancingConstants.ReceiverGroup.All } ) 
            self.mSendCount = self.mSendCount + 1
            if self.mSendCount >= MAX_SENDCOUNT then
                self.mState = "Data Sent"
            end
        end
    end
     
    function client:getStateString()
        return LoadBalancingClient.StateToName(self.state) .. "\n\nevents: " .. self.mState .."\nsent "..self.mLastSentEvent..", total: ".. self.mSendCount .. "\nreceived "..self.mLastReceiveEvent .. ", total: " .. self.mReceiveCount 
            .. "\n\n" .. lastErrMess
    end
    local prevStr = ""
    function client:timer(event)
        local str = nil
        --print("logger",trace("quant"))
        if self.mRunning then
            self:update()
        else
            self.ticktock:stop()
            self.mState = "Stopped"
        end
     
        str = client:getStateString()
        if(prevStr ~= str) then
            prevStr = str
            print("\n\n")        
            print(str)
    		if textObject then
    			textObject:setText(str)
    		end
        end
     
    end
     
    function client:startTimer()
    	self.ticktock=Timer.new(100)
    	self.ticktock:addEventListener(Event.TIMER,client.timer,self)
    	self.ticktock:start()
    end
     
    client:connectToRegionMaster("EU")
    print("info","Start")
    client:startTimer()
    Also don't forget to set your app_id in the cloud-app-info.lua file.



    Likes: PaulR

    2018-11-13_08-59-45.png
    341 x 468 - 3K
    +1 -1 (+1 / -0 ) Share on Facebook
  • btw, you don't need socket.lua after all, just remember to add the sockets plugin on export. :)

    Likes: Apollo14

    +1 -1 (+1 / -0 ) Share on Facebook
  • PaulRPaulR Member, Maintainer
    Great OTB thinking there @SinisterSoft !
    +1 -1 (+2 / -0 ) Share on Facebook
  • omg there're hell lot of calls in the Photon SDK, I'll have to check them in the morning when my mind is fresh!

    Likes: SinisterSoft

    > Newcomers roadmap: from where to start learning Gideros
    "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
    +1 -1 (+1 / -0 ) Share on Facebook
  • Apollo14Apollo14 Member
    edited November 13

    @Apollo14 Sticking with Gideros for a while now then? ;)

    OMG you guys what you have done, now I will have to stop whining and start working on an actually planned game project, there're no excuses anymore! It's not fair!!!! :D Especially you, mr.Hacker!
    I have no words, seriously... :*

    Likes: SinisterSoft

    > Newcomers roadmap: from where to start learning Gideros
    "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
    +1 -1 (+1 / -0 ) Share on Facebook
  • PaulRPaulR Member, Maintainer
    @Apollo14 : sorry to be so boring, but could you edit your first post at the top or next to where you say Spine and Photon are missing to clarify the situation when you get a moment? For people in the future who google and don't scroll down?

    Likes: SinisterSoft

    +1 -1 (+1 / -0 ) Share on Facebook
  • @PaulR yes, sure (I've also thought that topic name isn't good)
    > Newcomers roadmap: from where to start learning Gideros
    "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
    +1 -1 (+2 / -0 ) Share on Facebook
  • I've converted demo-helloworld-cloud and demo-console now. Anyone done any of the others?
  • Guys. Are you in the process of Photonifying Gideros on the fly? I'm bringing the popcorn!

    Would be so sweet (not the popcorn, obviously, they should be salty) to have a plug and play multiplayer option in Gideros.

    Likes: Apollo14

    My Gideros games: www.totebo.com
    +1 -1 (+1 / -0 ) Share on Facebook
  • The include file is done - it's in Lua so it's all platforms. It's just the demos to convert.
  • Apollo14Apollo14 Member
    edited November 14
    @SinisterSoft I've found only three corona demos (on this page: https://docs.coronalabs.com/plugin/photon/index.html )
    Are there any more demos somewhere? I didn't find "demo-console", can you pls share its converted version?

    p. s. uh, it took me so long to cut the bs from their corona example and understand how to perform the most necessary actions
    (probably they could've added more basic example, from which new developers could get general concept faster)
    anyway, let's continue grinding... :*
    totebo said:

    Guys. Are you in the process of Photonifying Gideros on the fly? I'm bringing the popcorn!

    Would be so sweet (not the popcorn, obviously, they should be salty) to have a plug and play multiplayer option in Gideros.

    you can help us too by testing and adopting corona examples! (after you finish tasty popcorn, of course)


    btw there's one alternative to photon, which is free from the start (i guess it's much more indie-friendly, but there's no info how do they accept developers to 'indie programme', probably they're not accepting all and everybody)
    https://www.gamesparks.com/pricing/
    (they have non-encrypted libs for Corona and Defold)
    > Newcomers roadmap: from where to start learning Gideros
    "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
  • @Apollo14 The demos are in the coronasdk download from the photonegine website.

    You could make different demos if you like?

    Here is the latest version of the hellowworld-cloud demo with the logging texts working (rather than just 'print')
    local LoadBalancingClient
    local LoadBalancingConstants
    local tableutil
    local Logger
    local photon
     
    print("Demo: main module:","Lua lib used")
    photon = require("photon")
    LoadBalancingClient = require("photon.loadbalancing.LoadBalancingClient")
    LoadBalancingConstants = require("photon.loadbalancing.constants")
    Logger = require("photon.common.Logger")
    tableutil = require("photon.common.util.tableutil")    
     
    local appInfo = require("cloud-app-info")
     
    local EVENT_CODE = 101
    local MAX_SENDCOUNT = 100
     
    local client = LoadBalancingClient.new(appInfo.ServerAddress, appInfo.AppId, appInfo.AppVersion)
    -- client:setLogLevel(Logger.Level.DEBUG)
    local lastErrMess = ""
     
    function client:onOperationResponse(errorCode, errorMsg, code, content)
        self.logger:debug("onOperationResponse", errorCode, errorMsg, code, tableutil.toStringReq(content))
        if errorCode ~= 0 then
            if code == LoadBalancingConstants.OperationCode.JoinRandomGame then  -- master random room fail - try create
                self.logger:info("createRoom")
                self:createRoom("helloworld")
    		else 
    			self.logger:error(errorCode, errorMsg)
            end
        end
    end
     
    function client:onStateChange(state)
        self.logger:debug("Demo: onStateChange " .. state .. ": " .. tostring(LoadBalancingClient.StateToName(state)))
        if state == LoadBalancingClient.State.JoinedLobby then
            self.logger:info("joinRandomRoom - 1")
            self:joinRandomRoom()
        end
    end
     
    function client:onError(errorCode, errorMsg)
        if errorCode == LoadBalancingClient.PeerErrorCode.MasterAuthenticationFailed then
            errorMsg = errorMsg .. " with appId = " .. self.appId .. "\nCheck app settings in cloud-app-info.lua"
        end
        self.logger:error(errorCode, errorMsg)
        lastErrMess = errorMsg;
    end
     
    function client:onEvent(code, content, actorNr)
        self.logger:debug("on event", code, tableutil.toStringReq(content))
        if code == EVENT_CODE then
            client.mReceiveCount = client.mReceiveCount + 1
            client.mLastReceiveEvent = content[2]
            if client.mReceiveCount == MAX_SENDCOUNT then
                self.mState = "Data Received"    
                client:disconnect();
            end
        end
    end
     
    local textObject=TextField.new(nil,"")
    textObject:setPosition(100,100)
    stage:addChild(textObject)
     
    client.mState = "Init"
    client.mLastSentEvent = ""
    client.mSendCount = 0
    client.mReceiveCount = 0
    client.mLastReceiveEvent= ""
    client.mRunning = true
     
     
    function client:update()
        self:sendData()
        self:service()
    end
     
    function client:sendData()
        if self:isJoinedToRoom() and self.mSendCount < MAX_SENDCOUNT then
            self.mState = "Data Sending"    
            local data = {}
            self.mLastSentEvent = "e" .. self.mSendCount
            data[2] = self.mLastSentEvent
            data[3] = string.rep("x", 160)
            self:raiseEvent(EVENT_CODE, data, { receivers = LoadBalancingConstants.ReceiverGroup.All } ) 
            self.mSendCount = self.mSendCount + 1
            if self.mSendCount >= MAX_SENDCOUNT then
                self.mState = "Data Sent"
            end
        end
    end
     
    function client:getStateString()
        return LoadBalancingClient.StateToName(self.state) .. "\n\nevents: " .. self.mState .."\nsent "..self.mLastSentEvent..", total: ".. self.mSendCount .. "\nreceived "..self.mLastReceiveEvent .. ", total: " .. self.mReceiveCount 
            .. "\n\n" .. lastErrMess
    end
    local prevStr = ""
    function client:timer(event)
        local str = nil
        self.logger:trace("quant")
        if self.mRunning then
            self:update()
        else
            self.ticktock:stop()
            self.mState = "Stopped"
        end
     
        str = client:getStateString()
        if(prevStr ~= str) then
            prevStr = str
            print("\n\n")        
            print(str)
    		if textObject then
    			textObject:setText(str)
    		end
        end
     
    end
     
    function client:startTimer()
    	self.ticktock=Timer.new(100)
    	self.ticktock:addEventListener(Event.TIMER,client.timer,self)
    	self.ticktock:start()
    end
     
    client:connectToRegionMaster("EU")
    client.logger:info("Start")
    client:startTimer()
  • Apollo14Apollo14 Member
    edited November 14
    uh, now I see them inside sdk zip file...
    i think demos are ok, I just expected them to be oversimplified :)
    for developing multiplayer game one has to understand all and everything in their API, so it's unavoidable anyway
    but I think I'll create more basic demo for quicker introduction to Photon :smile:
    > Newcomers roadmap: from where to start learning Gideros
    "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
Sign In or Register to comment.