All right, I should probably post my big Axe project for calc: Eitrix! Eitrix is a port of a Tetris remix made specifically for versus play. First, obviously, it features linkplay between two calcs. Secondly (and much more importantly), in the game, one of the blocks in the grid will become energized with a Special Power. Clearing that block will unleash the power, which will either help you or hurt your opponent severely.
Latest version is: 0.6
This is the last post on Omnimaga with the download on it.
Please playtest and look for bugs! I want to add CALCnet 2.2 support to it eventually.
Oooh, awesome! Can you post some screenshots in this thread for people to stare at? Also, you're more than invited to submit it to the Cemetech archives, probably in the ASM Games section.
*holy necropost to follow*
Hi all. I've gotten a bit lax about my Minecraft game recently because I am finally adding CALCnet 2.2 support to Eitrix, my multiplayer Tetris game, as was the original plan! I've been able to do this thanks to the recently released Calcnet Axiom.
The consideration that I'm thinking of to increase user friendliness is to create a system that will allow for any number of players, so that anyone can join the gCn hub without having to wait for more than one game to finish. One idea that I had was to allow players to join one of four teams and have each player target one team, but I wanted to throw out a more revolutionary idea first to see what you guys thought.
I call this system the Neural Network, although a better name for it would be the Conquest Network. Basically, the network will be abstracted into a 65536 x 65536 grid, centered around a point called the Core. The object of the game is to enter the Core and stay there as long as possible by battling players closer to the Core. Basically, the system works like this:
► When players join the network, they will poll players already on the network to find the point closest to the Core. If no one is on the network, that player will enter at the Core, and subsequent players will be added around them.
► Players will do battle with the players on the 8 points immediately adjacent to theirs, both laterally and diagonally. Special attacks can be directed at any of these 8 players.
► If a player finds that a spot adjacent to them that is closer to the Core is vacant (either by player death, a mistake in finding the closest point, or another player moving closer), that player will move to that spot and will do battle with his new neighbors.
► And, as a note: all players are playing a game of Eitrix the whole time while this is happening. Players that attain kills will have their speed reset, so that they can last longer.
Feel free to ask for clarification on any of these points.
*bump*
I thought it would be good for me to provide a step-by-step example of what happens using this system:
1a. KermM is the first person to join the network, and he sends some broadcast packets to see if anyone else is there.
1b. Since no one is, he gets no response back, so he goes ahead and takes the Core position.
2a. Merthsoft joins the network and sends a broadcast.
2b. KermM receives this broadcast, and invites him to enter the grid at position (-1, -1). He selects this position because, following the default winding order of left to right in each row going down, that is the position closest to the Core.
2c. Receiving no other invitations, Merthsoft accepts KermM's invitation and joins the network at position (-1, -1). Merthsoft records KermM's address as being to his bottom-right, for attacks later.
3a. Ashbad joins the network with his own broadcast.
3b. Both KermM and Merthsoft receive the broadcast. When both of them follow the default winding order (as explained in 2b), they will both invite Ashbad to the point (0, -1).
3c. Ashbad receives both invitations and accepts one of them, making a note of both player's addresses in the appropriate positions.
4. Six more people join the network. If no packets are lost in transit, those six people will fill in the remaining positions adjacent to KermM.
5. AHelper joins the network. Because all of the spots that are 1 spot away from the Core are now filled, the players on the outside will now send invites to join in various spots that are 2 away from the Core. One of these spots will be (-2, -2), the spot to the top right of Merthsoft. Let's say he takes it.
6a. Seconds later, Merthsoft dies in his game. Before he leaves the network, however, he notices that AHelper is the player further from the Core than he is. So, he sends a message to AHelper naming him as his successor, also sending him a list of Merth's immediate neighbors so that AHelper doesn't have to ask.
6b. Merthsoft also sends a message to the other players around him, notifying them of his death and asking them to replace his address in their neighbor tables with AHelper's. Once that is done, Merthsoft quits out of the network.
6c. AHelper receives this message. Because there is no one next to him that is three spaces away from the Core, he does not notify anyone of his movement. He simply takes Merthsoft's old position.
Compynerd255 wrote:
*bump*
I thought it would be good for me to provide a step-by-step example of what happens using this system:
1a. KermM is the first person to join the network, and he sends some broadcast packets to see if anyone else is there.
1b. Since no one is, he gets no response back, so he goes ahead and takes the Core position.
2a. Merthsoft joins the network and sends a broadcast.
2b. KermM receives this broadcast, and invites him to enter the grid at position (-1, -1). He selects this position because, following the default winding order of left to right in each row going down, that is the position closest to the Core.
2c. Receiving no other invitations, Merthsoft accepts KermM's invitation and joins the network at position (-1, -1). Merthsoft records KermM's address as being to his bottom-right, for attacks later.
3a. Ashbad joins the network with his own broadcast.
3b. Both KermM and Merthsoft receive the broadcast. When both of them follow the default winding order (as explained in 2b), they will both invite Ashbad to the point (0, -1).
3c. Ashbad receives both invitations and accepts one of them, making a note of both player's addresses in the appropriate positions.
4. Six more people join the network. If no packets are lost in transit, those six people will fill in the remaining positions adjacent to KermM.
5. AHelper joins the network. Because all of the spots that are 1 spot away from the Core are now filled, the players on the outside will now send invites to join in various spots that are 2 away from the Core. One of these spots will be (-2, -2), the spot to the top right of Merthsoft. Let's say he takes it.
6a. Seconds later, Merthsoft dies in his game. Before he leaves the network, however, he notices that AHelper is the player further from the Core than he is. So, he sends a message to AHelper naming him as his successor, also sending him a list of Merth's immediate neighbors so that AHelper doesn't have to ask.
6b. Merthsoft also sends a message to the other players around him, notifying them of his death and asking them to replace his address in their neighbor tables with AHelper's. Once that is done, Merthsoft quits out of the network.
6c. AHelper receives this message. Because there is no one next to him that is three spaces away from the Core, he does not notify anyone of his movement. He simply takes Merthsoft's old position.
Poor Merth dies
Sounds like a very interesting idea, but I'm curious how well it'd play out considering how (realistically) there are very few people who'd be on at a time, or ever, considering gCn isn't the most used innovation.
What if you made it an isometric grid? Then you would have at most, 4 neighbors.
Ashbad wrote:
Poor Merth dies
I actually wanted to kill KermM off, but I didn't have time to write that much into the example. In his case, he would find the adjacent player with the highest score (yes, I added that as well) and name him as the successor, just as Merth did to AHelper. If Merth was the player with the highest score, Merth would name AHelper as his successor before entering the Core.
Ashbad wrote:
Sounds like a very interesting idea, but I'm curious how well it'd play out considering how (realistically) there are very few people who'd be on at a time, or ever, considering gCn isn't the most used innovation.
That is a good point. The main point of this system would allow anyone to join the network at any time, yet allow individual players to play against each other. I'm actually worried about how this will play out with a lot of players, since lots of packets will have to be sent to maintain network state.
seana11 wrote:
What if you made it an isometric grid? Then you would have, at most, 4 neighbors.
That would be equivalent to using a lateral grid and just not considering the neighbors diagonal from you. I could consider that if 8 players are too difficult to manage, but this solution leaves the player in the Core at a disadvantage because the next four players to join after him will only have to fight him, while he has to fend off all four of them. However, should I choose to add bonuses for killing other players (such as slowing drop speed), the disadvantage could be neutralized because the Core player would have four times as many opportunities to earn them.
I have had this thread open waiting for a response from me for close to a week, I'd say, so my apologies for not responding sooner. My tardiness is largely due to the fact that I just was not sure what exactly to say. Reading through your initial play-through where I'm the core and Merth dies, it all makes sense, although I must warn you that broadcasts do not have guaranteed delivery. I recommend that a player send a bunch of broadcasts before deciding that it is the core, and perhaps the core should occasionally send broadcasts indicating it is the core so that two calculators that incorrectly are both the core can deterministically resolve the conflict (eg, both agree that whichever one has the lower ID sum is the real core, and the other one will attempt to re-join). I think this sounds like a very innovative system, and I absolutely hope you build it. I will be happy to contribute in any way I can. I'd try to switch to byte coordinates, ie, 256x256 instead of 64Kx64K, for simplicity.
KermMartian wrote:
I have had this thread open waiting for a response from me for close to a week, I'd say, so my apologies for not responding sooner. My tardiness is largely due to the fact that I just was not sure what exactly to say. Reading through your initial play-through where I'm the core and Merth dies, it all makes sense, although I must warn you that broadcasts do not have guaranteed delivery. I recommend that a player send a bunch of broadcasts before deciding that it is the core, and perhaps the core should occasionally send broadcasts indicating it is the core so that two calculators that incorrectly are both the core can deterministically resolve the conflict (eg, both agree that whichever one has the lower ID sum is the real core, and the other one will attempt to re-join). I think this sounds like a very innovative system, and I absolutely hope you build it. I will be happy to contribute in any way I can. I'd try to switch to byte coordinates, ie, 256x256 instead of 64Kx64K, for simplicity.
Thanks for the feedback, Kerm. I do understand that broadcasts are not guaranteed, so I'll use some magic number to determine connectivity (3 or 4 sounds good to me). Of course, this also means that there is a possibility that earlier layers might not get entirely filled up before later ones do.
For the occasional broadcast send to indicate being the core, I don't think that it needs to apply specifically to the core as much as it does to all spaces. If anyone sends invitations back, it can generally be assumed that there must be someone in the Core. However, if two players accept an invitation to the same space (which could very well happen if both players join at the same time), they should send a "I'm at this location" broadcast to resolve conflict and also to keep the network state in sync (e.g. in case players keep an incorrect table of neighboring addresses).
As for the coordinates, Axe easily supports two-byte integers (even more easily than 1-byte integers), so it isn't much of a jump from 1 byte to 2. While it might be somewhat realistic to see 65,535 players online, it will be virtually impossible to reach 4 billion.
I'm thinking more about how I'll implement this system, and I realize that I need some definitive way to win, because once you're in the core, all you're doing is fending off your opponents. What if, once the player in the Core reaches some arbitrary score (e.g. 10000 points), he wins the game, and propagates this message to all of his neighbors, who then propagate it to all of their further out neighbors, etc. Then, the network resets completely.
*necro*
Well, I guess I should make a little confession: Ever since I've gotten my new laptop, I've had a lot more computer programming opportunities, and I've kind of lost interest in calculator programming. Not that I'll be leaving forever - I'll still do other projects, just not calc ones. This means that I probably will not be writing the Conquest Network system into Eitrix.
However, I have done some improvements to Eitrix, and I think that I'll be able to make time for a much simpler CALCnet scheme that closely resembles the linkplay that already exists:
- When a player enters LINK mode, they look for other players on the network, randomly sending broadcasts.
- As soon as that player finds another player on the network, they exchange addresses and start a game.
- All messages thereafter are directed sends to the opponent.
I realize that adding this system will throw out any possibility for games with more than 2 players. However, two players has always been the norm for Tetris, and I won't have to write victim selection logic or stuff like that. In addition, by making all game packets simple directed sends, up to 2^39 games of Eitrix can take place on the same hub. And we still have gCn compatibility!
Well, I'm sad to hear that you won't be implementing the very fun-sounding Conquest Network system, but to the rest of the post, excellent! I would still use broadcasts to determine if there are any players waiting to play a game to look for random opponents, just as you say, and use directed messages for the rest of the game. That's exactly how (for example) Obliterate works.
KermMartian wrote:
Well, I'm sad to hear that you won't be implementing the very fun-sounding Conquest Network system, but to the rest of the post, excellent! I would still use broadcasts to determine if there are any players waiting to play a game to look for random opponents, just as you say, and use directed messages for the rest of the game. That's exactly how (for example) Obliterate works.
Thanks for the tip, Kerm. When I release the final version of Eitrix (which also includes several other improvements), I will include a complete description of the Conquest Network system, and give an invitation for any coder who feels up to the task to write the system in. And, if I can find feasible uses, I will use the Conquest Network system in other games.
Also, that is a nice tidbit of Obliterate that I did not know about! I think that it would be very helpful to mention that in Obliterate's documentation, because some players (myself included) probably feel a bit wary of connecting to the gCn Obliterate hub for fear of filling it up. Knowing that it can host many individual games is good to know.
And thanks right back, I will be sure to add that, particularly if I get around to fixing the Obliterate bug where broadcasts occasionally confuse calculators that are already in the middle of a game. I was also mentioning the fact that Obliterate does what you were describing as a segue to offering to share the code with you, should you desire.
So, I've been implementing the 1-on-1 in Cn2, and I am running into a confusing bug:
Setup: An 83 Plus (1.19) and an 84 Plus SE (2.43) are linked via an I/O cable. Both are running DCS 7.1, and have the same version of Eitrix installed.
1. I start Eitrix on one calculator and put it into link discovery mode, which listens for packets, then starts sending broadcasts.
2. I start Eitrix on the other calculator and put it into link discovery mode. The second calculator immediately recieves the first calculator's packet, and starts sending a reply packet.
3. Both calculators display the message that indicate that they have another player's address, right before the game starts.
4. But before one game loop gets a chance to update the screen, both calculators crash.
Additionally, if I comment out the in-game link logic (e.g. neither calc is actually listening to Cn2 during the game) and start with the 84 Plus SE, the 83 Plus crashes, but the 84 Plus runs fine!
Now, I have a question: for testing purposes, is it OK to post an unstable program to the Cemetech archives to get other users to reproduce the bug, analyze the source, and the like?
@Kerm: And thanks for offering to share the code with me. I don't think that it will be that useful to me, however, since this game is written in Axe, not ASM.
I believe that
http://dcs.cemetech.net/index.php?title=Interfacing_CALCnet2 mentions some of that; under Cn2_Setup, I see:
Quote:
Once this routine has been called, 547 bytes starting as SavesScreen ($86EC) will be used by CALCnet and should not be used other than the methods to clear buffers manually or automatically as outlined below. In addition, the RAM segment of the CALCnet2.2 interrupt is stored in 42 bytes starting at $9999 and ending at $99C3, and the jump table uses 257 bytes from $9A00 to $9B01.
I can put that somewhere different if you think it would be clearer. And superb, I'm very happy you added CALCnet support.
KermMartian wrote:
I believe that
http://dcs.cemetech.net/index.php?title=Interfacing_CALCnet2 mentions some of that; under Cn2_Setup, I see:
Quote:
Once this routine has been called, 547 bytes starting as SavesScreen ($86EC) will be used by CALCnet and should not be used other than the methods to clear buffers manually or automatically as outlined below. In addition, the RAM segment of the CALCnet2.2 interrupt is stored in 42 bytes starting at $9999 and ending at $99C3, and the jump table uses 257 bytes from $9A00 to $9B01.
I can put that somewhere different if you think it would be clearer. And superb, I'm very happy you added CALCnet support.
Thank you very much. Come to think of it, I do remember reading that information, but since I had no idea what those addresses actually meant for me (since I'm using Axe, which doesn't explicitly state any addresses at all unless you tell it to), I kind of glazed over them. I think that they could be made clearer simply by putting where these addresses are relative to the start of appBackUpScreen, so that users know that they can't use all of its bytes.
And thanks also for the congrats! I should also mention that I've been running into another bug that can still be fixed by any debuggers: sometimes, when I start the lobby routine on both calculators, neither of them recognize that another player is waiting, and I have to exit the lobby on both systems for it to work. Do you know of any common fallacies that cause this?
I have updated the Interfacing CALCnet page to make the memory areas a bit clearer, as per your suggestion; thanks again. Regarding the bug, do you have any code that can potentially disable interrupts? Try turning on the debug display (there's a byte flag for that, see
http://dcs.cemetech.net/index.php?title=Interfacing_CALCnet2#Using_Debugging_Mode ) and making sure you have a FastCopy-type routine in your main menu key loop. If the pixels in the bottom row of the LCD don't start flashing patterns, something is wrong.
Interestingly enough, the pixels do flash, but the bug still occurs sometimes. I will investigate my lobby code to make sure all my logistics are correct.