Updates, and when the real world leaks into the technical world

Over the weekend, I got to attend Triangle Code and Coffee! It was pretty exciting and I’m glad that I went. You always hear about how great it is to attend events that have a variety of people with a diversity of backgrounds and ideas. And it’s like, yeah, of course it would be pretty fantastic. However, actually being there for it certainly strengthens that perspective. It’s kind of annoying how often cliches are actually true.

If I were to give advice for anyone attending a networking event, go early. You’ll meet other fellow go-early-ers and by the time the event starts you’ll have people you can reliably approach. It makes meshing with groups a lot easier, especially if your go-early-er group is a decent size. That’s all I have for advice though; I’m still a programmer and you know how cliches go.

“That’s great and all,” you say while pointing at your watch, “but where’s that Python Django progress you were talking about last week? Don’t leave us hanging.” And to that I would say, oh yeah, you’re right just a sec.

shuffles metaphorical papers

The Django stuff

So this week I managed to make some considerable progress on my Python Django application. Admittedly, the size of the things I want to do increased in size faster than I could make the things. I understand if that comes as a surprise.

Last time I mentioned that I had 7 things I accomplished and 5 things I wanted to do. Now, I have…

  • 11 things I accomplished
  • 5 things I want to do as part of completing this project
  • An extra thing I decided to do in the middle of a programming frenzy
  • 5 things I’d like to do but I won’t strictly consider acceptance criteria for the purposes of finishing this within the current decade

To keep it simple, I will talk about the new and most interesting things I accomplished.

Following users and only seeing their posts

Given that the concept of following people is a many-to-many relationship, there was some database-related logic that needed to happen. Simply put, it was this:

Anybody with any amount of database experience will recognize this pattern, which is called a join table. These “following” entries can be created and deleted on the fly without affecting the users.

For those who are interested in the Python/Django representation of this, it is the following:

class User(AbstractUser):
    date_joined = models.DateField(auto_now_add=True)

class UserFollowing(models.Model):
    follower = models.ForeignKey(settings.AUTH_USER_MODEL, 
                                    related_name='following', 
                                    on_delete=models.CASCADE)
    following = models.ForeignKey(settings.AUTH_USER_MODEL, 
                                    related_name='followers',
                                    on_delete=models.CASCADE)

For those who may have noticed, User extends from Django’s AbstractUser class which has all the attributes you’d expect from a user. The attributes that you do not see (but definitely exist) are username, password, and email. For my particular use case, I added a date_joined attribute that allows you to see when the User was created.

The ForeignKey parts in UserFollowing essentially say that we are going to be pointing to a user for each of them. There are 2 entries for it, one for a follower and one for is being followed. Due to how Django allows you to access database info, any User object is capable of accessing their followers and who they follow by using the names described with the related_name parameters. A good example of this is from a function to generate posts based on a user’s following. This also includes the user’s own posts because it’s nice to be able to see your own posts too:

def aggregrate_tailored_posts(request):
    follow_relationships = request.user.following.all()
    posts = request.user.post_set.all()
    for relationship in follow_relationships:
        posts = posts.union(relationship.following.post_set.all())
    return posts.order_by('-date')

The posts returned from this function will then be passed to the HTML template represented by the feed. Then, the user will see their own stuff they posted, as well as the posts from people they’re following.

Improving site look with bootstrap

I put this off for a while because I knew that my creative eye can vary from “vaguely resembling insightful” to “trash can incarnate.” For a better idea, take a look at my pixel art section!

Self-deprecation aside, I was able to format the site in such a way that it looked like something a human could use. This not only applied to desktop, but also mobile.

In order to do this, I leveraged the different formatting classes that bootstrap has which allow for adjustments based on different screen sizes. As advice for those that are curious about Bootstrap, read into how containers, rows, columns, and how the 12-column system works. This will provide a solid foundation for picking up the rest of the things bootstrap has to offer.

Seeing a user’s previous posts in their profile (the extra thing I decided to do)

This next feature is very similar to the feed. The main difference is that the posts listed are all posts made by the user. There is currently a restriction where you can’t comment on posts when you’re looking at them from the user page. I may implement the ability to comment while on a user page but it’s not entirely high on my list of things to do.

Much like the feed, this is a mobile-compatible interface. If it sees that the user is on a mobile device, it will actually move the user’s card to the top of the page instead of having it on the left side like the image above.

Testing

Since my focus has been more on picking up the framework, I haven’t written as many tests as I wanted to. That said, I have a working test in Selenium which will login as a user and check that the main page is available.

I am currently running into an issue where I want to have a consistent starting database that would reset back to its original configuration after selenium tests are done. A little bit of work will need to be done there in order to not have to manually reset stuff before running the Selenium tests.

I currently have a Gitlab server set up on my local network, so I will be working towards trying to dockerize this project and set up ways to run the selenium tests in a pipeline. That will be the best time to address the aforementioned problem, as I can have everything running in neat little containers with their own scripts and things. I also need to look into the Gunicorn utility for hosting the site that will be tested against.

And that’s about it

I didn’t cover literally everything that I made in the past week since that’d be a pretty nasty-sized post, but I did want to get the important parts out at the very least. It’s been a pretty neat project so far so I’m hoping I can try and get at least the core parts completed.

‘Till next week!

Basically a devlog

I said I would do a post once a week and doggonit I’m doing it! I realized yesterday that almost seven days passed since the last post and my first reaction was “wow, how do actual professional writers do it?” Time itself decided it was time to be next week and here I am, at the mercy of it.

Jokes aside, it has been an absolute learning experience with Python and Django. Much like when I was learning Bevy, there was an initial phase of “this is confusing and has so many moving parts; how does any human function while working on this?” and then over time I started to think “Okay I want to do these things, so I just need to change this, and this, and this, oh and I gotta remember that. Why doesn’t this work? Oh yeah duh because of this.”

That’s essentially the sound of growth. Anyway, here are the things I recently accomplished so far with creating a sample media posting app in Python and Django:

  • Basic login/logout system
  • Making posts with images
  • Making comments on posts
  • Deleting your own posts
  • Seeing all listed users
  • Seeing user profiles
  • Editing own user profile

Here are the features I plan to add as well:

  • Following users and see only their posts
  • Making reactions on posts (ideally with ajax)
  • Full email authentication
  • Making things look nicer using bootstrap’s layout system
  • Automated testing

There are some additional nice-to-haves like lazy loading and real-time post updates, but we shall see on those. I ideally want to have those things but it won’t be the end of the world if I decide to move on to a newer project by the time I finish adding the things I definitely want to have.

One thing I want to do as well is construct a local Gitlab CI pipeline for the project. This effectively falls under the very broad category of “Automated Testing” that I listed above. The pipeline would ideally run my automated tests, then deploy to some local web server that I have. I’d be using my assortment of raspberry pis for this endeavor. I also want to use the Django unit testing framework as well as Selenium for product level testing. Therefore, “Automated Testing” will most likely take the most time out of the remaining tasks.

Anyway that’s about it. I hope to have at least have the remaining core features done by next week so that I can talk more about them. Thanks for reading and don’t do anything I wouldn’t do!

Tired, but free

Alrighty, so it’s been quite some time since my last post. For what it’s worth, it’s not entirely because I was lazy. There’s slightly more to it. Some good, some bad.

It’s frighteningly easy to go on autopilot sometimes and to think that life is one big routine that never changes. To some degree, it’s definitely true. But, once in a while, you’ll smack right into a brick wall to shift the balance. We tend to forget how tenuous the conditions of maintaining our equilibrium are, then when things are shaken up, we can get shaken up too. We begin to question reality and quickly recall that the universe is actually uncaring.

It’s easy to see that as a bad thing. And a lot of times it is.

In my case, let’s just say I have a lot more freedom now at the cost of stability. Thankfully, knowing the universe, I prepared for a time like this. I’ve been focusing a great amount of energy to figuring myself out and understanding the potential that I have. Guess what? It turns out I learned stuff about myself and the rich possibilities life has to offer.

Programming is still pretty neat

Firstly, I still like software and writing stuff for it. I like the process that goes into the problem solving for it. I like having a sick playlist in the background as I’m slamming out some code to bring an idea of mine to life. Yes, it’s hard some days. But everything worth being paid for is hard some days.

Being lost is fine and in fact encouraged

That’s basically it. I think being lost is the next step to being slightly less lost. From there it’s slowly chipping away at the ground you want to explore next, while mapping the ground you’ve covered.

Results-oriented retrospection is a slippery slope

With any decision you make, there’s almost definitely a better one. Probably. But nobody’s psychic and can come up with that optimal path. What matters is PICKING ONE. Seriously. You’d need all of the world’s information as well as the ability to process it in order to make the most optimal decision. Yes, maybe you’ll regret the decision, but it’s better than doing nothing.

In my case, I started learning the Django library in Python. At the time of writing, it is an absolute work in progress. I didn’t think too much about it when deciding to learn it. I just saw Django a decent amount in job descriptions and I kinda like Python. Plus, I’ve messed around with Flask in the past. Is the choice to learn Django the most optimal? No. Is it a waste of time? Absolutely not. In any case of doing software engineering, there’s something to learn from. What matters is I just pick something and roll with it because otherwise I’ll just sit and overthink things instead.

Maybe I won’t like Django. Maybe I will. Who knows? If I don’t, I definitely learned stuff. If I do, then I win. I’ve done enough overthinking.

It’s not about not failing, but rather increasing chances of success

I previously took the approach of getting by. It’s not sustainable. Yes, you can do it while technically growing, but there’s a lot of potential learning left on the table when you don’t try things that you know you’ll fail at the first time.

Some things, you basically just have to constantly fail over and over. As your failure counter rises up, throw the stupid failure counter in the garbage because who cares? If you learned from previous failures and applied them to future attempts, then you can sleep just fine.

Sometimes, you can do everything perfectly and still not succeed. Refer back to when I mentioned the universe and its relationship with people. All you can do is say, well, I am trying to just increase my chances of success with each new iteration. Sometimes the odds are stacked against you or literally at 0 and you’d just never know.

/ramble

That’s about it honestly. I will be making attempts to post on here weekly to have as part of my routine. I have had a lot of opportunity in the past month to grow as a person and reflect on what I like and what I do. Maybe this can help someone else do the same.

Stay safe; make good choices!

My handy Rust CLI

A week or two ago I started on creating a rust program that would accomplish two things:

  1. Improve my understanding of the package management system for Rust. More specifically, I wanted to understand how to organize modules a little bit better
  2. Create something that I could use to create challenges for myself using an automated and randomized method

I worked on it for a while and then get hung up on the specifics for parsing command line arguments. The approaches I thought about either seemed way too complicated, or were way too hacky to really be proud of writing them. I let the project for a sit for a little bit.

After some time, I realized that I could probably just outsource the parsing logic. Given that I was, at the time, the furthest from the first person ever needing to parse command line arguments, there had to be a library for it.

I was indeed correct and found clap. This library turned my project from a headache into a neat little organized oasis. More on that later. First, I’m gonna describe how the program works.

How the program works

The utility will look at a set of text files that you give it and create a set of challenges. For example, you could have some text files that describe pixel art challenges you can try.

theme.txt

Draw a house
Draw a mountain
Draw a bear

size.txt

at 128x64 pixels
at 256x128 pixels
at 64x64 pixels

palette.txt

with Midnight Ablaze Palette
with Oil 6 Palette
with Apollo Palette
with Spanish sunset palette

With these files in the root directory, you can run something like this:

cargo run -- -f theme.txt size.txt palette.txt -c 5

This will…

  1. Look through the listed files indicated by -f
  2. Print out the challenges’ details in the order they were listed, randomly picking an entry in each file. This will be done five times, as indicated by the -c 5 argument. --count can also be used instead.

One example output could be the following:

Draw a house at 64x64 pixels with Midnight Ablaze Palette 
Draw a mountain at 256x128 pixels with Oil 6 Palette
Draw a house at 128x64 pixels with Apollo Palette
Draw a bear at 128x64 pixels with Midnight Ablaze Palette
Draw a mountain at 256x128 pixels with Midnight Ablaze Palette

Now I have 5 challenges for pixel art I can work with! This is great for generating ideas, especially if you fill a text file with a million different ideas, then also fill another text file with a million other ideas to combine with it.

This could also be good for quizzing yourself, learning a new language, inspiration, you name it.

Anyway, so on the topic of my code being a neat organized oasis, Here is the parser and how it is used by my main program:

Parser & friends

cli.rs

use clap::Parser;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
pub struct Args {
    #[arg(short, long, num_args = 1.., required = true)]
    pub files: Vec<String>,

    #[arg(short, long, default_value_t = String::from(" "))]
    pub separator: String,

    #[arg(short, long, default_value_t = 1)]
    pub count: i32
}

main.rs

use chalgen::{file_processor, cli};
use clap::Parser;

fn main() {
    let args = cli::Args::parse();
    file_processor::output_challenges(args);
}

The code above does the following:

  1. Define the command line arguments for the library to look for and what characteristics they should have (cli.rs)
  2. Pass configuration that was gathered from command line arguments to the program doing the actual work (main.rs)

To provide some context for cli.rs, the following keywords are important:

  1. short: the flag can be represented by the first letter of the property name. e.g. files can be referred to as -f when calling the command line utility
  2. long: Effectively the same sort of option as short, except the flag is able to be represented by its full name. e.g. count can be represented as --count when calling the command line utility
  3. default_value_t: Essentially, this is what the flag will be set to if it is not mentioned when calling the command line utility
  4. num_args: How many arguments that are expected from the flag. In this case, I use it once with files and the number of arguments is represented by 1.. which essentially means “at least 1.” I specify it like this to provide the user the ability to provide any number of files they want
  5. required: The flag must be used. In this case, the files flag is required

All of the restrictions and allowances defined above are automatically enforced by the clap library. This is a huge weight off my back and allowed me to focus on the actual program (AKA the file_processor::output_challenges(args) part of the code that I don’t show.

Anyway, that’s about it. Here is the repository for the curious! Stay safe and make good choices.

Pixel art, its community, and my findings

I never was a huge creative. I made my attempts but it was easy to go back to old habits. Within the past few months I’ve been doing pixel art and it was kind of an accident. I started out with trying to make a game with Rust and Bevy (see Games and Experiments, namely the Avoider Game) and then realized that in addition to programming, pixel art is actually pretty neat.

After just trying to get some basics down for the sake of making something that looked functionable, I started to jump down the rabbit holes and eventually I could only think…

huh.

Now I’ve got a gallery and I can’t stop! This revelation made me realize that I had deprived myself of a creative outlet for quite some time. While I have tried creative endeavors in the past and didn’t care for them as much, I didn’t give myself the opportunity to continue looking. Thankfully, I’ve found a method of expression that wasn’t just typing at people or sending sick Rocket League clips.

Another surprise I’ve run into is that the community is pretty supportive. I’ve done some posting on twitter myself and it’s nice to see people sharing and liking each other’s work. Plus, hang around there long enough and you start to see the same people after a while; it feels like a wholesome little neighborhood of sorts.

I’ve also joined a pixel art discord that has a variety of channels, including one where you can post your work for feedback. In my time spent there, people have been surprisingly helpful as well.

Initially, my subconscious perception of the art community as an outsider seemed like it was a difficult-to-penetrate sphere where only the highly skilled dwell. That could not be further from the truth. People in the community understand the amount of work that goes into something that actually looks good and all the difficulties that you inevitably find along the way. Plus, looking at the work of others helps to inspire yourself. A little bit of support goes a long way when you want your favorite artists will keep making more stuff.

Overall, it’s just nice to be heard. If I make something, really enjoy how it came out, and others feel the same, it’s really validating. Sometimes I’ll make things that I’m not exactly excited about and some people people may still enjoy it nonetheless. Much like in the “real world,” people can still like what you do in spite of, or because of, your blemishes. I’m learning how much better it is to put your ego to the side and just create, instead of being afraid and doing nothing. As long as the process and the rewards after are worth it, That’s what matters. If you share your experiences or creations, there will be like-minded people out there that would like to see what you’re doing, or at the very least, help make it better.

‘Till next time. Make good choices.

Low times

It’s been a bit of a tough period since my last post. I had been dealing with some work stuff and thankfully that’s over, but it’s been really difficult to create on my free time.

I started on a small Rust program recently to learn a bit more about how Cargo works. In addition, the tool was supposed to help me with some of my other hobbies. After some days of spending time on it, I noticed that it was increasingly harder to press my fingers on the keyboard and make the code do stuff. I did learn more about Cargo, but I just couldn’t be bothered. I think it’s temporary, but we’ll see. I’m thinking of greatly down-scaling the project to make things easier. I may have also recently ran out of coffee but surely that can’t be related.

Pixel art has been more of a consistent interest for me at least. Even though I am still having a hard time producing stuff there too, it’s at least because it’s novel and I don’t have it figured out yet, and not because I’m just like ugh. It’s hard to explain, but it may be because I regularly code at my normal day job. It’s much more difficult to work on code stuff on my free time when I’m also spending 5 days a week programming at my job.

I don’t really have much of a point to the post. I think sometimes it’s good to reflect on accomplishments when you’re down. I’ve done a lot of stuff the past couple months! That’s neat. We take those. It’s easy to beat yourself up when you want to push yourself at low times, but honestly it’s not worth it. People who do that to themselves end up pushing themselves away from their interests.

I think what helps too is that I don’t plan to make money with what I do or make on my free time. There doesn’t need to be good enough writing, good enough art, good enough whatever. I finish and submit whatever I think is presentable. The void I’m filling with all this stuff I am doing is a creative one. I’ve kinda deprived myself of a creative outlet for long enough, so the fact that I have many of them now is worth its own celebration.

For anyone reading, thanks and stay cool 😎

The avoider game is complete! (enough)

For the anxious and the ravenously impatient, here is a link to the game. For more info, it can also be found in the Games and Experiments part of the website.

Whew! What an absolute experience it was getting this one out the door. I would say great strides were made in early March, with diminishing returns coming in towards the end of march and into April. I had hoped to have this done before my trip in mid-April, but sadly that was not the case. Thankfully I was able to still knock things out after and all is well!

My main goal here was to learn about Rust/Bevy while making something that seemed fun, no matter how basic and unoriginal it may be. I’ve found that waiting on the perfect idea is for people who never act on it, so I just went with my gut when starting production.

For me to consider this small project complete, the game needed to be fully functional with the ability to pause, resume, die, retry, and even win the game. Some of those features were vastly easier than others, but we got there.

Things I learned

While I am glad I finished this, it was definitely starting to get the rot of ignorant technical choices towards the end of development. This is fine. Making mistakes is a fact of life when doing complicated stuff. A lot of this stuff will echo what I have in the readme in the github repo for this game, but will go into a bit more detail.

Listeners and state changes

In Bevy, you can have systems listen for change of state and for events. These are two distinct things.

At the beginning, I thought the change of state was not something you can listen to. So, in some cases, when there was a change in application state I would also include an event that occurred alongside it. This did work, but it was inefficient. Once I figured out that change of application state could be listened to, I did not need to use events for those particular cases.

There is another distinguishing feature that events have however. They can carry data along with them. For example, there’s two ways the game can end. It can end with the player dying, or the win condition of the game being met. Depending on what causes the game to end, that is what the “end” screen will say.

  • If the player loses, the end screen will say something like “you died press these buttons to restart”
  • If the player wins, the end screen will say, and I know this may come as a surprise, it will say “you won”

So functionally, winning and losing is the same. This hits a bit too close to home but we’ll just not think about that for now. The only difference between the two is the string that is presented at the end state. Therefore, we can carry that string alongside the endgame event and just slap whatever we want on the end screen based on what occurred beforehand.

Here are some links for more technical info on events and state-based stuff. The latter is based on Bevy 0.10 which is the latest stable version as of writing.

Asset handling

Early on I wanted to just get my assets into the game without thinking about it too much. It turns out that people include loading screens in games for a reason. A more reasonable approach is to load up the assets by the asset server at the beginning and then pull upon them when the game is running.

What I did instead was pass the asset server into effectively any system that may or may not need to utilize an asset. That’s pretty goofy since passing it around everywhere is not only just a waste of performance if the game were scaled up, but also because it just created code clutter.

The solution to this, like I mentioned earlier, is next time to load the assets at the beginning, then refer to them using a resource.

I actually just don’t know how cargo works

When I read the Rust book, I may or may not have glossed over the cargo system since I figured it would be pretty straightforward. While in many regards it is simple to use when using other people’s libraries it’s a bit more intricate when you’re working with creating your own modules.

I’ve made it a point to learn more about the logic behind setting up my own modules, as this may also help with the architecture of future projects, too.

The biggest problem with this that I had was that I had to basically copy a function a couple of times because I could not get two files to share it. My code comment here kind of explains it some more. Definitely not one of my proudest moments but that’s why I’ll be reviewing how cargo and modules work.

Other things

The github repo readme has more points on things I should consider in the future. However, I think the above things are the things that stuck out to me the most, so I shall leave it at that for now.

And that’s about it

I’m looking forward to future projects. I have reason to believe my next stop will be the rapier physics engine. But first I’ll want to learn more about cargo and modules. ‘Till next time!

The falling sand Bevy app is available to mess around with! (and how I got it on the website)

For those who just want the goods, here’s the main attraction.

In my last post, I talked about the falling sand experiment I made with Rust’s Bevy library. I planned to get it to work on the website but I had a feeling it would be a headache. Turns out it was exactly enough of a pain for me to not immediately give up on it!

The rest will just be going into the technical details for the curious. For those who don’t care about the tech stuff, this is effectively the end of the post!

Essentially, it boils down to the following steps:

  1. Utilize wasm-bindgen to generate the files needed to run the game in the browser.
  2. Create a script that launches the .js file generated from the previous step.
  3. Create an HTML file that wraps around the script.
  4. Place all of the above files together somewhere that can be accessed publicly in my website, then point to the HTML . This HTML file is the one I linked to above.

Here’s some details on the steps:

Utilizing wasm-bindgen to generate files

I utilized the bottom portion of the Unofficial Bevy Book which talks about wasm-bindgen. If you have a project that utilizes Rust and Bevy and follow the instructions you should be good. I should mention though that when running the wasm-bindgen command, it is not made clear in the linked book (at least at the time of writing) that you need to point to the .wasm file that is generated in the wasm32-unknown-unknown folder generated by the previous cargo build command. So for example, you’d want to run something similar to this:

wasm-bindgen --out-dir ./out/ --target web ./target/wasm32-unknown-unknown/release/falling_sand.wasm

This should generate the files (in this case inside the out directory) for the next step.

Creating a script to launch the .js file from the previous step

Inside the out folder generated from the last step, a collection of files should exist. The one we care about is the .js file. It will most likely have its own name based on whatever the name of the project is. What I did here was create a new file in that folder with an init_game.js that has just the following:

import init from './falling_sand.js';
init();

…and that’s it! Well, for this step. The falling_sand.js will need to be replaced with whatever the .js file is in your case.

Create an HTML file that wraps around the script created above

From there, create an HTML file. It can be super bare bones, or you can get fancy with it. I’ll start with bare bones:

<html>
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    <script type="module" src=./init_game.js></script>
  </body>
</html>

Note that the init_game.js script (the two-line script) that we created is located in the script tag. The following is a fancy approach I did with the falling sand game:

<html>
  <head>
    <meta charset="UTF-8" />
    <style>
      body {
        background-color: black;
      }
      p {
        color: white;
      }
    </style>
  </head>
  <body>
    <p>Space: Change your brush to a different block type. The order is Sand (initial), Water, Solid</p>
    <p>Left click: Place block</p>
    <p>Right click: Delete block</p>
    <script type="module" src=./init_game.js></script>
    <script>
        function modify_initial_canvas () {
            const canvas = document.querySelector('canvas');

            if (canvas) {
                canvas.oncontextmenu = function(e) {
                    e.preventDefault(); 
                    e.stopPropagation();
                }
            } 
             else {
                setTimeout(modify_initial_canvas, 300); // try again in 300 milliseconds
            }
        }
        modify_initial_canvas();
    </script>
  </body>
</html>

This fancier approach solves the problem I was having where right clicking was causing the context menu to pop up when trying to right-click in the game. In addition, I have some style stuff there too. Also as an irrelevant note, this is HTML file is different from the actual falling sand HTML because I realized there was some styles I didn’t even need.

Place the files somewhere your website can access and link to it

The title says it all. All you need to do at this point is put the files somewhere that your website can access and link to. In my case, I put it along with my public WordPress media files. This involved going into my web server files and looking to see where my public media is located and how the website links to them. Then, I linked to the HTML file in the same way. There may be a better way of doing this, but this will at the least give another approach that could be useful for certain situations. At the end of the day, if you can provide a mechanism to open the HTML file, you’re good to go.

Anyway, that’s about it! That was a lot of stuff. If you’ve gotten far, I hope this helps. If I keep doing Bevy stuff, I at least know future me will appreciate it.

Falling sand!

Future me here, with an edit for this post: I got it working on the website! Here is a link to the falling sand. This does not work in mobile, only desktop.

As a side project that was also done in Bevy Rust, I decided to make a falling sand sim. I’ve always liked the idea of defining specific behaviors of individual entities and letting things unfold as they, or the user, interact with each other. Plus, who doesn’t like messing around with physics sims?

Here’s a sick and excessively dope demonstration of gravity working itself upon a buncha pixels (except those green guys, they don’t care what you think until they’re removed from existence. At that point, their ability to not care is completely overwritten by their inability to exist, which is entirely understandable).

Of course, this is hosted on Github for all to gawk at and chortle about. It was made in two days plus an evening as a hackathon at my job so it is at best a proof of concept. I do plan to leave it as-is though, unless I have a sudden burst of passion to expand on the falling sand idea.

The only other thing I plan to do with it is get it running on the website on its own page. It should “just work” with WASM, though I have some suspicions that may not be the case. Stay tuned for that.

Anyway go be a green pixel, friends. I’m sure there’s a cool way to expand that metaphor but you’re not gonna find that here. Look within or something.

Messing around with pixel art

A considerable step up from my last attempt

I’ve been enjoying pixel art more and more these days. It gives me a way to think without having to access the part of my mind that’s usually active when coding. Plus, you can sit down for an hour or two (or more) and usually have a finished product by the end. Is it something I’ll continue doing? Hopefully. I could use more creative outlets.

I decided to pick up Twitter to get more involved with the pixel art community ’cause why not, and I saw things that would make lots of aspiring artists quit on the spot. People make some insane stuff. One artist I’ve particularly enjoyed is Joseph Hyde. Call me basic but I’m a bit of a sucker for the landscapes honestly. Definitely worth checking out.

There’s also a twitter account called Pixel Dailies that posts a topic every day and people can make pixel art based on the topic. I like that they’re pretty open interpretation of the topics and they actually feature (by retweeting) the best works they find. Given my lack of experience, my submissions have been pretty juvenile so far; needless to say none of them have been featured yet. I’ll take my time with it. It turns out other people have been doing this for far longer than I have.

On the topic of my game, I’ve been slacking a bit on it, though it isn’t without any good news; my job does hackathons every quarter so I’ve been putting some work into a neat little side project with Bevy Rust. That’ll be a little extra something I hope to host on the site too. It’ll involve fancy sand.

One thing I know for sure is that in two weeks I’ll be taking a week-long trip to Colorado, speaking of sick landscapes. Knowing that, I want to have my projects in a complete state before I go. I highly suspect that whatever is incomplete when I get back won’t get done. I may try to mess around with pixel art during the trip though since that’s easier to pick up and put down.

Anyhow, that’s about it. ‘Till next time.