I tried to complete a full Rails project in two days – it was a disaster and I’m glad I tried it.

Pixel art of a plant in a pot

Sometimes, somehow, a fire gets lit under your butt and your path is clear. All you can think about is the code you’re writing. You turn around and all of a sudden 4 hours pass in what seemed like no time. Textbook flow-state.

This weekend, I attempted to manifest this feeling to no success. These things, as you will see, are not something you can just do on command. But you can make them more likely to happen. Let me explain.

The final step of the 1212 process

To give some context, I’ve been working on something called the 1212 learning process. I wanted to learn Ruby on Rails, so I challenged myself to work on four projects, each with increasingly aggressive deadlines.

✅ Complete a project within 1 month (Bloggington, blogging web app) (~60 hours of focused work)
✅ Complete another project within 2 weeks (Phasmid, bug tracker) (~50 hours of focused work)
✅ Complete another within 1 week (Evenfall, web chat) (~33 hours of focused work)
🚧 Complete a final project within 2 days (This project, Sesh, workout tracker) (~7 hours of focused work)

I normally would leave a checkmark next to my project once the time is over, but Sesh is not complete by any stretch of the imagination. The project timer started on August 9th, and ended August 10th.

Small forewarning

This post will be considerably less technical than my other posts in the 1212 process. This is a reflection on standards I set for myself, how I fell short of them, and why that’s fine.

What happened?

A few things happened.

Coming off of Evenfall, I wanted to get my two-day project started before I lost steam. Knowing that weekends would be the best time to do it, it meant that skipping a weekend was basically skipping a whole week. I decided to do it sooner than later because if not, I could see myself putting it off. This may not have been enough rest time between projects.

In addition, I had the gall to use leisure time during my two days. I knew that I was going to have to do a decent amount of serious, focused work, so I used a good chunk of my time to relax in between sessions. This obviously led to lost time.

The real problem, and the main topic of discussion, was my subconscious desire to step away from my code a lot while I was working on it. It almost felt like my mind was trying to find every possible reason to distract itself. While this wasn’t new territory, is was particularly acute during this project. In short, I found that I was procrastinating a lot.

Pushing past procrastination

Here is my time log for the two days:

8/9 1hr in morning, start 2:15pm. pause 4:00. Start 4:50, stop 6:35 
8/10 start 10:20 pause 11:00. Resume 11:15 pause 12:00. Resume 12:15, pause 12:45, start 1:45, pause 2:45, start 3:15, stop 4:00

By the time 4pm Sunday rolled around, I was already done. I knew that I wasn’t going to have anything resembling a finished project unless I hard grinded through to midnight. But I was already mentally exhausted. Not only because coding is coding, but because I spent so much energy fighting myself.

There’s a helpful chapter in Tiny Experiments by Anne-Laure Le Cunff which talks about procrastination. It describes how procrastination can potentially stem from three parts of you: your head, your heart, and your hands.

  • Head – Is this something worth doing?
  • Heart – Do I feel good doing this?
  • Hands – Is this within my capabilities?

Upon reflection, I realize that each of these things played a role in my subconscious desire to avoid working on this.

Is this something worth doing?

For the most part, yeah. The 1212 process had already shown its value in my first three projects and this seemed exactly like the logical next step. But it does come with a question when you look closer. Is it worth spending as much time as possible grinding out a full project on a weekend? To some, possibly. For me, I think on some level it wasn’t.

I know some people really enjoy hackathons and code jams; I do too. Though perhaps for a longer period than a weekend. Or maybe just a couple days within working hours and I’m getting paid for it.

Is this within my realm of capabilities?

Probably not. I’m still learning Rails and I don’t quite have the speed to do much of anything substantial within such a small amount of time. I think I knew this going into it, and as a result, there was probably a subconscious desire to avoid such a futile effort.

Do I feel good doing this?

While I am happy to commit a good chunk of my weekend to making stuff, confining a deadline into two days did not elicit a healthy attitude. If I wanted to get anything done, I had to really work on it! And what if I felt like I was done for the day after a couple of hours? I’ll just have to suffer through it.

Normally, for my longer-period projects I could jump into my work even if I wasn’t quite feeling it, because I knew I could consistently get an hour in if nothing else. For this, it was like yeah you’re committed once you start working.

The tough guy in the back of my mind

Even knowing that my expectations were unrealistic, there was a part of me while working on this project that was like “so you’re gonna just give up like that? In the real world, you don’t get to rest. Especially if you want to be self made.”

But you know what? You can rest. My goal is to design my life in such a way that insane deadlines are an absolute last resort. Not the norm. Yes, this requires leverage. You know how you build leverage? You upskill. A lot. You know how you upskill? Consistent, daily practice. You know how to make this easy? Enjoy the process. The moment you begin to resent your process, the more likely you are to abandon it, and the more likely it is to fall apart.

The mere act of falling short of my own unreasonable goal was enough for me to put off writing about this project. I could have just let this failure fade away. I could have let resentment go to a broil and then give up because it felt bad. Look, see, this stuff is stupid and not worth it. Nobody even reads these posts. But nah, I’m tired of doing that. It is worth it, and I am growing. Just because I can’t code something in two days doesn’t mean my efforts are for naught.

Lessons learned

Things to consider when shipping a real project

Disappoint people up front. Give a time period that’s at least twice what you think you’ll take to get it done. Yes, every situation is different, and you may have to make sacrifices from time to time. But those sacrifices need to be the exception, not the rule.

Many might know this already. And I bet good chunk of those people don’t follow it and need a reminder. Let this be your reminder.

Constantly overworking is not scalable

I like to think I learned a ton from Rails since May when I first started the 1212 process.

While I was working on Bloggington, I was on vacation to see family. I spent time out of my day whenever I had the chance to work on the project. I never pushed too hard and I never let it get in the way of quality family time.

When I worked on Evenfall, I worked on it every single day. I still had time for gaming or going out. Frankly, I don’t remember much of my in-between time for Phasmid. I think the project was interesting enough on its own to consume a lot of my time while still being interesting. And that’s perfectly fine too!

A time and a place for code-benders

Recall what I mentioned earlier about several hours passing by in a flash after an intense but satisfying coding session. By no stretch am I discouraging these things from happening. In fact, the act of working on things daily will put you in a much better position for these small miracles to happen.

However, you need know your limits. By working on the 1212 process, I think I found mine.

I created a web chat app in a week: my fastest Rails project yet

A pixel art image of a sunset, with mountains and buildings

I gave myself a goal: one week, one Rails project. And that I did. This one is called Evenfall. It is a real time chat application where people can make rooms and type back and forth. Is it reinventing the wheel? Yep. Is it going to make a splash? Nope. Did I learn a lot? Yep. As you’ll see, the biggest challenges did not come from the networking part of the chat, but rather making it not annoying to use.

This project started on July 23rd 2025 and ended July 30th.

Some context

Evenfall is part of a series of projects called the 1212 learning process. For this I am learning Ruby on Rails in an attempt to get past my nasty habit of overthinking everything and instead just get stuff done. You all know that over-thinker. You might even be one of them.

Anyway, to give a high level overview, here are my projects I completed as part of the process:

✅ Complete a project within 1 month (Bloggington) (~60 hours of focused work)
✅ Complete another project within 2 weeks (Phasmid) (~50 hours of focused work)
Complete another within 1 week (This project, Evenfall) (~33 hours of focused work)
🚧 Complete a final project within 2 days

For those who want to see the repository as it was after just the 7 days, refer to the legacy branch of the repository.

The end result

This is a quick 1 minute demo on creating a chat room and doing some simple back and forth chatting. I use two separate browsers on two separate accounts to simulate the interaction.

How it went

Day 0 – Strong start

I did the usual day 0 things. Got the Github repository up. Ran the convenience scripts to get things like authentication, ActionText, and the models in order. The database schema was simple this time, and I did my fair share of wrangling models during Phasmid, so it was easy to get a working database skeleton working in short order.

Day 1 – Plot twist

I got real time messaging working. This is huge news given how early it is in the project. I do want to elaborate on this a bit, as it is kind of the core gimmick of the whole project, and yet said gimmick was complete in 2 days.

How was this done so quickly?

This was done using ActionCable. This comes with Rails and makes it incredibly easy to incorporate real time updates pretty much whenever your business logic wants to. I will admit, I did use ActionCable when writing Phasmid so that contributed to my headstart.

Real-time messaging works in 3 major stages

  1. A message model instance is created
  2. A broadcast is triggered, sending the message’s HTML contents to a subscription
  3. The room that has the subscription receives it, and displays it in real time.

Here is the entire Message model in my project (edited slightly for formatting):

message.rb

class Message < ApplicationRecord
  belongs_to :user
  belongs_to :room
  has_rich_text :content

  after_create_commit -> { 
    broadcast_append_to "room_messages_sub_#{self.room.id}",
    partial: "messages/message",
    locals: {
      room: room,
      message: self
    }, 
    target: "messages"
  }
end

The important part is after_create_commit, which essentially does the following:

  • After a Message instance is created (AKA anybody sends a message), send a broadcast to all subscriptions associated with this message’s Room. For the purposes of this project, only one subscription exists which I will mention shortly.
  • partial refers to an HTML “chunk” which will be appended to a target called "messages". The target refers to the id of a div that is located in the chat room.
  • locals passes along the information to be used when appending the message data to the target div.

A moment ago, I mentioned a subscription that will receive the broadcast. This is where the subscription exists:

_messages.html.erb

<%= turbo_stream_from "room_messages_sub_#{room.id}" %>
<div id="messages" data-controller="messages" data-messages-target="messages">
    <%= render "layouts/flash" %>
    <p>--- This is the beginning of the chat ---</p>
    <% messages.each do |message| %>
        <%= render "messages/message", message: message, room: room %>
    <% end %>
</div>

The important part is the beginning, where we define the turbo_stream_from with the same name "room_messages_sub_#{room.id}" that is referred to in the broadcast_append_to line in message.rb. The second important part is the <div id="messages" ...> portion as this defines where the broadcast needs to append to (i.e. the target).

And for reference, this is the partial being broadcast, the HTML “chunk” as it were:

_message.html.erb

<div id=<%= combined_dom_id(room, message) %> class="room_message">
    <span><b><%= message.user.username %>:</b></span>
    <%= message.content %>
    <br>
</div>

I want to note that ActionCable is not perfect. If you are not actively looking at your tab, it’s easy to miss messages when you come back to it. While this can be fixed by refreshing, that’s obviously not very cash money of the application.

There are ways to improve this, such as setting something up to queue messages for you. Or perhaps you can use AnyCable, which is apparently a drop-in replacement of ActionCable with more stability/features. That said, I accepted the limitations of ActionCable in the meantime for the sake of moving my project along and not getting bogged down in trying to get an external library to work.

Day 2 – Making stuff look nice

This day was pretty run of the mill. A bit of HTML/CSS formatting to make things look neater.

Day 3 – Mobile, navbar, and early chat interaction logic

More stuff like day 3, as well as making the site look better on mobile. I made a navbar and edited chat rooms so that they will auto-submit when pressing enter. Chat room interactions start out simple, but the next day will show me that to get them precise is a different story.

Day 4 – Chat rooms are hard

So I did the thing where I underestimated the complexity of handling the intricacies of a chat room. Here is the layout of the chat room:

A chart showing a chat box with a submission form under it. The scroll bar is pointed out.

Here are the problems I had while making the chat room usable:

Scrollable elements in HTML start at the top and not at the bottom

This means that to show the latest messages, I have to auto-scroll the scrollbar to the bottom when the user enters the room. This was the easiest of the issues to solve.

When a user sends or receives a message, the scrollbar does not adjust

If the chat box has a new message, the position of the scroll bar stays the same. The message is “hidden” until the user scrolls down. This is of course really bad user experience.

Now, this could be solved by auto-scrolling to the bottom when any message is entered into chat. This creates a new problem though. If you’re looking through the chat history, you will get rudely interrupted every time someone in the chat posts a message. I could have invested time in a fancy thing that notifies you of new messages at the bottom, but the whole 1-week deadline said “no sir you’re keeping it simple.”

As a result, my simple solution was this: if your scroll bar is low enough in the container when any message comes in, then it will auto scroll down. This “low enough” value was definitely based on vibes. I settled at 200 pixels. This was eventually done on day 7.

Pressing return on the message editor does not send messages

This is an understandable problem. The Trix editor has no business auto-submitting forms when pressing return for a multitude of reasons. However, my app certainly has that kind of business. Fast paced messaging is the name of the game.

But of course, we still want people to be able to create newlines. As a result, I needed to account for shift + enter.

It all needed to work on mobile

I made it a point to try and make this site mobile compatible. So all of the problems above needed to be solved for mobile too. Most solutions transferred over, but pressing return was the only way for someone to realistically create a newline on mobile, so I had to code a workaround for that on day 7.

Time to learn Stimulus

I realized that regular Javascript inside of the HTML was not going to cut it, especially when you have stuff constantly changing around in a chat room. Using Stimulus controllers made it far easier to keep track of the state of the page, and act upon those changes.

I don’t like how my controllers came out, and as a result I will not be going into too much detail about them in this post. The good news is I think the next time I write a stimulus controller, it will be far more organized. And perhaps more worthy of writing about.

Day 5 – Centering some divs

I spent the session centering the forms so they look good on desktop and mobile. You heard that right gamers, I centered some divs.

Day 6 – UX improvements

I made the login/register forms a bit more informative if the application has any issues with form submissions. like mismatching passwords and cases where username/email are already taken.

Oh I also added the favicon.ico

A small icon depicting a road going into a sunset

Day 7 – Cleanup

A lot of this was a continuation of Day 4: Chat rooms are hard. I got around to fix the remaining issues I ran into that day. The rest of the time was spent cleaning up formatting, applying max character restrictions on forms/models, and stopping the chat box from taking any drag-and-drop files other than images.

The numbers and conclusions

ProjectTime WindowHours Worked% of Total Time
Bloggington1 month (~730 hrs)~60 hrs8.2%
Phasmid2 weeks (~336 hrs)~50 hrs14.8%
Evenfall1 week (~168 hrs)~33 hrs19.6%
Project 42 days (~48 hours)TBDTBD

The time spent on Evenfall was past my initial expectation of about 25 hours, which instead landed at about 33 hours.

Interestingly, even though I spent a considerable amount of time during the week, I didn’t burn myself out. There was plenty of time for me to do other things most evenings like gaming or going out. Having a remote job also helps.

Given my practice on the first two projects, it is reasonable to say I was able to do just a little more in less time. Plus, I’ve found it’s more enjoyable to code using Rails now that I’m getting the hang of things. Great news overall.

The two day project will be coming soon. It will need to be on a weekend where I don’t have much plans, so it may be some time. But it will happen, and it will be the toughest challenge yet. My projects sequentially halved my available time. This final one is the outlier, cutting my time by more than half. I described it as such in my initial post about the 1212 process:

“Project 4: The Crucible (2 days): Your ability to very quickly get something out the door will be forcibly squeezed out of you. The shortest path to success is the only path.”

Time for The Crucible. Stay tuned.

I created a Rails web app in two weeks: what I learned and what I will bring into my upcoming one week project

In my last post, I created a web application in one month as part of a series of Ruby on Rails projects designed to increase my speed of output for software prototypes. I halved the available time to two weeks with this most recent project, Phasmid. As of Monday, July 14th, Phasmid is complete and now I can say I’m officially halfway done with my goal of making four Rails projects.

Progress on the 1212 train

✅ Complete a project within 1 month (Bloggington) (~60 hours of focused work)
✅ Complete another project within 2 weeks (Phasmid) (~50 hours of focused work)
🚧Complete another within 1 week (Start day TBD)
🚧Complete a final project within 2 days (Start day TBD)

The grand goal at the end of this four-project process is to be more comfortable publicly shipping Rails web apps without the worry of burning myself out from lack of technical skill.

So what is Phasmid?

Phasmid is a simple bug tracking application. To be clear, it is a blatant reinvention of the wheel and is not meant to help anyone but myself. The features are as follows:

  • Users can create projects which have sets of bugs
  • Each project has a pool of tags that can be attached to bugs
  • Tags have a weight value, and bugs can have any number of tags
  • The multiplied weight of all tags attached to a bug determines the bug’s score
  • A higher bug score indicates a more concerning bug with (ideally) a higher priority

Having completed the one-month project, I went into Phasmid with valuable knowledge. I found that I was writing out code snippets before having to reference online sources for clarification on syntax and function parameters. Sure, it still took me some time to figure things out. However, the burden of learning the fundamentals was considerably lighter this time around; this gave me more bandwidth to learn new things.

As a side note, I shared this project with my public discord server. It was great to have others test it in a call and get real feedback!

Here is a simple demo video where I click around a bit. Note, there is no sound.

How it all went

Making the database

Starting out, I had issues wiring together relationships using join tables. I suspect that database wrangling will be easier next time, especially since I can use Phasmid as reference when I work on my next project. Part of my issue was generating scaffolds for models without considering that some models would be nested under each other. This led to a bunch of backtracking before I got things right where they needed to be.

The teeny smidge of testing

All good software should be released out the gate with testing. While I had a feeling I would not have time for a full test suite, I did want to get system tests running. After some messing around with my WSL instance, I was able to get it working. I made a simple system test where a project is created and then it asserts that the project was indeed created. It’s not much, but at least now I have a starting point when I test more in the future.

Freedom to format

I spent a decent amount of time writing the HTML and CSS of the web app. It was surprisingly fun and I felt far more in control of how things fell into place than how I did with Bloggington. I got my hands dirty with designing the web page using a simple grid system and a custom color palette.

When I was in the weeds of the last stretch, being able to work on something a tad more straightforward like HTML/CSS had huge returns on morale. It felt great to have a web app that had its own style and did not look like a complete disaster.

The wonderfully dense hour

On July 4th I saw the greatest evidence of my improvement. In the course of an hour, I implemented two features which took me multiple days to figure out the first time around with Bloggington. This was a huge win, and represented a speed boost by an order of magnitude. For the curious, it was these two commits (1, 2). They both involve real time updates on form submissions using Turbo and Action Cable.

The last stretch

It’s crazy how wide the gap gets between the size of a to-do list and your true velocity. This became readily apparent towards the end. There were also times where I was not sure what the priority should be.

I tried to deal with the difficulty through this lens: if there were an audience of just me, what would that audience want that would help the most with bug tracking? Even as myself, it was hard to know what I wanted. It turned out I had no idea what I wanted other than “thing that tracks bugs.” This does give me a little bit of a peek into what building for a customer would be like.

My takeaway was this: get a solid core out there and don’t worry about the rest. Remember, people don’t know and don’t care about what features were cut in your first iteration.

Cut features

Memberships

My original goal was to have users be members of projects with specific sets of permissions. The database had the pieces in place for it, but I never got around to it.

Instead, people can see all projects/bugs but can only edit things they own. If this was being monetized, people may not even want that if it became a platform that was more focused on transparency. In that case, not having done it may have been better. You can always adjust later if the opposite is true.

Fancy flash messages using Stimulus

When things were created, deleted, or something failed, I wanted a fancy bubble to show up describing said things. Sadly, that also did not make it. It was more of a nice-to-have, and I settled for the default Rails way of logging flash messages on the screen, a good ol’ paragraph tag.

Improved UI

The UI is vastly improved compared to Bloggington. For example:

Bloggington

The cats at least redeem this image.

Phasmid

Yes, Bloggington is listed in Phasmid as a project with bugs in it. It is quite fitting indeed. I heard Bloggington had a bug or two.

Room for improvement

Next time, I want to build with a mobile-first approach. Phasmid is a bit awkward on mobile, though it is still reasonably usable. I also want to make sure that the web app works just as well without any of the fancy Hotwire SPA-like features.

Findings

So what did I learn? In 2 weeks, I can construct a project that at least resembles something useful. I picked up these topics while making Phasmid:

  • Action Cable and redis
  • Getting system tests to run with WSL
  • Grid layout basics
  • Adding a new font
  • Simple time zones
  • CSS

That’s 6 things I didn’t know much about in my first project.

Expectations for the one-week project

While I improved my input by roughly 10 hours during the 2-week project, my available time is going to be cut in half. To give some perspective:

ProjectTime WindowHours Worked% of Total Time
Bloggington1 month (~730 hrs)~60 hrs8.2%
Phasmid2 weeks (~336 hrs)~50 hrs14.8%
Project 31 week (~168 hrs)TBD, but ideally 25 hrsTBD, but ideally 14.8%

Even if my efficiency improves where it takes 10 fewer hours to get the same output as I did with Phasmid, I would still need 40 hours in theory. And I’m not going to have those hours. 25 hours is 3.5 hours every day of the week if I want to at least maintain same the ratio from Phasmid.

Whatever my next project is, it will need to be incredibly laser focused if I want to make something of value. I have some ideas.

Project 3 is where real challenge begins.

The 1212 learning process

Without any ado, I’m going to discuss a new theoretical method, the 1212 learning process. The process is simple. Trying to learn new a new software stack quickly? Do four projects, each of which are your own choosing. They will be ugly, they will be painfully unoriginal, and they will be wonderful little troves of knowledge. You will spend decreasing amounts of time on each project:

  • 1 month on the first project
  • 2 weeks on the second project
  • 1 week on the third project
  • 2 days on the final project

These projects will most likely not see the light of day, but you will learn a bunch of things. They will also be distinct projects from one-another to encourage variety in your day-to-day problem solving.

Project 1: The Warm-Up (1 month)

This gives plenty of time to trip over yourself constantly at the beginning and not feel the immediate doom of a close deadline. Every mistake can be seen as a learning experience, and the time spent on hitches will be a smaller percentage of the total time you have.

Project 2: The Build-Up (2 weeks)

By this point, the small things should be easier to navigate around. More significant steps need to be made per day but there is still a bit of time to iron out any unexpected issues. It is possible that some polish may be foregone.

Project 3: The Refinement (1 week)

Efficiency combined with consistency will be paramount here. Some simple workflows may be second nature at this point, but now things are more serious. A bad enough setback could put you behind, but your skills from the previous two projects will help to understand the intricacies and work around the issues.

Project 4: The Crucible (2 days)

Your ability to very quickly get something out the door will be forcibly squeezed out of you. The shortest path to success is the only path.

What this is, and what this isn’t

This process flushes out the bad projects you will inevitably make when taking on a new tech stack. By setting progressively shorter deadlines, you’re pushing yourself to move. We want to see through the things that don’t matter and get to the core of what we want to get out of the door.

This process does not intend to produce any software of value. While happy accidents are always a nice possibility, they are not the intention.

Some last things

So you might be wondering, does this process actually work? No clue; I just made it up. The good news is that I’m currently working on my 1-month project, so I am on my way to understanding the viability of the approach.

The project is an aggressively simple one, create a simple blogging application using Ruby on Rails. It needs to be a straightforward, possibly ugly, but functional MVP. In theory, it would be something I’d use if I wanted to sell to the totally-niche subgroup who desperately needs yet another blogging software. My hard deadline is June 15th.

For the ultra curious, the project is available to look at on Github. At the time of writing, lots of stuff is (justifiably) missing, but stay tuned for progress on future posts!

Yes to all

radio room

They say one of the best things you can do is say yes to all kinds of plans. I’ve been doing that for the past month recently and my results say… yes you should. For the most part. But definitely not all the time.

To give some context, I spent the past week and change visiting family and doing the things that comes with visiting family. In that time frame, I had two interviews, a Python code jam to work on (with a video I made for the team’s presentation), and my personal projects.

It was absolutely one of the most productive and fun weeks I’ve had in a good while. That being said, it came at the cost of saying no to a few things in the process because I was just so incredibly busy, whether with code or with enjoying family time. That’s when began to I understand the limits of saying yes to everything, and these limits are not necessarily bad.

The way I see it, you’re going to be saying no to plans regardless of the approach you take. If you’re someone who typically says no to new things, you are denying yourself life experience. If you say yes to everything till you’re full, then saying no to things feels bad, but it’s because you’ve been saying yes to everything else. And that’s good.

That all being said, it’s easy to take the approach of saying yes to everything and then realizing it isn’t physically possible to follow up on all the things because of poor planning. Yeah, try not to be That Guy. I was pretty good at not being That Guy but sometimes certain things slipped through, whether through poor planning or other reasons. That’s part of the learning process though. How much can you handle at once? It’s hard to say ’till you try.

One thing that’s hugely important too, is to occasionally take a break from saying yes to everything. Reflect on it. What yeses did you enjoy? Which ones weren’t worth it? That’s where I am now, and that’s also why I have the time now to write this post.

So in return for a late (by my standards) post, you get some wisdom in addition to the reason for the lateness! We call that a win I think.

That’s about it anyhow. Thanks for reading!

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.

Starting a blog

This is my first post and a test to see how this website framework works. So far it’s been pretty neat with only a few snags here and there. I’ve been working on learning Rust and making games with the Bevy framework. It’s actually been a nice experience and I’m hoping to stick to a 1-game-a-month schedule. March is looking pretty good with a game I’m making that was originally supposed to be about *avoiding* bad guys but I could not resist adding a mechanic to also *destroy* the bad guys.

Currently, the annihilation works a little too efficiently and deletes the bad guys from existence with no trace of their previous existence. I’m working on trying to get an explosion sprite sheet I made to show an explosion occur when an enemy gets killed. Turns out it’s harder than I thought, due to my lack of knowledge in handling game assets in general. For the curious, here is the Github repository.

I’ve also been learning pixel art with Aseprite as a side-effort to at least come up with my own sprites for my games. I don’t expect to be good at it any time soon but that’s okay. It’s another avenue of creation if I don’t feel like coding.

Anyway, that’s all I got for now. This site may undergo lots of changes cosmetically and functionally, but for now it seems to work. Once I have a better workflow, I can hopefully start working on more in-depth and interesting blog posts. And with that, I am going to test out code blocks by writing the following:

fn main () {
    println!("Have an Awesome Day!")
}