Snake game clone: caterpillar

I am developing a TUI library https://github.com/daredemo/simple-text-ui-for-zig and as a testcase I’ve made a simple caterpillar game

https://github.com/daredemo/caterpillar-tui

Should run on any linux, maybe on Mac too.

2 Likes

It builds on my machine but segfaults, directly in debug build, and in any builds after I hit something, also it blinks quite a lot, so not very smooth, but it’s also quite good nice project :slight_smile:

Which operating system are you using?

On Ubuntu/Kubuntu it seems to work quite smooth… But I have to debug a bit more the memory deallocation.

I’m on vanillaOS but running things in a debian container if that make sense.

General protection exception (no address available)
/home/pollivie/.cache/zig/p/1220a7aca117f249ae046880d16787c21bf72f6c56a62c4d239d89ec9691decce440/src/Panel.zig:162:30: 0x10c172a in draw (caterpillar-tui)
            if (p.writer.list.len > 3072) {
                             ^
/home/pollivie/.cache/zig/p/1220a7aca117f249ae046880d16787c21bf72f6c56a62c4d239d89ec9691decce440/src/Panel.zig:1003:32: 0x10985b0 in draw (caterpillar-tui)
                _ = r_text.draw();
                               ^
/home/pollivie/workspace/trash/caterpillar-tui/src/main.zig:572:33: 0x10973cb in getHeartBeat (caterpillar-tui)
        _ = self.panel_root.draw();
                                ^
/home/pollivie/workspace/trash/caterpillar-tui/src/main.zig:702:25: 0x1099175 in doAppHeartBeatThread (caterpillar-tui)
    try arg.getHeartBeat();
                        ^
/home/pollivie/zig/0.14.0-dev.2293+6d781e095/files/lib/std/Thread.zig:505:21: 0x1076f0c in callFn__anon_8182 (caterpillar-tui)
                    @call(.auto, f, args) catch |err| {
                    ^
/home/pollivie/zig/0.14.0-dev.2293+6d781e095/files/lib/std/Thread.zig:755:30: 0x104f372 in entryFn (caterpillar-tui)
                return callFn(f, args_ptr.*);
                             ^
./nptl/pthread_create.c:447:8: 0x7fdbe04c8111 in start_thread (pthread_create.c)
../sysdeps/unix/sysv/linux/x86_64/clone3.S:78:0: 0x7fdbe05468f7 in __clone3 (../sysdeps/unix/sysv/linux/x86_64/clone3.S)
???:?:?: 0x0 in ??? (???)
run
└─ run caterpillar-tui failure
error: the following command terminated unexpectedly:
/home/pollivie/workspace/trash/caterpillar-tui/zig-out/bin/caterpillar-tui
Build Summary: 3/5 steps succeeded; 1 failed
run transitive failure
└─ run caterpillar-tui failure
error: the following build command failed with exit code 1:
/home/pollivie/workspace/trash/caterpillar-tui/.zig-cache/o/934e5f1beb7746de935acbc9d5d1b7b5/build /home/pollivie/zig/0.14.0-dev.2293+6d781e095/files/zig /home/pollivie/zig/0.14.0-dev.2293+6d781e095/files/lib /home/pollivie/workspace/trash/caterpillar-tui /home/pollivie/workspace/trash/caterpillar-tui/.zig-cache /home/pollivie/.cache/zig --seed 0x2f7cedf2 -Z32a3c67921dda72c run

And to clarify, which zig version?

Got it:

YOU MUST USE MUSL TARGET!

In other words something like this:

zig build -Doptimize=ReleaseSmall -Dtarget=x86_64-linux-musl -Dstrip

If you scroll to the end of the README, it warns that it is only tested on x86_64-linux-musl.

x85?? Surely a typo :wink:

sorry, of course, obviously a typo :dizzy_face:

Updated the way data is written to the stdout. it might flicker less now.

1 Like

I’ve tested it, and I still get a segfault when I crash I die on a surface, also it’s still flickering heavily. It seems that this is related to the fact that when I don’t press any inputs, it redraw less ? I’m not sure, but when I keep the keyDown it doesn’t flicker as much. Also from trying to fix the issue, it seems like every Buffered writer you have expect a size of 4096, maybe try to make that a bit more generic ?. Also after trying to dig into your code to figure it out, I think your approach could be improved for the drawing part.

Feel free to correct me if I’m wrong, but you use a bufferedWriter. write to it, than flush it to print to the stdout. A better approach, would be to skip the bufferedWritter entirely, and use a Frame buffer, with an array, in which you would write your rendering, and you should alternate between two of them, one that’s currently rendered, and another one that’s being written to. When you are ready to push the new frame, you should erase from your frame Buffer, everything that’s still the same. Such that you only move the cursor to update the part that have moved.

I’m no expert, but I know terminal rendering can be pretty slow, if you don’t juice it to the maximum. Also to be clear, I’m currently on a very slow computer with only a i5 6600u and 16g of slow ram (But I’m using Ghostty so it’s still very fast). But I’m sure this can be improved. :slight_smile: Happy to test it further!

Also I’ve just remembered about synchronized output, maybe worth looking into ? link

I cannot quite reproduce the issues you are experiencing. I ran it on i3 with 8Gb of RAM and I still get smooth play.

One thing that I might have to point out is that it is developed for zig 0.13.0. It seems to me that you are using zig 0.14.0-dev. There might be changes in the dev build that break my code. Not sure.

I did minor changes to the text ui engine. Now it should not flush as often as before. But the impact for this game should be marginal.

I’ll try later to double the buffer size, but somehow I suspect the issue is somewhere else.