Pages: 1 ... 7 8 [9] 10
  Print  
Author Topic: Online Spelunky Coop Mod  (Read 13406 times)
kinnik
Bean
*
Posts: 193


View Profile
« Reply #120 on: August 23, 2010, 05:44:22 PM »

Good question...  oCharacter is the parent of oPlayer1, so any call to oCharacter will address oPlayer1. BUT I don't think you could look at variables in oPlayer1 by calling oCharacter:

oCharacter.itemHeld = "oJar" for example, would not work...

It's more for:  with (oCharacter) { itemHeld = "oJar" }

That would check oPlayer1 AND oPlayer2 (assuming you made oPlayer2 child to oCharacter)

Or collision with oCharacter (as in oEnemy) would return any child oPlayerX... thus eliminating the need for two or more collision events (one for each player).


This 'could' be used to reduce the amount of code duplication when adding oPlayer2.  But it would have to be used intelligently.


Anyone else know more about this?

Would you like to see some specific examples of places to use that?
Logged
kinnik
Bean
*
Posts: 193


View Profile
« Reply #121 on: August 23, 2010, 06:43:39 PM »

I felt like making an example anyway..   Tongue


vanilla -> oShopkeeper -> step event -> line 70:

Code:
if (status == IDLE or status == FOLLOW)
{
    if (oPlayer1.holdItem > 0)
    {
        item = oPlayer1.holdItem;
        if (item.cost > 0)
        {
            global.message = item.buyMessage;
            if (global.gamepadOn) global.message2 = "PRESS " + scrGetJoy(global.joyPayVal) + " TO PURCHASE.";
            else global.message2 = "PRESS " + scrGetKey(global.keyPayVal) + " TO PURCHASE.";
            global.messageTimer = 200;
        }
    }
}


Kegluneq's method of adding oPlayer2:
Code:
if (status == IDLE or status == FOLLOW)
{
    if (oPlayer1.holdItem > 0)
    {
        item = oPlayer1.holdItem;
        if (item.cost > 0)
        {
            global.message = item.buyMessage;
            if (global.gamepadOn) global.message2 = "PRESS " + scrGetJoy(global.joyPayVal) + " TO PURCHASE.";
            else global.message2 = "PRESS " + scrGetKey(global.keyPayVal) + " TO PURCHASE.";
            global.messageTimer = 200;
        }
    }
    if (instance_exists(oPlayer2))
    {
        if (oPlayer2.holdItem > 0)
        {
            item = oPlayer2.holdItem;
            if (item.cost > 0)
            {
                global.message = item.buyMessage;
                if (global.gamepadOn) global.message2 = "PRESS " + scrGetJoy(global.joyPayVal2) + " TO PURCHASE.";
                else global.message2 = "PRESS " + scrGetKey(global.keyPayVal2) + " TO PURCHASE.";
                global.messageTimer = 200;
            }
        }
    }
}


The same thing using oCharacter and a 'with' statment:

Code:
if (status == IDLE or status == FOLLOW)
{
    with (oCharacter)
    {
        if (holdItem > 0)
        {
            item = holdItem;
            if (item.cost > 0)
            {
                global.message = item.buyMessage;
                if (global.gamepadOn) global.message2 = "PRESS " + scrGetJoy(global.joyPayVal) + " TO PURCHASE.";
                else global.message2 = "PRESS " + scrGetKey(global.keyPayVal) + " TO PURCHASE.";
                global.messageTimer = 200;
            }
        }
    }
}


Notice that you don't need a if(instance_exsists(oPlayerX)) because the 'with' statement won't execute if there is no instance.

Also note that this would make player 1 have to press the purchase button for player 2...  A work around for this would be if the keyPress variable (global.keyPayVal) were local variables instead of globals.

ie: in oPlayer1 & oPlayer2's create event add:

keyPayVal = global.keyPayVal1 or 2... ect..  ??

then delete the "global." from keyPayVal.

with(oCharacter) { scrGetKey(keyPayVal) }


You probably already know how to use the 'with' statement this way... but it's good for me to explain so I understand it better myself.

One 'other' note:  if you use the 'with' that way but want to refer to the object that called it, you can use the code 'other'.  Example:

from the oShopkeeper

with (oCharacter)
{
    do stuff
    if (other.isAngry)//is the shopkeeper angry
    {
        do this
    }
}



Mmmmm.. fun.
Logged
Thespis
Shoot
*
Posts: 20


View Profile
« Reply #122 on: August 23, 2010, 10:19:24 PM »

Nice! This will be VERY useful, I could see that the code would be different according to circumstance, and having an example to refer to really helps. I've plugged in the obvious instances of oPlayer1 with oPlayer2, and I'm getting errors. Seems I've messed up some variable work along the way. I replaced oPlayer1 with oPlayer2 in all scripts and objects, some minor tweaking is needed there because I forgot to replace some collision events with oPlayer2, but for the most part I got it. Now I need to figure out why the x and y variables seem to be freaking out, and I think that we'll be done with any work on a oPlayer2. After that, import resources and tweak. I know I'll have to combine the code so for things like enemies, ex:
oBat that targets only oPlayer2 and oBat that targets only oPlayer1, would need to be combined into a single bat that attacks the nearest player.
Once we've made these adjustments it will only be a matter of setting up the connection (hopefully).
Here she is:
https://docs.google.com/leaf?id=0BwusbxKg2FH-MTdhZDRmMDgtOTFlNS00MmI3LWFlODEtZGNmMzc2ZDE1YmEx&hl=en

Thanks to Twitch for posting your source btw, its a real beauty. Hope I can help produce a real gem too.
« Last Edit: August 23, 2010, 10:22:57 PM by Thespis » Logged
Twitch
Shoot
*
Posts: 20

me@tw1tchy.com
View Profile Email
« Reply #123 on: August 24, 2010, 12:07:11 AM »

Nice! This will be VERY useful, I could see that the code would be different according to circumstance, and having an example to refer to really helps. I've plugged in the obvious instances of oPlayer1 with oPlayer2, and I'm getting errors. Seems I've messed up some variable work along the way. I replaced oPlayer1 with oPlayer2 in all scripts and objects, some minor tweaking is needed there because I forgot to replace some collision events with oPlayer2, but for the most part I got it. Now I need to figure out why the x and y variables seem to be freaking out, and I think that we'll be done with any work on a oPlayer2. After that, import resources and tweak. I know I'll have to combine the code so for things like enemies, ex:
oBat that targets only oPlayer2 and oBat that targets only oPlayer1, would need to be combined into a single bat that attacks the nearest player.
Once we've made these adjustments it will only be a matter of setting up the connection (hopefully).
Here she is:
https://docs.google.com/leaf?id=0BwusbxKg2FH-MTdhZDRmMDgtOTFlNS00MmI3LWFlODEtZGNmMzc2ZDE1YmEx&hl=en

Thanks to Twitch for posting your source btw, its a real beauty. Hope I can help produce a real gem too.

Setting up the connection's the easiest part, that's why I finished it first. After you've finished all the code though for multiple players, it's time for the hard part. Setting up every single entity in the game to share variables between clients, such as position, is the shopkeeper angry, how much health does that mummy have, etc.
Logged
kinnik
Bean
*
Posts: 193


View Profile
« Reply #124 on: August 24, 2010, 01:30:53 AM »

Hmmm... yeah, nice. I've never done anything multiplayer before. But I think I remember reading this from someone's post maybe..

One way was to have keystrokes send from one computer to the other. Ie, the keys/joys one person is pressing is sent to the oPlayerX object on the other persons computer. If the games are set to each others seed from the start of the level and the keystrokes are sent quickly enough, all the enemies and objects would mimic themselves on each computer.  All the endless variables would be the same on each computer... ??

I donno if that would actually end up working or if maybe there would be lag enough to cause the two computers to become out of sync. Like, because the key'relase' to stop the oPlayer2 took to long to send to the other computer, that computer thinks oPlayer2 should be further right then the computer sending the keys.  If the comps sync the x/y's of the players from time to time...

I know I read about this somewhere.  Do you, Tweak, write about that earlier?
If I can figure out where I read about it I'll post the link.

Kind makes me think "why would stuff like bats not just pick one character to attack on one computer and a different one on another?"



Do anyone know other ways?
Logged
Thespis
Shoot
*
Posts: 20


View Profile
« Reply #125 on: August 29, 2010, 12:05:29 AM »

Okay, I'm just ONE step away from this working. However, before I take that step, I need thorough testing of Spelunky, and I can't play this game to save my life. I LOVE this game, and I'm terrible at it, nor can I seem to manipulate an invincible mod of any kind. However, it seems to be working as a single player mode with relative functionality. I just need to work out kinks. So play it! And then tell me what is wrong! Yay!

Also, I can't get Gdocs working, so sorry. Its a Mega Upload:
http://www.megaupload.com/?d=BSJTES0G


EDIT: I've only found one glitch: It errors when I'm carrying objects (I think objects that are affected by holdItem.type) and I die when I have the Ankh. That's all I've found, but I know that means there's at least one line of code that needs fixing before I can import these resources. Any ideas?
« Last Edit: August 29, 2010, 09:58:26 PM by Thespis » Logged
kinnik
Bean
*
Posts: 193


View Profile
« Reply #126 on: August 30, 2010, 02:09:13 PM »

Hi!  I downloaded and am willing to do some testing today (when I get back from running some chores).  So, it should run just like vanilla currently? Ie, no multiplayer from the user perspective?

How do you plan to implement MP? ((ie, players positions, level gen, enemy statues ect..) Where is the majority of the changes to this code? (I don't see a lot of change, perhaps I'm missing something)   
« Last Edit: August 30, 2010, 02:52:18 PM by kinnik » Logged
Thespis
Shoot
*
Posts: 20


View Profile
« Reply #127 on: August 30, 2010, 03:51:29 PM »

You're right, there is no major change, just one that's trouble to implement; I've tried changing all instances of oPlayer1 into oPlayer2, and I plan to import all the resources from my version into a vanilla source and tweak it from there. I'll combine the codes and objects and whatnot once I have it all working, and then use Mplay and a Master-Slave relationship between the players and some cursors with sprite indexes that work to relay positions and all that. This way, no syncing is necessary for levels or objects, just player images. At least that's what I hope to implement.
Logged
Thespis
Shoot
*
Posts: 20


View Profile
« Reply #128 on: August 30, 2010, 05:48:23 PM »

So the only bugs I can find are as follows:
When playing as the Spelunker, if I have the ankh and I die while holding a Damesl or an Idol, it generates an error indicating that there is an unknown variable holdItem.type, where type is the alleged unknown variable. The same thing happens if I play the damsel, but only if I'm holding the gold idol. It doesn't happen at all when I play as Tunnel Man. Does anyone have any idea as to what is causing this? I fixed the gun glitches, so after I fix this error I' going to start working on fusing to the vanilla source.
Logged
kinnik
Bean
*
Posts: 193


View Profile
« Reply #129 on: August 30, 2010, 06:27:32 PM »

I get ya.  Grin  Lots of work still, then....  :Smiley
Logged
Thespis
Shoot
*
Posts: 20


View Profile
« Reply #130 on: August 30, 2010, 10:11:06 PM »

Oh my God, I can't believe I didn't think of this before. I've got the basic outline here, it just needs minor tweaks with the networking and the controls and its done. Can anyone who knows how to manipulate Mplay give me a crash course?

https://docs.google.com/leaf?id=0BwusbxKg2FH-ZGFkZDU3ZjEtMTE4Ni00NDkyLWIyYWEtOGY1YjljN2FlMzMx&hl=en

It was too simple, I just wasn't thinking clearly. Here's the problems with this MUCH simpler solution:
Instead of creating one instance with two players, it is creating two instances with two players, one instance a slave and one a master. In the master instance, oPlayer1 moves and oPlayer2 does not, but in the slave instance, both players are controlled simultaneously. What I think I have to do is create a controller object that further instructs the game that the slave instance controls oPlayer2 and the master instance controls oPlayer1. After that, its a matter of configuring Mplay, and I know I can do the first part, so someone who knows Mplay could be my super best friend right now. For serial.

Aside from that, i need to put in seperate health trackers, and I was thinking about making passive items apply to both characters, so no work needs to be done there. This is CLOSE!
Logged
Thespis
Shoot
*
Posts: 20


View Profile
« Reply #131 on: September 01, 2010, 08:31:56 PM »

Ok, I need some MPlay or 39DLL expertise, here's what I've done since yesterday:

https://docs.google.com/leaf?id=0BwusbxKg2FH-MTBkNzcxZGMtNzYzOS00NWE3LWJiMzctMGE3ZDZkYTkyZmFh&hl=en
Logged
kinnik
Bean
*
Posts: 193


View Profile
« Reply #132 on: September 01, 2010, 10:49:16 PM »

 Embarrassed  Sry, I have no experience in MP.  But I'm reading this tutorial to get the gist:

http://gmlkb.wikidot.com/multiplayer-with-39dll

Maybe it will help you..  Not too sure the best way to apply to Spelunky.

It would very likely be useful to have a look at Twitch's code (a few pages ago)

Good skill!

 
Logged
kinnik
Bean
*
Posts: 193


View Profile
« Reply #133 on: September 02, 2010, 11:16:14 PM »

Booya!  Damb, MP is one hellava beast, eh?

BIG PROPS TO TWITCH FOR GETTING AS FAR AS HE DID!!

Soo..  I've been messing around with Twitch's code today.  Here is my code (some small additions / subtractions to his code):

http://www.mediafire.com/?r28jo7edl944ae4


And here is his most recent code for easy download (everyone say THANKYOU!):

http://www.mediafire.com/?b6nx6kwxk4j2gwy

In order to try it out you need the 39dll.dll in your spelunky folder:
http://www.mediafire.com/?3n3dp7vn39sj8k1

Then make a exe.  run two copys of the exe on your computer, set one to host the other join... voila!  For my version to work, the host needs to start the level... usually several times for some reason.  ??  Tongue


Edit: here is the single computer MP by Keglunq, with his permission. Could be useful as it's currently the most functional out of everything, by far.
http://www.mediafire.com/?75tt2lihx12cda6


So, lets start with how Tweak did:

He had everything setup so that one player can host and the other join.

Each computer sends the location and sprite_index of it's player (oPlayer1) to an empty shell of a player (oPlayer2) on the other computer.  This oPlayer2 contains no code for game elements, all it does is show where the other player is and what their doing (sprite wise).  

When one player starts a level, the level is randomly generated using a shared 'seed'. ("random_set_seed(global.seed);" )  This way, the level that is generated for both players is identical.

Players can run around together on the same level, but that is it.

The stuff lacking is many.  The enemies don't move in sync.  The oPlayer2 doesn't react to anything (or visa-versa). For example, one player can't see the other players ropes or,  If one player jumps on an enemy the other player will see that player fall though the enemy... stuff like that.   Bombs can;t be used by oPlayer2.. ectect..




Now me!
So, I tried my hand at fixing this.  The way I did this was by first:

Making oPlayer2 be fully (mostly) operational again.  Delete tweaks empty oPlayer2 and duplicate oPlayer1.  Then remove a few things from oPlayer2, such as the online send receive stuff and the change level on animation end stuff.

Then I added a whole new set of control scripts for oPlayer2... check2Left... check2JumpPressed.. ectect.

Added globals for player2 controls and send the keypresses from one computer to the other computers oPlayer2....

Now oPlayer2 will make ropes, jump on enemies and a few other things.

Problem is, still enemies are not in sync.  Even after having computer1 wait for computer2 to start before starting.  Whip still don't work (havn't tried to fix it yet).
Items still have trouble staying in the right hands and don't really fly in sync when thrown.  oPlayer2 gets knocked out for some un-thought-of reason when jumping sometimes.  oPlayer2 can get killed if he goes into a solid that is out of sync due to bombs.... ectectectect....  Lips Sealed Lips Sealed Lips Sealed Angry Grin


Yeah baby! This IS *FUN*!  the pinnacle of *FUN*!  That is rouge style 'fun' for anyone not knowing.

I donno if I will go any further with this..  Might be neat to try sending the location and sprite_index for ALL the enemies and items?  Owell, it was a fun break from labyrinth.  ;p


« Last Edit: September 02, 2010, 11:25:03 PM by kinnik » Logged
Thespis
Shoot
*
Posts: 20


View Profile
« Reply #134 on: September 03, 2010, 09:10:14 AM »

Great work, but I can't get your source or Kel's source to work. Any ideas? In your player1 dies after entering the level, and in Kel's it seems that it is only one player, and the down key is stuck permanently. No progress in mine yet, I'll update if possible, but if your's works then it looks like I won't need to work on it anymore.
Logged
Pages: 1 ... 7 8 [9] 10
  Print  
 
Jump to: