Online Features Design - 'Push Like?'

some1one

Villager
Member
Joined
May 20, 2015
Messages
11
Reaction score
0
First Language
English
Primarily Uses
I am creating my own online functionality. While I would like it to be real-time (or near real time), I can't think of a way to do that with rpg maker. I can make it async and even use sockets but real time still seems impossible. I even thought of making a companion application that would work in real time but a problem still exists.

The only way I have seen so far to retrieve online data is to manually make a request from within the rpg maker scripts. I could make this request fire off every second but that will most likely cause severe performance issues. So far all I can think of to do is make the request every minute or so but that defeats the purpose of real time.

I am wondering if there would be any way to implement sort of a 'push' functionality where I don't have manually make the request. I know this can't be done with dlls. Does anyone know of a way to do this in ruby? There is also a LoadSo script updated by FenixFyreX that allows you to load ruby extensions. I haven't looked into that much but can anyone think of a way to do this using that?

I have a usage scenario below. I would appreciate any ideas, simple or complex. No code is necessary, im mainly just looking for design ideas about this.

Example: In a battle system, normally I would just have turns last a certain amount of time. Regardless of whether or not you completed you turn you would have to wait until the time is up. What I would like to have happen, is that when someone finishes their turn, it would send sort of a 'push notification' to the server/other player that their turn is up. The problem I would like ideas about is receiving that push automatically.
 

Iavra

Veteran
Veteran
Joined
Apr 9, 2015
Messages
1,797
Reaction score
863
First Language
German
Primarily Uses
So far the only online functionality i've seen for Ace is maintaining an online highscore. What you need hasn't been done so far and you would not only need to write the whole netcode but also modify the engine in a way that it can actually work with it.
 

Hudell

Dog Lord
Veteran
Joined
Oct 2, 2014
Messages
3,545
Reaction score
3,715
First Language
Java's Crypt
Primarily Uses
RMMZ
I'm not sure I understand what you want. Both me and Dekita have created libs to connect to the internet, so that is not an issue here.

Making an async request every second (not every frame) shouldn't be a problem, but I'm still trying to understand what you're trying to achieve.

Edit: Ah, sorry, I misread the last paragraph. Sending information at the end of the a turn should be fairly easy. You will just need a loop checking if there's any response. Do not make a different request to get the information from the server, just wait for the response to the first request (on a thread or something)

And it can be done with DLLs. My connection lib uses a DLL, while Dekita's was made in RGSS.
 
Last edited by a moderator:

??????

Diabolical Codemaster
Veteran
Joined
May 11, 2012
Messages
6,513
Reaction score
3,203
First Language
Binary
Primarily Uses
RMMZ
And it can be done with DLLs. My connection lib uses a DLL, while Dekita's was made in RGSS.
It can be done in RGSS, but I also ended up opting for to use a dll. Made a few actually.. One to do basic synchronous requests, another to do advanced asynchronous requests and also allow the user much more control over how things are processed, then made a simple peer to peer one too - but thats a whole nother beast...


@some1one

Personally, I am not able to comprehend your idea.  I get what you mean about sending a request to the server to 'push' the data - but where do you expect to push the data to? (assuming you are trying to push data from the server to somewhere else?).

Now - assuming by 'real time' you mean having all players on the map in an mmo type scenario - or alternatively, an atb style pvp battle system, there is NO WAY YOU CAN EVER ACHIEVE THIS - GIVE UP!!

I'm being 100% serious btw.

Even all the big name titles cant do this, think about it. By the time you send a request, time has already started passing, then it has to get sent to the server and in turn sent to all other players (there are various ways to achieve this) - then, you might want a small reply back to confirm everyone got it - think how many seconds/milliseconds is lost in any single one of those steps and multiply it by the number of players (lets say 2), its 100% guaranteed that you will have lost at least 1 millisecond before data is sent - therefore, realtime has failed.

What you can do (and should, its what mmos and such do) is use prediction to anticipate the next movement and perform a correction if it was incorrectly predicted (this correction is what most perceive as lag).

So uhh... yea...
 
Last edited by a moderator:

Iavra

Veteran
Veteran
Joined
Apr 9, 2015
Messages
1,797
Reaction score
863
First Language
German
Primarily Uses
(this correction is what most perceive as lag).
Actually, this would be rubberbanding and is what the game does to correct lags ;)
 

??????

Diabolical Codemaster
Veteran
Joined
May 11, 2012
Messages
6,513
Reaction score
3,203
First Language
Binary
Primarily Uses
RMMZ
Lol yea, thats what I was saying - its what most people perceive to be lag - it isnt, but thats what most folk think. :)
 

some1one

Villager
Member
Joined
May 20, 2015
Messages
11
Reaction score
0
First Language
English
Primarily Uses
Let me see if I can explain this a little better. I am not trying to make this mmo with a bunch of people moving around or anything but I do want it to be as close to real time as possible. If making a request every second or few of seconds isn't that big of a performance hit I could settle for that but i would rather not. I know there are a bunch of connectivity libraries and scripts out there and I'm not trying to re-invent the wheel. I have no problem writing my own server application or dll though (I probably will anyways the scripts/libraries I have seen use http and I don't really want to use that). Part of my ambiguity is due to my lack of knowledge about ruby and rpg maker. The reason I thought it couldn't be done with a dll is because I thought it couldn't keep an open connection (as in I would have to re-open the connection when i called a function from the dll because I thought the connection would close when the call was finished).

Another usage scenario would be real-time chat. I would like it to function similarly to a websocket. A player sends a message and it goes to the server. The server handles whatever it needs to do (such as who is in a chat room or something) then pushes it to a player(s). Is this possible or would I have to manually make a request to the server to check for new messages?

@Huddel I guess I could keep a thread open until I receive a response. Should that be done in rgss, a dll, or does it matter? I normally would be worried that the game would lock while waiting on that it to return. I am not sure how ruby/rgss handles asynchronous operations/multiple threads. Or how it handles an asynchronous function from a dll. Guess I should of researched that a bit more before I asked this question. I guess I would just have a callback executed after I receive the response?

I hope that helps explain what I want a bit better. I'm pretty bad at explaining the things floating around in my head.
 

Hudell

Dog Lord
Veteran
Joined
Oct 2, 2014
Messages
3,545
Reaction score
3,715
First Language
Java's Crypt
Primarily Uses
RMMZ
For a real time chat, you will need to make a request to the server to check for new messages, or the people who are idle won't receive the content.

If I recall correctly, I keep the connection open on the dll and make regular calls to the dll to get the state of the request. Once I get a response, I'll close the connection.
 

some1one

Villager
Member
Joined
May 20, 2015
Messages
11
Reaction score
0
First Language
English
Primarily Uses
Why does that connection stay open? I would think the connection stored in memory would be dumped after the call to the dll is finished. Should I be doing my own GC for these dll's? Are you storing this connection in a variable in your dll or someplace else? If you are simply storing it in a variable, I don't understand how it persists after the call to the dll is finished.
 

Hudell

Dog Lord
Veteran
Joined
Oct 2, 2014
Messages
3,545
Reaction score
3,715
First Language
Java's Crypt
Primarily Uses
RMMZ
I'll have to check the sourcecode tomorrow, because I don't remember how I did that.
 

some1one

Villager
Member
Joined
May 20, 2015
Messages
11
Reaction score
0
First Language
English
Primarily Uses
That would be awesome. Much appreciated. So, the answer to my original question is basically no. However, yall gave me some good alternatives. From digging around the forums it looks there really isn't a secure online system out there for anyone to use. If I get this working nicely I may look into turning it into a web api(for ease of use) and write a guide on how to set it up. Assuming I get permission from the guy doing this for but I don't think that would be an issue.
 

Hudell

Dog Lord
Veteran
Joined
Oct 2, 2014
Messages
3,545
Reaction score
3,715
First Language
Java's Crypt
Primarily Uses
RMMZ
If you keep the connection open on the DLL, the next call will get the same instance of the DLL and you'll be able to check the same connection. Just remember to close the connection once you're done with it.
 

??????

Diabolical Codemaster
Veteran
Joined
May 11, 2012
Messages
6,513
Reaction score
3,203
First Language
Binary
Primarily Uses
RMMZ
@some1one - your 'real time' chat system is not only possible, but its insanely easy to do - thats one of the scripts I have done already :p
 

some1one

Villager
Member
Joined
May 20, 2015
Messages
11
Reaction score
0
First Language
English
Primarily Uses
@hudell That's interesting. I will have to look into why that is.

@Dekita I know it is. That's why it was the example. I was basically trying to figure out the best and most efficient way of doing things because this will be used by multiple systems in the game. I'm a stickler for writing code that's as efficient as possible.

Anyways, I think I got the information I needed. Thanks.
 

Zeriab

Huggins!
Veteran
Joined
Mar 20, 2012
Messages
1,268
Reaction score
1,422
First Language
English
Primarily Uses
RMXP
When you save a Win32API call it seems like the DLL is loaded into the game's memory space. (Within the same Virtual Address Space is my guess)

variable = Win32API.new(dll_filename, 'methodName', 'pi', 'i')What's more. It seems that with a DLL where you have multiple methods then each refers to the same DLL.

winapi_methodName = Win32API.new(dll_filename, 'methodName', 'pi', 'i')winapi_methodEvilName = Win32API.new(dll_filename, 'methodEvilName', 'pippi', 'i')Utilizing this you can have a initialization method setting up a native threads that the DLL will manage completely independently from RPG Maker. Then you can poll the DLL from RPG Maker every frame for the status. This allows a design where you have threads listening on sockets. Whether you use TCP or UDP is of course up to you. My old knowledge is that UDP is faster but more complex, whether it's still true, or if the actual performance gain is significant I don't know.

As a networking design that would be my recommendation. Well... Actually, no. My recommendation would be to use a game engine supporting networked gaming rather than an engine fighting against you.

*hugs*

 - Zeriab
 
Last edited by a moderator:

some1one

Villager
Member
Joined
May 20, 2015
Messages
11
Reaction score
0
First Language
English
Primarily Uses
@Zeriab That sounds like the best i could get and definitely good enough for my uses. Thank you for your detailed and informative answer. And yes, definitely another engine lol. I'm doing this for a friend who only has basic scripting knowledge though.

Now i gotta go learn more about threading in c++. Why can't I just use c# lol. Anyways, I probably shouldn't be asking this on this forum, but does anyone know any good resources or examples for writing asynchronous code in c++? Most of the examples I have been finding aren't real case usage scenarios (like you would never actually write code that did that) and use a bunch of magic strings and whatnot.
 

Hudell

Dog Lord
Veteran
Joined
Oct 2, 2014
Messages
3,545
Reaction score
3,715
First Language
Java's Crypt
Primarily Uses
RMMZ
@Zeriab That sounds like the best i could get and definitely good enough for my uses. Thank you for your detailed and informative answer. And yes, definitely another engine lol. I'm doing this for a friend who only has basic scripting knowledge though.

Now i gotta go learn more about threading in c++. Why can't I just use c# lol. Anyways, I probably shouldn't be asking this on this forum, but does anyone know any good resources or examples for writing asynchronous code in c++? Most of the examples I have been finding aren't real case usage scenarios (like you would never actually write code that did that) and use a bunch of magic strings and whatnot.
You can write it all in C# and just write a wrapper in C++.

You'll need to create two DLL files, but at least you won't need to use stuff you still need to learn :B
 

??????

Diabolical Codemaster
Veteran
Joined
May 11, 2012
Messages
6,513
Reaction score
3,203
First Language
Binary
Primarily Uses
RMMZ
The best approach (perhaps my personal preference, but whatever..) is to use the DL class to open your dll - this will trigger the 'attach' switch clause within the dll main function - then you use the DL class to allow for some constants to reference the functions you require.  Example:

# DLL Constant DLL = DL::dlopen('Dekyde P2P') # Function Constants STARTUP = DL::CFunc.new(DLL['Startup'], DL::TYPE_INT) CLEANUP = DL::CFunc.new(DLL['Cleanup'], DL::TYPE_INT) CONNECT = DL::CFunc.new(DLL['Connect'], DL::TYPE_INT)As you can tell when the dll became attached, you can simple ensure that the handle is kept in a global variable and create a new thread to run in the background that does the 'heavy lifting' for your application. 

From within your ruby environment you create some kinda updater class that handles the updating of your dll state, which in turn, updates some variables that you have sent to the dll from within the ruby environment (likely done via packing some array during the initial connection or when sending a request of some kind) - the aforementioned variable holds the reply (string) from the server - ie, the response. Using this approach your dll does not cause any kind of delay in rpg maker processing (providing you are using asynchronous / non blocking mode) and as you are creating the buffer string in rpg maker, the ruby garbage collector handles the cleanup of it (still have to close/cleanup the request and connection and such though).

With regards to TCP / UDP. Personally, I have not noticed any difference in performance from either. There likely is, but for the sake of RM, I really dont think it matters too much. That being said - depending on what you are trying to do, you may need to write up both like I have done.

Remember: A well written networking system knows when to use one type of connection over the other. ^_^

Sure there was something else, but I cant remember, so yea...
 
Last edited by a moderator:

some1one

Villager
Member
Joined
May 20, 2015
Messages
11
Reaction score
0
First Language
English
Primarily Uses
@Dekita Ah, thanks. That DL class looks more useful than the win32API method. Can't find any good documentation on it though but it looks simple enough to use. And that design is what I had in mind but I'm struggling with the thread management and packing arrays in ruby.
 
Last edited by a moderator:

Zeriab

Huggins!
Veteran
Joined
Mar 20, 2012
Messages
1,268
Reaction score
1,422
First Language
English
Primarily Uses
RMXP
Oh yeah, DL is available for Ace. Keep forgetting that >_>
Thanks Dekita!

As Dekita haven't noticed much difference between TCP and UDP, I highly recommend going with TCP. It's much easier to work with, you know, with the guarantees that messages arrives in correct order and such.

The packing and unpack you see in many Win32API and DL scripts is about the serialization of values for the communication between Ruby and C++.
You fill an array and its values pack it into a string based on a template: http://ruby-doc.org/core-1.9.2/Array.html#method-i-pack
After the call, you unpack the string into an array based on a format: http://ruby-doc.org/core-1.9.2/String.html#method-i-unpack

You do not need to use pack and unpack. It's just something that can be convenient in some cases. The important part is that you typically have a string, which you pass on with a pointer. In the C++ code you will interpret and possibly modify the string. Remember to null-terminate your strings! (Add \000 at the end)

Good luck with your endeavour

*hugs*
 - Zeriab
 
Last edited by a moderator:

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

Couple hours of work. Might use in my game as a secret find or something. Not sure. Fancy though no? :D
Holy stink, where have I been? Well, I started my temporary job this week. So less time to spend on game design... :(
Cartoonier cloud cover that better fits the art style, as well as (slightly) improved blending/fading... fading clouds when there are larger patterns is still somewhat abrupt for some reason.
Do you Find Tilesetting or Looking for Tilesets/Plugins more fun? Personally I like making my tileset for my Game (Cretaceous Park TM) xD
How many parameters is 'too many'??

Forum statistics

Threads
105,865
Messages
1,017,059
Members
137,574
Latest member
nikisknight
Top