I just deleted about 6 paragraphs of brain dump I will share later. I just want to mention I found out why TCP performance was so bad for small packets, it's an artificial wait period on TCP ACK(like I suspected). Espressif says their new firmware fixed this, I haven't tried, we need a custom firmware anyways for performance. We can do >60 packets a second with TCP, UDP more, it's the stupid Nagle-like algorithm causing the problem. I saw 8266 is capable of at least 2mbps(though we could never feed it that fast on Uzebox). I suggest we use AT for now, our work here is not wasted as, the custom firmware can start out in AT mode and run this stuff. For games that require higher performance send a "AT+BINARY\r\n" to switch to the new mode when it exists. I'm not just blowing smoke it will work, there really is so much work to be done on each of these parts and that's why it might seem like nothing is working yet. In reality about 1/2 of many things is at least working in proof of concept mode, which I think was required to spark interest as opposed to 1 finished thing with nothing connected to it. Each item will take time to polish but we can work in parallel. I'm started but pausing on the setup utility, finding AP's etc. I can start the conversation with the 8266 firmware upgrade process(8266 does auto-baud detect, any speed possible), it's waiting for firmware data in pages(~508kB total), not trivial.
kivan117 wrote:Has the API been expanded to include any Uzenet stuff or are we still doing this the hard way via UART?
I spent a lot of time trying to make a robust solution for high performance games using UART, the performance sucks because UART is too wasteful, the stock firmware has artificial TCP ACK delays, it's too cpu intensive to parse, and requires larger than minimum buffers. Maybe someone can get it, but not me, it burned me out and demotivated me so I just made a game instead... Considering binary performance it seems easier and better to make a custom firmware for that. For now I suggest we use AT and get simple stuff working like we are both working on, custom firmware will be backwards compatible with the non-latency critical AT code we write today.
kivan117 wrote:Additionally, has the server side portion of the Uzenet Score system been completed and does its API match what the wiki has to say about it?
Sort of, and no. I have a state machine that uses the vsync callback so the main game can continue on without worrying what Uzenet is doing. Essentially save your scores to EEPROM as usual, the state machine rapidly and continually reads and attempt to send your scores to the score server(which will sort out if they belong on the list) in the background. I would like to see your system at some point as well once we get things working. There should be a generic solution for this particular problem so the more ideas the better, and I will send you the source code immediately when I get it working right. The protocol has changed because it wasn't that easy for Uzebox to use I found. I want to support meager requirements like 4800 baud with 8 byte buffers for the scoring system(so we could drop it into say pacman with no redesign for resource considerations). The new protocol(and chatroom+everything else will change to this also) will always be based on
1 string commands with no challenge sub-states like this:
Code: Select all
[magic_number(8bit),reserverd(8bit),operation(8bit),game name(8 chars),variable number and length of arguments.....]
To get high scores off the server for my game I am sending this packet immediately after connecting(all 8bit bytes):
Code: Select all
[0xC7,0,1,'S','O','L','I','T','A','I','R',4,3,7,2]
The magic number (0xC7 which is an 8266 firmware thing)is the only challenge now, to indicate what's connecting is something that is aware of the protocol. The second number is reserved for flow control if necessary later. The third number is the operation(1 = read). Then you send the official 8 character rom name(
like we store it on the SD card). The following number 4 indicates I want to be sent entries starting with entry 4. The following 3 means I want to receive 3 entries total(so skip 0,1,2,3, receive 4,5,6). The 7 indicates I only want the first 7 characters of the names(since the server allows up to 32). The 2 indicates I only want the two least significant bytes of the score(since the server allows 64bit scores). The reason for this is to let the Uzebox describe the capabilities to the server to avoid overflow, while at the same time describing the game save format which the server does not care about. It is not practical for most games to have a large buffer around just for the purpose of retrieving scores(though we have SPI ram if we have Uzenet). As far as format, you can see you can make any format you want. You have 32 bytes for a name that you could use for other things if you coded your game right. The only consideration is if you have some strange scoring system, it would have to be converted back and forth so that a higher value is always better so the server can sort things without knowledge of the format. I intend to add in the "save game" thing using the exact same format except using a different command later. There you can read/write blocks of any size specifying just a offset+length, that is trivial and the reason for the reserved "flow control".
To send a high score with the name "CARDBOT" and a score of 0x02F4(756 dec)I send this string:
Code: Select all
[0xC7,0,2,'S','O','L','I','T','A','I','R','E',7,2,0x02,0xF4,'C','A','R','D','B','O','T']
Again the magic number 0xC7(199), 1 reserved byte, 1 byte for the command(2 = write),8 chars of the official rom name. The 7 indicates I will send 7 name bytes(store them in the first 7 of the 32 available for name). The 2 indicates I will be sending a 2 byte score(store them in the first 2 bytes of the 8 available). Then follows 2 bytes of score, and 7 bytes of name which we specified. The server replies with 1 byte indicating what position this made it into, which if 255 indicates it did not make it on the list.
You can close the connection whenever you want on Uzebox side, otherwise you can continue to send commands and receive responses indefinitely. It might be a good idea to send a heart beat command packet(which does nothing but generate a 2 byte server response indicating a rolling 16bit 1/1000 second timer on the server; used to calculate round trip latency if you wanted) every couple minutes if lingering but not sending data. This keeps the TCP connection alive which may or may not be required depending on what crazy network tunneling stuff someone might use someday.
Code: Select all
//commands
#define UZENET_HEART_BEAT 0
#define UZENET_DISCONNECT 1
#define UZENET_READ_SCORE 2
#define UZENET_WRITE_SCORE 3
//...
Forgive any errors I'm just brain dumping here from amongst 1000 thoughts and this is my only day to mess around with it this week, more to come. Please throw ideas out.