After a considerable time, I finally managed to polish all the bits and pieces I have been working on and release it in a usable package. This version will look like the Blinklib you are used to but with a few notable differences:
Differences from the official Blinklib release at the time of publication
Improved management of deadlines virtually removing collisions (which improves transfer performance).
Built-in simple but effective guaranteed delivery for datagrams.
Datagrams can not cause face value starvation.
Clean up of public API.
Slightly smaller storage requirements.
Notable API changes
All 256 possible byte values are available for face values (as opposed to 64 currently).
sendDatagramOnFace now returns a bool that indicates if the value was scheduled to be sent or not. If it returns false, the caller must try to send again at the next loop() iteration. If it returns true, it is guaranteed that the datagram will be received by the other Blink eventually.
If a datagram is not consumed when it reaches a Blink and a new datagram is sent, the new datagram will now overwrite the existing one (currently the incoming one is ignored).
markDatagramOnFace() is still there but it is basically a NOP now.
BGA_CUSTOM_BLINKLIB define can be used to check for this specific Blinklib.
Please try it out with your games and let me know if you see any issues. This was mostly created because I wanted some specific things for my game but it might potentially be useful to any games that make heavy use of face values and datagrams in general.
Forgot to mention that this can be installed alongside the existing blinklib. You will then see 2 similar entries and one will be identified as Custom Blinklib. This is good to be able to compare possible different behaviors between the official and custom versions.
Beta 2 has been released and is available for download. Unfortunately it uses a different Board Manager URL so you will have to update the url before updating the package.
Updates in this release:
Fixed guaranteed delivery of datagrams.
New function isDatagramPendingOnFace() that returns true if there is a datagram pending delivery on the given face.
The golden v1.0.0 version is released. The only relevant change on this is that I fixed the last bug I knew off where there would be cases faces would show as not expired due to phantom IR transfers (transfers that started but never completed). Not anymore. Other than that, it has everything I wanted it to have and it is still using less flash storage than the original Blinklib.
Well, as projects like this go, I assume they are up to a point. I had a primary objective to do this which was add guaranteed delivery datagrams without increasing the footprint of blinklib. The other things I did were just things I thought would be nice to have but might be a bit controversial. I am up for breaking this in smaller changes and sending pull requests but I am not sure about what would fly and what would not. Meanwhile I just make my version available. It is easy enough to have both installed and select wich one to use. And using the BGA_CUSTOM_BLINKLIB define you can even change your program to support features in one or another depending on what is available.
I just updated my custom Blinklib to v1.0.1. This is a minor release where the main feature is a reduction of its footprint to 1500 bytes (compared to 1888 bytes in the original one, a 7% gain in total storage space).
The savings are real in the sense that it will be visible in all apps. Apps that rely a lot on timers will see even bigger gains than this.
If you setup Board Manager to point to the v1.0.0 release, you can update directly from it. No need to change URLs anymore.
I just did a real life experiment and got the code to Pirates & Lasers (which is the biggest current game I know off) and compiled it with my custom blinklib (no change to the game whatsoever. Download and compile). The numbers speak for themselves.
Original Blinklib:
Sketch uses 5834 bytes (99%) of program storage space. Maximum is 5888 bytes.
Global variables use 725 bytes (70%) of dynamic memory, leaving 299 bytes for local variables. Maximum is 1024 bytes.
Custom Blinklib:
Sketch uses 5430 bytes (92%) of program storage space. Maximum is 5888 bytes.
Global variables use 718 bytes (70%) of dynamic memory, leaving 306 bytes for local variables. Maximum is 1024 bytes.
Are the authors around? Maybe you want to implement something you left out due to space constraints?
Thank you so much for doing this. I just tested it for my own project and it shaved 3% off during a crucial time where I’m trying to sneak in some last animations.
Glad to help. If you do not use datagrams in your game, it might be possible to free even more storage space by disabling guaranteed delivery. I will see about adding a defined to do that.
I juts hacked this up. When datagram support is disabled, any calls to datagram related functions will return the zero value for the return type or will symply do nothing in case of void functions.
Here is my current custom blinklib with datagrams enabled:
Sketch uses 1504 bytes (25%) of program storage space. Maximum is 5888 bytes.
Global variables use 683 bytes (66%) of dynamic memory, leaving 341 bytes for local variables. Maximum is 1024 bytes.
And here is it with datagrams disabled.
Sketch uses 1362 bytes (23%) of program storage space. Maximum is 5888 bytes.
Global variables use 473 bytes (46%) of dynamic memory, leaving 551 bytes for local variables. Maximum is 1024 bytes.
Non-negligible storage savings and a considerable memory saving. Considering the amount of games that only use face values around, this might be worth it.
Another real world test. Now I used the new Move38 game, Crownfall. Again, no modifications whatsoever in the game:
Original Blinklib:
Sketch uses 5654 bytes (96%) of program storage space. Maximum is 5888 bytes.
Global variables use 725 bytes (70%) of dynamic memory, leaving 299 bytes for local variables. Maximum is 1024 bytes.
Custom Blinklib:
Sketch uses 5230 bytes (88%) of program storage space. Maximum is 5888 bytes.
Global variables use 718 bytes (70%) of dynamic memory, leaving 306 bytes for local variables. Maximum is 1024 bytes.
Custom Blinklib with datagrams disabled:
Sketch uses 5096 bytes (86%) of program storage space. Maximum is 5888 bytes.
Global variables use 508 bytes (49%) of dynamic memory, leaving 516 bytes for local variables. Maximum is 1024 bytes.
Hey @jbobrow, in case there was something that was left out from Crownfall due to space constraints, maybe it can be added now.
I need to do a new release. I was waiting to do it in a proper way (currently it is hacked together) but if it will help you, I can do a release as is. One I do it, you just need to enable a define in your sketch to disable datagrams completely.
I installed this and switched Terrarium over to use it. Not only did it work without issue, it shaved off almost 400 bytes from my compiled sketch size
The project went from 5612 bytes (95%) to 5238 bytes (88%). Data space also saved ~10 bytes, which was welcome.
I am now rethinking future plans in a good way. For instance, using all eight bits of the IR interface will let plants grow larger because I can easily transmit larger packets of plant energy.
I did apply my own mods as mentioned in my post on optimizing space. Namely changing dim() to be a nop (saves ~100 bytes) and changing setColorOnFace() to accept a pointer to the color instead of the color struct itself (saves 80 bytes).
Changing dim() like you did would be a breaking chance for obvious reasons. The setColor change can be done by simply adding a new variant without breaking things so I might as well do that.
Oh yeah, totally understand about keeping dim. Other games surely use it so it can’t be changed. The issue I see is that blinklib itself uses dim, which forces that function to be included regardless of whether the game uses it. Ideally blinklib would use a lighter-weight algorithm.