I came across a ttyrec file that held inside a recorded NetHack-game. NetHack (for those who don’t know) is an open-source single-player roguelike video game, first released in 1987. The game is played in terminal screen and looks like this.


Image Source: Wikipedia

Some people record their games and share their games using this ttyrec-file format. The file contains the movements of a player, move by move. I wanted to make an animated gif from that; such a gif that it ends with the image of a grave and I can build it from a command line of Raspberry Pi to a specific length of time. First, I need to parse the ttyrec-file into an editable form. Re-playing the ttyrec-file with PHP is a simple piece of code, but parsing, so I can modify that, is another issue.

I wanted to find a screen that has “Killed by” text and drop the rest of the screens with a piece of code. So time to do some coding. First I need to extract the screens from the file and interpret the commands to a printable format.

Ttyrec-file is a text file that starts with the [seconds from 1970-01-01 00:00:00]/[microseconds]/[length of content] and then the content of a screen, followed by the same kind of block of the next screen. The content is filled with vt100-commands that are used to move cursor and print characters in a terminal. They are identified by an ESC-character and then a command which tells the terminal what to do. For example, ESC[30m tells the terminal to turn the foreground color to white and ESC[2;24H the command tells the terminal to move the cursor to row 2 column 24. Everything else is outputted to the terminal.

The parser structure

First I load the ttyrec-file into a class called Terminal. Then I separate the screens from the input and then interpret the strings into commands. The commands may or may not have a printable output. Output is a string that contains ascii characters that shape the dungeon, monsters and items shown in the first image. I also added commands for backspace, newline, and carriage return for easier interpreting later with a simple str_replace. Phases (1) and (2) are in the below picture.

Interpreting the commands to present the actual terminal

In ttyrec-format, the screens follow each other, and from the previous screen, there might be characters left to the next screen. if I want to know what is printed in screen 401, I need to go through all the screens from 1 to 400 in case they leave any output to be printed in screen 401. All the commands have an output, which is the actual printable string. For some commands, I added different variables to describe the command better. For example, MoveArrowCommand has booleans up, down, left, and right to determine which way to move the cursor. CursorMoveCommand has variables row and col to tell where to move the cursor before output. Interpreting commands to actual output is just looping the commands of a screen. In the end we “print out” the output with parseOutputToTerminal-function.

(The (3) path in the above picture) We get the screen, loop the commands of the screen, and output strings to build the actual console state. The functions which interpret the commands look like this.

After this looping, we have an array that is filled with rows that have an output. We set this ready array back to the screen object so we can access the state of the screen. Then we can just output them into anything, like to a text file.

or to a gif

Nice. After doing this for all of the screens, I have 6415 individual gif files. Now we come to the next problem. How do I combine them into a single animated gif?

Making an animated gif with PHP

Link to repository

ANSI Escape sequences – VT100

Duukkis

Duukkis has been building the Internet for 20 years in multiple various size projects. He is a coder and maker of things. He has done over 70 Twitter-bots, a noun- and verb- conjugator with PHP, and a portrait from 7366 pieces of Lego. He is a developer, architect and a nice guy.

Linkedin profileTwitter profile

Do you know a perfect match? Sharing is caring

We Goforeans are experts in all things digital, and we want to make sure that digitalisation is a force for good. We want to build ethical, human-centric solutions, and work towards a digital future that is human and increasingly sustainable.

The greatest impact together with our customers

We aim to act as responsibly as possible (you can read about our choices on the Responsibility page), but we understand that the biggest, most positive impact is made by helping our customers make decisions that benefit both their business and society at large.

For almost 20 years, we have been helping our clients achieve good growth in the public sector in Finland, one of the most digital and ethical societies in the world. That work has given us expertise and insight we can leverage when we help our clients identify and develop the capabilities they need in building a sustainable digital business.

Of course, no one can know what the future will hold and what the ethical digital world will mean in practice. But when digital services are designed and built around people and the environment, we can equalise access, democratise information, preserve our planet, and more.

Pioneering an ethical digital world

According to my colleague Pasi Lehtimäki, legislation is currently unable to react fast enough to what artificial intelligence can and cannot do. Companies that develop algorithms have been given a great deal of responsibility for the direction in which society is evolving and how technology affects it. Facebook, for example, has a significant impact on our society in facilitating conversations and what we can say.

Through other examples, we need to encourage individuals and organizations to engage in these discussions, because decisions that seem to make sense now can have long-term consequences.

In addition to doing our very best in using technology to strengthen our society, we would like to invite our customers and other industry players to discuss ethics and to make ethical choices. It’s not going to be easy or unambiguous, but a culture of experimentation is part of the pioneering spirit that drives us.

As the ethicist Anna Seppänen says, there are no sure truths or latest facts in ethics. Indeed, in her opinion, ethics is similar to the nature of a negotiation, with different views on what is right and what is wrong. And together we need to decide which view to act on in the given situation.

Our new brand promise Pioneering an ethical digital world will be launched today. It will initially appear on our website and it will be applied gradually in all of our materials. Hopefully soon also in other blog posts and media.

Welcome to the journey towards an ethical digital world!

Petra Sievinen

Petra has worked in the IT industry for nearly 20 years in sales, marketing and communications, at startups and at corporations. As Gofore’s Director of Marketing and Communications, she supports company’s growth strategy and strengthens its reputation as a digitalisation expert and an attractive employer. Petra believes that communication is the most important tool in a leader’s toolbox. She’s also interested in company culture, sustainability, and investing. Today the motto of a recovering perfectionist is Better done than perfect.

Linkedin profileTwitter profile

Do you know a perfect match? Sharing is caring