This week's #devlog for my sokoban style prototype. #godot #gameDev
We did it! πΊπΌ
"Cat a shooter πΊ" appeared on F-Droid, and you can download it from here already π https://f-droid.org/en/packages/org.xolatgames.catashoot/
Thanks so much to https://gitlab.com/linsui who really helped me to rewrite the final YML file π https://gitlab.com/fdroid/fdroiddata/-/blob/master/metadata/org.xolatgames.catashoot.yml π€
#lua #love2d #game #games #gamedev #dev #devlog #development #fdroid #android #androiddev #mobile #mobiledev #inkscape #arcade #2d #thanks #opensource #codeberg #git #spaceinvaders #gitlab #publish #publishing
Got back to my functional hierarchical state machine having not worked on it for ages.
It's pretty close to done although a number of questions remain.
What to do with errors during transition?
Would it make sense to allow a Revert Phase to allow undo of any effects?
I suppose on_error should probably be configurable.
To what degree can the engine ping-pong between states using internal messages?
How to handle messages received during transition?
I'm erring on the side of predictability.
I also need some sort of markup to make the creation of state trees less verbose.
I've started to copy some of my old mastodon posts onto my blog https://engineer-game.org/blog.html, to keep a history of the #devlog, and make it easier to browse and read.
I may later add more detailed posts on the blog only (when it's too long for a mastodon post).
But actually I'm wondering, would you prefer to read the full posts content here, even if that means a thread of multiple posts, or have a link here that brings to the blog post?
There's a place in Haxe macros where we can't get a hold of the position information, I can just tag the log with whatever I need to distinguish it in filters.
here "c", I'm starting to look into the area where ammer does it's lookup.
I can filter in a number of places, something like the following would do in Haxe
```haxe
x.stamp.tags.any(x -> x == "c");
```
Added to my `bake` library to snarf up selected environment variables at compile time and have them available with the `Baking` and `Baked` class instances.
This was so I can use the compile environment to configure the log format.
```hxml
-D bake.env.capture="STX_LOG_FORMAT"
```
```dotenv
STX_LOG_FORMAT="INCLUDE_LEVEL,INCLUDE_TIMESTAMP,INCLUDE_TAGS,INCLUDE_LOCATION,INCLUDE_NEWLINE_FOR_DETAIL,INCLUDE_DETAIL";
```
```haxe
Bake.pop().env_capture.get("STX_LOG_FORMAT");
```
`stx_log_transport_stderr` sends logs to stderr and format just goes so far as to include certain parts of it.
And because `stx_log` has an array of tags to filter on, it'll be helpful for introspection, the logs stay in the code for debugging and are low resource use if `--debug` is off.
I've been quietly working on porting my engine over from Windows to Linux.
Normally people just
char string[]="hello world";
But I'm not normal people.
I like to pass a text inside quotations to a function pretending its just a const char* pointer.
void foo(char *text){ printf(text); }
foo("hello world");
This works fine in MSVC but when I tried this stunt in GCC, things get silly. When the function spins up, it immediately de-refs the string you gave it. Just fyi π
teaser time :) #devlog #indiedev #gamedesign #gamedevelopment #gamedev #gaming
Up the proverbial creek today. I've an error in ammer, the FFI thing in the type lookup section of the macro.
It looks like I have to take the library on because the author moved to Rust, which means tooling with the logger so I can get to understand it.
However, there's still an issue with reflection throwing an error at macro time when doing type discrimination so **all** serialization is likely to fail while that's still the case.
On the upside, I'm getting to know duckdb and sql in general via it's json ingress, and stx is getting pretty mature.
#Haxe #DevLog
New devlog: exploring a βRegroupβ mechanic for Absolution that ties player direction, mood systems, and replayability together.
#gamedev #indiedev #rpgmaker #gamedesign #devlog #Absolution
Blinkers are on! Multipliers are now displayed much more clearly, and thanks to a sophisticated blinking effect, you can instantly see when upgrades cancel each other out. (Of course, only if you feel like doing math during gameplay: 8x2x1/2 is β¦ wait!?)
In other news, I finished (for now) working on my animation system. By "animation" I mean tweening. Back in the day I had a lot of fun just throwing animation component with a tween inside of it on entity and let animation system do the job, so I decided that for now at least that will cover 90% of my needs for animation in my engine.
Hi folks! βοΈ I have the last new for today, because here's the night π
Now Birdy π¦ has a smooth animation for picking up Crisps π
You can download the new version right from here ποΈπ https://codeberg.org/xolatgames/Birdy-wants-crisps/releases/tag/v1.4.1
Have a good sleep! π₯±ππ΄
#sdl #sdl2 #game #games #gamedev #dev #development #devlog #inkscape #2d #adventure #TiledMapEditor #cpp #cplusplus #codelite #opensource #cmake #linux #codeberg #release #releases #MiniGames #box2d #topview
Hello folks! πβοΈ Here's an update of Birdy π¦
I changed a text of the indicators in the Mini-games on images.
You can download the new version from here ποΈπ https://codeberg.org/xolatgames/Birdy-wants-crisps/releases/tag/v1.4.0 already.
Have a good day to everyone π
#sdl #sdl2 #cpp #cplusplus #box2d #TiledMapEditor #2d #game #games #gamedev #dev #devlog #development #opensource #codeberg #adventure #StoryRich #minigames #inkscape #cmake #appimage #linux #codelite #toonstyle #colorful #release #releases
Finally dug into Mode X. It can do some neat tricks 13h can't, but it's got some challenges as well... so I had to dust off my very rusty assembly skills
https://www.youtube.com/watch?v=Cc0xtavXOUE
#gamedev #retrogamedev #retrocomputing #retrogaming #msdos #indiedev #devlog #pascal #turbopascal
dev log #1 (a long one)
I did a write up no my recent pytest optimisation sprint:
https://www.leadr.gg/blog/what-2000-ai-generated-tests-taught-me-about-pytest
DevLog: Orange Sentry Sprint 2 - MQTT Client Implementation
Introduction
This week's mission was to create a functional MQTT pub/sub client that can grab it's payloads to publish from FIFO pipes (mkfifo) and send them to the broker, as well as to subscribe to a topic and send the messages received through FIFO pipes to other processes to treat.
As you can maybe guess,this week's theme has been plumbing more than anything!
But I also learned more about build systems, why splitting functionality between multiple files is important and why writing utils is so.. useful..
My main blockers were my overall noviceness with the C programming language and trying to learn the Eclipse Paho C MQTT library.
So I dove deep into library docs, man pages and some AI code review to learn about industry best practices, in which the AI was surprisingly good and helpful, especially at providing guidance about best practices.
The Engineering
As a summary, this week provided the mqtt-client implementation, complete with mqtt.h/.c auxiliary files. But also the logging.h util and the fifo-ipc.h/.c library.
The main challenge I faced was to hook everything up in a consistent and well structured manner, while providing adequate levels of abstraction through libraries and utils to avoid calling the vendor library directly from main.
I am planning to use the logging and fifo-ipc libs extensively through the rest of this project, both to keep things consistent and clear.
Speaking of pipes (FIFO is a very funny name btw), I chose to use this technology because I needed some sort of Inter Process Communication (IPC) to let my microservice-inspired architecture's processes talk to one another.
My options were basically Unix Sockets, Signals, Shared Memory, Direct Piping, and FIFO pipes.
Unix sockets looked promising at first, but they were kind of awkward to use (requiring handshakes), so I looked at the other options.
I eliminated signals basically right away, because They can't communicate text in a flexible manner.
Even ignoring the nightmare of memory management with Shared Memory, it was just a security disaster waiting to happen, so I dumped them right away.
Direct Piping just was not repeatable and robust enough.
So I looked at FIFO pipes, and they just fit so goldilockedly perfect. They were challenging but not impossible to implement right (they code basically the same as files), they can be easily debugged from the terminal by echoing to them, and they implement nicely with both C and Python (a technical requirement for this project). So I stuck with them.
They are not perfect, though, and need special treatment for concurrency reasons, and as with any other way of inputting data into a program, they need extensive input sanitization and treatment to avoid security and other kinds of bugs.
I ended up running out of time before I could actually finish implementing the subscribing part of the client, though from the docs it should not be that hard, since I've already done most of the groundwork to handle MQTT connections.
And since I did not have the adequate time to actually test out and debug stuff on ARM and on the board, as well as to clear some TODOS on the code, I will join those tasks into one micro sprint that should last less than a week, a week at most, and try to implement those things there. The plan is to have a really functional and kind of robust (I plan to have at least input sanitization and message formatting/parsing functionalities by the end) client to thoroughly test. If I want to add some more work on top of that I can maybe start to figure out some sort of system to test and benchmark my code on the board.
The Next Steps
The next sprint, a micro one, is also related to MQTT. I plan to implement the subscribing functionality that I could not implement this week, as the complexity of the tasks was too big to handle. I plan to also do some general cleanup across the codebase and dedicate some time to validate and debug the functionality on the ARM board, As I have not been able to even boot up the board for time constraints
Greatest Hits
//snippet of buggy code
int ipc_open_channel(IPC_Channel *channel, const char *path) {
channel->path = path;
if (mkfifo(path, 0666) == -1) {
LOG_ERROR("Failed to create FIFO named pipe");
return -1;
}
channel->fd = open(path, O_RDWR | O_NONBLOCK);
if (channel->fd == -1) {
LOG_ERROR("Failed to open FIFO named pipe");
return -1;
}
return 0;
}
Error:
$ ./bin/x86/mqtt-client
[Error] Failed to create FIFO Named Pipe: File exists
<3>[MQTT_CLIENT] ERROR: Failed to open log FIFO at /tmp/test_fifo
Fixed code:
int ipc_open_channel(IPC_Channel *channel, const char *path) {
channel->path = path;
if (mkfifo(path, 0666) == -1) {
// throw error if there is an actual issue
if (errno != EEXIST) {
LOG_ERROR("Failed to create FIFO named pipe at %s", path);
return -1;
}
// if it gets here then the file already existed, so we just update the
chmod(path, 0666);
}
channel->fd = open(path, O_RDWR | O_NONBLOCK);
if (channel->fd == -1) {
LOG_ERROR("Failed to open FIFO named pipe at %s", path);
return -1;
}
LOG_INFO("Channel opened successfully at %s", path);
return 0;
}
Conclusion
This was a very good and rewarding week for my first big milestone (yeah, I know it's only a sprint) of developing C code beyond just uni courses and quick Udemy projects. Feels nice to build something, and even nicer to ship it.
It may not be perfect, but it's mine and I leaned a lot along the way, and that is what matters.