Studios, twenty and over. 2014 Edition.

Earlier this year, I compiled a list of game studios that had maintained continuous operation for more than twenty years because … well because it interested me. Here’s an updated list for 2014 (a couple of days early).

Studio history fascinates me — how studios have developed over time, studios with long lists of popular games, or short lists of unpopular ones. Revealing names that have been influential to me as a young gamer and game developer, and places that friends and acquaintances have worked at. Seeing video game development as an industry with significant history (good and bad), and to learn about how we got to where we are. What has endured, and what has not.

There’s a lot that can be learned. Here are links to some of it.

(These lists are assuredly incomplete — let me know what I’ve missed)

Studios, twenty and over in 2014 (60)

Closed studios, twenty and over

(I’ve not made any effort to fill out the above list — contributions welcome)

Other long-running studios closed during 2013

Other game companies (including publishers) like Square Enix (2003)Ubisoft (1986)Capcom (1983)EA (1982)Activision (1979)Taito (1973)Konami (1969)NAMCO (1955), and Nintendo (1889) have been around for more than twenty years, but I don’t know if they have [other] studios that have been running that long.

SN Systems has been making tools for game development since 1988. RAD Game Tools has also been around since 1988.

Updates:
Added Egosoft thanks to @RonPieket
Added Guerrilla Cambridge, SCE Bend Studio, and SCE London Studio thanks to @TobiasBerghoff
Added Ubisoft Paris thanks to @wsmind
Added Atod AB thanks to @martinlindell
Added EA Phenomic (closed 2013) thanks to @JanDavidHassel
Added Ubisoft Bucharest thanks to @kitzkar
Added Traveller’s Tales thanks to @DanOppenheim
Added Llamasoft thanks to @RonPieket
Added Frontier Developments thanks to @tom_forsyth
Added Visual Concepts thanks to Lisa Buechele
Added Image Space Incorporated thanks to Gjon Camaj
Added WayForward Technologies after meeting the CEO John Beck at the USC Fall Demo Day :)

Bug review, 2013-04-10

A fairly quiet two weeks compared to the one before. The main reasons being a week of illness (I find fever and an ability to concentrate to be mutually exclusive :\) and a change in work focus to a time of information gathering and planning for a different project, which has resulted in less opportunity for writing new bugs.

Summary of the weeks

Wednesday 2013-03-27

An optimistic beginning to the new week: no bugs to write about, so I posted a photograph.

Thursday 2013-03-28

An example of using the compiler to help identify particular code patterns that I wanted to eliminate.

Friday 2013-03-29

An actual bug, and worse than a runtime bug: checked-in build breaker. Shameful.

Tuesday 2013-04-02

  • Implicitly finding bugs in other people’s code

Sunday 2013-04-07

Not at all bug related, but a point of curiosity that (thanks to a lot of input from others) turned into a interesting list of studios that have been around for more than twenty years.

Trends

Not a many bugs in the list this time, so doesn’t seem like there’s a lot to say about these two weeks — except that the rate of bugs does go down when you’re not writing any code…

Studios, twenty and over.

[This post is no longer being updated. See this post instead.]

With recent news of studio closures and layoffs, I was curious about the number of game studios that have been running continuously for more than a (fairly arbitrary) twenty years. I put the question on twitter and was able to gather this list:

(Current count: 40)

There are other game companies (including publishers) such as Square Enix (2003)Ubisoft (1986)Capcom (1983)EA (1982)Activision (1979), Taito (1973)Konami (1969), NAMCO (1955), and Nintendo (1889) that have been around for more than twenty years, but I don’t know if they have [other] studios that have been running that long.

What is the significance of a short list of game studios?

A couple of things happened recently that got me thinking:

  1. I watched Hackers. The movie features a scene with footage from a prototype of Wipeout, and the movie credits Sony Psygnosis. Psygnosis was founded in 1984, acquired by SCE in 1993, became Studio Liverpool in 1999, and was closed in 2012. (and plenty of other things — go read the linked article)
  2. LucasArts (Lucasfilm Games), formed in 1982, was closed down.

Were they to be continuing, these two names would appear near the top of the list above. LucasArts was one of the longest running game development studios in existence at the time of its closure, behind only to HAL Laboratory and Falcom.

The closure of a long-lived studio is a significant thing. Foremost, it has a huge impact on the lives of its employees. But it is a loss, I believe, to the industry as a whole.

(I’m not looking to make a judgement about whether LucasArts should have been closed or not. Whatever the reasons for the closure — and I know nothing of them — it has happened.)

The passage of time

There are clearly some benefits to a little bit of age.

Top of my list is experience. The ability to reflect on a long sequence of games — as a team. To learn from that experience, and to try to make better decisions for future ones. Having a group of people who have worked together over an extended period of time, who may not always agree (or who may rarely agree) but who continue in their commitment to working together to make the best games they can make together. The evidence of investment.

Experience making games is one thing. Experience making games with largely the same group of people over many years is another. To know who to ask about a particular ancient system. To know some of the history that has led to otherwise inexplicable artifacts in the technology, tools, and processes of a studio. To have a shared understanding and investment in the company’s accrued building blocks of game development.

And it’s not all shiny pony rainbows — not only good things accrue over time. Investments are made based on decisions that once may have made sense but now may not. Finding agreement and goodwill on all things across any company is nigh impossible. And so there is much effort required to continually move an organization forward.

The list of studios older than twenty years seems pretty short to me, but they’re all evidence of companies that have been able to grow, change, adapt (in some cases shrink), to move forward in response to outside pressures: changes in technology, changes to the market, to distribution models, and more. There is the possibility of endurance within the industry.

But does this endurance matter? Is it important that we have companies that can endure, and change over time? Or is it enough that teams can come together for a time, make a game and disband again only to reform for another project?

One consequence of persistence is the development of a shared identity — a team culture. The establishment of trajectories, good and bad, that are hard to break. These identities become crystallized in the games we make: the passions, the neuroses, the striving for technical excellence, the pursuit of new experiences, the desire to improve upon the existing, the decisions in the face of so many limitations, these things are reflected in the character of the games produced by a team.

Another consequence is an often implicit snapshot of shared history. Few game developers and publishers seem interested in preserving or enhancing the games they’ve made beyond a short period of profitability. Archiving — particularly, providing a public archive of games — is almost unheard of. A small number of companies release source code. Some interested parties attempt to archive older games, to preserve some part of our gaming history. But there are many more games that are created for a time and live only at the whim of their operators, with essential servers lasting a year or less. And just today I see a case where publishers are unable to identify the owner of a game.

In the absence of a widespread commitment to preserving our developing history, longer lived studios are at least some visible evidence that we have that history captured in some form, good or bad.

And there is financial benefit in being a studio that has persisted. Especially one that has made popular products :) An established identity is a valuable thing — no small part of my motivation to write about this comes from the fact that I have a lot of good memories associated with both LucasArts and Psygnosis.

Is it important?

I don’t know. Maybe it doesn’t matter if there are many “older” game studios.

What I do know is that I want studios thrive and live long, productive lives. I want the existence of older game studios to matter. I want games to be more than just one-time projects worked by a group that has come together for a short time only. I want teams of game developers persisting, struggling, wrestling to go beyond what they can do on their own. To inspire one another and to achieve unimagined heights.

I want game development to take itself seriously. To record and preserve its history. To provide a the shoulders for later developers to stand upon. I want there to be companies that persist, to be a foundation for the industry. To invest in talent and technology, and to make it available for the benefit of the industry (one way or another).

I want an industry with substance and depth, with studios capable of investing in long-haul projects, able and motivated to be looking long years into the future to consider what they might yet achieve and how to get there.

Selfishly, I want to make games, and I want a secure, reliable job to be able to work for the well-being of my family. I want there to be workplaces that I can commit to, invest in, and that I can trust to be around for years to come. I want to work with experienced, exceptional people. I want to be in that struggle to make great games, with others, for a long time.

I am convinced that the presence of long-lived studios is a good thing for this industry. It is my hope that the list of twenty-and-overs will grow.


SN Systems has been providing tools for game development since 1988.

RAD Game Tools has also been around since 1988.


Please let me know of any corrections or additions to the list — it’s based on wikipedia entries and tweets from people I do and don’t know.

My thanks to twitterers 666uille, JanDavidHassel, SamuelePanzeri, Mimus_, brett_douville, girayozil, Nshk, Allagash, pthiben, RonPieket, and michaelellerman for their suggestions, and to my dear wife for listening to me ramble through some of these thoughts.

Update 2013-12-26: Added System 3 and RAD Game Tools.

Update 2013-04-07-6: Added Namco, Falcom and Treasure. Thanks to @janvanvalburg

Update 2013-04-07-5: Added Radical and High Voltage Software. Thanks to @TheJare

Update 2013-04-07-4: Added Criterion, Eutechnyx, Edge, Raven, Maxis. Thanks to @SebHillaire, @choddlander, @ChristerEricson, and @BrianKaris.

Update 2013-04-07-3: Added Blitz Game Studios, Rebellion, Climax, Stainless, Crystal Dynamix, Taito. Thanks to @zebrabox, @ggatheral, @HazelMcKendrick, @wuffles, @thinkinggamer, and @jasperbekkers.

Not sure about Square Enix – merger of Square (1983) and Enix (making games since 1982) in 2003.

Update 2013-04-07-2: Added Codemasters. Thanks to @Poita_.

Update 2013-04-07: Added Funcom. Thanks to fred r.

Update 2013-04-06-2: Added EA Canada, Ubisoft Blue Byte. Thanks to @h4kr and @p1xelcoder.

Update 2013-04-06: Added Bungie, Digital Extremes, HAL Laboratory, Nintendo EAD, Rockstar North, Rockstar San Diego, Team 17 and Volition to The List. Thanks to @alexr, @msinilo, @chrisjrn, @flawe, @morten_skaaning and @fahickman.

Added SN Systems as an addendum, thanks @gregbedwell.

Can C++11’s final qualifier affect codegen?

To satisfy my curiosity, I compiled this

struct A { void f(); };
struct B { virtual void f(); };
struct C { virtual void f() final; };
void a(A& a) { a.f(); }
void b(B& b) { b.f(); }
void c(C& c) { c.f(); }

like this

g++ call.cpp -std=c++11 -O3 -S -o- -masm=intel # gcc-4.7.2 i686-pc-cygwin

which produced [output that included] this

__Z1aR1A:
    jmp __ZN1A1fEv

__Z1bR1B:
    mov eax, DWORD PTR [esp+4]
    mov edx, DWORD PTR [eax]
    mov eax, DWORD PTR [edx]
    jmp eax

__Z1cR1C:
    jmp __ZN1C1fEv

What does it mean? Because C::f() is marked final, calls to it can be devirtualized by the compiler, so there is no extra indirection when calling it in the above case.

(Trying the same code with VS2012’s cl.exe, the call to C::f() does not appear to be devirtualized)

struct C does still appear to have a virtual function table pointer: (sizeof(C) == sizeof(B) == 4), whereas (sizeof(A) == 1)It seems to me that the vtable pointer could be omitted in this case…

Update (2015-01-24): As Tom points out below, anyone with a B* or B& that is actually pointing to an object of type C will still require the vtable pointer to find the correct implementation of f().

Bug review, 2013-03-26

Last week, I started writing about runtime bugs that I’ve encountered in my own code, for my own interest and potential benefit. This post contains a summary of the issues I noticed, and a brief self-review of the week.

Summary of the week

Tuesday

  • Changed virtual function prototype results in correct function not being called
  • memcpy() into an uninitialized pointer variable
  • Bad loop counting
  • Failing to store updated state

Wednesday

  • Uninitialized class member
  • Sliced inheritance
  • Undesired printf() output

Thursday

  • Failed to initialize instance-specific member variable correctly because I was calling the wrong constructor
  • Use of uninitialized system
  • Yet another uninitialized member variable crash

Friday

  • Unexpected use of class
  • Hard-coded array size, no checking
  • General disaster

Monday

  • Initialized, but not in the right order (fallout from Unexpected use of class)

Tuesday

  • Local static state is local, static
  • Redux: Changed virtual function prototype results in correct function not being called

Trends

Looking back over the week, failure to initialize, failure to init at the right time or in the right order stands out as a primary source of bugs. Maybe I need to be asking myself questions like “where did this variable’s state come from” to try and prompt more consideration of this.

Broadly, there is also what appears to be insufficient familiarity with various of C++’s OO features, resulting in silly mistakes. I don’t generally write much OO-style code — this week has been unusual in that way. It is a problem if I can’t use them reliably.

I’m pretty happy with the solution to the “Changed version prototype” situation. Finding ways to prevent possible runtime bugs at compile-time always feels like a worthy achievement.

Meta

Thus far, I’ve found the process of logging these bugs to be worthwhile — attempting to explain the bugs helps me to understand them more clearly. I have found myself thinking about the bugs: the solutions I’ve attempted, and how to try to avoid writing the same bugs in the future.

My plan for now is to continue to write these posts. Hopefully, it leads to fewer bugs.

Some notes on memcpy

Recently I encountered a bug due to memcpy() being used like this:

    memcpy( elem, elem + 1, n * sizeof(Element) );

What’s the problem?

The prototype for memcpy is defined something like:

    void* memcpy(void* dest, const void* source, size_t size);

memcpy is wonderfully simple – use it to copy size bytes from source to dest. But the definition of memcpy from the standard goes something like this:

“The memcpy() function shall copy n bytes from the object pointed to by s2 into the object pointed to by s1. If copying takes place between objects that overlap, the behavior is undefined.” [source]

If you notice the example at the top of the email, the copy is from elem + 1 to elem with a size of (potentially) more than one Element. It’s quite possible that objects overlap. And they did.

The magic word in the definition is undefined. When you do something that is undefined in C or C++, anything can happen. The compiler can format your hard drive, email a resignation letter to your manager, there could be nose goblins. Or your data could become corrupt. Relying on undefined behavior is a bad idea.

Nose goblins notwithstanding, what can actually go wrong for memcpy? If memcpy is implemented as walking forward through the source range and writing to the destination, the above case should be OK, right?

Well, maybe.

But if it starts at the end of the source array and works backwards, the destination range will end up with corrupt data.

Probably.

Even if memcpy walks forward, data could be corrupted if the source has a lower address than the destination (and they overlap). There are plenty of ways to write a fast memcpy implementation that can corrupt data for overlapping ranges. And implementations that will cause problems exist and are widely used: e.g. http://lwn.net/Articles/414467/ Even better are implementations that will step forward through memory for small values of size, and backwards for larger ones.

Conclusion: don’t use memcpy for overlapping ranges. Instead, use memmove which is well defined if the ranges overlap:

“The memmove() function shall copy n bytes from the object pointed to by s2 into the object pointed to by s1. Copying takes place as if the n bytes from the object pointed to by s2 are first copied into a temporary array of n bytes that does not overlap the objects pointed to by s1 and s2, and then the n bytes from the temporary array are copied into the object pointed to by s1.” — [source]

(With thanks to Andreas for his help in finding the source of the bug that inspired this piece)

Processor architectures: seeking source material

To satisfy my own curiosity I want to do some writing about CPU architectures – analysis, comparison, origins, history/evolution, variants, etc. I envision writing blog posts, possibly many — it depends on how things go.

CPUs/families that I’d like to know more about include (off the top of my head) x86, ppc, arm, mips, m68k/coldfire, z80, 6502, SuperH, sparc, alpha, m88k. (to start with — there’s many more with interesting stories :)

Before I write about these, I want to be well informed. As such, I’m looking for recommendations of enlightening things to read. In many cases I can look at technical documentation provided by vendors, but these usually don’t provide a lot of background, context or history of an architecture.

What has been written about these (or other) CPU architectures? I’m keen to know about the origins and evolution of architectures. What forces (technical, financial, marketing, etc) influenced designs? How have they changed over time? I’m interested in comparisons between architectures, implementation details, extensions, variations, anything that will illuminate the reasons, benefits, deficiencies, and more about a design.

So, what should I be reading? (or who should I talk to? :D)

[I’ve asked the same question over on google plus, and I will be collating answers there]

Review of Careers in Gamedev presentations
[aka Memoirs of a Career Motivational Speaker (retired)]

In my previous post, I wrote about my outline and intent for talking about getting into a career in game development (or elsewhere). In the end, I delivered the presentation ten times at five different high schools. Here are my recollections and reflection on the experience.

High School 1

The first high school was a lot of fun. As I mentioned in the previous post, I was somewhat uncertain about what would constitute an appropriate pitch and this was my first such talk to a group of unknown teenagers — which makes it exciting/scary/fun :)

I talked to two groups of around 40 students back to back. There was a mix of grades (7-10) and a pretty good balance of male/female. The room was smallish for the group, which I like as it makes it all feel nice and cosy, and helps focus attention. Unfortunately, there was limited ventilation, so it did get a bit stuffy through the talks. I got lots of good questions throughout the presentation. There were dead patches (combination of stuffiness and me talking for too long), but overall I was very happy with these sessions. The majority of questions came from younger students, with fewer from those in grade 9 and 10, though those seemed to be (at least) weighing up what I had to say.

I don’t recall giving the same presentation back-to-back before, and due to my talk-about-things-as-I-get-to-them style, at various stages in the second talk I lost track of whether I was repeating myself to the group. Fortunately, I had the Pathway Planning Officer present in the room (sitting among the group) who asked some useful leading questions from time to time, which seemed to work well.

Also, I had some pacman-shaped keychains from the UTas School of Computing. They were popular ;)

Feedback: see the comment here.

High School 2

After being advertised to other high schools around the state, I was contacted about visiting another one nearby. The original suggestion was that I would talk to the ICT class(es) — I pushed back against this, suggesting that it would be far better to talk to students with some interest in the industry, and this was agreed to.

The presentation was — I believe — advertised to students, and they could opt in. The group was 40+ students, mostly year 9 and 10, some 7 and 8, and included one female.

The setting was a larger area in an open-plan building, which meant attention was less focussed inwards. I would describe this talk as being “more work”. I got far fewer questions and less interaction, which resulted in me talking more. I don’t like that — it tends to be a cycle that is hard to break. That said, I still got a number of good questions. Particularly, some of the younger guys were very keen and were making games. At this school I was asked for suggestions about how to get into gamedev when you don’t have a computer or internet access outside of school.

At one stage in the presentation, I was certain that I saw a look of horror on the face of one of the staff due to something I’d said. Not sure what it was (or — in hindsight — if I’d read it correctly), but it stood out and amused me just a bit.

High School 3

Another room full of guys, opted-in, nicely structured seating, great attention, lots of questions and engagement. Grades 7–10 (iirc). Turned out that this school uses GameMaker as part of the ICT curriculum, and these were a particular eager and interested bunch.

After the presentation, one asked to show me a game he had been working on, which was absolutely fantastic to see — I got to see it in action, hear his plans for what he wanted to do with it, offer some ideas. Also, some days afterwards, one of the students sent me a thank-you card! :D

High School 4

This place was hard work. Three sessions, each to a different grade computing class (against my stated preference). Included students who were vocally opposed to being there, and consequently an environment where it was difficult to get engagement (answers to questions or questions from the audience). Sessions were held in computing classrooms, with PCs around the outside of the room, and chairs clustered (somewhat awkwardly) in the middle.

It wasn’t a total loss — there were certainly students interested in gamedev careers, and there were others that (I’m pretty sure) heard enough about what I had to say about career preparation in general that it might be of benefit.

The second session was with the grade 10 class, who were very short on questions. There were a number in this group who were clearly a lot more thoughtful and calculating — there were looks of concentration on and consideration of what I had to say. Also, the couple of teachers in the room threw in some questions to help focus the content on what was relevant to this age group — questions of subject selection for college and later came up from teachers a few times through the talk. My answer to that is do what is useful for the sort of career you want — there are potential benefits to both broader and narrower paths.

The three talks at this school were spread out over a whole school day, and the last group, at the end of the day were grade 7 and 8s. There was not a lot of focussed attention in the room. There were a number that were distracted and distracting for most of the session. In the end, it kind of devolved into me asking for games people had played recently and me providing a quick fact/anecdote/news headline about the game/mechanic/developer/development process/whatever. In hindsight, I’m not sure what it was the best way to round out the session — it kept their attention, but probably wasn’t all that useful.

There was a cool conclusion to the day — after the last session, one of the students demoed some gameplay extensions he’d made to a game he’d downloaded from @notch’s website (I think it was this). Getting to meet students with this kind of interest and enthusiasm (and this wasn’t the only time it happened) was the high point for me of the whole series of presentations.

High School 5

Final school, another three presentations. This time, I spoke to all of the grade 10 students (and one grade 9 guy who was super keen). I was a bit worried that this one would be another one stifled by objectors, but overall things went very well. The students were interested and engaged, and mostly the dynamic within the room was comfortable/amiable. It was a great place to finish.

The school has a large kitchen operated by students, and I was provided lunch from there which was also pretty cool — students eager, active and making stuff (eats!) was consistent with what I was trying to encourage and a delight to see :D

Summing up

Themes of questions did tend to vary from school to school — I do recall answering different styles of questions at different schools, though it’s hard to generalise what the differences were. I did get quite a few questions about what my favourite game is that I was not well prepared for — “I like lots of different types of games” is not a satisfying answer, even to me.

I had very little with me in terms of props — a whiteboard, upon which I wrote my name and wrote the 5 points as I went through them, and my Touchpad (containing notes, in case of catastrophic memory failure). My name — deliberately written out in full — tended to lead to some banter between myself and those gathered before the presentation regarding its pronunciation, which worked as a starting ice breaker. I did try chatting with the students beforehand in most cases to try to help lower the barrier to interaction during the talk.

Another stand-out was arriving early at one of the schools and getting to hear a couple of pieces performed by the small male choir, which was very impressive :)

Was it worth it? What was the benefit? Would I do it again? I enjoyed delivering the presentations, and the experience overall — but that wasn’t the point of the exercise. The feedback I have received is that there were students who were impacted by what I had to say — there were consequences. Students (and teachers) gained a slightly better understanding of the industry. I didn’t sugar-coat it — I presented what I think was a fair summary of risk and reward. I told no one to go into gamedev — rather, encouraged them to work for what they’re passionate about, to choose to do things that will help, and maybe to aspire a little higher than they otherwise might do. Given the chance, I would be very happy to do this sort of thing again.

Getting into gamedev [aka Career Motivational Speaker]

Before departing Tasmania, I visited several high schools where I talked about getting into a career in gamedev. That was the premise, at least — I really talked more about what you can do to get a job doing what you like. Lots of high school students like games and I was getting ready to move for a gamedev job, so it was a good hook.

The opportunity came about from a conversation (with a high school student) about my upcoming move, what I was doing and how it had come about, and about what part of my experience was relevant to his own. The conversation was had while the Pathway Planning Officer for a local school was nearby, and she invited me to the school to talk to some of the students there.

The problem then became how to turn a spontaneous conversation into something sufficiently well-prepared and engaging that I could talk to a room of teenagers for up to an hour. I enjoy presenting to/speaking with groups, particularly on topics that I’m passionate about, but I have little experience talking to teenagers and was somewhat uncertain about what I’d need to do to get and keep their attention. I like to keep presentations interactive and flexible — I’d rather talk about what interests the listeners than about my own prepared material. For that reason, I don’t tend to use slides and try to be interesting, engaging and memorable all on my own. (there’s always a risk leaving out something “important” — but as there’s always far more material than I can cover in a single presentation, if the audience has been interested it’s probably a nett win :P)

For all my desire to keep it free-flowing and interactive, to give a talk without a clear idea of what I want to talk about and how it fits together in a coherent and plausible manner, I’m going to struggle to impart any useful information/knowledge to the students that have so generously taken time out from their Social Science class (or whatever). It’s hard to evoke passion without passion. I find it easier to convey my excitement and passion for something when I’m well prepared to talk about it.

I did some reading in preparation of the talk to make sure that I wouldn’t be talking nonsense. While I was about to start in the industry, I had not worked in the industry. While I didn’t think I had many incorrect preconceptions or invalid assumptions about the industry (who would?), my lack of experience was one thing that cropped up repeatedly through recent job applications. I thought it appropriate to do my best to make sure what I had to say would be generally useful.

I read what I could find, but a couple of sites stood out in particular: there’s a lot of the great advice on tinysubversions.com, particularly the material on effective networking in the games industry.  Linked from there, I found a link to a list of New Year’s Resolutions for Game Industry Newbies (or people who want to eventually be one),  which I basically ripped off to form the core of my presentation (many thanks to Chris Hecker and Jonathan Blow for the list).

Here’s an outline of what I talked about:

  • who I am
    • always good for the audience to know the name of the guy they’re listening to.
    • talk about my education and work history with emphasis on what are likely to be common points of reference — educated/live in local area, personal history back to the age of the audience
    • upcoming move — mention Insomniac and the games they’ve made, find out how many people in the room knew Insomniac IP (lots)
    • (made the point that my own education history is not being held up as any ideal for how to get into the industry — far from it)
  • why I like gamedev (or talk about the sort of gamedev role I aspire to…)
  • the diversity of careers available in gamedev
    • used this to kick of some interaction — ask the audience “What goes into making a game? What sort of jobs are there in gamedev?”
    • purpose was to emphasise diversity of opportunity. It’s not just programmers. (more on that later, though)
  • nature of the industry —
    • games are popular
      • high % of people play electronic games of one kind or another
      • lots of money spent on games
    • often unreliable working situation
      • recent history of  gamedev studios in .au (and elsewhere) is not good
    • not many Australian gamedevs
      • estimates of <3,000 gamedevs in .au
      • contrast: >300,000 teachers in .au (not sure if it was a useful stat, but I like it :)
    • opportunity in smaller scale
      • low entry options to making games
      • no guarantees of success…
      • the indie life is not for everyone
  • invite questions
  • on to five points (taken from the New Year’s Resolutions post — see more there)
    1. make things
      • build experience, build portfolio
      • good idea, regardless of specialisation or desired industry
    2. play games
      • play for purpose of critique, understanding
      • what makes this game good? why do I hate this one? how could it be better?
      • tie back to point 1 — make things based on what you’ve played, remake, modify, extend
    3. learn things
      • generally a good idea :)
      • learn things that will help get to your desired career — be selective
      • I spruiked the UTas Bachelor of Computing (Games Technology) degree as one option
      • more learning -> more understanding (hopefully). Helps with 1 and 2.
      • what you know matters
    4. people
      • who you know matters
      • work with people locally with similar interests — opportunity now! Useful with 1, 2, 3
      • be active in the wider gamedev community e.g. follow gamedevs on twitter. Caveat: don’t be an annoying fanboi. Read, watch, learn, interact in a civil fashion.
      • being visible to people can help when applying for jobs
    5. learn to program
      • presented as “optional”
      • useful skill no matter what — understand how computers work and how to bend them to your will
  • answer questions until time/questions run out

For all the game-related content in the presentation, it was presented to make clear that these things will work outside the gamedev industry, too — do things that will help get you a job doing what you want, here are some things that can help.

Prepare yourself — opportunities come along from time to time. While you typically can’t make them happen, you can encourage their arrival. Don’t expect you can get a job with no experience/training/portfolio/etc – rather, do what you can to be as ready as you can be for when opportunities arrive.

(Additional: I was interested to hear TJ Fixman talk about similar ideas when recounting his own gamedev career path in a recent Feedback episode)

Assembly Primer Part 7 — Working with Strings — ARM

These are my notes for where I can see ARM varying from IA32, as presented in the video Part 7 — Working with Strings.

I’ve not remotely attempted to implement anything approximating optimal string operations for this part — I’m just working my way through the examples and finding obvious mappings to the ARM arch (or, at least what seem to be obvious). When I do something particularly stupid, leave a comment and let me know :)

Working with Strings

.data
     HelloWorldString:
        .asciz "Hello World of Assembly!"
    H3110:
        .asciz "H3110"

.bss
    .lcomm Destination, 100
    .lcomm DestinationUsingRep, 100
    .lcomm DestinationUsingStos, 100

Here’s the storage that the provided example StringBasics.s uses. No changes are required to compile this for ARM.

1. Simple copying using movsb, movsw, movsl

    @movl $HelloWorldString, %esi
    movw r0, #:lower16:HelloWorldString
    movt r0, #:upper16:HelloWorldString

    @movl $Destination, %edi
    movw r1, #:lower16:Destination
    movt r1, #:upper16:Destination

    @movsb
    ldrb r2, [r0], #1
    strb r2, [r1], #1

    @movsw
    ldrh r3, [r0], #2
    strh r3, [r1], #2

    @movsl
    ldr r4, [r0], #4
    str r4, [r1], #4

More visible complexity than IA32, but not too bad overall.

IA32’s movs instructions implicitly take their source and destination addresses from %esi and %edi, and increment/decrement both. Because of ARM’s load/store architecture, separate load and store instructions are required in each case, but there is support for indexing of these registers:

ARM addressing modes

According to ARM A8.5, memory access instructions commonly support three addressing modes:

  • Offset addressing — An offset is applied to an address from a base register and the result is used to perform the memory access. It’s the form of addressing I’ve used in previous parts and looks like [rN, offset]
  • Pre-indexed addressing — An offset is applied to an address from a base register, the result is used to perform the memory access and also written back into the base register. It looks like [rN, offset]!
  • Post-indexed addressing — An address is used as-is from a base register for memory access. The offset is applied and the result is stored back to the base register. It looks like [rN], offset and is what I’ve used in the example above.

2. Setting / Clearing the DF flag

ARM doesn’t have a DF flag (to the best of my understanding). It could perhaps be simulated through the use of two instructions and conditional execution to select the right direction. I’ll look further into conditional execution of instructions on ARM in a later post.

3. Using Rep

ARM also doesn’t appear to have an instruction quite like IA32’s rep instruction. A conditional branch and a decrement will be the long-form equivalent. As branches are part of a later section, I’ll skip them for now.

    @movl $HelloWorldString, %esi
    movw r0, #:lower16:HelloWorldString
    movt r0, #:upper16:HelloWorldString

    @movl $DestinationUsingRep, %edi
    movw r1, #:lower16:DestinationUsingRep
    movt r1, #:upper16:DestinationUsingRep

    @movl $25, %ecx # set the string length in ECX
    @cld # clear the DF
    @rep movsb
    @std

    ldm r0!, {r2,r3,r4,r5,r6,r7}
    ldrb r8, [r0,#0]
    stm r1!, {r2,r3,r4,r5,r6,r7}
    strb r8, [r1,#0]

To avoid conditional branches, I’ll start with the assumption that the string length is known (25 bytes). One approach would be using multiple load instructions, but the load multiple (ldm) instruction makes it somewhat easier for us — one instruction to fetch 24 bytes, and a load register byte (ldrb) for the last one. Using the ! after the source-address register indicates that it should be updated with the address of the next byte after those that have been read.

The storing of the data back to memory is done analogously. Store multiple (stm) writes 6 registers×4 bytes = 24 bytes (with the ! to have the destination address updated). The final byte is written using strb.

4. Loading string from memory into EAX register

    @cld
    @leal HelloWorldString, %esi
    movw r0, #:lower16:HelloWorldString
    movt r0, #:upper16:HelloWorldString

    @lodsb
    ldrb r1, [r0, #0]

    @movb $0, %al
    mov r1, #0

    @dec %esi  @ unneeded. equiv: sub r0, r0, #1
    @lodsw
    ldrh r1, [r0, #0]

    @movw $0, %ax
    mov r1, #0

    @subl $2, %esi # Make ESI point back to the original string. unneeded. equiv: sub r0, r0, #2
    @lodsl
    ldr r1, [r0, #0]

In this section, we are shown how the IA32 lodsb, lodsw and lodsl instructions work. Again, they have implicitly assigned register usage, which isn’t how ARM operates.

So, instead of a simple, no-operand instruction like lodsb, we have a ldrb r1, [r0, #0] loading a byte from the address in r0 into r1. Because I didn’t use post indexed addressing, there’s no need to dec or subl the address after the load. If I were to do so, it could look like this:

    ldrb r1, [r0], #1
    sub r0, r0, #1

    ldrh r1, [r0], #2
    sub r0, r0, #2

    ldr r1, [r0], #4

If you trace through it in gdb, look at how the value in r0 changes after each instruction.

5. Storing strings from EAX to memory

    @leal DestinationUsingStos, %edi
    movw r0, #:lower16:DestinationUsingStos
    movt r0, #:upper16:DestinationUsingStos

    @stosb
    strb r1, [r0], #1
    @stosw
    strh r1, [r0], #2
    @stosl
    str r1, [r0], #4

Same kind of thing as for the loads. Writes the letters in r1 (being “Hell” — leftovers from the previous section) into DestinationUsingStos (the result being “HHeHell”). String processing on little endian architectures has its appeal.

6. Comparing Strings

    @cld
    @leal HelloWorldString, %esi
    movw r0, #:lower16:HelloWorldString
    movt r0, #:upper16:HelloWorldString
    @leal H3110, %edi
    movw r1, #:lower16:H3110
    movt r1, #:upper16:H3110

    @cmpsb
    ldrb r2, [r0,#0]
    ldrb r3, [r1,#0]
    cmp r2, r3

    @dec %esi
    @dec %edi
    @not needed because of the addressing mode used

    @cmpsw
    ldrh r2, [r0,#0]
    ldrh r3, [r1,#0]
    cmp r2, r3

    @subl $2, %esi
    @subl $2, %edi
    @not needed because of the addressing mode used
    @cmpsl
    ldr r2, [r0,#0]
    ldr r3, [r1,#0]
    cmp r2, r3

Where IA32’s cmps instructions implicitly load through the pointers in %edi and %esi, explicit loads are needed for ARM. The compare then works in pretty much the same way as for IA32, setting condition code flags in the current program status register (cpsr). If you run the above code, and check the status registers before and after execution of the cmp instructions, you’ll see the zero flag set and unset in the same way as is demonstrated in the video.

The condition code flags are:

  • bit 31 — negative (N)
  • bit 30 — zero (Z)
  • bit 29 — carry (C)
  • bit 28 — overflow (V)

There’s other flags in that register — all the details are on page B1-16 and B1-17 in the ARM Architecture Reference Manual.

And with that, I think we’ve made it (finally) to the end of this part for ARM.

Other assembly primer notes are linked here.