|
29608
|
My very own WebOS by @techsam12 | Stardance
|
techsam12
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My very own WebOS by @techsam12 | Stardance
|
1793544762.2972884
|
1794149562.2972884
|
|
29651
|
Ham Connect - Australian Ham Radio Dashboard Ham R Ham Connect - Australian Ham Radio Dashboard Ham Radio by @techsam12 | Stardance...
|
techsam12
|
1
|
5.76
|
0
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-07-08T09:33:33Z", "hours": 5.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "This is Aus Ham Radio Connect, my first project, it is 98% vibecoded, most of it is working, and requires an aprs.fi API key, you can view the project at https://sammakesstuff.github.io/Aus-Ham-Radio-Connect/ it uses HTML as a front end and a bit of JS for the back end.", "repo": "https://github.com/Sammakesstuff/Aus-Ham-Radio-Connect", "demo": "https://sammakesstuff.github.io/Aus-Ham-Radio-Connect/"}]...
|
[{"post_id": 25762, "ts": "202 [{"post_id": 25762, "ts": "2026-07-10T06:33:59Z", "hours": 0.4133, "text": "Did some coding and made a settings page, APRS requires an API key from APRS.fi, added some links and functioning data sources. used claude"}, {"post_id": 25073, "ts": "2026-07-09T01:11:35Z", "hours": 0.3486, "text": "So me and claude put our heads together to try and fix a mapping issue that was brought up to me. fixed it, and updated git"}, {"post_id": 24595, "ts": "2026-07-08T09:30:43Z", "hours": 1.0658, "text": "So, yeah just finalizing it up, APRS works (requires an APRS.fi api key which is free to obtain, finalized and polished a few things with claude, most of it is vibecoded but yeah, you can view it at https://sammakesstuff.github.io/Aus-Ham-Radio-Connect/"}, {"post_id": 22037, "ts": "2026-07-04T09:09:34Z", "hours": 1.4153, "text": "Added local ham radio clubs map, data sourced from WIA, not perfect but works :)"}, {"post_id": 21392, "ts": "2026-07-03T09:40:23Z", "hours": 1.5747, "text": "so uh, claude is the goat, if your in australia youve most likely heard of the WIA, (there like the ARRL) but aus version, so they have like a giant ahh pdf of just repeaters coords stuff like that, so it gets plot on this map that claude made, and processed, with a few fine tweaks from me, like correcting some of the slop data, but i’d say for a few hours work, its pretty goated, looking for some suggestions and or improvements from hams"}, {"post_id": 20552, "ts": "2026-07-02T05:09:26Z", "hours": 0.9222, "text": "Hi, My Name Is Sam - VK4AHA, I’m a Ham Radio Operator, and would like to announce my new project: Ham Connect, for those that are licensed G’day, If you have used hamclock before, you’ve most likely gone, hmm you know what, we should add integrations to it, think of Ham connect as a dashboard that will display things like DMR, Yaesu Fusion, APRS, D-star, and much much more integrations, this project is fairly vibecoded, but is my first project on Hackclub :3"}]...
|
Title: Ham Connect - Australian Ham Radio Dashboar Title: Ham Connect - Australian Ham Radio Dashboard Ham Radio by @techsam12 | Stardance
Devlogs:
Hi, My Name Is Sam - VK4AHA, I’m a Ham Radio Operator, and would like to announce my new project: Ham Connect, for those that are licensed G’day, If you have used hamclock before, you’ve most likely gone, hmm you know what, we should add integrations to it, think of Ham connect as a dashboard that will display things like DMR, Yaesu Fusion, APRS, D-star, and much much more integrations, this project is fairly vibecoded, but is my first project on Hackclub :3
so uh, claude is the goat, if your in australia youve most likely heard of the WIA, (there like the ARRL) but aus version, so they have like a giant ahh pdf of just repeaters coords stuff like that, so it gets plot on this map that claude made, and processed, with a few fine tweaks from me, like correcting some of the slop data, but i’d say for a few hours work, its pretty goated, looking for some suggestions and or improvements from hams
Added local ham radio clubs map, data sourced from WIA, not perfect but works :)
So, yeah just finalizing it up, APRS works (requires an APRS.fi api key which is free to obtain, finalized and polished a few things with claude, most of it is vibecoded but yeah, you can view it at https://sammakesstuff.github.io/Aus-Ham-Radio-Connect/
So me and claude put our heads together to try and fix a mapping issue that was brought up to me. fixed it, and updated git
Did some coding and made a settings page, APRS requires an API key from APRS.fi, added some links and functioning data sources. used claude
Ships:
This is Aus Ham Radio Connect, my first project, it is 98% vibecoded, most of it is working, and requires an aprs.fi API key, you can view the project at https://sammakesstuff.github.io/Aus-Ham-Radio-Connect/ it uses HTML as a front end and a bit of JS for the back end....
|
1793649076.8192604
|
1793735476.8192604
|
|
30919
|
White Monster Vending Machine by @techsam12 | Star White Monster Vending Machine by @techsam12 | Stardance...
|
techsam12
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: White Monster Vending Machine by @techsam12 Title: White Monster Vending Machine by @techsam12 | Stardance...
|
1793465372.9325197
|
1794070172.9325197
|
|
13764
|
wayland screenshot tool in zig or maybe rust by @t wayland screenshot tool in zig or maybe rust by @techs-sus | Stardance...
|
techs-sus
|
0
|
0.72
|
0
|
[]
|
[{"post_id": 5690, "ts": "2026 [{"post_id": 5690, "ts": "2026-06-09T16:03:44Z", "hours": 0.7231, "text": "i setup the project there are many options in zig for using wayland + vulkan together but i decided on using wio https://github.com/ypsvlq/wio instead of other options like raylib because it exposes the wl_display and wl_surface we would need to make the window display on top of everything else using wayland protocols for now though it is just an orange square example"}]...
|
Title: wayland screenshot tool in zig or maybe rus Title: wayland screenshot tool in zig or maybe rust by @techs-sus | Stardance
Devlogs:
i setup the project there are many options in zig for using wayland + vulkan together but i decided on using wio https://github.com/ypsvlq/wio instead of other options like raylib because it exposes the wl_display and wl_surface we would need to make the window display on top of everything else using wayland protocols for now though it is just an orange square example...
|
1792954237.4148002
|
1793818237.4148002
|
|
32375
|
Music Syncer by @techs-sus | Stardance
|
techs-sus
|
1
|
64.46
|
833
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-09-02T23:54:31Z", "hours": 45.0, "multiplier": 18.46, "payout": 833, "blessing": "neutral", "text": "I made a Kotlin CLI program that synchronizes a YouTube Music playlist to a SQLite database locally. I made this because I want to be able to play my music freely even when YouTube Music or my network is down. The main challenge was finding a library that would let me get the data I needed (artist, thumbnail, audio tracks, etc.) from YouTube Music, and I even had to rewrite the entire program in Kotlin from Rust because the library I was using couldn’t download audio properly.", "repo": "https://github.com/techs-sus/music-syncer", "demo": "https://github.com/techs-sus/music-syncer/releases"}]...
|
[{"post_id": 78225, "ts": "202 [{"post_id": 78225, "ts": "2026-10-10T00:53:04Z", "hours": 1.1172, "text": "I fixed another Nix graalvm issue. Some mp4s wouldn’t be tagged properly, so I fixed that."}, {"post_id": 74678, "ts": "2026-09-27T23:46:37Z", "hours": 0.6, "text": "I fixed the binary in Nix, it works now, also updated the asciinema cast it was missing some reachability metadata and required LD_LIBRARY_PATH to be set to the jdk’s libraries."}, {"post_id": 74664, "ts": "2026-09-27T22:23:13Z", "hours": 0.7189, "text": "Tiny change, I switched from scrimage to ImageIO. It works much better and should be less error prone as scrimage would vendor in webp binaries, which is not cross platform."}, {"post_id": 74533, "ts": "2026-09-27T16:04:10Z", "hours": 2.7108, "text": "Squashed more bugs, updated NativeMetadataMain.kt so that reachability metadata includes image i/o. This makes the Graal native image actually work when having to convert from webp to png. This will be a non issue when I can find an image library that is written in pure Kotlin. The last shipwright to review my project tried syncing a mix, which is infinite. So I added an error for that and made sure no one will run into unexplainable errors again."}, {"post_id": 71298, "ts": "2026-09-20T16:18:29Z", "hours": 1.1267, "text": "I added GraalVM native image support. The actual implementation is boring but this makes the program’s cold starts faster and makes it feel more native. Not sure if this helps with battery life, but it might. This definitely helps with memory usage, the program only uses ~100mb syncing my 400 track playlist. I restricted the native image to Nix because the releases are supposed to always work on all platforms."}, {"post_id": 71243, "ts": "2026-09-20T14:51:47Z", "hours": 0.3306, "text": "I finally silenced those pesky slf4j and unsafe memory access warnings. Just added the slf4j-nop library and a JVM flag."}, {"post_id": 70926, "ts": "2026-09-20T01:43:13Z", "hours": 2.5042, "text": "I redid the cli structure to group all the playlist commands under one common playlist parent command. I also implemented a clean up command to help people save disk space because SSDs are expensive right now. For example: music-syncer-kotlin -p path init -> music-syncer-kotlin playlist -p path init This was a necessary step so I could implement the clean up command, which deletes audio and thumbnail files that are not used by any playlists in a container. A container is the folder holding all the databases. Here’s everything I did, stolen from my commit message: feature: add clean-container command - refactor: add hasTrackInDatabase to the Playlist class - refactor: move knownFinal{Audio,Thumbnail}Extension out of class and make it const - refactor: nest all playlist commands as one subcommand - refactor: make cli help text more helpful - refactor: always print something to the console to let the user know that everything went well - refactor: do not use PlaylistHolder, use currentContext.registerJvmCloseable to clean up playlist - fix: when thumbnail is newly created, retag should silently fail"}, {"post_id": 64580, "ts": "2026-09-09T02:50:12Z", "hours": 2.7675, "text": "I watched a Kotlin talk about Flows and I was inspired to rewrite my program using them. This made my program more efficient, idiomatic and also helped me fix the annoying progress bar refresh bug (multiple old bars shown). It also let me actually properly sort by position across all 4 status types (added, removed, moved, errored). I also made the downloading functions use one underlying common function to clean up the codebase. I also removed sqlx4k because it wasn’t actually parallel and was causing issues with init. Here, in the screenshot I am showing the new elegant code for the logging of track statuses. It used to be many individual async calls, but flows allow me to group them up and sort them."}, {"post_id": 64390, "ts": "2026-09-08T18:35:35Z", "hours": 0.81, "text": "I now detect invalid playlist ids and print out an error telling the user how to get a valid playlist id."}, {"post_id": 63814, "ts": "2026-09-07T19:41:24Z", "hours": 0.5508, "text": "I made position diffing aware of insertions and deletions, so that output is less bloated with useless move info such as 0->1, 1->2, etc. I also did some optimization by using database transactions wherever possible. I can’t do it in the main sync body because it is bounded to its own coroutine scope."}, {"post_id": 63724, "ts": "2026-09-07T17:36:43Z", "hours": 1.365, "text": "I added duration tracking to the database. The M3U generation now doesn’t hardcode 0 as the duration."}, {"post_id": 61576, "ts": "2026-09-04T15:35:33Z", "hours": 0.3597, "text": "I made it so that thumbnails should now be even higher quality, it does take more storage but the difference is quite noticeable on some music players. Also small hotfix, if you accidentally pass in another unrelated SQLite database it will now not run migrations on it before erroring."}, {"post_id": 61148, "ts": "2026-09-03T22:22:37Z", "hours": 0.6486, "text": "To help users migrate from the old Rust implementation, I made it so that a sync will re-tag the track if the track’s thumbnail does not exist on disk. The Kotlin implementation always gets higher resolution images, so this allows for much higher resolution track covers."}, {"post_id": 61131, "ts": "2026-09-03T21:37:19Z", "hours": 1.3225, "text": "In my attempt to make the streamExtractor lazily loaded, I caused a deadlock. I have fixed the deadlock and this fixed version is at v0.2.7. The fix was pretty simple, it was to not use CoroutineStart.Lazy because a lazy coroutine may never run, meaning the parent coroutineScope will hang forever. I also switched the backend driver to sqlx4k as it provides a connection pool but more importantly makes the suspend code flow cleaner. I wont switch to Exposed (the official SQL driver) because it doesn’t have the same parallel capabilities as sql4k."}, {"post_id": 60984, "ts": "2026-09-03T17:48:56Z", "hours": 1.7597, "text": "I forgot to add error handling from the original Rust project, so I did that. I also fixed the parallelism by using a Semaphore as limitedParallelism still wakes all the coroutines. Using a Semaphore only allows N permits to be handed out at once. This means that only N tasks would be running at once, given that each task takes one permit. I set N to 8 as that should not cause any throttling but still allow multiple tracks to be downloaded at once. I also implemented better lazy fetching than the old Rust implementation. Now only pieces that must be fetched are fetched, and if they don’t need to be fetched, a StreamExtractor is never fetched. This causes a huge speed up, allowing my ~400 track playlist to be incrementally synced in 8 seconds. Other notable quality of life features (taken from the git log): - refactor: make output use terminal.theme.* - refactor: make output more human readable by using title instead of youtube_playlist_id - fix: reorder items in subtasks so that the text doesn't move everything else"}, {"post_id": 60623, "ts": "2026-09-03T02:30:33Z", "hours": 0.7667, "text": "Shortly after I shipped, I found a better library for progress bars and displaying to the terminal in general. I also made sure that the exists locally log line would be printed out in order. I decided to use it, and I am really happy with the result!!!!"}, {"post_id": 60558, "ts": "2026-09-02T23:48:06Z", "hours": 1.2247, "text": "Preparing to ship the project, so here’s a list of everything I did: added back an edited readme added back the apache 2.0 license fixed the github actions auto release recorded an asciinema cast and put it in the readme made the cli say music-player-kotlin instead of cli …other small changes to make sure its ready for release"}, {"post_id": 60487, "ts": "2026-09-02T21:02:16Z", "hours": 0.7539, "text": "added a progress bar and actually actually fixed the deadlock this time"}, {"post_id": 60469, "ts": "2026-09-02T20:12:04Z", "hours": 0.4286, "text": "I fixed position tracking, so that moved tracks will output a line telling you they have moved. I attempted to fix a deadlock that was happening, and fixed some database queries targetting the wrong table."}, {"post_id": 60450, "ts": "2026-09-02T19:45:23Z", "hours": 1.5511, "text": "I cleaned up the code, bounded parallelism to 8 with limitedParallelism, and tried to optimize the detection of moved tracks"}, {"post_id": 60347, "ts": "2026-09-02T17:08:19Z", "hours": 4.1644, "text": "the rewrite is almost finished thumbnails are now way higher in resolution because we can now get youtube’s webp images. unfortunately jaudiotagger does not support webp images, so i force all images from youtube to turn into a lossless png kotlin is pretty cool, especially coroutines, its like lua’s coroutines but actually backed by a thread pool i need to limit the concurrency but otherwise this is great! very fast even on a debug build what’s left: currently unlimited concurrency, this will definitely crash the jvm on large playlists better terminal output with colors and a diff generator use a temporary table in sqlite to make diffing more memory efficient packaging and ci should be fine since “java runs anywhere”"}, {"post_id": 59975, "ts": "2026-09-02T01:52:56Z", "hours": 4.3806, "text": "i begun porting the project to kotlin while i love rust i also want this project to actually work rustypipe will always be a bit behind youtube’s protections so i decided to just rewrite the whole thing in kotlin so i can use newpipeextractor directly what’s left: tag audio with jaudiotagger use clikt to make a nice command line interface (maybe) add unit tests there is no actual screenshot because i didn’t actually implement the commands yet"}, {"post_id": 51282, "ts": "2026-08-20T20:29:43Z", "hours": 4.3222, "text": "i got rustypipe-botguard working with Nix i still can’t figure out why some videos don’t work sometimes but other videos work all the time i updated the test suite to reflect that"}, {"post_id": 50736, "ts": "2026-08-20T02:44:23Z", "hours": 1.0564, "text": "i finally did the ci pipeline for windows, linux, and macos i wrote a readme but i’ll need to add an asciinema cast to it to make it look better and allow me to ship the project"}, {"post_id": 50703, "ts": "2026-08-20T01:04:16Z", "hours": 1.5878, "text": "thumbnails were really low quality, this change allows for higher quality thumbnails. one example would be 60x60 -> 120x120 still low quality but a higher low quality. other notable changes: unification of all track identifiers into one refetch thumbnails if not existing & do not fetch thumbnail if its {id}.{png,jpeg,jpg} exist m3a -> m3u, it is more compatible with music players (this happened in 4c337f491dd949fdc3f1f5d51363b0342defaac1 on aug 15, i forgot to log it) next thing to do is packaging . this is my worst nightmare so the whole program will be statically linked"}, {"post_id": 50425, "ts": "2026-08-19T16:22:13Z", "hours": 0.5014, "text": "progress bars with tracing-indicatif might have to increase tick rate, it flickers a bunch on release mode"}, {"post_id": 47821, "ts": "2026-08-16T01:05:27Z", "hours": 0.4694, "text": "tracks that are only available as m4a’s can now be downloaded ffmpeg won’t be spawned to remux screenshot is forcefully required so heres the main fix"}, {"post_id": 47801, "ts": "2026-08-16T00:26:22Z", "hours": 3.2114, "text": "/tmp is now only hardcoded in the singular unit test errors are more friendly, m3a generation has been refitted to be m3u generation so that more music players are supported, fixed a bug where songs would be downloaded with audio/{id}..m4a which is an invalid path, and updated the user agent to be a firefox extended support release so i dont have to update it more downloads were broken by the rustypipe switch, so i fixed them by forcing the AndroidVr client. some tracks are weird and still don’t work, but most do"}, {"post_id": 45281, "ts": "2026-08-11T17:10:58Z", "hours": 0.3233, "text": "i fixed the nix build this should allow me to cross compile to windows (maybe with mingw, and after i don’t hardcode /tmp), mac, and linux"}, {"post_id": 45263, "ts": "2026-08-11T16:43:26Z", "hours": 1.645, "text": "i switched from kopuz-server to rustypipe it is much faster and more accurate which may allow me to bypass youtube music’s weird quirk of some tracks only being playable directly on youtube the playlist is now synced in 3.2 seconds, and not 5"}, {"post_id": 44961, "ts": "2026-08-11T02:10:07Z", "hours": 0.8017, "text": "i made tracks that cause errors to show up in the diff form"}, {"post_id": 44936, "ts": "2026-08-11T01:05:27Z", "hours": 1.8956, "text": "i added the base diffing feature i wanted i still need to make it filter out tracks that are unfetchable that are currently marked as “removed” and i need to rename the project to music-syncer"}, {"post_id": 43011, "ts": "2026-08-08T01:30:07Z", "hours": 0.4114, "text": "i added configurable concurrency it doesn’t seem to improve download or sync times but i think now it has to be stdio performance thats holding it back, logging is not free"}, {"post_id": 42935, "ts": "2026-08-07T22:27:17Z", "hours": 0.2881, "text": "i shrunk the number of crates being built from 700-800 to 500 by stripping my fork of kopuz-server of all bloat it depended on lots of crates and most importantly it doesn’t rely on rusqlite 0.31 and sqlx 0.8 the screenshot shows how much smaller the build is now"}, {"post_id": 42401, "ts": "2026-08-07T02:51:53Z", "hours": 0.7711, "text": "parallelism!!! i was able to download my whole playlist in ~30 seconds (with unbounded parallelism that lagged the rest of my laptop) next steps: maybe change parallelism from hardcoded 16 to num_cpus::get() or ask tokio how many threads we have use ratatui and display the status of each song being downloaded, since we’re using tracing we can use https://github.com/gin66/tui-logger use color_eyre https://ratatui.rs/recipes/apps/color-eyre/ maybe add login, some songs are age restricted (even if they have no lyrics) definitely add configurable parallelism; i think this software would rip through playlists if it had more sqlite connections and more threads not really any screenshots to show anymore……. but i can try and show how many tracks were downloaded successfully and how long it took the screenshot is bounded by 16 futures at a time, which is probably too small and the sqlite connection pool is capped at 5. 2 minutes is a lot. but on a good note incremental syncs only take ~5.7 seconds"}, {"post_id": 42363, "ts": "2026-08-07T01:25:53Z", "hours": 2.9161, "text": "i switched to sqlx and the code is much cleaner but now i have to hack around how sqlx builds offline with SQLX_OFFLINE=true cargo build but i only have to do it once then its cached using sqlx is much more developer friendly and it taught me that a connection pool can harm the application because temp tables are only kept per connection not per entire database since nothing really changed but the code became cleaner i will show another music player that can display the generated playlist"}, {"post_id": 42258, "ts": "2026-08-06T21:41:07Z", "hours": 2.185, "text": "audio metadata for this dev log you will see 2 hours for one command spawn and a small refactor. but what you have not seen was 2 hours fighting ffmpeg-next, ffmpeg-sys-next, bindgen, libclang all that to say i decided to not link against ffmpeg, and i am much happier with the result audio players get the title, artist, even cover art all from the track’s metadata unfortunately, youtube music does not attach metadata to the tracks we scrape, so we need to attach metadata attaching metadata to audio files is actually pretty simple thanks to the lofty crate unless the file is a webm. webm does not have any sort of audio metadata (?) so you will need to transcode webm into another audio format to put metadata into the file. i decided to just pick m4a because everything supports it. lastly i did a small refactor because main.rs was pushing 600 lines of code, and i plan to: separate the db functions from the Playlist struct make the code truly asynchronous, which involves moving to sqlx pipeline everything the end result is pretty metadata in Gapless (or any other modern music player)"}, {"post_id": 42119, "ts": "2026-08-06T18:10:03Z", "hours": 0.3578, "text": "I switched from directly printing to stderr to using tracing. The m3a playlist generation works quite well, as you can see in the screenshot."}, {"post_id": 42100, "ts": "2026-08-06T17:43:20Z", "hours": 5.0975, "text": "after a lot of thinking i decided to not make a music player and instead decided to instead make a really fast youtube music playlist syncer the upstream library i was gonna use anyway does not expose YoutubeMusicClient, so i forked it and added a patch so i can use that everything was working until i realized downloads were really slow and the fix was to add a Range header with a value of “bytes=0-” and now downloads are very fast. i suspect that this makes my code look like a real browser to youtube/google which lets me get the normal download speed. i used rusqlite (sqlite rust wrapper) and each playlist is its own database file. i might switch to sqlx because it has compile time sql checking and has a very good async sqlite wrapper everything should work except m3a playlist generation, there are no good m3a playlist libraries so i hand coded it myself and have not tested it yet; UPDATE: it works i tested it now i plan on adding thumbnail deduplication, songs from the same album can have the same thumbnail"}, {"post_id": 24905, "ts": "2026-07-08T19:23:54Z", "hours": 0.8556, "text": "i added support for loading custom tinted-theming themes such as from https://github.com/tinted-theming/schemes the screenshot is using ayu_dark: https://github.com/tinted-theming/schemes/blob/spec-0.11/base16/ayu-dark.yaml"}, {"post_id": 24854, "ts": "2026-07-08T18:14:47Z", "hours": 1.3539, "text": "i added the base code for base16 themes and the skeleton sidebar (no buttons or actual pages yet) i plan for the sidebar to do something with navigation so like a playlists button and because i want the music player to be minimal it will probably become floating and will probably become a small menu icon that when clicked will expose the Playlists button i will probably make some sort of abstract button wrapper since i still need to make the actual full screen player ui which will at least have 3 icons (pause/play, backwards, forwards) the slow resizing issue was fixed by using gpui’s git repository and not crates.io the next steps are to add custom theme support which means i will need to also locate a config folder; i plan on using https://codeberg.org/dirs/directories-rs ; colors will probably be in yaml so that you can copy and paste tinted-theming schemes from https://github.com/tinted-theming/schemes other config settings will likely be in toml oh also i will need to set up automatic binary releases for amd64 and arm64 on linux and macos with github actions, which should be easier because it already uses Nix"}, {"post_id": 24798, "ts": "2026-07-08T16:20:27Z", "hours": 1.6167, "text": "gpui at least with the crates.io version has very slow resizing so i might switch to iced i have some ideas for how data will be stored: sqlite for database engine via sqlx or pure rust library (depends on which one allows to decode into structs) migrations can be done as a map to sql string (version -> appropriate migration) each playlist can be its own database & can store its own downloaded songs because fetching from db is faster: https://sqlite.org/fasterthanfs.html settings (theme) can be done in toml i have also disabled bounds on the gpui window, so thats the screenshot"}, {"post_id": 24396, "ts": "2026-07-07T22:28:27Z", "hours": 0.9344, "text": "I set up the flake at first using rust-overlay but realized crane is probably better so I asked opencode to refactor it to use crane The default gpui example now runs"}]...
|
Title: Music Syncer by @techs-sus | Stardance
Dev Title: Music Syncer by @techs-sus | Stardance
Devlogs:
I set up the flake at first using rust-overlay but realized crane is probably better so I asked opencode to refactor it to use crane The default gpui example now runs
gpui at least with the crates.io version has very slow resizing so i might switch to iced i have some ideas for how data will be stored: sqlite for database engine via sqlx or pure rust library (depends on which one allows to decode into structs) migrations can be done as a map to sql string (version -> appropriate migration) each playlist can be its own database & can store its own downloaded songs because fetching from db is faster: https://sqlite.org/fasterthanfs.html settings (theme) can be done in toml i have also disabled bounds on the gpui window, so thats the screenshot
i added the base code for base16 themes and the skeleton sidebar (no buttons or actual pages yet) i plan for the sidebar to do something with navigation so like a playlists button and because i want the music player to be minimal it will probably become floating and will probably become a small menu icon that when clicked will expose the Playlists button i will probably make some sort of abstract button wrapper since i still need to make the actual full screen player ui which will at least have 3 icons (pause/play, backwards, forwards) the slow resizing issue was fixed by using gpui’s git repository and not crates.io the next steps are to add custom theme support which means i will need to also locate a config folder; i plan on using https://codeberg.org/dirs/directories-rs ; colors will probably be in yaml so that you can copy and paste tinted-theming schemes from https://github.com/tinted-theming/schemes other config settings will likely be in toml oh also i will need to set up automatic binary releases for amd64 and arm64 on linux and macos with github actions, which should be easier because it already uses Nix
i added support for loading custom tinted-theming themes such as from https://github.com/tinted-theming/schemes the screenshot is using ayu_dark: https://github.com/tinted-theming/schemes/blob/spec-0.11/base16/ayu-dark.yaml
after a lot of thinking i decided to not make a music player and instead decided to instead make a really fast youtube music playlist syncer the upstream library i was gonna use anyway does not expose YoutubeMusicClient, so i forked it and added a patch so i can use that everything was working until i realized downloads were really slow and the fix was to add a Range header with a value of “bytes=0-” and now downloads are very fast. i suspect that this makes my code look like a real browser to youtube/google which lets me get the normal download speed. i used rusqlite (sqlite rust wrapper) and each playlist is its own database file. i might switch to sqlx because it has compile time sql checking and has a very good async sqlite wrapper everything should work except m3a playlist generation, there are no good m3a playlist libraries so i hand coded it myself and have not tested it yet; UPDATE: it works i tested it now i plan on adding thumbnail deduplication, songs from the same album can have the same thumbnail
I switched from directly printing to stderr to using tracing. The m3a playlist generation works quite well, as you can see in the screenshot.
audio metadata for this dev log you will see 2 hours for one command spawn and a small refactor. but what you have not seen was 2 hours fighting ffmpeg-next, ffmpeg-sys-next, bindgen, libclang all that to say i decided to not link against ffmpeg, and i am much happier with the result audio players get the title, artist, even cover art all from the track’s metadata unfortunately, youtube music does not attach metadata to the tracks we scrape, so we need to attach metadata attaching metadata to audio files is actually pretty simple thanks to the lofty crate unless the file is a webm. webm does not have any sort of audio metadata (?) so you will need to transcode webm into another audio format to put metadata into the file. i decided to just pick m4a because everything supports it. lastly i did a small refactor because main.rs was pushing 600 lines of code, and i plan to: separate the db functions from the Playlist struct make the code truly asynchronous, which involves moving to sqlx pipeline everything the end result is pretty metadata in Gapless (or any other modern music player)
i switched to sqlx and the code is much cleaner but now i have to hack around how sqlx builds offline with SQLX_OFFLINE=true cargo build but i only have to do it once then its cached using sqlx is much more developer friendly and it taught me that a connection pool can harm the application because temp tables are only kept per connection not per entire database since nothing really changed but the code became cleaner i will show another music player that can display the generated playlist
parallelism!!! i was able to download my whole playlist in ~30 seconds (with unbounded parallelism that lagged the rest of my laptop) next steps: maybe change parallelism from hardcoded 16 to num_cpus::get() or ask tokio how many threads we have use ratatui and display the status of each song being downloaded, since we’re using tracing we can use https://github.com/gin66/tui-logger use color_eyre https://ratatui.rs/recipes/apps/color-eyre/ maybe add login, some songs are age restricted (even if they have no lyrics) definitely add configurable parallelism; i think this software would rip through playlists if it had more sqlite connections and more threads not really any screenshots to show anymore……. but i can try and show how many tracks were downloaded successfully and how long it took the screenshot is bounded by 16 futures at a time, which is probably too small and the sqlite connection pool is capped at 5. 2 minutes is a lot. but on a good note incremental syncs only take ~5.7 seconds
i shrunk the number of crates being built from 700-800 to 500 by stripping my fork of kopuz-server of all bloat it depended on lots of crates and most importantly it doesn’t rely on rusqlite 0.31 and sqlx 0.8 the screenshot shows how much smaller the build is now
i added configurable concurrency it doesn’t seem to improve download or sync times but i think now it has to be stdio performance thats holding it back, logging is not free
i added the base diffing feature i wanted i still need to make it filter out tracks that are unfetchable that are currently marked as “removed” and i need to rename the project to music-syncer
i made tracks that cause errors to show up in the diff form
i switched from kopuz-server to rustypipe it is much faster and more accurate which may allow me to bypass youtube music’s weird quirk of some tracks only being playable directly on youtube the playlist is now synced in 3.2 seconds, and not 5
i fixed the nix build this should allow me to cross compile to windows (maybe with mingw, and after i don’t hardcode /tmp), mac, and linux
/tmp is now only hardcoded in the singular unit test errors are more friendly, m3a generation has been refitted to be m3u generation so that more music players are supported, fixed a bug where songs would be downloaded with audio/{id}..m4a which is an invalid path, and updated the user agent to be a firefox extended support release so i dont have to update it more downloads were broken by the rustypipe switch, so i fixed them by forcing the AndroidVr client. some tracks are weird and still don’t work, but most do
tracks that are only available as m4a’s can now be downloaded ffmpeg won’t be spawned to remux screenshot is forcefully required so heres the main fix
progress bars with tracing-indicatif might have to increase tick rate, it flickers a bunch on release mode
thumbnails were really low quality, this change allows for higher quality thumbnails. one example would be 60x60 -> 120x120 still low quality but a higher low quality. other notable changes: unification of all track identifiers into one refetch thumbnails if not existing & do not fetch thumbnail if its {id}.{png,jpeg,jpg} exist m3a -> m3u, it is more compatible with music players (this happened in 4c337f491dd949fdc3f1f5d51363b0342defaac1 on aug 15, i forgot to log it) next thing to do is packaging . this is my worst nightmare so the whole program will be statically linked
i finally did the ci pipeline for windows, linux, and macos i wrote a readme but i’ll need to add an asciinema cast to it to make it look better and allow me to ship the project
i got rustypipe-botguard working with Nix i still can’t figure out why some videos don’t work sometimes but other videos work all the time i updated the test suite to reflect that
i begun porting the project to kotlin while i love rust i also want this project to actually work rustypipe will always be a bit behind youtube’s protections so i decided to just rewrite the whole thing in kotlin so i can use newpipeextractor directly what’s left: tag audio with jaudiotagger use clikt to make a nice command line interface (maybe) add unit tests there is no actual screenshot because i didn’t actually implement the commands yet
the rewrite is almost finished thumbnails are now way higher in resolution because we can now get youtube’s webp images. unfortunately jaudiotagger does not support webp images, so i force all images from youtube to turn into a lossless png kotlin is pretty cool, especially coroutines, its like lua’s coroutines but actually backed by a thread pool i need to limit the concurrency but otherwise this is great! very fast even on a debug build what’s left: currently unlimited concurrency, this will definitely crash the jvm on large playlists better terminal output with colors and a diff generator use a temporary table in sqlite to make diffing more memory efficient packaging and ci should be fine since “java runs anywhere”
I cleaned up the code, bounded parallelism to 8 with limitedParallelism, and tried to optimize the detection of moved tracks
I fixed position tracking, so that moved tracks will output a line telling you they have moved. I attempted to fix a deadlock that was happening, and fixed some database queries targetting the wrong table.
added a progress bar and actually actually fixed the deadlock this time
Preparing to ship the project, so here’s a list of everything I did: added back an edited readme added back the apache 2.0 license fixed the github actions auto release recorded an asciinema cast and put it in the readme made the cli say music-player-kotlin instead of cli …other small changes to make sure its ready for release
Shortly after I shipped, I found a better library for progress bars and displaying to the terminal in general. I also made sure that the exists locally log line would be printed out in order. I decided to use it, and I am really happy with the result!!!!
I forgot to add error handling from the original Rust project, so I did that. I also fixed the parallelism by using a Semaphore as limitedParallelism still wakes all the coroutines. Using a Semaphore only allows N permits to be handed out at once. This means that only N tasks would be running at once, given that each task takes one permit. I set N to 8 as that should not cause any throttling but still allow multiple tracks to be downloaded at once. I also implemented better lazy fetching than the old Rust implementation. Now only pieces that must be fetched are fetched, and if they don’t need to be fetched, a StreamExtractor is never fetched. This causes a huge speed up, allowing my ~400 track playlist to be incrementally synced in 8 seconds. Other notable quality of life features (taken from the git log): - refactor: make output use terminal.theme.* - refactor: make output more human readable by using title instead of youtube_playlist_id - fix: reorder items in subtasks so that the text doesn't move everything else
In my attempt to make the streamExtractor lazily loaded, I caused a deadlock. I have fixed the deadlock and this fixed version is at v0.2.7. The fix was pretty simple, it was to not use CoroutineStart.Lazy because a lazy coroutine may never run, meaning the parent coroutineScope will hang forever. I also switched the backend driver to sqlx4k as it provides a connection pool but more importantly makes the suspend code flow cleaner. I wont switch to Exposed (the official SQL driver) because it doesn’t have the same parallel capabilities as sql4k.
To help users migrate from the old Rust implementation, I made it so that a sync will re-tag the track if the track’s thumbnail does not exist on disk. The Kotlin implementation always gets higher resolution images, so this allows for much higher resolution track covers.
I made it so that thumbnails should now be even higher quality, it does take more storage but the difference is quite noticeable on some music players. Also small hotfix, if you accidentally pass in another unrelated SQLite database it will now not run migrations on it before erroring.
I added duration tracking to the database. The M3U generation now doesn’t hardcode 0 as the duration.
I made position diffing aware of insertions and deletions, so that output is less bloated with useless move info such as 0->1, 1->2, etc. I also did some optimization by using database transactions wherever possible. I can’t do it in the main sync body because it is bounded to its own coroutine scope.
I now detect invalid playlist ids and print out an error telling the user how to get a valid playlist id.
I watched a Kotlin talk about Flows and I was inspired to rewrite my program using them. This made my program more efficient, idiomatic and also helped me fix the annoying progress bar refresh bug (multiple old bars shown). It also let me actually properly sort by position across all 4 status types (added, removed, moved, errored). I also made the downloading functions use one underlying common function to clean up the codebase. I also removed sqlx4k because it wasn’t actually parallel and was causing issues with init. Here, in the screenshot I am showing the new elegant code for the logging of track statuses. It used to be many individual async calls, but flows allow me to group them up and sort them.
I redid the cli structure to group all the playlist commands under one common playlist parent command. I also implemented a clean up command to help people save disk space because SSDs are expensive right now. For example: music-syncer-kotlin -p path init -> music-syncer-kotlin playlist -p path init This was a necessary step so I could implement the clean up command, which deletes audio and thumbnail files that are not used by any playlists in a container. A container is the folder holding all the databases. Here’s everything I did, stolen from my commit message: feature: add clean-container command - refactor: add hasTrackInDatabase to the Playlist class - refactor: move knownFinal{Audio,Thumbnail}Extension out of class and make it const - refactor: nest all playlist commands as one subcommand - refactor: make cli help text more helpful - refactor: always print something to the console to let the user know that everything went well - refactor: do not use PlaylistHolder, use currentContext.registerJvmCloseable to clean up playlist - fix: when thumbnail is newly created, retag should silently fail
I finally silenced those pesky slf4j and unsafe memory access warnings. Just added the slf4j-nop library and a JVM flag.
I added GraalVM native image support. The actual implementation is boring but this makes the program’s cold starts faster and makes it feel more native. Not sure if this helps with battery life, but it might. This definitely helps with memory usage, the program only uses ~100mb syncing my 400 track playlist. I restricted the native image to Nix because the releases are supposed to always work on all platforms.
Squashed more bugs, updated NativeMetadataMain.kt so that reachability metadata includes image i/o. This makes the Graal native image actually work when having to convert from webp to png. This will be a non issue when I can find an image library that is written in pure Kotlin. The last shipwright to review my project tried syncing a mix, which is infinite. So I added an error for that and made sure no one will run into unexplainable errors again.
Tiny change, I switched from scrimage to ImageIO. It works much better and should be less error prone as scrimage would vendor in webp binaries, which is not cross platform.
I fixed the binary in Nix, it works now, also updated the asciinema cast it was missing some reachability metadata and required LD_LIBRARY_PATH to be set to the jdk’s libraries.
I fixed another Nix graalvm issue. Some mp4s wouldn’t be tagged properly, so I fixed that.
Ships:
I made a Kotlin CLI program that synchronizes a YouTube Music playlist to a SQLite database locally. I made this because I want to be able to play my music freely even when YouTube Music or my network is down. The main challenge was finding a library that would let me get the data I needed (artist, thumbnail, audio tracks, etc.) from YouTube Music, and I even had to rewrite the entire program in Kotlin from Rust because the library I was using couldn’t download audio properly....
|
1793703212.514274
|
1793789612.514274
|
|
56775
|
My own site! by @technokid5241 | Stardance
|
technokid5241
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My own site! by @technokid5241 | Stardance
|
1793400502.7551908
|
1794005302.7551908
|
|
63112
|
Hi by @technokid5241 | Stardance
|
technokid5241
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Hi by @technokid5241 | Stardance
|
1793659908.9405906
|
1794264708.9405906
|
|
63113
|
Hi by @technokid5241 | Stardance
|
technokid5241
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Hi by @technokid5241 | Stardance
|
1793659909.7995872
|
1794264709.7995872
|
|
289
|
Untitled project by @technodot | Stardance
|
technodot
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Untitled project by @technodot | Stardance
|
1793310910.059877
|
1793915710.059877
|
|
835
|
My awesome macropad! by @technodot | Stardance
|
technodot
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @technodot | Starda Title: My awesome macropad! by @technodot | Stardance...
|
1793533898.1114407
|
1794138698.1114407
|
|
69694
|
WarioWare Game by @techno_login555 | Stardance
|
techno_login555
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: WarioWare Game by @techno_login555 | Starda Title: WarioWare Game by @techno_login555 | Stardance...
|
1793584411.8802044
|
1794189211.8802044
|
|
62329
|
My awesome macropad! by @technicallyfish | Stardan My awesome macropad! by @technicallyfish | Stardance...
|
technicallyfish
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @technicallyfish | Title: My awesome macropad! by @technicallyfish | Stardance...
|
1793653009.6289299
|
1794257809.6289299
|
|
4652
|
sudokun by @techmoocher | Stardance
|
techmoocher
|
0
|
1.73
|
0
|
[]
|
[{"post_id": 65773, "ts": "202 [{"post_id": 65773, "ts": "2026-09-11T04:18:21Z", "hours": 1.7275, "text": "Right now, I’m trying to implement the killer mode of sudoku!!!"}]...
|
Title: sudokun by @techmoocher | Stardance
Devlog Title: sudokun by @techmoocher | Stardance
Devlogs:
Right now, I’m trying to implement the killer mode of sudoku!!!...
|
1793332613.8103483
|
1793937413.8103483
|
|
25032
|
KSP MacroPad by @techmanminty | Stardance
|
techmanminty
|
0
|
7.59
|
0
|
[]
|
[{"post_id": 75093, "ts": "202 [{"post_id": 75093, "ts": "2026-09-29T04:15:14Z", "hours": 1.8517, "text": "I have completed everything for a sufficient ship, the mod and firmware is at an acceptable place and the case and board have been restructured to fit the requirements. This was a very fun project and I can’t wait to see it in action."}, {"post_id": 73840, "ts": "2026-09-26T04:30:46Z", "hours": 1.5806, "text": "I finished the case so it is now time to start working on the firmware and the mod. The case wasn’t that hard to build just laying out the holes for each part and making sure all the tolerances were correct. The holes are intentionally there so that the underglow of the board can be seen"}, {"post_id": 28109, "ts": "2026-07-14T05:24:56Z", "hours": 1.8122, "text": "After running into issues with missing 3D models for my components, I had to manually source STEP files from GrabCAD and assign them to their footprints in KiCad. This taught me a lot about how KiCad handles footprints and 3D models separately, and how component libraries work. I also learned the difference between standard and reverse mount components. For example, the SK6812 MINI-E is reverse mount, meaning it sits on the back of the PCB and shines through a hole toward the keycap. With all that sorted, the PCB is complete and ready for case design."}, {"post_id": 27732, "ts": "2026-07-13T15:30:28Z", "hours": 2.3469, "text": "My macropad is inspired by my love for the game Kerbal Space Program. For a long time I have wanted to make a mod for it, but I didn’t have an inspiration for what to do with it. With my hackpad, macros will be made to execute certain actions within the game. Because it is made for a game, this project is a little bit more than just PCB, case, and firmware. I am also developing a mod for KSP so that the macropad can control certain actions in game and the pad can be real-time responsive to what is happening in the game. So far I have been working on the skeleton of the mod as well as the hardware for the macropad. I’ve almost completely finished the schematic and PCB with the exception of some appearance things I would like to change on the PCB. The most complex thing so far, was figuring out how to utilize all the parts provided by the stardance team in tandem with the microcontrollers limited pins. I am using a 4x4 matrix which would usually require 8 pins, however I have reduced it to 4, using a resistor ladder voltage divider. Using ohm’s law and power cycling between 2 of the 4 analog pins will allow the microcontroller to determine which exact key is being pressed."}]...
|
Title: KSP MacroPad by @techmanminty | Stardance
Title: KSP MacroPad by @techmanminty | Stardance
Devlogs:
My macropad is inspired by my love for the game Kerbal Space Program. For a long time I have wanted to make a mod for it, but I didn’t have an inspiration for what to do with it. With my hackpad, macros will be made to execute certain actions within the game. Because it is made for a game, this project is a little bit more than just PCB, case, and firmware. I am also developing a mod for KSP so that the macropad can control certain actions in game and the pad can be real-time responsive to what is happening in the game. So far I have been working on the skeleton of the mod as well as the hardware for the macropad. I’ve almost completely finished the schematic and PCB with the exception of some appearance things I would like to change on the PCB. The most complex thing so far, was figuring out how to utilize all the parts provided by the stardance team in tandem with the microcontrollers limited pins. I am using a 4x4 matrix which would usually require 8 pins, however I have reduced it to 4, using a resistor ladder voltage divider. Using ohm’s law and power cycling between 2 of the 4 analog pins will allow the microcontroller to determine which exact key is being pressed.
After running into issues with missing 3D models for my components, I had to manually source STEP files from GrabCAD and assign them to their footprints in KiCad. This taught me a lot about how KiCad handles footprints and 3D models separately, and how component libraries work. I also learned the difference between standard and reverse mount components. For example, the SK6812 MINI-E is reverse mount, meaning it sits on the back of the PCB and shines through a hole toward the keycap. With all that sorted, the PCB is complete and ready for case design.
I finished the case so it is now time to start working on the firmware and the mod. The case wasn’t that hard to build just laying out the holes for each part and making sure all the tolerances were correct. The holes are intentionally there so that the underglow of the board can be seen
I have completed everything for a sufficient ship, the mod and firmware is at an acceptable place and the case and board have been restructured to fit the requirements. This was a very fun project and I can’t wait to see it in action....
|
1793491034.3951023
|
1794095834.3951023
|
|
71291
|
a BB gun using electronics by @techkunjapppan | St a BB gun using electronics by @techkunjapppan | Stardance...
|
techkunjapppan
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: a BB gun using electronics by @techkunjappp Title: a BB gun using electronics by @techkunjapppan | Stardance...
|
1793595370.534632
|
1794200170.534632
|
|
70780
|
The super gun by @techkunjappan | Stardance
|
techkunjappan
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: The super gun by @techkunjappan | Stardance
|
1793267574.2134855
|
1794131574.2134855
|
|
71292
|
BB GUN by @techkunjappan | Stardance
|
techkunjappan
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: BB GUN by @techkunjappan | Stardance
|
1793598452.1830974
|
1794203252.1830974
|
|
25764
|
My first slack bot! by @techieaaryan | Stardance
|
techieaaryan
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My first slack bot! by @techieaaryan | Star Title: My first slack bot! by @techieaaryan | Stardance...
|
1792932648.86747
|
1793796648.86747
|
|
25768
|
Crack by @techieaaryan | Stardance
|
techieaaryan
|
0
|
53.21
|
0
|
[]
|
[{"post_id": 55060, "ts": "202 [{"post_id": 55060, "ts": "2026-08-26T14:21:08Z", "hours": 10.0936, "text": "#Crack Devlog #10 What new?? finally i deployed the mvp, you can check the project out i will provide demo link…… finally made a frontend, used figma to design it (timelapsed). connected it using flask. and deployed on Render What next?? well add some more roles and then fix some bugs. then ship it"}, {"post_id": 48211, "ts": "2026-08-16T14:45:13Z", "hours": 3.2094, "text": "Crack devlog #9 what new? well i completed designing frontend on figma wrote code for it and it is a bit different but yea still good as this is my first full stack software project i have ever built. frontend designed on figma is the first image. after the 2 images are errors i faced when tried to write the code . and the last when after when i took help of claude it is looking cool. what next? ahh… will implement flask i guess"}, {"post_id": 46728, "ts": "2026-08-14T05:49:45Z", "hours": 4.9247, "text": "Crack devlog #8 What new? Started working on frontend. Frontend So the color theme i choose was purple and golden. Dark mode by default. Minimalistic. Glassmorphism. What next? Will soon implement Flask in backend and connect the frontend. Also provide demo link so that you can try it out, well the project still at max will take up to ~5 days to finish."}, {"post_id": 41942, "ts": "2026-08-06T14:02:14Z", "hours": 5.2103, "text": "Crack devlog #7 What new? Implemented a dynamic interview engine for asking question. Using OOP . So if you saw my previous devlog i implemented an interview session engine using OOP, that engine handles the interview session starting and finishing, sending answers of the question to the AI and then receives the evaluation in JSON format which then also the engine parses to convert it into a report. Well right now i implemented another engine using OOP to make the interview more dynamic. The newly implemented engine. So basically i implemented an dynamic interview session engine to make it feel like real interview. What does that engine do? Well that engine is basically asking question, but if you have read my previous devlogs, what we implemented first was that user will be asked the role, difficulty and number questions. But…… that was just a prototype!! Well i made the engine more smarter. So basically now the user has to choose the role, then the difficulty and number of questions will be decided by this engine. So the questions will start from easy, after every question the engine makes an average of the scores of every questions asked, then it decides whether to level the difficulty or not, if not then it will ask you a few more questions, if the average score will increase to be eligible for next difficulty, the engine will automatically increases the difficulty , the same goes for difficulty medium, hard and scenario based questions too………"}, {"post_id": 40654, "ts": "2026-08-04T10:35:27Z", "hours": 4.7939, "text": "Crack Devlog #6 What new? Backend is almost finished. The prompt is being sent successfully. Prompt The data received from Claude Sonnet - 5 is parsed and converted into a report successfully (as you can see in the images). What next? Still this milestone is huge i guess that only ~37% of the Crack is completed. Will finish backend soon . Will start working on Frontend after the backend finishes. The color theme for the frontend of Crack will be Purple and White, also Gold on some parts (very minimal). Will make it aesthetic and minimalistic with glassmorphism . Also deciding to add more features and more roles so this project might reach ~100+ hours easily. Sad news!! 😭 Since in my previous devlogs i was mentioning that I will use Claude Sonnet - 5 , well now I will use ChatGPT , because i got $10 AI grant from Stardance from my another project HCAI (check it out ) so i decided to use Claude Sonnet - 5 but i don’t know why but the card i got from HCB was declining, i contacted HCB and they told me that it is the problem with Anthropic, reimbursement wasn’t viable because of $25 Fees (as i am not from USA), the fees itself is more than my $10 AI grant so i decided upon using it for ChatGPT will use Terra model I guess……………"}, {"post_id": 38366, "ts": "2026-07-31T18:27:09Z", "hours": 5.0772, "text": "Crack Devlog #5 What is done so far? Well my project was at pause since I started it in between my python course, but like now the course is completed so I am back. I have made and completed the Interview engine by using OOP . I have implemented time tracking system inside the engine. Also successfully implemented the answer tracking system, which corresponds to the question asked in the engine. Also it records time taken for each question and time taken for the whole interview. What next? So what I will build next is a system for sending the prompt to AI for evaluation . Then with the data received I will convert it to scores, graphs and charts; will create a full analysis. I will use Claude Sonnet 5 , since it’s one of the strength is detailed and nice explanations, so it fits well for my evaluation and suggestions report. For testing I will use Hack Club’s AI API keys , then will shift to Anthropic’s AI API keys , lets hope that my another project named “HCAI” get ratings fulfilled since its been almost a week, but haven’t got no rating at all . If it gets rated before “Crack” (which I think will be rated by the time ) then I will buy $10 credits of Anthropic and will use it in my project ."}, {"post_id": 28818, "ts": "2026-07-15T09:55:19Z", "hours": 4.3744, "text": "Crack Devlog #4 well i have completed Interview Engine v1 . it asks for a specific role, topic and no. of questions. and then according to the role, topic and no. of question it pulls questions randomly from topic inside the roles database stored in json files. will make it more dynamic by starting from easy question and then increasing difficulty to medium and then to hard, then comes scenario based questions, where the user will be asked real world problems to solve, only if they can answer hard questions very well. after making engine more dynamic i will add more roles to it, it has right now 9 full roles."}, {"post_id": 25909, "ts": "2026-07-10T12:19:58Z", "hours": 7.1458, "text": "Crack Devlog #3 –> hmm……yo! –> well nothing interesting but completed 4 roles. –> i also got an idea that i might also add practical or scenario based questions, since thats where real thinking is required. according to my plan questions will be asked from easy and then if the answer is correct then the difficulty will increase from easy to medium and then to hard also if answered very well. –> if the user can answer hard questions easily then the difficulty levels up to scenario based questions, where user will be asked practical or scenario based questions, like real world problems which he/she needs to answer. –> then the report of their interview will be created by AI, accordingly how they answered the question –> if the user was not able to answer easy/medium/hard difficulty questions correctly then the interview will stop at that difficulty level and the report will be handed to them accordingly by AI."}, {"post_id": 18324, "ts": "2026-06-29T13:04:52Z", "hours": 4.7064, "text": "Crack Devlog #2 –>hmm………. –> Well, I have been working on this project for like 3-4 days, have completed the software engineer database, and will soon end the backend developer database. What am i making?? –> i am making an ai interview coach, which asks the questions that can be asked in an actual CS job interview. –> it starts with easy questions , and then increases the difficulty according to the performance of the user. –> after the interview ends, it creates a full-fledged report of the user highlighting strong and weak points and also give overall rating out of 100, and also suggest what and how to improve the answer."}, {"post_id": 16267, "ts": "2026-06-26T13:32:55Z", "hours": 3.6783, "text": "Crack Devlog #1 well………… it’s been almost 2 days i have been working on a project called Crack🥀 so that you can crack your interviews easily . idea is pretty simple: –> the user can select an option from the list of CS roles for ex. Software Engineer, Data Scientist, DevOps etc. –> the user will be asked few questions on the roles or option they selected (just like in job interviews). –> number and difficulty of questions will depend on how user will answer the question. –> after the interview is over, the AI will create a full fledged report of the answers given by the users, and will be given score with report on how they performed. as of now: –> i have created i guess approx. 5% of the database. –> a working prototype which pulls question from the database according to the user input. –> UI is still on terminal 🥀 . –> not very user friendly or dynamic but a working prototype which i will further improve and polish. what’s next?: –> write the database, at least completing 7-8% of it. –> make the code more dynamic. how will it work?: –> well i will use APIs to get the report from an AI."}]...
|
Title: Crack by @techieaaryan | Stardance
Devlogs Title: Crack by @techieaaryan | Stardance
Devlogs:
Crack Devlog #1 well………… it’s been almost 2 days i have been working on a project called Crack🥀 so that you can crack your interviews easily . idea is pretty simple: –> the user can select an option from the list of CS roles for ex. Software Engineer, Data Scientist, DevOps etc. –> the user will be asked few questions on the roles or option they selected (just like in job interviews). –> number and difficulty of questions will depend on how user will answer the question. –> after the interview is over, the AI will create a full fledged report of the answers given by the users, and will be given score with report on how they performed. as of now: –> i have created i guess approx. 5% of the database. –> a working prototype which pulls question from the database according to the user input. –> UI is still on terminal 🥀 . –> not very user friendly or dynamic but a working prototype which i will further improve and polish. what’s next?: –> write the database, at least completing 7-8% of it. –> make the code more dynamic. how will it work?: –> well i will use APIs to get the report from an AI.
Crack Devlog #2 –>hmm………. –> Well, I have been working on this project for like 3-4 days, have completed the software engineer database, and will soon end the backend developer database. What am i making?? –> i am making an ai interview coach, which asks the questions that can be asked in an actual CS job interview. –> it starts with easy questions , and then increases the difficulty according to the performance of the user. –> after the interview ends, it creates a full-fledged report of the user highlighting strong and weak points and also give overall rating out of 100, and also suggest what and how to improve the answer.
Crack Devlog #3 –> hmm……yo! –> well nothing interesting but completed 4 roles. –> i also got an idea that i might also add practical or scenario based questions, since thats where real thinking is required. according to my plan questions will be asked from easy and then if the answer is correct then the difficulty will increase from easy to medium and then to hard also if answered very well. –> if the user can answer hard questions easily then the difficulty levels up to scenario based questions, where user will be asked practical or scenario based questions, like real world problems which he/she needs to answer. –> then the report of their interview will be created by AI, accordingly how they answered the question –> if the user was not able to answer easy/medium/hard difficulty questions correctly then the interview will stop at that difficulty level and the report will be handed to them accordingly by AI.
Crack Devlog #4 well i have completed Interview Engine v1 . it asks for a specific role, topic and no. of questions. and then according to the role, topic and no. of question it pulls questions randomly from topic inside the roles database stored in json files. will make it more dynamic by starting from easy question and then increasing difficulty to medium and then to hard, then comes scenario based questions, where the user will be asked real world problems to solve, only if they can answer hard questions very well. after making engine more dynamic i will add more roles to it, it has right now 9 full roles.
Crack Devlog #5 What is done so far? Well my project was at pause since I started it in between my python course, but like now the course is completed so I am back. I have made and completed the Interview engine by using OOP . I have implemented time tracking system inside the engine. Also successfully implemented the answer tracking system, which corresponds to the question asked in the engine. Also it records time taken for each question and time taken for the whole interview. What next? So what I will build next is a system for sending the prompt to AI for evaluation . Then with the data received I will convert it to scores, graphs and charts; will create a full analysis. I will use Claude Sonnet 5 , since it’s one of the strength is detailed and nice explanations, so it fits well for my evaluation and suggestions report. For testing I will use Hack Club’s AI API keys , then will shift to Anthropic’s AI API keys , lets hope that my another project named “HCAI” get ratings fulfilled since its been almost a week, but haven’t got no rating at all . If it gets rated before “Crack” (which I think will be rated by the time ) then I will buy $10 credits of Anthropic and will use it in my project .
Crack Devlog #6 What new? Backend is almost finished. The prompt is being sent successfully. Prompt The data received from Claude Sonnet - 5 is parsed and converted into a report successfully (as you can see in the images). What next? Still this milestone is huge i guess that only ~37% of the Crack is completed. Will finish backend soon . Will start working on Frontend after the backend finishes. The color theme for the frontend of Crack will be Purple and White, also Gold on some parts (very minimal). Will make it aesthetic and minimalistic with glassmorphism . Also deciding to add more features and more roles so this project might reach ~100+ hours easily. Sad news!! 😭 Since in my previous devlogs i was mentioning that I will use Claude Sonnet - 5 , well now I will use ChatGPT , because i got $10 AI grant from Stardance from my another project HCAI (check it out ) so i decided to use Claude Sonnet - 5 but i don’t know why but the card i got from HCB was declining, i contacted HCB and they told me that it is the problem with Anthropic, reimbursement wasn’t viable because of $25 Fees (as i am not from USA), the fees itself is more than my $10 AI grant so i decided upon using it for ChatGPT will use Terra model I guess……………
Crack devlog #7 What new? Implemented a dynamic interview engine for asking question. Using OOP . So if you saw my previous devlog i implemented an interview session engine using OOP, that engine handles the interview session starting and finishing, sending answers of the question to the AI and then receives the evaluation in JSON format which then also the engine parses to convert it into a report. Well right now i implemented another engine using OOP to make the interview more dynamic. The newly implemented engine. So basically i implemented an dynamic interview session engine to make it feel like real interview. What does that engine do? Well that engine is basically asking question, but if you have read my previous devlogs, what we implemented first was that user will be asked the role, difficulty and number questions. But…… that was just a prototype!! Well i made the engine more smarter. So basically now the user has to choose the role, then the difficulty and number of questions will be decided by this engine. So the questions will start from easy, after every question the engine makes an average of the scores of every questions asked, then it decides whether to level the difficulty or not, if not then it will ask you a few more questions, if the average score will increase to be eligible for next difficulty, the engine will automatically increases the difficulty , the same goes for difficulty medium, hard and scenario based questions too………
Crack devlog #8 What new? Started working on frontend. Frontend So the color theme i choose was purple and golden. Dark mode by default. Minimalistic. Glassmorphism. What next? Will soon implement Flask in backend and connect the frontend. Also provide demo link so that you can try it out, well the project still at max will take up to ~5 days to finish.
Crack devlog #9 what new? well i completed designing frontend on figma wrote code for it and it is a bit different but yea still good as this is my first full stack software project i have ever built. frontend designed on figma is the first image. after the 2 images are errors i faced when tried to write the code . and the last when after when i took help of claude it is looking cool. what next? ahh… will implement flask i guess
#Crack Devlog #10 What new?? finally i deployed the mvp, you can check the project out i will provide demo link…… finally made a frontend, used figma to design it (timelapsed). connected it using flask. and deployed on Render What next?? well add some more roles and then fix some bugs. then ship it...
|
1793552191.0374057
|
1794416191.0374057
|
|
26795
|
Cosmos by @techieaaryan | Stardance
|
techieaaryan
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Cosmos by @techieaaryan | Stardance
|
1793515857.7857137
|
1794379857.7857137
|
|
37938
|
HCAI by @techieaaryan | Stardance
|
techieaaryan
|
1
|
13.0
|
93
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-07-24T19:50:27Z", "hours": 13.0, "multiplier": 7.35, "payout": 93, "blessing": "neutral", "text": "I made a lightweight AI command-line interface powered by Hack Club AI. Why I made this? I came to know about OpenCode, yes the AI coding agent and I loved the feature of switching between AI models. Like I can use Claude for Frontend, ChatGPT for Backend and Gemini or Qwen models for simple question and answer. But guess what? It is not allowed to use, I asked people on the Slack about why it is not allowed, they told me that because it can let the AI modify files on the computer, that’s why it is not allowed. So I decided upon making one of my own terminal based program. What does it do? You can change whichever model you want to use as per the user’s choice and requirements for the work directly from your terminal with just one simple command. It won’t take control of the user’s computer to modify files, just a simple Q/A between AI model and the user. Features I was impressed of how much it is good and also better than I have imagined it to be. Like user can directly access the models available by writing a single command and even if it will be from the other provider it will change the provider too as well as model of course. There are commands I have made, you use /help for seeing the commands and what they do (also for more detail for the command check out my GitHub repo for this project and read “README”). It handles error very nicely and user friendly too! How to use it? Don’t clone GitHub repo or somehow download the course code for it. I have published it on PyPI so you can directly install the package from there on your computer via terminal (I have provided with the demo link which is the page of my package on PyPI and also provide a user friendly documentation). What next? (important) I decided upon releasing v1.0.0 version of the HCAI, but during polishing I improved it so much that I released v1.0.1 after an hour of initial v1.0.0 release, on GitHub and PyPI both (Note: the version I am shipping is v1.0.1). Also when I was making the database, there were only 338 models available, but today when I will ship this project the number of models have been increased. So when the v1.0.2 will have the remaining models too, also the package will handle more and rare Errors too (making it user friendly also) and will minimize credit burns (the plan for v1.0.2 is as of now this, who knows I might end up adding more feature in future and improve it). Thank you!!", "repo": "https://github.com/Aaryan410/HCAI", "demo": "https://pypi.org/project/hcai/"}]...
|
[{"post_id": 34229, "ts": "202 [{"post_id": 34229, "ts": "2026-07-24T19:12:41Z", "hours": 2.7881, "text": "HCAI Devlog #2 (Final) HCAI is ready to use now. What new? I was gonna release v1.0.0 but then during polishing I improved it so much that after 1 hour of releasing v1.0.0 on GitHub I released v1.0.1 on GitHub 🥀. I published my package on PyPI also so you can directly use it on your terminal by installing that package. Also handled storing your chats with the AI so that you can continue where you left off. I improved error handling and made it more user friendly. Made commands that you can use with the package. What does it do? Basically it provides you a way you can switch between different AI models you want to as per your work requirements, so that you can minimize the credit burn and maximize the productivity with the free quota provided by Hack Club. You can even switch between with a command like /use in between the session. About v1.0.2 Well when I made the database there were only 338 models at that time, now the models have increased on the day I will ship it, so will add that models in the v1.0.2 release which will shortly come in the near future. Will reduce credit burn more as to make AI remember the history of the chats where the user left off. For more information visit my GitHub, and my documentation on PyPI, just search “hcai” on ‘pypi.org’ or you can directly visit it through the demo link of the project I will provide you with when I ship the project."}, {"post_id": 33947, "ts": "2026-07-24T08:54:15Z", "hours": 9.8619, "text": "HCAI Devlog #1 What is HCAI? HCAI is a terminal based dev tool I am making for programmers in Hack Club using Hack Club AI APIs for their software/program they are building. What problem is solved? Well I was thinking of using OpenCode for my software projects in Stardance but then I found out that Hack Club don’t allow it for their AI API keys. The reason I wanted to use OpenCode was to switch between AI models so that I can use credits efficiently, for ex. I might use Claude Opus 4.8 or Sonnet 5 for frontend, ChatGPT for backend stuff and Gemini or some Qwen models (light models) for simple question and answer. OpenCode does the same but it is a AI Coding Agent so it might be used to write code for the program, giving access of the files to modify code, so it is not allowed and it is completely understandable why it is not allowed. What does it do? HCAI is almost same but you can’t give access to your files to HCAI, so AI will not be directly able to modify the users file who is using HCAI. HCAI will work on the users terminal and will give the flexibility to user to switch between models to use AI credits efficiently and minimize useless credit burns and maximize the productivity with the free quota given by Hack Club. The user can directly start a session in terminal with whichever model they want and then can switch between the models they prefer for the type of work they are doing. The best part now, your chat history will be saved , so for ex. if you first used Claude then switched to ChatGPT and then again switched to Gemini then came back to using Claude, you can directly continue the conversation you left on when switched to ChatGPT, and also the same for ChatGPT and Gemini too. How much completed and what next? I already hit 9+ hours of work time on this project in 2 days, that’s why I am writing this Devlog 🥀 , I was thinking that I might ship the project by writing the first Devlog itself but can’t manage time efficiently and it is larger project than I expected so yea I will finish it in next 1-2 days max (might be even earlier, who knows?). I have completed the setup for the user, made the database of the AI models provided by Hack Club, made a model pulling engine, and right now working on making an engine where to send prompt directly from the terminal and retrieving answer from the model inside the terminal. Something I guess…….🥀 It will be made in near future, till then follow me out so that you can use it whenever it is released. Also check out my other projects too ."}]...
|
Title: HCAI by @techieaaryan | Stardance
Devlogs: Title: HCAI by @techieaaryan | Stardance
Devlogs:
HCAI Devlog #1 What is HCAI? HCAI is a terminal based dev tool I am making for programmers in Hack Club using Hack Club AI APIs for their software/program they are building. What problem is solved? Well I was thinking of using OpenCode for my software projects in Stardance but then I found out that Hack Club don’t allow it for their AI API keys. The reason I wanted to use OpenCode was to switch between AI models so that I can use credits efficiently, for ex. I might use Claude Opus 4.8 or Sonnet 5 for frontend, ChatGPT for backend stuff and Gemini or some Qwen models (light models) for simple question and answer. OpenCode does the same but it is a AI Coding Agent so it might be used to write code for the program, giving access of the files to modify code, so it is not allowed and it is completely understandable why it is not allowed. What does it do? HCAI is almost same but you can’t give access to your files to HCAI, so AI will not be directly able to modify the users file who is using HCAI. HCAI will work on the users terminal and will give the flexibility to user to switch between models to use AI credits efficiently and minimize useless credit burns and maximize the productivity with the free quota given by Hack Club. The user can directly start a session in terminal with whichever model they want and then can switch between the models they prefer for the type of work they are doing. The best part now, your chat history will be saved , so for ex. if you first used Claude then switched to ChatGPT and then again switched to Gemini then came back to using Claude, you can directly continue the conversation you left on when switched to ChatGPT, and also the same for ChatGPT and Gemini too. How much completed and what next? I already hit 9+ hours of work time on this project in 2 days, that’s why I am writing this Devlog 🥀 , I was thinking that I might ship the project by writing the first Devlog itself but can’t manage time efficiently and it is larger project than I expected so yea I will finish it in next 1-2 days max (might be even earlier, who knows?). I have completed the setup for the user, made the database of the AI models provided by Hack Club, made a model pulling engine, and right now working on making an engine where to send prompt directly from the terminal and retrieving answer from the model inside the terminal. Something I guess…….🥀 It will be made in near future, till then follow me out so that you can use it whenever it is released. Also check out my other projects too .
HCAI Devlog #2 (Final) HCAI is ready to use now. What new? I was gonna release v1.0.0 but then during polishing I improved it so much that after 1 hour of releasing v1.0.0 on GitHub I released v1.0.1 on GitHub 🥀. I published my package on PyPI also so you can directly use it on your terminal by installing that package. Also handled storing your chats with the AI so that you can continue where you left off. I improved error handling and made it more user friendly. Made commands that you can use with the package. What does it do? Basically it provides you a way you can switch between different AI models you want to as per your work requirements, so that you can minimize the credit burn and maximize the productivity with the free quota provided by Hack Club. You can even switch between with a command like /use in between the session. About v1.0.2 Well when I made the database there were only 338 models at that time, now the models have increased on the day I will ship it, so will add that models in the v1.0.2 release which will shortly come in the near future. Will reduce credit burn more as to make AI remember the history of the chats where the user left off. For more information visit my GitHub, and my documentation on PyPI, just search “hcai” on ‘pypi.org’ or you can directly visit it through the demo link of the project I will provide you with when I ship the project.
Ships:
I made a lightweight AI command-line interface powered by Hack Club AI. Why I made this? I came to know about OpenCode, yes the AI coding agent and I loved the feature of switching between AI models. Like I can use Claude for Frontend, ChatGPT for Backend and Gemini or Qwen models for simple question and answer. But guess what? It is not allowed to use, I asked people on the Slack about why it is not allowed, they told me that because it can let the AI modify files on the computer, that’s why it is not allowed. So I decided upon making one of my own terminal based program. What does it do? You can change whichever model you want to use as per the user’s choice and requirements for the work directly from your terminal with just one simple command. It won’t take control of the user’s computer to modify files, just a simple Q/A between AI model and the user. Features I was impressed of how much it is good and also better than I have imagined it to be. Like user can directly access the models available by writing a single command and even if it will be from the other provider it will change the provider too as well as model of course. There are commands I have made, you use /help for seeing the commands and what they do (also for more detail for the command check out my GitHub repo for this project and read “README”). It handles error very nicely and user friendly too! How to use it? Don’t clone GitHub repo or somehow download the course code for it. I have published it on PyPI so you can directly install the package from there on your computer via terminal (I have provided with the demo link which is the page of my package on PyPI and also provide a user friendly documentation). What next? (important) I decided upon releasing v1.0.0 version of the HCAI, but during polishing I improved it so much that I released v1.0.1 after an hour of initial v1.0.0 release, on GitHub and PyPI both (Note: the version I am shipping is v1.0.1). Also when I was making the database, there were only 338 models available, but today when I will ship this project the number of models have been increased. So when the v1.0.2 will have the remaining models too, also the package will handle more and rare Errors too (making it user friendly also) and will minimize credit burns (the plan for v1.0.2 is as of now this, who knows I might end up adding more feature in future and improve it). Thank you!!...
|
1793627451.4469612
|
1793713851.4469612
|
|
57143
|
Nine-O by @techibaggy | Stardance
|
techibaggy
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Nine-O by @techibaggy | Stardance
|
1793418662.7190847
|
1794023462.7190847
|
|
71303
|
a whimisical website by @techgirl | Stardance
|
techgirl
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: a whimisical website by @techgirl | Stardan Title: a whimisical website by @techgirl | Stardance...
|
1793598515.302528
|
1794203315.302528
|
|
48845
|
My first slack bot! by @techburner | Stardance
|
techburner
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My first slack bot! by @techburner | Starda Title: My first slack bot! by @techburner | Stardance...
|
1793249307.2711387
|
1793854107.2711387
|
|
72412
|
My first slack bot! by @techbobkl | Stardance
|
techbobkl
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My first slack bot! by @techbobkl | Stardan Title: My first slack bot! by @techbobkl | Stardance...
|
1793461654.5320058
|
1794066454.5320058
|
|
44584
|
a dino game with no mercy by @techak974 | Stardanc a dino game with no mercy by @techak974 | Stardance...
|
techak974
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: a dino game with no mercy by @techak974 | S Title: a dino game with no mercy by @techak974 | Stardance...
|
1792914581.9728959
|
1793778581.9728959
|
|
44991
|
study verse ai by @techak974 | Stardance
|
techak974
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: study verse ai by @techak974 | Stardance
|
1792914795.441645
|
1793778795.441645
|
|
21187
|
My awesome macropad! by @teanuawtefan | Stardance
|
teanuawtefan
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @teanuawtefan | Sta Title: My awesome macropad! by @teanuawtefan | Stardance...
|
1793238458.4975662
|
1793843258.4975662
|
|
28809
|
#1 ENDLESS RUNNER by @teamnepalnerds | Stardance
|
teamnepalnerds
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: #1 ENDLESS RUNNER by @teamnepalnerds | Star Title: #1 ENDLESS RUNNER by @teamnepalnerds | Stardance...
|
1793307472.2239752
|
1793912272.2239752
|
|
2351
|
Kernel Panic Tower Defence by @teamlewiscrafty | S Kernel Panic Tower Defence by @teamlewiscrafty | Stardance...
|
teamlewiscrafty
|
1
|
48.0
|
745
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-09-15T20:46:27Z", "hours": 48.0, "multiplier": 15.59, "payout": 745, "blessing": "neutral", "text": "Kernel Panic Hold off malware to give your firewall time to be repaired in this tower defence game prototype built using the Godot engine ! It is inspired by 1990s Unix systems and sci-fi classics like ‘The Matrix’. Play the demo at https://gianthotdog.itch.io/Kernel-Panic The game demo includes: Multiple levels including a tutorial GRUB-style menu A settings menu (Audio settings, Credits, VSync settings) A config file system so settings persist across play sessions An upgrade tree that contains global upgrades to towers and XP gains An XP and skill point system for purchasing those upgrades 4 distinct types of towers with adjustable targeting priorities Several enemy types Custom resources to handle: Single tower upgrades Enemy counts in waves Global upgrades Controls: Enter to skip startup sequence Click to select / interact / modify values AI: AI was used to write about 50 lines of code for the two shaders, and very occasionally for solving persistent bugs. It was only used for bug fixes after I tried repeatedly and failed to find a solution myself. It was also used for some feedback on aesthetic choices. All assets were designed by hand. All AI code was reviewed before implementation. Credits: Initial prototyping asset pack by Kenney Music by iamoneabe: https://opengameart.org/content/trunkful-of-junk", "repo": "https://github.com/GiantHotdog/tower-defence-game", "demo": "https://gianthotdog.itch.io/kernel-panic"}]...
|
[{"post_id": 68782, "ts": "202 [{"post_id": 68782, "ts": "2026-09-15T18:58:47Z", "hours": 5.0969, "text": "Improving the global upgrade system Additions : Support for panning around the upgrade tree More upgrades ! Added icons to upgrades Added file saving for XP earned Allow accessing the skill tree from the menu Changes: Level completion is now tracked across multiple play sessions Refined “Currently: …” messages in the upgrade tree The features from the last devlog are now also public ! 🎉 I added some more upgrades to the upgrade tree, and I also gave all of them icons. The icons are… passable. I’m not a graphical artist, and it kind of shows. The “Currently…” messages at the bottom of the side panel got an overhaul, including the addition of units, specific to the type of value being upgraded The game now saves both xp earned and levels completed to files, so they persist between play sessions. This means you don’t have to replay the whole game every time you close it - this is no longer an 80s game ! The skill tree can also be accessed from the menu, so I’m no longer just booting it straight from the Godot editor. This makes it slightly more user friendly. This is probably where I will leave this project for now. I may come back to it now and then, but I’m happy with where this game demo has ended up. I’ll ship it soon, so watch out for that ! If you want to play the game, it is live here . If you are interested in the code, it is available here . To Do list : Add a “reset all to default” option in settings Quote of the update: “Next time I do this, remind me to actually build a proper tree structure” Any suggestions, please let me know in the comments below. Thanks for reading !"}, {"post_id": 42676, "ts": "2026-08-07T15:04:25Z", "hours": 10.5378, "text": "Adding a global upgrade system Additions : Added ‘Zero day’ enemy Added a second level with 6 waves Added a xp system, with skill points and a skill tree Changes: Expanded wave variety in other levels I added a ‘Zero day’ enemy to my game. This enemy is invulnerable for the first 5 seconds after it first spawns in. This makes it highly annoying as it has a tendency to draw and absorb all attacks from high damage towers, and pass through a large portion of your damaging towers unscathed. I also added more waves and a second level, and I’ll slowly expand the playtime of the game as I also add more features The big change here is the xp system. Currently, finishing a level rewards you with some xp, which counts towards your level. Each level up rewards you with a skill point that can be spent in the skill tree. The xp required to level up increases exponentially as the current level gets higher and higher. Unlocks in the tree save to a file and read back on load, so progress is maintained. I was reminded here of my vehement dislike of handling files. For the second time during this project, I forgot where userspace files were stored in Godot. Check this devlog for a bit more detail. Now unfortunately, the demo currently online doesn’t include these new features because I need to write a devlog every 10 hours, but the features aren’t finished. I’ll push them as soon as they are ready™ To Do list : Add file saving for XP earned Allow actually accessing the skill tree from the menu Add a “reset all to default” option in settings Quote of the update: “I. Really. Hate. Files” Any suggestions, please let me know in the comments below."}, {"post_id": 22190, "ts": "2026-07-04T15:02:38Z", "hours": 10.0806, "text": "Added a compendium Alright, this is a big one Additions : Added an indicator that shows the progress through the level Added a “Zip bomb” enemy Added cloaked enemies Added a pause menu Added a compendium Changes: Rebuilt the tutorial I added an indicator to show the player’s progress through the level. It also adds a tiny bit of story - you have to hold off malware until a firewall is constructed, and that bar shows you the progress. And I didn’t even build it from scratch - I’m just using the health bar from the enemies ! 🤫 Next - a zip bomb enemy that, as the name suggests, spawns a burst of child enemies when killed. It moves very slowly, but has high health - this makes it a great target for the SIGTERM sniper tower, which was previously useless not always the best choice. Cloaking was my way of trying to spice up the types of enemies the player would have to deal with. Some enemies in a level will now be cloaked, which means they cannot be attacked until they have their cloaking removed by the new ‘defragmenter’ tower. I wanted a way for players to easily compare the stats of the various towers and enemies, and I also needed something else to add to my pause menu. I decided to kill two pieces of malware with one antivirus quarantine, by adding a compendium. This currently has two tabs, for towers and enemies, each showing you the stats of a tower / enemy when it’s selected. Please don’t ask me how long this took. I don’t want to talk about it. I also rebuilt the tutorial because it looked bad was a pain to build and test would break if i breathed too close to it So I completely scrapped the old system and built a new one Quote of the update: “Hidden malware is a pain - in this game, and in real life” Any suggestions, please let me know in the comments below."}, {"post_id": 10191, "ts": "2026-06-16T20:02:36Z", "hours": 4.1847, "text": "Added a terminal window that logs game events and a tower blocker for level design Changes : Reorganised the UI to provide more space for the level and generally give everything a more unified aesthetic Additions : Added a terminal window at the bottom of the screen that logs game events Added a ‘towerblocker’ tool that the level designer can use to restrict tower placement opportunities Plus (as always) quite a few bug fixes So what is the key feature for any 90s UNIX Linux system? A terminal, of course ! And what is a UNIX-themed game without a terminal? So I added a system where game events, such as waves starting, or enemies being killed, are logged to a terminal window at the bottom of the screen. This window can be opened and closed, and has a little coloured pulse around it whenever a new log is entered. The coloured pulse is synced to the type of event (red for ‘errors’, yellow for ‘warnings’ white for everything else) as well. Each message contains some details about the event and a timestamp on the left. This feature was my first time using the richTextLabel, which allowed me to colour the text. The towerblocker is simple - it’s an invisible tile that can only be placed when the levels are being designed in order to add difficulty or avoid placing of towers offscreen I also reorganised the UI to provide more space for the level - it was all feeling a bit cramped. That reorg also helped to give everything a more unified aesthetic because I took the opportunity to apply some styles to everything, making it feel just a little more together. Quote of the update: “An empty terminal log is always nice. Unfortunately, I don’t think things will be that peaceful…” Any suggestions, please let me know in the comments."}, {"post_id": 8701, "ts": "2026-06-14T13:37:38Z", "hours": 6.4575, "text": "Overhauled the game over screen’s aesthetic and added mouse support to the menu Changes : Changed the game over screen to better fit with the game’s aesthetic Changed the font to a monospaced one Additions : Added mouse support to the menu Added a spray of particles to enemies when they die Added a chromatic aberration effect to enemies when they are hit Plus quite a few bug fixes The first change in this devlog is the game over screen, which used to look like a boring window with a restart button, but now looks like a crash screen [ Image below ] that uses the actual system data to display its message, via a template string and an 8 line formatting statement. I am quite proud of this one Adding mouse support to the menu was, in a word, painful. Because I’d built my own menu system using labels instead of buttons, I had to almost completely rewrite the code to allow for conversion of a Label reference (from one of Godot’s built-in functions) to a child id (which my functions were expecting). And then I had to add some overrides to that so some labels that were not part of the menu system wouldn’t break everything. The spray of particles from enemies when they die is one of my personal favourite effects in this game, mostly because of what I’ve learnt from it. I made the particles be text based by using a subviewport, which basically is a viewport that doesn’t display anything and can then be attached to a texture to show its contents, in this case, on the particles as they are emitted. I also made the text randomise to a 2 digit hexadecimal value - that felt suitably ‘techy’ One of the smaller features in this devlog is the font change. Instead of using Godot’s default font, I found the font used in the actual GRUB and used that instead. Where did I find this font, you ask? It came directly from my PC - I copied the file straight out of /usr/share/fonts . And now we come to chromatic aberration which, as it turns out, is easy to implement for the whole screen, but slightly harder to make work for only a single sprite without discolouring the background. After messing around with shaders for a bit, I gave up and just made 2 versions of my enemy sprite (in red and blue) and just physically offset them in code. And it works. And, if I dare to blow my own trumpet for just a second, it looks great ! Quote of the update: “Please never make me look at my menu code again.”"}, {"post_id": 5836, "ts": "2026-06-09T19:35:21Z", "hours": 4.2917, "text": "Overhauled the menu aesthetic and added a settings menu So, I realised that I’d called this game ‘Kernel Panic’, a very techy name, and yet done little to lean into the aesthetic that evoked. I decided to fix that. Changes: Rebuilt the main menu to use a similar aesthetic to the Linux GRUB Added a settings menu: Support for 2 Vsync modes A slider to control audio A credits page This was my first time using config files, so I also got to learn something; Godot’s user:// directory is not the same as res://. A file created in the user:// directory cannot be seen in the res:// directory. From my uneducated perspective, it seemed as if this file (which I couldn’t find in the editor, since that only shows res:// ) was persisting across runtimes - something non-existent files famously don’t do. I saw someone else do a ‘quote of the update’, but I was unable to find their username to credit them, so please tell me if you know who they are: Quote of the update: “I really don’t like config files” Next plan is to overhaul the game over screen so it better fits with the aesthetic"}, {"post_id": 3590, "ts": "2026-06-06T16:17:25Z", "hours": 0.2508, "text": "Made a dictionary of wave information resources in the level . I exported a dictionary of custom WaveInfo resources in my level scene, and went to add a new resource to the dictionary. I typed in the key, added a new WaveInfo, and clicked Ctrl+s. My new key-value pair promptly vanished without a trace And so began the hour of removing variables, re-adding variables, trawling through the Godot forums and generally wanting to set fire to my computer to try to find the problem. The urge that was not improved by the discovery that I’d forgotten to press the button to actually add the key-value pair, and the error firmly existed between chair and keyboard."}, {"post_id": 3545, "ts": "2026-06-06T15:10:06Z", "hours": 0.4167, "text": "Added a resource to allow upgrades to towers. For those who haven’t used Godot, a resource is a fancy name for a data container that counts the number of other objects referencing it and automatically frees itself when it is no longer needed. According to a quick glance at the Godot docs, creating a custom Resource is as simple as creating a new script that extends Resource and adding a couple of @export variables. I failed at step one, used the default ‘ extend Node ’ instead of ‘ extend Resource ’, and then spent over half an hour trying to work out why it didn’t show up in the inspector. Lesson learned then? Not really, because I did the exact same thing again the next day."}, {"post_id": 3523, "ts": "2026-06-06T14:35:36Z", "hours": 7.0975, "text": "First devlog for Kernel Panic , a tower defence game built in Godot. Here is my progress so far: A menu which allows the user to select levels Multiple custom resources to allow for: Flexible enemy counts and spawn rates during waves Changing of range, damage, or attack speed of a tower Creation of ‘upgrade paths’, which store several upgrades, as well as progress along the path Inspection window that allows: Customisable targeting priority Upgrades to be applied from multiple upgrade paths Multiple towers with several unique upgrade paths each Next step - building a tutorial level that explains the key mechanics of the game."}]...
|
Title: Kernel Panic Tower Defence by @teamlewiscra Title: Kernel Panic Tower Defence by @teamlewiscrafty | Stardance
Devlogs:
First devlog for Kernel Panic , a tower defence game built in Godot. Here is my progress so far: A menu which allows the user to select levels Multiple custom resources to allow for: Flexible enemy counts and spawn rates during waves Changing of range, damage, or attack speed of a tower Creation of ‘upgrade paths’, which store several upgrades, as well as progress along the path Inspection window that allows: Customisable targeting priority Upgrades to be applied from multiple upgrade paths Multiple towers with several unique upgrade paths each Next step - building a tutorial level that explains the key mechanics of the game.
Added a resource to allow upgrades to towers. For those who haven’t used Godot, a resource is a fancy name for a data container that counts the number of other objects referencing it and automatically frees itself when it is no longer needed. According to a quick glance at the Godot docs, creating a custom Resource is as simple as creating a new script that extends Resource and adding a couple of @export variables. I failed at step one, used the default ‘ extend Node ’ instead of ‘ extend Resource ’, and then spent over half an hour trying to work out why it didn’t show up in the inspector. Lesson learned then? Not really, because I did the exact same thing again the next day.
Made a dictionary of wave information resources in the level . I exported a dictionary of custom WaveInfo resources in my level scene, and went to add a new resource to the dictionary. I typed in the key, added a new WaveInfo, and clicked Ctrl+s. My new key-value pair promptly vanished without a trace And so began the hour of removing variables, re-adding variables, trawling through the Godot forums and generally wanting to set fire to my computer to try to find the problem. The urge that was not improved by the discovery that I’d forgotten to press the button to actually add the key-value pair, and the error firmly existed between chair and keyboard.
Overhauled the menu aesthetic and added a settings menu So, I realised that I’d called this game ‘Kernel Panic’, a very techy name, and yet done little to lean into the aesthetic that evoked. I decided to fix that. Changes: Rebuilt the main menu to use a similar aesthetic to the Linux GRUB Added a settings menu: Support for 2 Vsync modes A slider to control audio A credits page This was my first time using config files, so I also got to learn something; Godot’s user:// directory is not the same as res://. A file created in the user:// directory cannot be seen in the res:// directory. From my uneducated perspective, it seemed as if this file (which I couldn’t find in the editor, since that only shows res:// ) was persisting across runtimes - something non-existent files famously don’t do. I saw someone else do a ‘quote of the update’, but I was unable to find their username to credit them, so please tell me if you know who they are: Quote of the update: “I really don’t like config files” Next plan is to overhaul the game over screen so it better fits with the aesthetic
Overhauled the game over screen’s aesthetic and added mouse support to the menu Changes : Changed the game over screen to better fit with the game’s aesthetic Changed the font to a monospaced one Additions : Added mouse support to the menu Added a spray of particles to enemies when they die Added a chromatic aberration effect to enemies when they are hit Plus quite a few bug fixes The first change in this devlog is the game over screen, which used to look like a boring window with a restart button, but now looks like a crash screen [ Image below ] that uses the actual system data to display its message, via a template string and an 8 line formatting statement. I am quite proud of this one Adding mouse support to the menu was, in a word, painful. Because I’d built my own menu system using labels instead of buttons, I had to almost completely rewrite the code to allow for conversion of a Label reference (from one of Godot’s built-in functions) to a child id (which my functions were expecting). And then I had to add some overrides to that so some labels that were not part of the menu system wouldn’t break everything. The spray of particles from enemies when they die is one of my personal favourite effects in this game, mostly because of what I’ve learnt from it. I made the particles be text based by using a subviewport, which basically is a viewport that doesn’t display anything and can then be attached to a texture to show its contents, in this case, on the particles as they are emitted. I also made the text randomise to a 2 digit hexadecimal value - that felt suitably ‘techy’ One of the smaller features in this devlog is the font change. Instead of using Godot’s default font, I found the font used in the actual GRUB and used that instead. Where did I find this font, you ask? It came directly from my PC - I copied the file straight out of /usr/share/fonts . And now we come to chromatic aberration which, as it turns out, is easy to implement for the whole screen, but slightly harder to make work for only a single sprite without discolouring the background. After messing around with shaders for a bit, I gave up and just made 2 versions of my enemy sprite (in red and blue) and just physically offset them in code. And it works. And, if I dare to blow my own trumpet for just a second, it looks great ! Quote of the update: “Please never make me look at my menu code again.”
Added a terminal window that logs game events and a tower blocker for level design Changes : Reorganised the UI to provide more space for the level and generally give everything a more unified aesthetic Additions : Added a terminal window at the bottom of the screen that logs game events Added a ‘towerblocker’ tool that the level designer can use to restrict tower placement opportunities Plus (as always) quite a few bug fixes So what is the key feature for any 90s UNIX Linux system? A terminal, of course ! And what is a UNIX-themed game without a terminal? So I added a system where game events, such as waves starting, or enemies being killed, are logged to a terminal window at the bottom of the screen. This window can be opened and closed, and has a little coloured pulse around it whenever a new log is entered. The coloured pulse is synced to the type of event (red for ‘errors’, yellow for ‘warnings’ white for everything else) as well. Each message contains some details about the event and a timestamp on the left. This feature was my first time using the richTextLabel, which allowed me to colour the text. The towerblocker is simple - it’s an invisible tile that can only be placed when the levels are being designed in order to add difficulty or avoid placing of towers offscreen I also reorganised the UI to provide more space for the level - it was all feeling a bit cramped. That reorg also helped to give everything a more unified aesthetic because I took the opportunity to apply some styles to everything, making it feel just a little more together. Quote of the update: “An empty terminal log is always nice. Unfortunately, I don’t think things will be that peaceful…” Any suggestions, please let me know in the comments.
Added a compendium Alright, this is a big one Additions : Added an indicator that shows the progress through the level Added a “Zip bomb” enemy Added cloaked enemies Added a pause menu Added a compendium Changes: Rebuilt the tutorial I added an indicator to show the player’s progress through the level. It also adds a tiny bit of story - you have to hold off malware until a firewall is constructed, and that bar shows you the progress. And I didn’t even build it from scratch - I’m just using the health bar from the enemies ! 🤫 Next - a zip bomb enemy that, as the name suggests, spawns a burst of child enemies when killed. It moves very slowly, but has high health - this makes it a great target for the SIGTERM sniper tower, which was previously useless not always the best choice. Cloaking was my way of trying to spice up the types of enemies the player would have to deal with. Some enemies in a level will now be cloaked, which means they cannot be attacked until they have their cloaking removed by the new ‘defragmenter’ tower. I wanted a way for players to easily compare the stats of the various towers and enemies, and I also needed something else to add to my pause menu. I decided to kill two pieces of malware with one antivirus quarantine, by adding a compendium. This currently has two tabs, for towers and enemies, each showing you the stats of a tower / enemy when it’s selected. Please don’t ask me how long this took. I don’t want to talk about it. I also rebuilt the tutorial because it looked bad was a pain to build and test would break if i breathed too close to it So I completely scrapped the old system and built a new one Quote of the update: “Hidden malware is a pain - in this game, and in real life” Any suggestions, please let me know in the comments below.
Adding a global upgrade system Additions : Added ‘Zero day’ enemy Added a second level with 6 waves Added a xp system, with skill points and a skill tree Changes: Expanded wave variety in other levels I added a ‘Zero day’ enemy to my game. This enemy is invulnerable for the first 5 seconds after it first spawns in. This makes it highly annoying as it has a tendency to draw and absorb all attacks from high damage towers, and pass through a large portion of your damaging towers unscathed. I also added more waves and a second level, and I’ll slowly expand the playtime of the game as I also add more features The big change here is the xp system. Currently, finishing a level rewards you with some xp, which counts towards your level. Each level up rewards you with a skill point that can be spent in the skill tree. The xp required to level up increases exponentially as the current level gets higher and higher. Unlocks in the tree save to a file and read back on load, so progress is maintained. I was reminded here of my vehement dislike of handling files. For the second time during this project, I forgot where userspace files were stored in Godot. Check this devlog for a bit more detail. Now unfortunately, the demo currently online doesn’t include these new features because I need to write a devlog every 10 hours, but the features aren’t finished. I’ll push them as soon as they are ready™ To Do list : Add file saving for XP earned Allow actually accessing the skill tree from the menu Add a “reset all to default” option in settings Quote of the update: “I. Really. Hate. Files” Any suggestions, please let me know in the comments below.
Improving the global upgrade system Additions : Support for panning around the upgrade tree More upgrades ! Added icons to upgrades Added file saving for XP earned Allow accessing the skill tree from the menu Changes: Level completion is now tracked across multiple play sessions Refined “Currently: …” messages in the upgrade tree The features from the last devlog are now also public ! 🎉 I added some more upgrades to the upgrade tree, and I also gave all of them icons. The icons are… passable. I’m not a graphical artist, and it kind of shows. The “Currently…” messages at the bottom of the side panel got an overhaul, including the addition of units, specific to the type of value being upgraded The game now saves both xp earned and levels completed to files, so they persist between play sessions. This means you don’t have to replay the whole game every time you close it - this is no longer an 80s game ! The skill tree can also be accessed from the menu, so I’m no longer just booting it straight from the Godot editor. This makes it slightly more user friendly. This is probably where I will leave this project for now. I may come back to it now and then, but I’m happy with where this game demo has ended up. I’ll ship it soon, so watch out for that ! If you want to play the game, it is live here . If you are interested in the code, it is available here . To Do list : Add a “reset all to default” option in settings Quote of the update: “Next time I do this, remind me to actually build a proper tree structure” Any suggestions, please let me know in the comments below. Thanks for reading !
Ships:
Kernel Panic Hold off malware to give your firewall time to be repaired in this tower defence game prototype built using the Godot engine ! It is inspired by 1990s Unix systems and sci-fi classics like ‘The Matrix’. Play the demo at https://gianthotdog.itch.io/Kernel-Panic The game demo includes: Multiple levels including a tutorial GRUB-style menu A settings menu (Audio settings, Credits, VSync settings) A config file system so settings persist across play sessions An upgrade tree that contains global upgrades to towers and XP gains An XP and skill point system for purchasing those upgrades 4 distinct types of towers with adjustable targeting priorities Several enemy types Custom resources to handle: Single tower upgrades Enemy counts in waves Global upgrades Controls: Enter to skip startup sequence Click to select / interact / modify values AI: AI was used to write about 50 lines of code for the two shaders, and very occasionally for solving persistent bugs. It was only used for bug fixes after I tried repeatedly and failed to find a solution myself. It was also used for some feedback on aesthetic choices. All assets were designed by hand. All AI code was reviewed before implementation. Credits: Initial prototyping asset pack by Kenney Music by iamoneabe: https://opengameart.org/content/trunkful-of-junk...
|
1793674071.473663
|
1793760471.473663
|
|
9776
|
Untitled by @teamlewiscrafty | Stardance
|
teamlewiscrafty
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Untitled by @teamlewiscrafty | Stardance
|
1793494584.6352882
|
1794099384.6352882
|
|
68943
|
Bass Circuit by @teamjammw | Stardance
|
teamjammw
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Bass Circuit by @teamjammw | Stardance
|
1793127229.6524143
|
1793732029.6524143
|
|
66728
|
My awesome macropad! by @team_lavirtz | Stardance
|
team_lavirtz
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @team_lavirtz | Sta Title: My awesome macropad! by @team_lavirtz | Stardance...
|
1793101905.382802
|
1793706705.382802
|
|
40731
|
My awesome macropad! by @tealsnow | Stardance
|
tealsnow
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @tealsnow | Stardan Title: My awesome macropad! by @tealsnow | Stardance...
|
1793519552.6291103
|
1794124352.6291103
|
|
40899
|
My own site! by @tealsnow | Stardance
|
tealsnow
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My own site! by @tealsnow | Stardance
|
1793530068.3626473
|
1794134868.3626473
|
|
12168
|
My awesome macropad! by @teakzc | Stardance
|
teakzc
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @teakzc | Stardance
|
1793271353.0046961
|
1793876153.0046961
|
|
12610
|
Oceantype by @teakzc | Stardance
|
teakzc
|
1
|
3.0
|
56
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-06-12T15:26:47Z", "hours": 3.0, "multiplier": 16.59, "payout": 56, "blessing": "neutral", "text": "I made a website where anyone can express any thoughts and leave it in the ocean for anyone to see. Messages are circulated (when no new messages are sent) frequently just like objects floating around in the ocean current. The challenge of this is to learn supabase and nextjs. I already have experience with react, so just some guidance from ai taught me how it works. For example ‘use client’ on files to mark a clientsided component. It taught me how to communicate from server to public I am proud as alot of messages have been left already, and the fact that a real website I made is actually running and working properly. You can go to https://oceantype.vercel.app for testing. Mobile is supported too", "repo": "https://github.com/Hyperworks-Studio/oceantype", "demo": "https://oceantype.vercel.app/"}]...
|
[{"post_id": 7489, "ts": "2026 [{"post_id": 7489, "ts": "2026-06-12T14:30:02Z", "hours": 1.055, "text": "Bugs fixed I have fixed the counter bar. Previously, It would just accept a initial message count from the server and increment every new message. This is prone is some issues and does not hydrate properly I have now fixed this by just listening to postgresql changes and applying state immediantly on client. Features added Mobile is now more optimized, as it changed the interval to “roll” for recycled messages from 250ms to 1000ms on mobile. Same with the message spawning height, on mobile it would spawn on the visible page which is not very convincing as a effect. I used a new package: react-device-detect to check for mobile. Below is the code for counter, I fetch the initial counter in a promise, and apply. Then we also listen for changes and apply"}, {"post_id": 6236, "ts": "2026-06-10T14:15:06Z", "hours": 1.8453, "text": "New features and fixes: I have added transitions between the main page and the info page, which is needed because it was very awkward without it I also fixed the scrollbar in the text area so that it has no background when hovered. Here is a demonstration video where I test out the websites (message filtering, rate limiting) The messages here are left by real people who I have shared the website with! But, there still is a problem with the counter, as it has stale data that is not hydrated from the database. Thus next devlog I will be fixing that. If you want to drop by and say something: https://oceantype.vercel.app/"}, {"post_id": 5352, "ts": "2026-06-09T02:51:09Z", "hours": 0.5286, "text": "Oceantype, A website where you can leave a message into the ocean where anyone can read it. Old messages are recycled when no one is typing anything. This is a project I made to learn more about web dev, before I discovered the stardance challenge. I have now added text moderation (before this it wasn’t), by using the package obscenity found on npm. Before this, I tried using openai’s moderation which they said was free, but it didn’t work for me. (Error, too many requests when i only sent one message) Now if the message contains any profanities it will be filtered out! Also this is a project I have started before stardance challenge. What I used to make this website: nextjs supabase tailwind css"}]...
|
Title: Oceantype by @teakzc | Stardance
Devlogs:
Title: Oceantype by @teakzc | Stardance
Devlogs:
Oceantype, A website where you can leave a message into the ocean where anyone can read it. Old messages are recycled when no one is typing anything. This is a project I made to learn more about web dev, before I discovered the stardance challenge. I have now added text moderation (before this it wasn’t), by using the package obscenity found on npm. Before this, I tried using openai’s moderation which they said was free, but it didn’t work for me. (Error, too many requests when i only sent one message) Now if the message contains any profanities it will be filtered out! Also this is a project I have started before stardance challenge. What I used to make this website: nextjs supabase tailwind css
New features and fixes: I have added transitions between the main page and the info page, which is needed because it was very awkward without it I also fixed the scrollbar in the text area so that it has no background when hovered. Here is a demonstration video where I test out the websites (message filtering, rate limiting) The messages here are left by real people who I have shared the website with! But, there still is a problem with the counter, as it has stale data that is not hydrated from the database. Thus next devlog I will be fixing that. If you want to drop by and say something: https://oceantype.vercel.app/
Bugs fixed I have fixed the counter bar. Previously, It would just accept a initial message count from the server and increment every new message. This is prone is some issues and does not hydrate properly I have now fixed this by just listening to postgresql changes and applying state immediantly on client. Features added Mobile is now more optimized, as it changed the interval to “roll” for recycled messages from 250ms to 1000ms on mobile. Same with the message spawning height, on mobile it would spawn on the visible page which is not very convincing as a effect. I used a new package: react-device-detect to check for mobile. Below is the code for counter, I fetch the initial counter in a promise, and apply. Then we also listen for changes and apply
Ships:
I made a website where anyone can express any thoughts and leave it in the ocean for anyone to see. Messages are circulated (when no new messages are sent) frequently just like objects floating around in the ocean current. The challenge of this is to learn supabase and nextjs. I already have experience with react, so just some guidance from ai taught me how it works. For example ‘use client’ on files to mark a clientsided component. It taught me how to communicate from server to public I am proud as alot of messages have been left already, and the fact that a real website I made is actually running and working properly. You can go to https://oceantype.vercel.app for testing. Mobile is supported too...
|
1793692214.196595
|
1793778614.196595
|
|
51164
|
AI text detector by @teakzc | Stardance
|
teakzc
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: AI text detector by @teakzc | Stardance
|
1793379243.2956092
|
1793984043.2956092
|
|
19232
|
goldilocks by @teabagames | Stardance
|
teabagames
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: goldilocks by @teabagames | Stardance
|
1793174056.3881571
|
1793778856.3881571
|
|
27697
|
Wazza by @teaangoat | Stardance
|
teaangoat
|
0
|
5.97
|
0
|
[]
|
[{"post_id": 17982, "ts": "202 [{"post_id": 17982, "ts": "2026-06-28T22:54:25Z", "hours": 5.9667, "text": "Schematic is finally done!! Coming into this schematic, I knew I wanted to focus on one thing; which was my microcontroller. It served as the main component. However, in hopes of organization lol, I thought otherwise. At first, I originally wanted to split my schematic into different pages, each serving their own purpose (one for the sensor interface, another for the audio interface, and so on and so forth). However, due to redundcy (I tried to add a connections page combining everything) and time constraints, I realized the easier pathway led on to one single schematic. The basis of my schematic focuses on – as said before – my microcontroller: ESP32. ESP32 served as the central component of my project, the OLED display – used to provide the user basic info; the MPU-6050 – used to track the users gestures and movements (litt one of the most impo parts of my wand LOL); and other components all centralized around the microcontroller. Tomorrow, I will get to the PCB and hopefully get most of it done, although it’s an impending doom, I am really excited to work on that aspect of my project! Thanks!"}]...
|
Title: Wazza by @teaangoat | Stardance
Devlogs:
S Title: Wazza by @teaangoat | Stardance
Devlogs:
Schematic is finally done!! Coming into this schematic, I knew I wanted to focus on one thing; which was my microcontroller. It served as the main component. However, in hopes of organization lol, I thought otherwise. At first, I originally wanted to split my schematic into different pages, each serving their own purpose (one for the sensor interface, another for the audio interface, and so on and so forth). However, due to redundcy (I tried to add a connections page combining everything) and time constraints, I realized the easier pathway led on to one single schematic. The basis of my schematic focuses on – as said before – my microcontroller: ESP32. ESP32 served as the central component of my project, the OLED display – used to provide the user basic info; the MPU-6050 – used to track the users gestures and movements (litt one of the most impo parts of my wand LOL); and other components all centralized around the microcontroller. Tomorrow, I will get to the PCB and hopefully get most of it done, although it’s an impending doom, I am really excited to work on that aspect of my project! Thanks!...
|
1793382549.7837245
|
1793987349.7837245
|
|
23412
|
DUNGEONS AND DRAGONS by @tea | Stardance
|
tea
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: DUNGEONS AND DRAGONS by @tea | Stardance
|
1793325149.371636
|
1793929949.371636
|
|
46850
|
Butter Robot Better (BRB) by @te_hack | Stardance
|
te_hack
|
0
|
15.05
|
0
|
[]
|
[{"post_id": 76929, "ts": "202 [{"post_id": 76929, "ts": "2026-10-05T03:23:19Z", "hours": 0.9, "text": "Almost done with the body"}, {"post_id": 76584, "ts": "2026-10-04T01:57:49Z", "hours": 0.7669, "text": "Servo Body (Modeled)"}, {"post_id": 76273, "ts": "2026-10-03T01:22:14Z", "hours": 0.7506, "text": "Worked on the sketch of the servo"}, {"post_id": 75781, "ts": "2026-10-01T03:19:45Z", "hours": 0.3333, "text": "Trying to create the rest of the arm"}, {"post_id": 75441, "ts": "2026-09-30T03:24:56Z", "hours": 0.4333, "text": "Worked on the base of the servo arm."}, {"post_id": 75075, "ts": "2026-09-29T02:20:53Z", "hours": 0.5303, "text": "Redoing the arms to be servo based."}, {"post_id": 73436, "ts": "2026-09-25T02:41:35Z", "hours": 0.2708, "text": "Worked on the code for the robot."}, {"post_id": 72951, "ts": "2026-09-24T03:01:32Z", "hours": 0.3, "text": "Added a hat."}, {"post_id": 70372, "ts": "2026-09-19T01:46:38Z", "hours": 0.4833, "text": "Altered the Legs of the robot."}, {"post_id": 68943, "ts": "2026-09-16T02:53:31Z", "hours": 0.3836, "text": "Changing the wheels of the robot."}, {"post_id": 68426, "ts": "2026-09-15T03:05:38Z", "hours": 0.2833, "text": "Put it all together so far. will make smaller adjustments."}, {"post_id": 67039, "ts": "2026-09-13T02:37:30Z", "hours": 0.9, "text": "Revamped the arms and saw how it looked in assembly. Coming together so far."}, {"post_id": 66212, "ts": "2026-09-11T21:54:55Z", "hours": 0.6839, "text": "First work on the robot hands (separated from the rest of the arms for now)"}, {"post_id": 64557, "ts": "2026-09-09T01:54:26Z", "hours": 0.2669, "text": "start of the first draft of the second draft of the arms"}, {"post_id": 60503, "ts": "2026-09-02T21:43:01Z", "hours": 0.3503, "text": "Changed the wheels to put together later in assembly."}, {"post_id": 59974, "ts": "2026-09-02T01:48:11Z", "hours": 0.4833, "text": "finished first draft of wheels."}, {"post_id": 59259, "ts": "2026-08-31T23:02:57Z", "hours": 0.5169, "text": "Trying to create the wheels (first draft)."}, {"post_id": 58202, "ts": "2026-08-30T15:43:06Z", "hours": 1.0667, "text": "Just the first draft of the wheels."}, {"post_id": 57432, "ts": "2026-08-29T16:08:50Z", "hours": 3.9211, "text": "This is the draft model so far. Going to update at lot of the parts to make them involve motion."}, {"post_id": 47077, "ts": "2026-08-14T18:21:28Z", "hours": 1.4275, "text": "Butter Robot that passes Butter"}]...
|
Title: Butter Robot Better (BRB) by @te_hack | Sta Title: Butter Robot Better (BRB) by @te_hack | Stardance
Devlogs:
Butter Robot that passes Butter
This is the draft model so far. Going to update at lot of the parts to make them involve motion.
Just the first draft of the wheels.
Trying to create the wheels (first draft).
finished first draft of wheels.
Changed the wheels to put together later in assembly.
start of the first draft of the second draft of the arms
First work on the robot hands (separated from the rest of the arms for now)
Revamped the arms and saw how it looked in assembly. Coming together so far.
Put it all together so far. will make smaller adjustments.
Changing the wheels of the robot.
Altered the Legs of the robot.
Added a hat.
Worked on the code for the robot.
Redoing the arms to be servo based.
Worked on the base of the servo arm.
Trying to create the rest of the arm
Worked on the sketch of the servo
Servo Body (Modeled)
Almost done with the body...
|
1793159292.533921
|
1793764092.533921
|
|
24992
|
dotsong by @te | Stardance
|
te
|
1
|
29.51
|
44
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-06-25T02:41:15Z", "hours": 9.0, "multiplier": 4.96, "payout": 44, "blessing": "neutral", "text": "dotsong in its current state supports discord rich presence and scrobbling to last.fm, libre.fm, and any listenbrainz-compatible scrobbler. it can pick up tracks from any music player that interfaces with the system media center (i.e. MediaRemote on macOS, the media control thing on Windows that i always forget the name of, and MPRIS on linux). on the todo list is: better browser detection (might end up defaulting to off) scrobble retries optimization image uploading", "repo": "https://github.com/thrzl/dotsong", "demo": "https://github.com/thrzl/dotsong/releases/latest"}]...
|
[{"post_id": 42062, "ts": "202 [{"post_id": 42062, "ts": "2026-08-06T16:54:01Z", "hours": 2.9975, "text": "detecting browsers is annoying i discovered the issue when dotsong was trying to scrobble “Instagram”. i had to design this weird detection logic that runs if the process name matches a list of known browsers: is allow_browsers even enabled in settings? could we find it on deezer this feels a bit shoddy because for more niche tracks (which is totally possible if you’re playing them from a browser) it probably won’t be found. this makes me think i should lookup on musicbrainz instead. i also don’t want to rely on a private API, metabrainz seems more trustworthy especially considering spotify’s latest API changes also: i think i want to add a few custom discord apps for certain common players, like apple music and spotify so it can be “Listening to Apple Music” and stuff yk?"}, {"post_id": 21795, "ts": "2026-07-03T22:18:48Z", "hours": 4.4486, "text": "started rewriting the entire pipeline. main changes: complete MediaCenter::process_event rewrite rewritten completely from scratch. now takes up 40 less lines, skips invalid tracks earlier, and is much simpler to understand ticking logic improvement the app used to tick every 5 s to check track duration, which means 12/min. instead, i now calculate how far the 50% mark is and sleep for only that long; when we’re past it, it’ll just idle until the next track. the app now only wakes once per event, rather than 12 times/min use unicase crate to avoid unnecessary allocations most of the String allocations i make in the program are to_lowercase() calls for comparisons. the unicase crate allows me to make case-insensitive comparisons without extra allocations. all of this SHOULD mean less CPU and memory usage (i’m a bit obsessed with that, if you can’t tell yet), but i havent benched anything yet this PR edits like 500 lines but there’s only like 20 lines more than there were originally lol"}, {"post_id": 21295, "ts": "2026-07-03T04:32:00Z", "hours": 0.7556, "text": "i had been initializing a whole new last.fm/libre.fm client on every now playing request/scrobble, which was unnecessary and clunky. so i now: store a static CLIENT_POOL: LazyLock<DashMap<String, Client>> where the keys are the Scrobbler ids get the client for this scrobbler or create a new one and store it. this only runs on new requests, so we don’t unnecessarily create client. remove the client when the scrobbler is dropped, e.g. when the config is updated i’ve never used drop logic before but i think its like the coolest thing ever, so i was excuted about that"}, {"post_id": 20890, "ts": "2026-07-02T16:51:10Z", "hours": 5.135, "text": "originally, i had written two completely separate track detection pipelines for macOS and windows/linux, but i realized that it resulted in a lot of redundant logic, and making changes to that logic required testing on both macOS and windows for things that shouldnt have (e.g. cover art uploading), so i decided to unify it into one processing pipeline, and the platform-specific parts are just getting it to be a MediaInfo type as soon as possible. by the end of it, there were only 20 more lines than there were before, but there is now only one processing pipeline which is a huge help for implementing stuff in the future! also, some more tangible things: dark mode UI dotsong will do its best to filter out tracks from browsers instead of just taking it with no questions arm64 builds for linux now!"}, {"post_id": 17915, "ts": "2026-06-28T21:03:56Z", "hours": 1.7003, "text": "finally merged the cover art uploading feature! works on all platforms (linux is untested, but… we’ll get there)"}, {"post_id": 16727, "ts": "2026-06-27T05:22:26Z", "hours": 0.7731, "text": "fixed a really obnoxious bug i’ve been dealing with pretty much the whole time. on macOS apple music, when you pick a new track, it’ll broadcast a pause event and THEN a play event immediately after. for whatever reason, pause events always LOSE the race against the play event, and therefore overwrite the play event. it probably has to do with deezer caching. the fix was just short circuiting; check early if this is a pause event and we alr have the info; if so, dont worry about processing anything else"}, {"post_id": 16694, "ts": "2026-06-27T03:56:21Z", "hours": 2.8658, "text": "published another two versions today! first update contained a lot of those optimization fixes from before, but the second one was me testing with a user on windows (i normally use macOS, so testing on windows isn’t the easiest) now i’m doing testing on debian which is not working in any way at all </3"}, {"post_id": 16081, "ts": "2026-06-26T04:22:02Z", "hours": 0.7939, "text": "created a litterbox mock api with bun so i can test against image uploading against it compliant-ish. enough that it only accepts valid parameters and returns realistic URL responses. and its only 57 lines! i <3 bun forever the source is here https://gist.github.com/thrzl/22cde52746d4febf2c513b7fc7b829eb"}, {"post_id": 15509, "ts": "2026-06-25T06:26:35Z", "hours": 0.5628, "text": "more subtle improvements in this session, i removed some unnecessary ui elements (like a redundant separator and useless buttons) the more interesting thing is i fixed a bug where i was loading stale states, which cause it to spam now, i’m about to test AppImage builds, whenever i feel comfortable enough to put out another release"}, {"post_id": 15474, "ts": "2026-06-25T05:00:04Z", "hours": 0.4772, "text": "spent a LOT longer than 20 minutes trying to debug this weird memory leak that happens whenever i even ACCEPT image data on track events i literally gain a whole 200 MB PER EVENT, an “event” being any time the track info doesn’t stay the same. so if you pause it, play it, or the track changes for any reason, that’s an event, and it stacks so its totally unreasonable rn for me to get the images cus bro?? and i know its not in my code because i didn’t even add the handling yet i literally just accept the image data and it does that so i just filed an issue in the upstream crate pray for me guys"}, {"post_id": 15409, "ts": "2026-06-25T01:34:27Z", "hours": 0.9381, "text": "today i was trying to implement scrobble retries but i ended up not liking the current shape. i was gonna write to a file and send scrobbles later next time the host succeeds, but that was super annoying to implement i think i might end up trying a threads based approach where i just spawn a new thread whenever a scrobble fails; but that wouldnt handle network conditions as well. i think ima take a break from that and look at getting image support working tomorrow. that needs me to fix the upstream media-remote crate to fix a memory leak, first and foremost; then i’d want to lazy load images cus 70 MB just for getting a track is absurd"}, {"post_id": 14813, "ts": "2026-06-24T01:45:22Z", "hours": 7.9556, "text": "lots of code cleanup learned today that you can’t just use Arc<Mutex<...>> everywhere (well you can but its not necessarily a good thing) so i’m now using RwLock and ArcSwap which makes things a lot easier. i ended up changing tons of internal stuff in basically every file and still my PR only added like 30 something lines"}]...
|
Title: dotsong by @te | Stardance
Devlogs:
lots o Title: dotsong by @te | Stardance
Devlogs:
lots of code cleanup learned today that you can’t just use Arc<Mutex<...>> everywhere (well you can but its not necessarily a good thing) so i’m now using RwLock and ArcSwap which makes things a lot easier. i ended up changing tons of internal stuff in basically every file and still my PR only added like 30 something lines
today i was trying to implement scrobble retries but i ended up not liking the current shape. i was gonna write to a file and send scrobbles later next time the host succeeds, but that was super annoying to implement i think i might end up trying a threads based approach where i just spawn a new thread whenever a scrobble fails; but that wouldnt handle network conditions as well. i think ima take a break from that and look at getting image support working tomorrow. that needs me to fix the upstream media-remote crate to fix a memory leak, first and foremost; then i’d want to lazy load images cus 70 MB just for getting a track is absurd
spent a LOT longer than 20 minutes trying to debug this weird memory leak that happens whenever i even ACCEPT image data on track events i literally gain a whole 200 MB PER EVENT, an “event” being any time the track info doesn’t stay the same. so if you pause it, play it, or the track changes for any reason, that’s an event, and it stacks so its totally unreasonable rn for me to get the images cus bro?? and i know its not in my code because i didn’t even add the handling yet i literally just accept the image data and it does that so i just filed an issue in the upstream crate pray for me guys
more subtle improvements in this session, i removed some unnecessary ui elements (like a redundant separator and useless buttons) the more interesting thing is i fixed a bug where i was loading stale states, which cause it to spam now, i’m about to test AppImage builds, whenever i feel comfortable enough to put out another release
created a litterbox mock api with bun so i can test against image uploading against it compliant-ish. enough that it only accepts valid parameters and returns realistic URL responses. and its only 57 lines! i <3 bun forever the source is here https://gist.github.com/thrzl/22cde52746d4febf2c513b7fc7b829eb
published another two versions today! first update contained a lot of those optimization fixes from before, but the second one was me testing with a user on windows (i normally use macOS, so testing on windows isn’t the easiest) now i’m doing testing on debian which is not working in any way at all </3
fixed a really obnoxious bug i’ve been dealing with pretty much the whole time. on macOS apple music, when you pick a new track, it’ll broadcast a pause event and THEN a play event immediately after. for whatever reason, pause events always LOSE the race against the play event, and therefore overwrite the play event. it probably has to do with deezer caching. the fix was just short circuiting; check early if this is a pause event and we alr have the info; if so, dont worry about processing anything else
finally merged the cover art uploading feature! works on all platforms (linux is untested, but… we’ll get there)
originally, i had written two completely separate track detection pipelines for macOS and windows/linux, but i realized that it resulted in a lot of redundant logic, and making changes to that logic required testing on both macOS and windows for things that shouldnt have (e.g. cover art uploading), so i decided to unify it into one processing pipeline, and the platform-specific parts are just getting it to be a MediaInfo type as soon as possible. by the end of it, there were only 20 more lines than there were before, but there is now only one processing pipeline which is a huge help for implementing stuff in the future! also, some more tangible things: dark mode UI dotsong will do its best to filter out tracks from browsers instead of just taking it with no questions arm64 builds for linux now!
i had been initializing a whole new last.fm/libre.fm client on every now playing request/scrobble, which was unnecessary and clunky. so i now: store a static CLIENT_POOL: LazyLock<DashMap<String, Client>> where the keys are the Scrobbler ids get the client for this scrobbler or create a new one and store it. this only runs on new requests, so we don’t unnecessarily create client. remove the client when the scrobbler is dropped, e.g. when the config is updated i’ve never used drop logic before but i think its like the coolest thing ever, so i was excuted about that
started rewriting the entire pipeline. main changes: complete MediaCenter::process_event rewrite rewritten completely from scratch. now takes up 40 less lines, skips invalid tracks earlier, and is much simpler to understand ticking logic improvement the app used to tick every 5 s to check track duration, which means 12/min. instead, i now calculate how far the 50% mark is and sleep for only that long; when we’re past it, it’ll just idle until the next track. the app now only wakes once per event, rather than 12 times/min use unicase crate to avoid unnecessary allocations most of the String allocations i make in the program are to_lowercase() calls for comparisons. the unicase crate allows me to make case-insensitive comparisons without extra allocations. all of this SHOULD mean less CPU and memory usage (i’m a bit obsessed with that, if you can’t tell yet), but i havent benched anything yet this PR edits like 500 lines but there’s only like 20 lines more than there were originally lol
detecting browsers is annoying i discovered the issue when dotsong was trying to scrobble “Instagram”. i had to design this weird detection logic that runs if the process name matches a list of known browsers: is allow_browsers even enabled in settings? could we find it on deezer this feels a bit shoddy because for more niche tracks (which is totally possible if you’re playing them from a browser) it probably won’t be found. this makes me think i should lookup on musicbrainz instead. i also don’t want to rely on a private API, metabrainz seems more trustworthy especially considering spotify’s latest API changes also: i think i want to add a few custom discord apps for certain common players, like apple music and spotify so it can be “Listening to Apple Music” and stuff yk?
Ships:
dotsong in its current state supports discord rich presence and scrobbling to last.fm, libre.fm, and any listenbrainz-compatible scrobbler. it can pick up tracks from any music player that interfaces with the system media center (i.e. MediaRemote on macOS, the media control thing on Windows that i always forget the name of, and MPRIS on linux). on the todo list is: better browser detection (might end up defaulting to off) scrobble retries optimization image uploading...
|
1793631001.2145317
|
1793717401.2145317
|
|
12048
|
I.c.o.r.u.s by @tcthunderms | Stardance
|
tcthunderms
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: I.c.o.r.u.s by @tcthunderms | Stardance
|
1793235274.2457728
|
1793840074.2457728
|
|
67463
|
My Cool Blog by @tcshaksham | Stardance
|
tcshaksham
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My Cool Blog by @tcshaksham | Stardance
|
1793109275.9390764
|
1793714075.9390764
|
|
67470
|
TC OS by @tcshaksham | Stardance
|
tcshaksham
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: TC OS by @tcshaksham | Stardance
|
1793109286.6925616
|
1793714086.6925616
|
|
29504
|
hiii by @tchuekrostand | Stardance
|
tchuekrostand
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: hiii by @tchuekrostand | Stardance
|
1793501708.7175932
|
1794106508.7175932
|
|
70704
|
Crowly by @tchijo | Stardance
|
tchijo
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Crowly by @tchijo | Stardance
|
1793220658.093643
|
1793825458.093643
|
|
7516
|
My awesome macropad! by @tchang29 | Stardance
|
tchang29
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @tchang29 | Stardan Title: My awesome macropad! by @tchang29 | Stardance...
|
1793231464.7889884
|
1793836264.7889884
|
|
7518
|
Untitled by @tchang29 | Stardance
|
tchang29
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Untitled by @tchang29 | Stardance
|
1793354053.270535
|
1793958853.270535
|