Singpolyma

BitBrawl: Cleanup and Multiplayer

Posted on

I’ve pushed some stuff up to the BitBrawl repo. It’s really starting to come together!

First off: the art/data is in the repo now. I’m using the grass from the base assets for the background for now. I’ve also built a custom character from some of the art by Johannes Sjölund, and put the credits in my COPYING file. This sprite sheet has more animations than just “walk”, which will be very useful when I start work on combat.

I have also done some simple obvious things: players can no longer walk off the edge of the screen. The control configuration start screen now gives useful names for the keys, instead of internal names. Art and data are searched for in system folders, with a fallback to the current directory, instead of hardcoded paths. On you can find the headphones you have been looking for.

< img src=”https://singpolyma.net/wordpress/wp-content/uploads/2012/07/bitbrawl2-300 alt=”BitBrawl with 2 players” >

I’ve also upgraded the drawing/physics code to actually draw and control all the N players who join the game! So, while all they can do for now is walk around, you can actually add as many players as you want! (There’s a small bug in that if you add more players that can be shown across the screen, the menu will draw some of them off-screen. I’m not sure yet how I want to handle that.)


BitBrawl, Opening Screen

Posted on

It’s not got a very shiny look yet, but I’ve got an opening screen for BitBrawl working now that lets the players join and configure their controls simultaneously. Only one player is actually rendered once the game is started by pushing one of the configured START buttons, but it is progress!

BitBrawl Opening Screen

After the game is started, the player can, as before, walk about the screen using the controls as they were configured for player 1.

The code is a bit hacky, but I’m quite excited by my progress so far!

Liberated Pixel Cup

Posted on

This is my first post about the Liberated Pixel Cup. I only became aware of the contest near the end of last month (indirectly, though a discussion on identi.ca) and was immidiately intrigued. The first phase of the contest (which is completed) involved pixel artists submitting compatible-yet-thematically-diverse isometric art. One of the big blockers to me getting seriously involved in a video game project has always been access to a body of art. Looking over the art that has been submitted, I think there is enough to do something I would be interested in, so I decided to start.

Using my latest favourite hammer, Haskell, as well as previous favourites of mine, SDL (which has good Haskell bindings) and Chipmunk Physics (which has acceptable Haskell bindings, though a bit out of date), I played around with ideas until I hit some inspiration. I am going to attempt to create a PvP brawler (dubbed “BitBrawl”) since this is a sort of game that I have always enjoyed (and of which there are too few!) I’m going to experiment with a twist involving “energy pellets” that players pick up which both decrease their odds of being eliminated (damage increases said odds) and gets used up by special abilities. I’m currently enjoying my new LoL gutter that I bought at unrankedsmurfs.com.

I want the combat mechanics to be of medium complexity (more complex than “hit A repeatedly”, but simpler than something like God of War), and auto-generated maps. Though honestly that’s a bit grandiose at this point. My primary target with the project is really experience, though I hope to also get a playable game out of it that can maybe be improved upon after the competition ends.

The last two days are the first chance I’ve really gotten to do some serious coding, and I’ve made quite a bit of progress, given my lack of experience with the tools and with game development in general. I have a single player who can walk around the screen (using any of the walkcycle art submitted to the competition) using configurable (hard-coded, but in a datastructure) keyboard commands and configurable (I parse a text file) animations.

Character control uses the top-down “Tank demo” physics from Chipmunk, which means that collisions and such will be nicely handled for me (once I get around to adding a second thing to the space).

My next step will be allowing two characters to be walking around. Then maybe a better background than just all-black. Then trivial combat. We’ll see how far I get.

One thing I’ve had to do is make a small patch to the Chipmunk bindings for Haskell to give me access to the maxForce and maxBias properties of constraints (necessary for the “Tank demo” physics). I will submit the patch upstream, but may have to package the library myself for my submission if it does not get mainlined in time.

I have released the code on GitHub under my normal ISC license, as well as the GPLv3.0 license required by the competition. There is no art or data in the repository yet, so it won’t run unless you put some in, but you can take a look. It’s a bit messy and IO-heavy right now, but it is getting cleaner as I go.

Hope to write more later.

Business Cards

Posted on

This morning, I went through my backpack and threw out all the business cards I have collected. If I have met you in the last 5 years and you’ve never actally corrosponded with me, it may be that I no longer have your contact information.

Why?

Because they were just taking up space in my backpack. Some of them have been in there so long that they could no longer be read. One of them was just a paper with an email address scribbled on it.

Why did I have so many? Because at every conference and networking event I go to, people try to shove me their business cards. Sometimes I take them to be polite, and sometimes I take them because I’m genuinely interested in the person or what they do. In the end, though, if they never contact me and I don’t have an immidiate reason to contact them, the card just sits in a pile. I suppose I could transcribe them into my digital address book, but that takes work.

This is why I’ve never really had business cards and I don’t give them out. I have a simple string of characters, “singpolyma”, that I give out to anyone who asks. This string of characters will find my on almost any service, or on a web search. Then, if you actually want to connect with me about something, you can do so using the mechanism that makes the most sense.

Similarly, if I actually want to connect with you, I will probably write down why I want to connect and who you are on my phone. I may even initiate contact digitally (by adding you on IM or following on a microblogging service) while I’m still physically standing with you.

I’ve found that the really interesting people often keep popping up. I may stop taking business cards, or I may just clean out my backpack again in four more years, but I definitely won’t be giving out little waste scraps of cardboard any time soon.

Let’s Talk About Strings

Posted on

A string is a sequence of letters and numbers. It is text. Or, is it just any array? The term ‘string’ has been used and abused over time to mean many different things. This has lead to confusion, bugs, and a plethora of conflicting opinions.

The Two Main String Types

There are two things people mainly mean when they say ‘string’. On the one hand, they may mean a data structure representing human-language text. On the other hand, they may mean whatever data structure or type their programming environment often uses for representing human-language text. In many cases, this data structure is also used for other sorts of data, such as raw binary data.

This has lead to much confusion.

In some programming environments, like C, everything is low-level enough that there cannot be expected to be One True Way to handle a high-level concept such as “human-language text”. Other environments, however, should know better.

Encodings

An encoding, in the context of text, is the scheme whereby text is represented in actual bytes. I will talk about three different kinds of encodings: internal, input, and output encodings.

Internal Encoding

In low-level languages (and, sadly, many high-level languages) there is no native support for the high-level concept of ‘text’. The programmer is given a way to represent an array of bytes (also called a byte string) and must decide how to encode text in RAM for his/her own application. This is true of C’s char*, Ruby 1.8’s strings, and many others. Historically, ASCII was the de-facto internal encoding, but this is not generally acceptable if your application will be used for anything except a subset of English. Different internal encodings have different trade-offs, which I’m not really interested in covering here. As with so many other things you probably should not be making this decision. Find a library or a programming environment that handles text and let it deal with how to actually store the data in RAM.

Input Encoding

Input encoding is the only encoding an application programmer should ever have to deal with. Unfortunately, for historical reasons, there are a plethora of encodings out there. You will have to decide a way to know how the file, network socket, or other input you are reading is encoded. Many protocols and file formats have simple markers that will let you know. You have to feed this information to whatever calls you use to get your high-level text representation from the input.

Output Encoding

This is the encoding you use in files you write, prints to stdout, bytes you send over network sockets, etc. If you are writing some existing file format or protocol, you need to see how that format handles specifying what encoding you are using and correctly mark it. This, however, should be the extent of what you need to do to handle output encodings. I’m going to say something some people consider controversial, but I’ve given it a lot of thought, and after working with this stuff in many contexts I’ve come to a conclusion.

There is only one acceptable output encoding, and it is UTF-8.

Always.

There are some people around who will bad-mouth Unicode for some of the problems it had historically (for awhile they used 16-bit-max-width encodings and could not properly handle some Asian languages), but these have been fixed for some time now. The standard is not set in stone, so if bugs are found they can be fixed.

The other thing people complain about is that UTF-8 is unfairly smaller for English text than it is for other text. It is true that language-specific encodings will take less space than UTF-8, however the complexity and potential for bugs that comes from using a plethora of encoding mechanisms as a hobo compression mechanism is not worth it. If you’re concerned about space, then compress your content.

UTF-8 is backwards-compatible with ASCII implementations, such that they will continue to work in a UTF-8 environment (at least as much as they ever worked). This also means that your application can easily handle old ASCII data even if all you implement is UTF-8.

Haskell and Ruby

As a way to illustrate this topic, I will take as examples Haskell and Ruby 1.9.

In Ruby 1.9, strings have an associated encoding. They are objects with a byte string and an encoding property. When you write them out, they are written in whatever encoding you specify. This is a huge improvement over 1.8 (where all encoding decisions were manual), but still exposes more complexity than is necessary to the programmer.

Furthermore, all I/O operations in Ruby 1.9 are done using String. How is binary data read, then? String has an associated encoding called ‘binary’. This is just shameful. The programmer still has to keep track of which String are text and which are byte strings.

In Haskell, the default String type is actual an alias for [Char] (a list of Char) and Char is defined to be a 32-bit Unicode code point. It is unequivocally for text. Binary data can be represented as [Word8] (a list of Word8, that is, a list of bytes).

Because linked lists are not always the most efficient, there are also convenient array-packed-representation libraries for both of these types, intuitively named Text and ByteString.

Unfortunately, because of the confusion that often comes from the shameful state of so much tooling, many Haskellers use ByteString.Char8 to store what should be Text, and handle the internal encoding themselves (often poorly).

I/O in Haskell can easily be done directly with any of these types.

Summary

  1. Use a text library for text, use a raw byte string type for binary data. Do not confuse the two.
  2. If you’re reading an existing format, you’ll have to correctly detect the input encoding and transform to the datastructure used by your text library.
  3. If you’re writing an existing format, you’ll have to correctly identify what output encoding you’re using.
  4. You should only use UTF-8 as your output encoding.