I've been playing Minecraft for a while and after doing some travelling, I've
ran into the issue where I'd like to syncronize my Minecraft saves across
computers.
I already use git for software version control, so why not shoehorn Minecraft
into it? Not only would I get easy syncronization, I would also get version
control so if I seriously mung something up, I can revert back to a previous
save! Here's how I did it.
First, I had to make sure git was installed on all of my machines. Luckily
on Linux git is usually provided in the package repository (git-core), but
since my desktop also runs Windows (for gaming), I use
msysgit. For example,
on Debian/Ubuntu all you need to do is:
sudo apt-get install git-core
Once git was installed, I decided to go with a centralized approach since I
want one 'official' spot where I can push and pull my Mincraft saves to.
I already have a server
from the wonderful folks at Linode, so I just
initialized a bare (centralized) repository on there:
cd /path/to/repos/minecraft
git init --bare
Then, since I already have Minecraft installed on my desktop with quite a few
saves, I had to clone the central repository, add my saves, commit, and then
push back to the central repository.
cd /home/nick/.minecraft/
git clone nick@nickpegg.com:/path/to/repos/minecraft temp
mv temp/.git ./
Since you can't clone a repository into a non-empty folder, I had to clone it
to a temporary folder and then copy the .git folder from there into my
.minecraft folder. Now that my local repository was setup, I added the files
I wanted to syncronize.
Once I had the files commited, all I needed to do was push them up to the
central repository on my server.
git push
And now I have my Minecraft files in a central spot! Now every time I'm done
playing a bit, all I have to do to sync my files up is:
git commit -a -m 'Played a bit'
git push
Now, on other machines, all I need to do is clone once, git pull
before playing,
and then commit and push when I'm done playing!
Easy peasy. Of course, you can do more fancy things with git since it's a
full-blown version control system. If you feel inlined to play with those
features, go read some documentation.
Yes, it's that time of year. Time to change my website design
yet again!
I got tired of dealing with Wordpress and wrote my own static page generator
in Python, dubbed Posty. I know, I'm
kind of re-inventing the wheel here and there
are some really nice solutions to
this problem, but why not just make something for making's sake?
Plus, I just feel cool using Markdown and YAML to update my website.
I've been struggling getting my work phone number verified with Google Voice. The way that number verification works is that Google Voice calls you and asks
you to enter the two-digit code that's displayed on the website. But for some reason when I get a call on my outside line and I press a number button, it
doesn't send that DTMF tone. Instead it tries to place another call.
My solution? I found a DTMF tone generator online and I played the code DTMF tones through my computer speakers.
It's nice to see that these old phone tricks still work.
Those of you who know me fairly well know that I'm a total HTPC
geek. It's to the point where I outright refuse to subscribe to cable television
or even hook up an antenna to my TV. This geekery combined with my affinity
for Linux leads me to running XBMC on Linux on my little home theater machine.
It's been a pretty smooth experience with the exception of getting my remote
work with it. If you're struggling with it too, hopefully my tales will help you
get it going.
So, here's my setup. I've got an Antec Fusion 430 (a silver one
with the VFD), a Logitech Harmony remote, and Ubuntu 10.04. The Antec case is
pretty cool since it looks like it belongs
in my home theater setup, and it
even includes an IR receiver built right into the case! Cool! It should accept
signals from any IR remote, right?
Wrong
In the hardware developer's infinite
wisdom, they made it only work with Windows Media Center remotes instead of just
making it a dumb device that passes data along. They actually put
more effort
into designing the thing just to make my life harder. Augh! Luckily, when I got
this case my then-roommate had an Xbox 360 remote which
magically
worked! So I eventually got a Logitech Harmony remote and told it
that my HTPC was actually an Xbox 360. Step one complete.
The next step was
to get LIRC to accept the remote. This is a bit tricky, but luckily I had backed
up my configs. If you're starting out from scratch, here's how to do it in an
Ubuntu system.
First of all, you need to install LIRC:
sudo aptitude
install lirc
During the configuration phase of the install, it'll ask you for
what kind of device you have. I selected Soundgraph iMON PAD IR/VFD, which uses
the lircimon driver. Unfortunately, since I have the silver Antec Fusion
430 I have the VFD and not the LCD display, which has a slightly different IR
receiver. You have to specify the displaytype=1 when the module is loaded.
You can do this by adding a file called lirc-imon.conf to /etc/modprobe.d/ with
these contents.
If you don't want to restart, you'll have to throw commands at the system to reload
the module with the correct options.
While you have LIRC stopped, you might as well double-check that the IR receiver is
actually receiving data with the following command (hit Ctrl-C to stop):
sudo cat /dev/lirc0
You should see a bunch of garbage get printed to
the terminal when you press buttons on your remote. If you don't, then either
you have the wrong type of remote or you don't need the
display_type argument to modprobe.
Next, you need to setup the button config for your remote. Since
I'm using a Logitech Harmony remote to emulate an Xbox 360 remote, I used the
irrecord command to generate my config.
Luckily there's plenty of people out there
who have already done this for you for a large amount of remotes
(here's a good list, for example).
Once you have the remote config file downloaded or created,
add an include to your lircd.conf
for it, fire up LIRC, and test it out with the irw command.
sudo service
lirc start
irw
When you press buttons, you should see the button commands
scroll by in the terminal.
*whew* Almost there. Still with me? Good, because
we only have one thing left, the XBMC Lircmap.xml file! I'll spare you the nitty-girtty
of it and just give you
mine (right-click
and save it). If you feel like making your own or need to tweak mine a bit, the
XBMC wiki has some
good information
on how to do it.
For the impatient, here's all of my files associated with getting this to work:
It was the Friday before my Spring Break and quite possibly the worst thing in the world happened to me: I got rear-ended while at a stop.
Well, okay, it's not the worst thing in the world but to a college student who loves his car, it was pretty bad. The lady who hit me did quite a
number on my back end, and then pushed me into the car in front of me. Despite my airbags not going off, my car was totaled. The damage to the bumper,
right rear quarter panel, and unibody frame were just too much.
With the Jetta totaled I had three options: Buy it back and spend the $1000 left over on repairs/hookers, give it away to the insurance company and
spend <$2400 on a beater from Craigslist, or do the financially irresponsible thing and buy the new car I've been dreaming of, going into debt even
further than I already was.
Guess which option I chose:
Yes, that's right. I bought myself a new MkVI GTI. Since I had some money saved up from my recent internship, will be starting work in a couple of months,
and was planning on buying one within a year I decided to go for it. I ended up paying $22,500 for it, which is a few hundred below dealer invoice for the
options that I wanted on it. I won't go into any car buying tips here, I'll save that for another post.
Overall, I'm very pleased with my purchase. Here's why:
Performance: It's got the VW 2.0L TSI turbocharged engine in it which puts out 200 hp. That's only a little more than my old VR6 Jetta, but the lighter
engine makes a difference. I'm still breaking the engine in, but from what I can tell from accidentally giving too much gas, it can put down some power.
Handling: With the sport-tuned suspension, this thing handles like a beast. With simply taking corners quickly and turning smoothly, I have yet to break
the tires loose from the road. There's also a roundabout here in Rolla which I took at speeds that I'm not at liberty to discuss publicly since I'm sure that
the city police would frown upon that.
The car also has a pseudo-locking differential called XDS. This is part of the electronic stability control system. What XDS does is when it senses that one
wheel is getting too much power compared to the other, it applies the brakes to that first wheel to slow it down, giving more power to the second wheel. I
haven't noticed this kick in yet, but probably because I'm not giving it full throttle due to the break-in period
Electronics: Included standard on the car is a touchscreen radio with Volkswagen's MDI interface. The MDI interface provides a port in the arm rest where
different devices can be plugged in, such as an iPod or USB drive. With the addition of an SD card slot right in the radio, with support up to 32 GB, I no
longer need a car computer. The software can be a little flaky at times and could use certain features (like creating an on-the-go playlist), but it suits my needs fine.
Also included is the MFI, which is essentially a trip computer. It tells you trip time, distance, fuel consumption, range left on the tank of gas, etc. The cool
part about this is that in the settings menu, you can adjust some convenience settings which normally could only be done using a VAG-COM, such as which doors
unlock when you use the keyfob, rolling windows down with the key, etc.
Practicality: The folks on Top Gear always talk about the practicality of a car whenever they review something the average person could buy. Since I'm not
going through a mid-life crisis, something practical is what I need. The GTI fits this bill nicely.
There's plenty of room for passengers in the back (a change VW made starting with the MkV) along with all of the creature comforts you would expect from sitting
in the front. There's also a good amount of space in the hatch area, and the back seats fold down in case I need to haul anything big. I was able to fit a whole
recliner in the back with room to spare, for example.
All in all, I really love this car. It's quick, fun to drive, can get good gas mileage, and it's still useful for when I need it.
I've been having an insane time trying to squash a weird unicode bug in
Beertraq. This was one of the first bugs that was found after starting the beta
and it's taken me this long to get it worked out. It all started with
a cryptic-seeming error upon viewing the add-a-beer page:
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-9:
ordinal not in range(128)
Real descriptive, right? Looking through the stack trace wasn't much
help either. It was a bunch of stuff pertaining to trying to render the
template. One thing I did notice is that a brewer with a unicode name had
recently gotten added and this error was only happening on the new beer form
(which includes a ChoiceField of brewers), but the brewer was being displayed
just fine on its own page.
After asking my friend and fellow Django-user Dan-o what he thought, he asked
if I had str() and unicode() defined in my models. I had str()
defined (generally a good idea) but not unicode(). I popped it in to my
Brewer model as so:
class Brewer(models.Model):
TYPE_CHOICES = (
('Macrobrewer', 'Macrobrewer'),
('Microbrewer', 'Microbrewer/Craft brewer'),
('Homebrewer', 'Homebrewer'),
('Unknown', 'Unknown'),
)
name = models.CharField("Brewer name", max_length=255)
brewer_type = models.CharField("Type of brewer", max_length=25, choices=TYPE_CHOICES)
city = models.CharField("Brewer's city", max_length=255, blank=True)
approved = models.BooleanField(default=False)
def __str__(self):
return self.name
def __unicode__(self):
return self.name
class Meta:
ordering = ['name']
And guess what? My problems went away. I feel like an idiot for being foiled by
something so simple that I overlooked. It makes sense too because str() is used
quite a bit in forms where the model instance's name needs to be magically
generated. Without unicode() it would cause Django to barf on unicode names,
just like it did on me.
Let this be a lesson to you. If you might EVER have ANY unicode text in your
model instance's names, for crap's sake define _unicode_()!
If you know me personally, you know that I can be pretty scatterbrained from
time to time. I've desperately needed a whiteboard to keep my thoughts
organized, and I've finally gotten one. I know, it's not the
most exciting thing in the world to talk about, but it should be a change
in the right direction for me.
But, wait. What's this? "Beertraq Road to Stable"?
Part of why I want to get my thoughts organized is because I want a good
view of what all is left before I fully release Beertraq to the public.
With this list looming over my head (literally) it will hopefully get my
butt in gear to reach a stable release.
I don't cook/bake all that often, but when I do I like to have some fun
with it. I came up with a ham recipe that turned out well, so I figured
I'd share it with everyone.
First, put your ham in a baking pan and cut the diamond pattern into it. Trust
Alton Brown when he says that utility knives work well for this. Then, mix the
following in a bowl
1 cup brown sugar
1/2 teaspoon ground mustard
4 ounces of fine bourbon. My preference is Maker's Mark.
Once you have that all mixed up, pack it gently onto the ham. Uniformity is nice,
but not required. Then cook the ham at 325 degrees Fahrenheit until the inside
meat temperature reaches 150 degrees (about 3 hours with a 20 pound ham). I
guarantee that it'll be tasty when it's done.