
Share Your Code
Browse Code
- All (902)
-
(94)
-
(84)
-
(44)
-
(4)
-
(42)
-
(135)
-
(21)
-
(41)
-
(13)
-
(65)
-
(150)
-
(209)
Multiplayer Networking and Push Notifications
Corona Multiplayer Networking and Push Notifications API for Mobile Apps and Games
Enable Networking with your Mobile Apps with 3 functions. Networking your apps allows you to implement multiplayer games and more! Implement push notifications between phones, tablets, laptops and web servers. Everything can send and receive data from everywhere on Earth.
- Init PubNub Multiplayer Object
- Call Subscribe() to begin receiving messages.
- Call Publish() to send messages.
NEW! Sample Apps:
Download Corona Networking API
Download Source Code here: https://github.com/pubnub/pubnub-api/tree/master/lua-corona
Download Other Platform APIs
Download Source Code here: https://github.com/pubnub/pubnub-api/
FAQ
- Receive Messages while app is running in the Background?: Yes, however you will need to use APN to force the app to focus.
- How long is the channel available?: Forever.
- Just like words with Friends could I possible make my move hours later?: Yes.
- Would Pubnub still have the channel open or would a new channel have to be opened?: Channel Stays Open.
- What if the message is not delivered? How long will pubnub keep it for?: 24 Hours.
Video Tutorial: PubNub Corona SDK Multiplayer Networking and Push Notifications API
PubNub Corona SDK Multiplayer Networking and Push Notifications API - Watch Video Tutorial on YouTube

Follow these easy steps to get starting with your Networking API for Multiplayer Games and Push Notification Support.
- Download Lua Corona Multiplayer API
- Get Your PubNub Keys Here
- Copy the files into your Lua Code Directory
- Continue Reading to add just 3 functions to Enable Multiplayer Support.
Get Your PubNub Keys Here
http://www.pubnub.com/account#api-keys
Learn about PubNub Cloud-Hosted Service for Real-Time Messaging
http://www.pubnub.com PubNub is a new kind of Cloud-Hosted Broadcasting Service for Mass Communication on Mobile Phones, Tablets, TVs, HTML5 Web Browsers and Game Consoles. Already more messages are published to PubNub each day than to Twitter. We believe in unified broadcasting and mass communication empowerment for application and game developers who build on Mobile Phones, TVs, HTML5 Web Browsers, Tablets and Game Consoles.
Initiate Multiplayer PubNub Object.
1 2 3 4 5 6 7 8 9 10 11 12 13 | require "pubnub" -- -- GET YOUR PUBNUB KEYS HERE: -- http://www.pubnub.com/account#api-keys -- multiplayer = pubnub.new({ publish_key = "demo", -- YOUR PUBLISH KEY subscribe_key = "demo", -- YOUR SUBSCRIBE KEY secret_key = nil, -- YOUR SECRET KEY ssl = nil, -- ENABLE SSL? origin = "pubsub.pubnub.com" -- PUBNUB CLOUD ORIGIN }) |
Listen for Messages from Other Players.
1 2 3 4 5 6 7 8 9 10 11 12 13 | -- -- PUBNUB SUBSCRIBE CHANNEL (RECEIVE MESSAGES) -- multiplayer:subscribe({ channel = "lua-corona-demo-channel", callback = function(message) -- MESSAGE RECEIVED!!! print(message) end, errorback = function() print("Network Connection Lost") end }) |
Send Message To Other Players.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | -- -- PUBNUB PUBLISH MESSAGE (SEND A MESSAGE) -- multiplayer:publish({ channel = "lua-corona-demo-channel", message = { "1234", 2, 3, 4 }, callback = function(info) -- WAS MESSAGE DELIVERED? if info[1] then print("MESSAGE DELIVERED SUCCESSFULLY!") else print("MESSAGE FAILED BECAUSE -> " .. info[2]) end end }) |
Stop Listening for Messages.
1 2 3 4 5 6 | -- -- PUBNUB UN-SUBSCRIBE CHANNEL (STOP RECEIVING MESSAGES) -- multiplayer:unsubscribe({ channel = "lua-corona-demo-channel" }) |
Load Message History
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | -- -- PUBNUB LOAD MESSAGE HISTORY -- multiplayer:history({ channel = "lua-corona-demo-channel", limit = 10, callback = function(messages) if not messages then return print("ERROR LOADING HISTORY") end -- NO HISTORY? if not (#messages > 0) then return print("NO HISTORY YET") end -- LOOP THROUGH MESSAGE HISTORY for i, message in ipairs(messages) do print(Json.Encode(message)) end end }) |
Get PubNub Server Time
1 2 3 4 5 6 7 8 9 | -- -- PUBNUB SERVER TIME -- multiplayer:time({ callback = function(time) -- PRINT TIME print("PUBNUB SERVER TIME: " .. time) end }) |
Checkers Player 1-v-1 Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | -- -- HOSTING PLAYER LISTENS FOR CHALLENGER 1v1 -- multiplayer:subscribe({ channel = "checkers-game-room-" .. game_room_id, callback = function(message) -- NEW CHALLENGER? if message.action and message.action == "request_game_play" then -- ACCEPT CHALLENGER and BEGIN GAMEPLAY end end, errorback = function() print("Network Connection Lost") end }) |
1 2 3 4 5 6 7 | -- -- REQUEST GAME PLAY IN GAME ROOM X -- multiplayer:publish({ channel = "checkers-game-room-" .. game_room_id, message = { action = "request_game_play" } }) |
Game Lobby Room
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | -- -- GAME LOBBY ROOM -- players_in_lobby = {} multiplayer:subscribe({ channel = "game-lobby-room", callback = function(message) -- REQUEST FOR PLAYERS IN GAME LOBBY ROOM? if message.action == "ping" then -- EVERYONE ANNOUNCES PRESENCE -- THIS GIVES EVERYONE IN THE LOBBY A FULL LIST OF PLAYERS multiplayer:publish({ channel = "game-lobby-room", message = { action = "pong", -- REPLY TO "ping" REQUEST player = { id = 12345, name = "JohnyPlayer" } } }) -- RECEIVE PLAYERS IN GAME LOBBY ROOM elseif message.action == "pong" then -- UPDATE PLAYERS TABLE IN GAME LOBBY players_in_lobby[message.player.id] = message.player end end, errorback = function() print("Network Connection Lost") end }) |
1 2 3 4 5 6 7 | -- -- REQUEST ALL PLAYER'S DETAILS IN GAME LOBBY ROOM -- multiplayer:publish({ channel = "game-lobby-room", message = { action = "ping" } }) |
GENERATE UNIQUE ID FOR A PLAYER
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | -- -- GENERATING A UNIQUE ID FOR A PLAYER -- my_player_details = { id = nil, name = "Johny Player" } multiplayer:time({ callback = function(time) -- GIVE PLAYER A UNIQUE ID my_player_details.id = time .. '-' .. math.random( 1, 999999 ) end }) |
Full Game Lobby Room Starting Point
Retrieve Information from Players in Channel
This sample code shows how to retrieve information from other people on the same channel. You will use this to collect a list of player names, IDs, locations and more! This can be done in game, or used as analytics.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | require "pubnub" multiplayer = pubnub.new({ publish_key = "demo", subscribe_key = "demo", secret_key = nil, ssl = nil, origin = "pubsub.pubnub.com" }) -- -- Player ID (Generated Later) -- my_player_id = nil my_player_name = "John Smith" -- -- Generate Player ID -- multiplayer:time({ callback = function(time) my_player_id.id = time .. '-' .. math.random( 1, 999999 ) end }) -- -- Players Per Channel -- players_per_game_room = { game_room_1234 = {}, game_room_5678 = {} } game_room_1234 = "game_room_1234" -- -- Join Game Room 1234 -- multiplayer:subscribe({ channel = game_room_1234, callback = function(message) -- -- Ping? then Pong! -- This sends a message from all players, to all players. -- This lets you know who and how many players are on a channel. -- if message.action == "ping" then multiplayer:publish({ channel = game_room_1234, message = { action = "pong", id = my_player_id, name = my_player_name } }) -- -- Collect Live Players who are in this Game Room. -- elseif message.action == "pong" then players_per_game_room[game_room_1234][message.id] = message -- -- Some Other Game Event -- elseif message.action == "something-else" then end end }) -- -- Request Info About Connected Players -- multiplayer:publish({ channel = game_room_1234, message = { action = "ping" } }) -- -- Print info on Game Room 1234 -- function wait_for_info_from_players() -- -- Print Number of Players -- print("Number of Players in channel: " .. game_room_1234) print(#players_per_game_room[game_room_1234]) -- -- Print Info about Each Player -- for id, player in pairs(players_per_game_room[game_room_1234]) do print("Player: " .. id "'s Name is " .. player.name) end end -- -- Wait at 1 to 3 seconds for player response -- before we assume we've received messages from everyone. -- timer.performWithDelay( 2000, wait_for_info_from_players ) |
- Type:
- Tags:
Replies
frankberlanga,
I have updated the documentation above with additional sample code. It includes examples for a Game Lobby Room and an example for Checkers style 1-vs-1 game play setup.
Great examples, so can you then send and receive game data? For instance, if player 1 won you could send the data this way to end the game for player 2?
Fixdit,
Thank you. Yes, this approach may work to end the game. However for security, ensure winning conditions are calculated on each player's device.
Creating a turn-based Player 1 vs. Player 2 game. I'm right in thinking this will work for that? So there should be a UI button which initiates a new game and a channel ID is generated. Then the second player taps the 'Join game' button where they'll be prompted to enter a channel ID … is this sounding right so far?
Fixdit,
Yes, the channel ID should be random and unpredictable. However it makes sense for a Player to be able to define a "Game Title".
So there'd be a list of unstarted games that players may chose to join. Also a player would be able to "Create" a game and give it a "Game Title".
Of course this is a recommendation and may be implemented many different and fun ways!
Perhaps the game players may be paired automatically, removing the need for a game lobby room.
Thanks,
this is all really useful. Apologies for the number of questions, just feel very close to getting a full grasp of this; it's a new concept. Just a couple last things:
How do you know that the two players have successfully joined via their devices and then also that a connection isn't lost during the game?
Fixdit,
I updated the document above with a "Full Game Lobby Room" Example which shows where a new game would be hosted and announced to the lobby room. This will show allow you to display a list of unstarted games.
An "errorback" function can be used to detect if a connection is dropped.
Fixdit,
Thank you for asking all the questions! The Full Game Lobby Room Example has been updated to include how a Hosted Game will Start between two players.
Yeah that looks really comprehensive now, great work :)
I think I have found an issue with using embedded object data to send a message.
pubnub.lua:
1 2 3 4 5 6 7 8 9 10 | function publish_my_details() multiplayer:publish({ channel = "game-lobby-room", message = { action = "respond-to-call", -- REPLY player = my_player, -- SEND MY PLAYER DETAILS game = my_game -- SEND MY GAME HOSTING DETAILS } }) end |
I get the following error:
1 | pubnub.lua:195: bad argument #4 to 'gsub' (number expected, got string) |
Fixdit,
Thank you for reporting this. An update will be available in 24 hours.
I'm working on tweaking it now. If I get it to work, I'll post it back here :)
I found what I believe to be the problem. It was 'spaces' In the embeded object data. For instance, the 'my_player' object contains the name: "Johnny Player". I used "JohnnyPlayer" which worked fine.
Needed to take a look at the encoding fuction in the pubnub.lua file. Downloaded a fresh pubnub.lua to check I hadn't edited the file myself and I found on line 196:
Before:
1 | str = string.gsub( str, "([^%w ])", function(c) |
The 'space' after the 'w' in the regular expression kicks up the error. Remove this and things work fine.
After:
1 | str = string.gsub( str, "([^%w])", function(c) |
Fixdit,
Great job! We will implement this update after testing it. Have you confirmed it to be working?
Does it makes sense to you to remove the commented lines:
1 2 3 4 5 6 7 8 9 10 11 12 13 | function self:_encode(str) -- REMOVE -- str = string.gsub( str, "\n", "\r\n" ) -- REMOVE -- KEEP str = string.gsub( str, "([^%w])", function(c) return string.format( "%%%02X", string.byte(c) ) end ) -- REMOVE -- str = string.gsub( str, " ", "%20" ) -- REMOVE return str end |
We'll test this too, however we want your suggestion.
Updated Encoding Function:
1 2 3 4 5 | function self:_encode(str) return string.gsub( str, "([^%a%d])", function(c) return string.format( "%%%02X", string.byte(c) ) end ) end |
Fixdit,
We updated the pubnub.lua file with the latest fixes. Thank you for reporting and finding a fix!
Would PubNub be suitable for turn-based games that aren't continuously active, as when each player has one day to complete a turn? I assume the process would involve creating a channel, destroying it, and recreating it as needed?
Dotnaught,
Yes, this type of communication is suitable. This low level of activity would for sure keep your account in the daily free quota range. Your Bi-directional communication layer would be free.
It looks like this is a sort of in-app push notification system. How would this work if the receiver's app weren't running? Could you still send a message to another "player" without their app running? I'm assuming that would call for a native push notification. Maybe this will be integrated with true iOS push notifications?
Also, how would you go about connecting to specific other people? Say I want to connect to a friend or family member. How to do you make that initial connection? Over email? Through Facebook?
Hesadanza,
Yes, this is an in-app high performance push notification addition in Corona SDK for multiplayer games and real-time networked applications.
The app must be running to receive messages. Bidirectional communication is ready between multiple platforms and devices. For example, your friend on a Facebook App could send a message to your phone. Or your phone can send a message to your buddies phone.
How would you set up a channel between one user and their friend, or multiple friends? How would you establish that link? Looks like both users need to know the channel name to subscribe to it. Would your app send out a code that the other users would put into their apps to join the channel?
Hesadanza,
In order to send messages directly to your friends, you will set a channel name as the USER ID. Each of your friends will listen (subscribe) to their own USER ID as the channel. When you want to send a message to your friend, you will use their USER ID as the Channel Name.
For example, set the channel name to be the Facebook User ID of your friend.
1 2 3 4 5 6 7 8 9 10 | -- -- YOUR FRIEND LISTENS TO THEIR OWN USER ID CHANNEL -- multiplayer:subscribe({ channel = 4757484985, callback = function(message) -- YOUR FRIEND RECEIVED A MESSAGE FROM YOU. print(message.text_message) end }) |
Then you may send messages to the User ID Channel of your friend. Now you friend will receive your messages!
1 2 3 4 5 6 7 | -- -- SEND A MESSAGE TO YOUR FRIEND -- multiplayer:publish({ channel = 4757484985, message = { text_message = "Hello Friend!" } }) |
Interesting solution!
Hopefully this can be integrated with native push notifications soon, so if you send a message to a friend, and the app isn't open, it would send a native push, which could open the app and deliver the message to the app.
Hesadanza,
Great idea. We will support Corona SDK with Apple Push Notifications. Though this isn't necessary to build multiplayer games today. The Corona SDK is ready today for creating Multiplayer games and Networked Apps right now.
Hi Stephen,
Is it advisable to use the 'demo' pubnub key in a final draft, published app? Is it required that you use a unique secret, subscribe and publish key or is this just required for security?
1 2 | publish_key = "demo", subscribe_key = "demo", |
Fixdit,
Get your publish_key and subscribe_key from this URL:
The "demo" keys must not be deployed in a production application. For example, the "demo" keys must not be deployed on the Apple App Store.
You must deploy your application with your API Keys found here:
This is for security and other beneficial reasons associated with your app.
Thanks for sharing this piece of code. I tried it on an iphone and works very well.
However, when I build for the Android, it does not work. I just don't get the messages when they are sent.
Any idea?
Lourenco,
The current release of Corona SDK offers iPhone support only. https://developer.anscamobile.com/downloads/corona-sdk#Async_HTTP_Access_iOS_Only
This may be remedied by using the Daily Builds:
http://developer.anscamobile.com/downloads/daily-builds
Click the link above to download a daily build.
Thanks Stephen.
I got the latest daily build. But still does not work for Android device... perhaps async http access still not available in those builds.
Do you know when this feature will be available for android.
Lourenco,
We are working on implementing multiplayer for Android. There will be an announcement when this is ready.
Has been working fine, then all of a sudden, this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | .../json.lua:294: Invalid input: '<html> <head><title>502 Bad Gateway</title></head> <body bgcolor="white"> <center><h1>502 Bad Gateway</h1></center> <hr><center>nginx/0.9.3</center> </body> </html> ' stack traceback: [C]: ? [C]: in function 'error' .../json.lua:294: in function <.../json.lua:269> (tail call): ? .../pubnub.lua:192: in function <...bnub.lua:188> |
Definately something on the side of PubNub. Nothing has changed in my app's code. Is it temporary server issue?
Fixdit,
Thank you for reporting this. It is a rare edge case in the Lua API. We will provide a patch for this in the next few days.
This page http://www.pubnub.com/javascript-unit-test is a Cloud Uptime Indication. If the test passes 100% complete, then the PubNub Cloud is fully functional.
Fixdit,
We updated the PubNub Lua Corona SDK API for Multiplayer Networking and Push Notifications. Find the updated API file here:
https://github.com/pubnub/pubnub-api/tree/master/lua-corona
Download the latest pubnub.lua file replacing your old pubnub.lua file in your project folder.
New Video: PubNub Corona SDK Multiplayer Networking and Push Notifications API
http://vimeo.com/pubnub/pubnub-corona-sdk-multiplayer-networking-api
This is really awesome... I was looking for a solution to do this. Will definitely look deeper into it.
digitalblur,
That is great to here. Let us know if you are building real-time communication for games or applications.
Is there a way to limit the amount of connected players to a channel? We need to limit it to 2 if this is possible through the API.
Fixdit,
You may implement this by sending a message on the channel to be limited by 2 people. The message would invoke a reply from anyone connected to the channel. So if two people are already connected, then you will know to prevent more then two people from running on the same channel.
This is a simple Ping/Pong type message. Because the multiplayer Corona SDK is so simple, it does not come with this functionality built in. However it is powerful and allows you to implement complex or simple design patterns. Let us know if you need som sample code based on our description.
I would like to see some examples. Can you post/send the sample code? Also can you talk more about the design patterns that is supported? Which patterns are supported and do you have examples?
Thanks!
digitalblur,
All design patterns are available to you. You are converted to a cloud networking expert by taking advantage of the Multiplayer Networking API in Corona SDK. This means you must consider how best to implement the two most important functions: Publish (send) and Subscribe (receive). Sample code design patterns are available here: http://www.pubnub.com/tutorial/developer#advanced on the PubNub website. The examples are in other Programming Languages, not Lua. However the design patterns still apply. A following post will include Fixdit's requested design pattern.
This sample code shows how to retrieve information from other people on the same channel. You will use this to collect a list of player names, IDs, locations and more! This can be done in game, or used as analytics. The code below has been re-posted in the primary doc area higher in this page.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | require "pubnub" multiplayer = pubnub.new({ publish_key = "demo", subscribe_key = "demo", secret_key = nil, ssl = nil, origin = "pubsub.pubnub.com" }) -- -- Player ID (Generated Later) -- my_player_id = nil my_player_name = "John Smith" -- -- Generate Player ID -- multiplayer:time({ callback = function(time) my_player_id.id = time .. '-' .. math.random( 1, 999999 ) end }) -- -- Players Per Channel -- players_per_game_room = { game_room_1234 = {}, game_room_5678 = {} } game_room_1234 = "game_room_1234" -- -- Join Game Room 1234 -- multiplayer:subscribe({ channel = game_room_1234, callback = function(message) -- -- Ping? then Pong! -- This sends a message from all players, to all players. -- This lets you know who and how many players are on a channel. -- if message.action == "ping" then multiplayer:publish({ channel = game_room_1234, message = { action = "pong", id = my_player_id, name = my_player_name } }) -- -- Collect Live Players who are in this Game Room. -- elseif message.action == "pong" then players_per_game_room[game_room_1234][message.id] = message -- -- Some Other Game Event -- elseif message.action == "something-else" then end end }) -- -- Request Info About Connected Players -- multiplayer:publish({ channel = game_room_1234, message = { action = "ping" } }) -- -- Print info on Game Room 1234 -- function wait_for_info_from_players() -- -- Print Number of Players -- print("Number of Players in channel: " .. game_room_1234) print(#players_per_game_room[game_room_1234]) -- -- Print Info about Each Player -- for player_id, player in pairs(players_per_game_room[game_room_1234]) do print("Player: " .. player_id "'s Name is " .. player.name) end end -- -- Wait at 1 to 3 seconds for player response -- before we assume we've received messages from everyone. -- timer.performWithDelay( 2000, wait_for_info_from_players ) |
Thank you! This is very cool and will begin experimenting...
I know this might sound like a dummy question, but how could I test the game "Full Game Lobby Room Example" you posted in the Corona simulator?
I see nothing printed on my console.
Thanks
Mxhneo,
You are correct. The code in the example will not by default print anything. You must supply the interface.
We recommend starting with a simple example: https://github.com/pubnub/pubnub-api/blob/master/lua-corona/example-hello-world
After familiarizing yourself with how to send messages between multiple devices, begin to dissect the Game Lobby Room code.
Is the hello world example supposed to work in the simulator of Corona? I don't get anything in the console.
However, the java example works fine.
mxhneo,
Multiplayer Networking in Corona SDK currently only supports iOS. Android support is under development.
At the final testing stage for the creation of a 2 player turn based game. We'e been finding latency problems using Pubnub. One player ends their turn sending a message for the next player's to begin. On a good many occasions it has taken 10-30 seconds from the 'publish' action being sent, to it received by the subscriber down the channel at the other end.
Why might this be taking so long? The devices are communicating over a reliable Wi-Fi connection. Is there anyway to optimise this?
@Stephen: ok, I haven't seen that. I'm waiting for the Android version :)
Another questions I have:
- Could you tell us more about the strategy of pricing? I saw you charge per message. But it is not clear to me who will pay this money: the players of my game or me?
- Does your licence allow me to host pubnub? If I do so, will the sending of messages be free of charge?
Thanks!
Fixdit,
http://stats.pingdom.com/e7pvn9wfotdy/302344 - fast deliverability for the PubNub Public Cloud Origin. The response times are less than 1 second.





This is excellent. I do have a question regarding a 1-vs-1 game scenario. Based on the example above, it appears that anyone subscribing to the 'lua-corona-demo-channel' can send/receive messages to everyone else on the channel. If all players share the same channel, how can you target a specific player? Can you dynamically create channels that only certain players can send/receive messages to, or is there some other mechanism to achieve this? For instance, how would you use PubNub to support an online game of checkers between two players?