gbdev / gb-asm-tutorial

Learn to create games for the Game Boy using Assembly
http://gbdev.io/gb-asm-tutorial/
MIT License
102 stars 32 forks source link

Serial Transfer to share High Scores in Part 2 #42

Open leinacc opened 1 year ago

leinacc commented 1 year ago

This lesson will introduce how to work with the 2 serial registers SB (0xff01) and SC (0xff02) in order to get a variety of multiplayer capability in the game.

  1. Basic sending and receiving of a byte
  2. Comms code considerations depending on if the current GB is master/slave, and how they would keep each other synced
  3. Timeouts to ensure that the communication doesn't just hang

As a starting use case, this code should be used to add a very simple multiplayer feature to Part 2: share the saved high scores between different Game Boys.

[!Note] When trying to transfer a bit when the other GB isn't connected, the bit received is 1. I don't think that's documented anywhere?

eievui5 commented 1 year ago

I think this would be simple enough. We could have a “versus” mode where by doing well one player could send ships over to the other side like in some versions of Tetris. Both systems could also trade high scores when linked.

ISSOtm commented 1 year ago

I was thinking the versus mode could outright be a deathmatch, with an "opposing ship" actor controlled by the other console.

eievui5 commented 1 year ago

I’m hesitant to commit to that because “real time” multiplayer like that needs very low latency whereas sending enemies over gives us some room to take a bit if needed.

ISSOtm commented 1 year ago

GB serial is super low latency, so that's not a problem.

zlago commented 1 year ago

i seen a game where the playfield is split across both screens and when a bullet leaves one players screen it appears on the other players screen its gimmicky, but should encourage being more creative than "exchange player inputs" or something

avivace commented 4 months ago

@quinnyo maybe you're interested in this?

quinnyo commented 4 months ago

Yes, I'm keen to have a go at this.

To clarify the scope, let me know if I've got this right:

Also, maybe I'm missing something, but it looks like the score keeping for Part 2 hasn't been implemented yet?

XoToM commented 4 months ago

I've been slowly trying to crack this as well, but I don't have much experience with serial transfers...

Also, maybe I'm missing something, but it looks like the score keeping for Part 2 hasn't been implemented yet?

From what I've read this is most likely going to be implemented somewhere in #39

avivace commented 4 months ago

I've been slowly trying to crack this as well, but I don't have much experience with serial transfers...

Also, maybe I'm missing something, but it looks like the score keeping for Part 2 hasn't been implemented yet?

From what I've read this is most likely going to be implemented somewhere in #39

I think that was the idea (to leave it to exercise to the reader) but I think it would be better at this point to leave #39 to focus on "introducing separate "scenes", and the transitions between them" while a proper score system can be presented in another lesson. I created https://github.com/gbdev/gb-asm-tutorial/issues/82 about that.

It also looks like a scoring system would require first some basic notions about rendering decimals etc so that could be a separate task as well, as suggested by @XoToM in https://github.com/gbdev/gb-asm-tutorial/issues/81.

In parallel, this task (Serial Transfer) can now give those details for granted and just "expect" to find high score data somewhere known and focus on the exchange/protocol/sync part.

avivace commented 4 months ago

Yes, I'm keen to have a go at this.

To clarify the scope, let me know if I've got this right:

* I'd be writing the prose and implementation/code to go with it

* The code will be used to support the high score sharing feature (at least), but

* this lesson is only concerned with the serial data transfer itself, not e.g. the high scores themselves or logic behind sharing/trading high scores

Also, maybe I'm missing something, but it looks like the score keeping for Part 2 hasn't been implemented yet?

Yep, seems like a good plan, this issue shouldn't really care about the scoring system, we can just "imply" the values to "send" are stored somewhere and the one we'll received will be saved locally

ISSOtm commented 4 months ago
  • this lesson is only concerned with the serial data transfer itself, not e.g. the high scores themselves or logic behind sharing/trading high scores

That alone I'm anticipating to be quite difficult: syncing two Game Boys is very error-prone in the face of any bit being possibly lost. Timeouts are essentially mandatory, since then the two GBs' very byte boundaries will get desynced—but I doubt any emulator supports that, further complicating testing.

Knowing myself, that would translate to a lot of bringing up edge cases, and thus more back-and-forth than usual on the implementation. Thus I'd suggest the following steps:

  1. In parallel to the below three[^parallel], writing the prose for the higher-level introduction to serial transfers.
  2. Writing the implementation
  3. Iterating on it in reviews
  4. Once the implementation is agreed upon, writing its description prose

[^parallel]: It may be a good idea to write about the higher-level concepts first, since clarifications at this stage could avoid some confusion in the next step. But OTOH, it's mostly independent from the rest, so it would make for something to work on while waiting for reviews on the implementation.

quinnyo commented 3 months ago

Thanks for the suggestions and advice! Expecting a lot of back-and-forth and iterating on the implementation makes a lot of sense.

That alone I'm anticipating to be quite difficult: syncing two Game Boys is very error-prone

To be sure, I'm not expecting it to be easy. The error detection and handling will likely be one of the more significant parts of the impl/development. (The challenge of it is probably largely responsible for my interest in the subject.)