Activity

Oignon

I was fed up with hardcoding text display in the menus, so I refactored the entire menu rendering system. To do this, I built a component rendering module with a simplified Layout system.

I probably over-invested in this new system, it was a huge sink in terms of time and brainpower, but I truly hated how I was handling UI text before.

Attachment
0
Oignon

v1.1.0 - The States saving!

This version introduces a game state saving system! When you quit the game while in the middle of a match, it is automatically saved. As soon as you relaunch the game, it reloads and you can continue playing as if nothing happened. Your game time will not be affected.

This is very useful, especially if you are working on your Hard Grid and suddenly need to calculate 1 + 1well, you can now exit the game, do your math, and come back. Or, if you don’t want anyone to see you playing Minesweeper, you can close it without losing your current progress.


The principle is simple: when you exit the game, it saves all the important parameters of the current match into a minesweeper_game.sav file. Then, when the app launches, if the file exists, the data inside is loaded.

Technically, this feature was not easy to implement at all! Fortunately, I had already planned the game’s structure from the beginning to potentially add this feature, which saved me from having to build something flimsy or rewrite part of the engine.

I realized there was an error, there was a dummy version of the file-reading functions in eadkp (the lib I wrote and am using here), so I ended up doing some bug hunting.

In any case, this was an addition I was dreading, but it all came together nicely in the end, so it’s all good (:

0
Oignon

Refactored documentation and guide to be clearer for people outside the NumWorks community.

Translated the documentation into English.

Moved the documentation to the GitHub repot wiki section.

Attachment
0
Oignon

v1.0.0

First version of Minesweeper for the Numworks calculator.

New features:

  • Added a rust.yml workflow to automatically include the compiled package (NWA) in every release and tag.
  • Added a README (you just gotta have one).
  • Added a LOGO (I didn’t have one yet ¯_(ツ)_/¯ ).

Test video on the real hardware! (It worked on the very first try!)

0
Oignon

I added explanatory text and the final time to the EndGame screen. I also added a ‘Hard’ mode with the largest possible grid (small cells and 15% mines).

Attachment
Attachment
0
Oignon

I added a timer and the theoretical number of remaining mines.

Attachment
0
Oignon

I added the title bar rendering for both the game and the main menu. I also refactored part of the code for these bars and moved the rendering functions into a separate file.

Attachment
Attachment
0
Oignon

I improved a few details, like centering the grid on the screen, fixing the main menu text alignment, and adding a background to the main menu.

I also made some code improvements, such as reducing memory fragmentation by eliminating unnecessary heap allocations and deallocations whenever possible.

0
Oignon

I added the Game End screen (won and lose). Also, when you lose, all the mines are revealed.

0
Oignon

I’ve implemented the system that reveals all empty tiles (I don’t know what this system is called, but there you go).

Next step: the Game Over system!

0
Oignon

I added mine rendering

0
Oignon

I’ve added the main interactions (reveal, flag). I also fixed a bit-shift bug in how I was storing the number of adjacent mines, as well as a bug in the randint function of my eadkp library used here.

0
Oignon

So, you can’t tell just by looking at it, but I’ve written the state management code and the cell display logic (which was more complicated than expected!).

I’ve also coded the cursor movement. Now, I’m going to tackle the interaction system.

0
Oignon

I added:

  • Background rendering
  • Cell margins
  • Different cell rendering based on size (large or small)

And fixed:

  • Cell sizing
0
Oignon

I am currently creating a Minesweeper game for the Numworks calculator.

Well then! It turns out I might have forgotten to install Wakatime in my
Docker container, so a good portion of my coding time wasn’t tracked ):
You can easily add at least 2 more hours to the total.

First off, I spent 2 days thinking about the code structure. Since there’s
no engine, no multi-threading, and especially some nasty screen tearing
that forces me to only update what’s necessary, I can’t redraw the whole
screen every time (that’s my main constraint).

First, I coded a State system to manage what to render (menu, game,
game over). Then, I built an event-driven graphical rendering pipeline.
Everything works through a shared object, allowing all components to
access the same data (position, score, etc.).


I admit the current rendering isn’t great (I forgot the background
instruction, sorry), but you’ve got to have the vision! This is literally
the first test render (by the way, my code worked in only two tries,
which is remarkable).

0
Oignon

Shipped this project!

Hours: 12.43
Cookies: 🍪 146
Multiplier: 9.82 cookies/hr

This is a simple template for my main project, eadkp. It actually took quite a bit of time because I had to adapt all the build tools. they were originally designed to compile eadkp’s internal examples (as a library) rather than standalone projects using it. I then reworked the scripts to make them more universal across both the library and the template, and updated the template example.

All in all, it was more about designing configuration tools than anything else. and honestly, it was very useful to revise those old scripts to make them more modular.

Oignon

Fixed the Dockerfile (the one I use in the template) to include the Numworks linker dependencies. I had cleaned up the dependencies earlier, but I guess I shouldn’t have! :)

Updated the ‘demo link’ to point to the beta1 release.

Just to clarify, the build tools like the justfile (a cmake equivalent) were created by me for this project’s needs, and then reused or adapted for the project template that uses my lib.


IMPORTANT: I forgot to mention that this library must operate under extreme
constraints!
The Numworks calculator features a Cortex-M7 and only allocates
64KB of RAM to external applications. This library must use as little of
that 64KB as possible (which is already very limited) to leave maximum
resources for the application using it.

I could have applied for the “Optimization” category, but I already knew
what I was getting into, so I didn’t, sniff. However, I am using methods
like zero-copy via segmented file writing functions, as well as optimized
randomization algorithms like Xorshift32 and Lemire’s algorithm.

0
Oignon

Changed the image loading method (updated the loader in the eadkp library), updated the license application terms (switched eadkp to LGPL), and made minor documentation and code fixes.Changed the image loading method (updated the loader in the eadkp library), updated the license application terms (switched eadkp to LGPL), and made minor documentation and code fixes.
(fix script removing befor .git)

Attachment
0
Oignon

Shipped this project!

Hours: 53.31
Cookies: 🍪 1397
Multiplier: 21.84 cookies/hr

This is quite literally my first-ever Rust project.

Originally, I wanted to make a game for the Numworks calculator, but I realized that for every app I created, I’d have to rewrite the same boilerplate code and deal with the same specific configuration over and over. So, I built a library to handle it! (I might have gotten a bit carried away though—I’ve spent so much time on the lib that I haven’t even started the game yet).

The library is called EADKP, which stands for Epsilon Application Development Kit Plus, because there’s already a basic ‘eadk’ that mainly acts as a Rust wrapper for the C ABI.

This project required me to dive deep into the Numworks architecture: SlotInfo, UserLand, Kernel, Filesystem, etc. Since modifying files requires accessing specific RAM addresses, understanding the structure, and performing hot-patching in RAM—which is no small feat in Rust, especially when trying to keep it memory-safe. The lib also adds abstractions, a smart image loader (since images are a real pain to work with), extra features like battery level retrieval, and a template to easily kickstart new projects using the library.

Template demo: https://www.youtube.com/watch?v=KNKvgqE-Wmg

I’ve clearly learned a lot, especially since this is not only my first Rust project but also my first low-level project (I usually come from a TypeScript background).

Oignon

Added documentation files: CODE_OF_CONDUCT.md, CONTRIBUTING.md, SECURITY.md,
and included a demo video of the base application.

0
Oignon

v0.18.0: random and images

I have finalized the last elements before moving to Beta.

  • Image System Refactor: Optimized and modularized the system. You can now choose whether an image is stored in RAM (for speed) or kept in Flash (slower, but saves RAM).
  • Random Module Refactor: Improved the internal implementation of the Xorshift32 algorithm and implemented Lemire’s algorithm for unbiased sampling.
  • Removed the requirement for cargo-nightly.

These two refactors were (normally) the last remaining major API changes. I am now moving to Beta 1 and marking the project as feature-complete. Once I have thoroughly verified everything and completed the documentation, it will move to a full release. This will happen over time as it gets battle-tested by other projects.

Attachment
0
Oignon

I wanted to implement cargo-release, but their system is too rigid for my specific needs. Instead, I’ve created a .sh script that aligns better with my requirements. However, please ensure that the script is as secure as possible and that it reverts to the original state if any error occurs.

Attachment
0
Oignon

Alpha 4 (v0.13.0): Switched to LGPL-3.0 License!

I have officially moved the project to the LGPL-3.0 license! LGPL-3.0 allows you to use this library in your own projects without the license “contaminating” your entire codebase. This means your project’s license remains independent of this library.

I have also (mostly) translated all code comments into French, as the NumWorks community is almost exclusively French. Additionally, I’ve added two new functions to input (is_alphanumeric and to_alphanumeric) to easily convert keyboard input into strings.

Attachment
0
Oignon

v1.12.0 is Here! - Important update: Storage sub-module refactor!

After 67 days of working on refactoring the calculator’s storage management sub-module, it’s finally done!
The logic in storage.rs has been entirely rewritten to be faster, more secure, and more modular. It’s been a long journey, but I finally made it!

-> Release here

For this third overhaul of storage.rs, I had to create a new sub-module: epsilon.rs. This module contains the structures and representations of Epsilon’s system objects. Thanks to this centralized logic, fixing a mapping error on an object will now have an immediate effect across the entire project. This is a huge plus!

This refactor forced me to dive even deeper into the calculator’s memory structure and gain a thorough understanding of its layout.

Minor Changes:

  • Updated README
  • Synced justfile
  • Updated example files
  • Added Errors enum
  • Added Rust CI workflow

I can now focus on adding new features to the library’s API !

Attachment
0
Oignon

Seems I’ve fixed the infinite loading issue!


BUT, because why not, I found more major bugs. Most are fixed, but one is a real wall:

Under unknown conditions, the host gets timed out from their own server. I’ve ensured that if the server cuts out, clients now return to the menu with an error message. The base game didn’t handle this, leaving everyone stuck on infinite loads—mind-blowing, since handling connection loss is Networking 101.


Problem is, I can’t find the cause of the host timeout yet. Limited tester availability and the bug’s random nature are slowing me down.


Other issues: Laser Triggers are totally desynced 🤷, and conveyor belts are broken even in solo…

List of fixes/patchs applied:

  • Fix #12: Simplified (removed the code causing HarmonyX warnings)
  • Fix #13: Computer.ReceiveVirtualFunctionExecute() - Checks bounds before access
  • Fix #14: Computer.ReceiveVirtualEventInvoke() - Checks bounds
  • Fix #15: Computer.ReceiveVirtualObjectDestroy() - Checks bounds
  • Fix #16: ObjectManager.ApplyAllGUS() - Absorbs NullRefs during shutdown
  • Fix #17: Automatic recovery and menu return if the server crashes or disappears.
  • Fix #18: Proper disconnection handling (prevents infinite loading and shows clear error reasons).
  • Fix #19: Improved stability and error prevention for Spline/Curve calculations.
  • Fix #20: Added safety nets to prevent crashes during control point processing.
  • Fix #21: Final security layer to catch remaining errors in curve refreshing.

Sorry for the random image, I didn’t really have any ideas for a proper illustration for this devlog.

Attachment
0
Oignon

I wrote a Python script to check the date format in the save files to see if they’ve been patched by the mod

Attachment
0
Oignon

The main issue with Mechanica’s multiplayer is the infinite loading when a player joins a game that has already been created.

I conducted extensive tests and collected logs to identify the causes of this problem. I decompiled the game code and used profiling tools to pinpoint failure points.

This allowed me to discover several major issues, some of which were much harder to identify than others. So far, I have identified and theoretically fixed 12 problems, ranging from simple precautions to logging improvements to help identify new issues in the future.

I also wrote a PowerShell build script to automatically compile the mod and update it in the game.

The patches I applied are as follows:

  1. Date reading issue

    • Fixed saved dates with incompatible formats between players.
  2. New game creation issue

    • Corrected date formats when creating new games.
  3. Save sorting issue

    • Fixed incorrectly sorted saves caused by invalid date formats.
  4. Corrupted lobby data

    • Prevented crashes caused by corrupted Steam data.
  5. Inventory loading issue

    • Prevented crashes when loading inventories with invalid Steam IDs.
  6. Network errors

    • Logged network errors without interrupting sessions.
  7. Premature disconnection

    • Blocked unintentional disconnections when the game is not paused.
  8. Lobby transition issue

    • Prevented UI crashes during lobby state changes.
  9. Lobby refresh issue

    • Prevented crashes during lobby UI refreshes.
  10. Lobby connection issue

    • Prevented crashes when attempting to join a lobby.
  11. Player connect/disconnect issue

    • Prevented crashes during player connection or disconnection events.
  12. Disconnection without saving

    • Logged and validated premature disconnections.
Attachment
0
Oignon

Version 0.10, 0.11, 0.11.1 and 0.11.2 :

  • Removed conditional imports, unnecessary since std already provides alloc when OS=YES.
  • Cleaned up imports in the setup macro.
  • Switch to 0.11.2-alpha.2
  • Publish 0.11.2 to crates.io
Attachment
0
Oignon

Adding a project initialization automation script, independent of cargo-generate!

By using a simple command:
bash <(curl -s https://raw.githubusercontent.com/Oignontom8283/eadkp_template/main/bootstrap.sh)
(Make sure to have curl and git installed), you can start a new NumWorks application using EADKP in the blink of an eye!

OR use:
git clone https://github.com/Oignontom8283/eadkp_template.git project_name
cd project_name
chmod +x ./bootstrap.sh && ./bootstrap.sh

PS: I was tired of manually reconfiguring everything every time, so here it is! (:

0
Oignon

Improving the application visuals from the default template code!

Changes:

  • feat: Added a subtitle
  • feat: Added a footer
  • fix: Readjusted the centering of the logo, title, and subtitle
  • fix: Moved the rendering code to a pre-display section before the loop to fix a hardware horizontal sync issue.
Attachment
0
Oignon

Refactoring of the default template demonstration code ! (1/2)
AND adding a function (push_image()) to the eadkp library.

Attachment
Attachment
0
Oignon

Testing the simulator on Linux (Ubuntu-based) !

  • Fixed the Docker start command in start.sh from docker-compose to docker compose.
  • Added settings.json and extensions.json to recommend the Rust-Analyzer extension and its specific configuration for Numworks.
Attachment
0
Oignon

Functional Simulator !

The simulator has been tested and debugged :

  • Fixed incorrect app compilation path:
    ./target/release/target/libsimulator.so -> ./target/release/examples/libsimulator.so
  • Updated default app name in source code.
  • Added information message displayed prior to simulator execution.
Attachment
0
Oignon

Testing compilation and exporting the compiled application to NWA format for the calculator 🥳 !

  • In Cargo.toml: The [target] sections for “device” and “simulator” have been replaced with [[example]]. This changes how builds are managed, now using the --example flag instead of --target.
  • In cargo-generate.toml: The justfile has been added to the exclusion list when generating a new project.
  • In justfile:
    • Build, check, and send commands now use --example device or --example simulator instead of the previous --target flags.
    • Added a just target command to ensure the thumbv7em-none-eabihf Rust target is correctly installed before building.
    • The export command now uses the correct path for the generated binary (target/thumbv7em-none-eabihf/release/examples/device).
    • The export command now displays a success or error message depending on whether the file move was successful.
    • Added a target recipe to install the required Rust target.
    • The justfile is now excluded during new project generation.
Attachment
0
Oignon

‘cargo generate’ is finally working correctly 😊.

Update templates and fix docker config :

  • Use {{project-name}} placeholders for better compatibility
  • Enforce snake_case via project_name_case
  • Exclude assets/ from variable substitution
  • Fix docker-compose paths and remove obsolete Dockerfile
Attachment
0
Oignon

Initial template code. Implementation of the Cargo template system (Untested 😕).

Attachment
0
Oignon

Fix MAJOR compilation ISSUES in the eadkp::builder::setup() script and embedded dynamic allocator imports within the setup macro.

Code preview of the future template using the library (after bug fixes):

Attachment
0
Oignon

Moved build script inside the EADKP library:
- The build script has been moved into the EADKP library for easier usage and project integration.

Attachment
0
Oignon
  • C/C++ support testing
  • Binary generation optimization:
    • Unused C/C++ code is no longer compiled or linked, reducing final binary sizes.
  • C/C++ support in the simulator:
    • C/C++ code will now be compiled and linked when running in the simulator, rather than only on the physical device.
  • Support for c/ and cpp/ folders for C/C++ code.
  • EIF file extension change:
    • EIF files now use the .eif extension instead of .bin.
  • Added Micro and Nano text editors to the Docker image to facilitate editing files directly from the shell.
Attachment
0