Friday 17 July 2015

Painting the future

First things first, I currently have three open issues in the Github-page. 2 of them are trivial to fix, I'll probably start with them friday evening, but the memory leak will be slightly more interesting to solve. Were I leaking file handle or even naked pointers, they'd be easy to fix with a bit of macrology. No such luck though. I have a hunch I'm doing something incredibly stupid with STM. Memory-usage rises like hell when manipulating the state of the map. I thought STM-primitives carried their history all the time, but it seems I'm wrong. And I'm happy about that. In general case such behaviour would explode the already ridiculous RAM usage of JVM.

Sometimes I wonder if I romanticize the sixth-generation and older video game consoles a bit too much

Anyway, let's assume I'll get those bugs fixed on friday evening. That leaves me ˜48 hours to create new things. I should use them wisely.

First I have to parametrize hit-layer's tiles' size. I'm not certain, with the whopping 0 users this editor has, that 50px*50px isn't too big rectangle for controlling the places player can or cannot step on. I have a feeling though that it is. Thus, in the next version, hit-layer's tile-size can be anything, as long as (= h w).

In case I get really experimental, I'll parametrize the regular layers' tile-size too. It will have to be a different param though. (not= hitlayer-tile-w layer-tile-w) can be true.

Like I've spoken in the past, this map-editor will not be only a map-editor when I have realized my vision. I have this vision of a unity-like 2d-games editor with the added benefit of being Lisp all the way down, at least till you find pieces of crusty Java-machinery. So this editor will gain a possibility to load characters. They should probably be loaded as children of the Map-struct. These characters can be then moved and rotated around by either a script or a player. Animation subsystem should be easy to write.

The way I've imagined scripting to work will be different to Unity's kind. Scripts do not live in the file system. Instead they are in the same image as maps, characters, and other objects I haven't yet come up with. When editor loads an image (yes, henceforth the .memap-files editor produces are called images) it opens up an nrepl-server for scripting both the game and the engine. It also opens another server for my own protocol that dumps the image's script-files to the Emacs minor mode. This minor mode overrides find-file (C-x C-f) and save-buffer (C-x C-s) to communicate with this fileserver instead of operating system's.

Game is running in the background, rendering the scene, animations, scripts and updating AI and physics if I'll ever implement such luxury. User can edit maps and character-animations in the editor window. They can peek and poke the state of the game in REPL. On top of the game's namespaces, also editor's namespaces are open for customizing. Considering that by default Clojure's compiler (or whatever component Leiningen calls when uberjarring) keeps as much code inside a jar noncompiled as possible, it shouldn't be hard to provide the editor's sources too to Emacs through the aforementioned protocol. It should be a setting defaulted to off though, because unless user is sure to know what they want to create, they probably don't want to customize the editor.

So what am I to implement? Loading of animations (or static characters), decide what interesting properties I'm going to base my interpration of animations on (initial-frame-index, amount of sprites in a spritesheet, is-playing?, location and angle probably), and some sort of selection-rotating-and-moving tool for them. Some context-specific views on editor's sidebar would be nice too. Maybe a listbox where user could open certain frames to the pxart-editor? And replacing the animation sequence with another spritesheet without scrapping rest of the character's properties should be supported too.

Once characters can be loaded, scripted, and they can react and interact with the map, I'll probably have another go at game-design (instead of game-devtool-design). I'm a little on the fence on what I'll actually put into to game. Last October's spec on the game mechanics should be mostly applicable. Story will cause me most pain. On the other hand, the old, finnish manuscript found somewhere in merpg.webs.com is shit. On the other hand, it's my best finished game-manuscript (as opposed to a book-manuscript), and if Nintendo dares to save a princess in every other Zelda and Mario (a hyperbole, I know), I can use this as a source. I'll sell a better story to my next game then.

But, before I can take any stress of what I've written, I want to make a pxart-application (with possible dropbox-bindings) to Android! I've done it before, somewhere in Memapper's history you might even find the code for it, so it shouldn't be a long project. Hardest part will probably be finding how one commanded Android's 2D-rendering from Clojure again.

But now I'm off to sauna. Hack merrily!

Monday 13 July 2015

MEMAP-format

This is just a technical specification. If you're expecting war stories, this text might be a bit disappointment.

Specification for the memap-format

Files editor spits out are zip-files with a funny extension designed mostly to screw with prehistoric Windowses. Root of an example zip-file looks like this:

  • Map 0.memap
  • Map 1.memap
  • Map N.memap
  • initial.png
  • G__1312.png
  • G__4332.png
  • asdfgh.png

Where N means arbitrary number, and names of the pngs' aren't strongly defined. Editor creates sequential id-numbers for the inner memap-files, but upon loading they may be called anything. Only *.memap-extension is needed. As for *.pngs, only requirement for them that filename is a legal Clojure keyword

.png-files are tilesets, .memap-files contain the maps. For each .png an expression

(and (= (rem (width *png-image*) 50) 0)
     (= (rem (height *png-image*) 50) 0))

is true. I highly recommend to keep an initial.png - tileset in your file. Editor allows removing it, but skies will open and horrible things will happen if it is removed.

Each .memap-file has a clojure-map full of data. Example of this follows:

  ^{:tyyppi :map,
  :id :G__9092,
  :hit-layer ^{:tyyppi :layer...}
              [[true ...] 
               [true ...]
               ...], :zonetiles {}, 
  :name "Map 228E9"}
  [^{:tyyppi :layer, :name "New layer", :opacity 255, :visible? true}
    [;;Layer begins here
     [{:x 3, :y 1, :tileset :G__8862, :rotation 0} ...]
     ...]]

First we have a map of metadata. :tyyppi (:type in english) can be either :map or :layer. It's used in editor's multimethod-dispatching machinery. :id:s are just to ease seeking a map, and in future I might write an upgradeable format where maps are stored in a map instead of a seq, and :id:s are used keys there. Map's :hit-layer is a layer with all the ordinary metadata, and the interesting data comes next: a 2D vector of booleans. Editor/future game engine will query if player can step on a tile with the following function:

(get-in hit-layer [x y])

:name is the string visible in editor's Maps-listbox. The actual data this metadata describes is a vector of layers. Layer's metadata is in my opinion self-explanatory. All values editor cares of are present in the example above. Valid :opacity values are 0<=:opacity<=255

Layers are again 2D-vectors, where one queries tile located at (x,y) completely the same way as with hit-layer. Instead of booleans real layers consist of tile-structures.

Tile's 4 interesting values are :x, :y, :tileset and :rotation. :tileset is the key editor queries the tileset with, valid values are defined by the names of the png-files in your zip-file. :x and :y define which of the 50px*50px chunks in the aforementioned tileset tile is rendered with. The origin is, similar to most of the 2D-things, in the upper left corner. :rotation's valid values are 0<=:rotation<4. Tile is rendered in the angle of 90&dg;*:rotation.

Map's origin is also in the upper left corner

Upgrade-path

It's possible that this isn't the final format :D. In case I screw with the format of the map I'll change the inner .memap-files' extension to something else, .memapx or something, and write an upgrade procedure. If I add something else (like, for example, script files), I'll just dump them to a specific folder in the root of the .zip-package.

That's it

It's really not a complex format. Files are not exactly small, but structure is loose, with Clojure's reader-facilities made implementation unbelievably easy, and XML would've been twice bigger.

Anyway, are there details I've overlooked?

Sunday 12 July 2015

Initial release of MEMAPPER

It's released!

Wow,

Back in 2011 I incrementally developed five versions of this infamous tilemap editor and published them $deity knows where, probably in the initial F&C. Then I understood that spec was too simple, we needed a multilayered format. One which understood alpha channel and layer-transparencies Paint.NET-style. One which could rotate tiles in real-time. One which understood multiple maps per file, with multiple tilesets per file.

I created an interpration of this spec with Java. It was shit. I began a software-job, which negatively impacted the schedule. I spent most of 2012 trying to understand Linux and Lisps. April -13, I began with a new revision of clj-memapper. I hacked it till christmas and decided it was shit. I sulked until summer of '14. I hacked a better version in July, and for $deity knows why, left it rotting 80% ready for a year. Last weekend I decided that the image-thing I had tech-wanked over for two years would be the death of this thing. I wrote procedures that dump editor's state to disk and the inverse of that, plus fixed a few bugs, and released the damn thing.

Look!

It is released!

I repeat: the thing I've techwanked over for last four years is released. Feature-freeze of 2011 is finally implemented. Codebase doesn't suck. Everything is fine and underdocumented.

What's interesting is that if I do radical stuff like this more, this project called MERPG has a slight chance of shipping before my grandchildren roam the earth.

 What now?

If you have a project where you'd need tilemaps, with 50px*50px tiles, and actually understand clojure (enough to use the github-visible merpg.IO.out - functions) or are able to deduce the yet-undocumented file format (hint: editor produces zip-packages), please do give this thing a try. I'm certain there are ways to break the system, and I'd love to find them.

What next?

I'll need to document this thing. At least the file format, although one versed in Clojure (or EDN) can probably understand it easily. Do I have to create the documents that hold user's hand through the main use-cases?

After that I think a new blogpost will follow. There are some new techwankments I'd love to explore while waiting for the new story and any graphics to materialize.

Let me repeat:

MEMAPPER IS RELEASED. DOWNLOAD FROM GITHUB. 

It runs on Java, so it shouldn't matter which OS you run it on. Currently I've only tested it on Linux though, but I have no idea why it should refuse to run anywhere else. It needs at least a Java 6 JRE. I recommend the latest OpenJRE. As far as I know Oracle is still distributing ask-malware with their Windows-JRE.

Memapper is tested only on a powerful workstation. Due to Swing's software renderer and not-really-optimized code of mine Memapper might get high CPU Usage that drains laptop battery fast.

This is beta quality software. It doesn't implement Ctrl+Z - functionality (yet I hope) and might crash without a notice. If it does so, I'd love some sort of a report.

Tuesday 31 March 2015

Road this far (sort-of like-a speech)

I'm tasked with making a speech tomorrow at school. Interesting. To fill the gaping void of my blog, I decided to write it up here too.

Note to those who shared these experiences I'm telling here with me: this is obviously a bit dramatized and I'm pulling the years mostly out of my arse. They might be correct, but their exact correctness doesn't matter to my message.

Specs of this speech are: 5 minutes of talk about a subject somehow relating to my profession of choice, with optional ppt-diashow.

So, hello everybody. I'm Feuer and I've come here today to tell you of my history as a programmer. I might draw some nice conclusions along the way, but let's not go there yet.

Let's return to the year of our lord 2005. It's christmas. I've caught cold just in time for the holidays. At 24th the sun rises, sun sets and somewhere along the evening Santa Claus arrives. Cool. The best part of christmas has arrived for the 12-year-old me. I open the minor presents, which I sadly can't recite anymore almost a decade after. Then I get to the last, surprisingly heavy present. I tear the wrappings off. It seems to be a new bag. Whatever has Santa thought I'd need that for? It was way too heavy and small to be used as a schoolbag. Fortunately I get my thoughts together and check if the bag contains some surprise.

It did

(META: It wasn't exactly that computer, but it was some sort of presario from early -00s. I seem to have forgotten the model and unfortunately have got rid of the computer)

There was a used Compaq from early -00s. She had some sort of duron, 128MB of RAM and a real S3-graphics chip. OS was XP. With that beauty I really began my career. I played the first two Age of Empires games and the Age of Mythology deity knows how much. I think I also began my first really long prose with her. We shared so many great moments I've not been able to relive with any of my later computers.

But I don't think you're here to listen about my first love. You want to know how that computer prepared me for this education and profession.

As an avid gamer I had always wanted to make a game. One fine day in the summer of -06 I was visiting a friend. We were playing with a computer, or something. The day before I had downloaded Coolbasic, but as the code seemed incomprehensible (albeit being almost pure, imperative, english). I took a glance on it and decided I'd try to understand it later. That day I was considering on removing the whole programming environment, for I probably wouldn't understand a thing of it or its tutorials.

Then my friend's father, my idol in the context of computers, arrived to the scene. "Feuer, do you know how to program a computer?" he asked. "Well.. I have downloaded a thing. I don't know how to use it though." I told him. "You should learn to. It's a nice feeling to hold a complete command of the computer in your fingertips" he said the truest words I have ever heard anyone speaking.

That inspired me to change the way I had approached programming. Instead of probably never understanding a thing of it, I decided, like I had so many times before as a kid done, to understand the trade as well as it's possible to in one lifetime. I learned (Cool)basic, hacking with it until I could tear the very seams of the runtime interpreter open.

My hardware got upgraded a few times during that era. Two years later I had moved from a 128MT/XP-laptop to a 4GB/Vista - self-assembled desktop computer.

By 2010 I began to be fed up with the limitations of the environment. I learned enough C++ to be dangerous. I spent a few months trying to hack an implementation of a game design of mine with C++ & SDL. I never got a finished product, but I got enough scars and knowledge to gain a new perspective on this field. Programming can be hard and most programmers seem to like pain in great amounts.

After the first half of 2011 I spoke fluently Java and C# . With C# I've never had a specific goal in mind, it has just been a nicer java with lousier 2D-drawing libraries. With Java I've always been on the road to implement my game any day now. Back in -11, instead of actually listening in the programming classes of my vocational school I proved my worth to the lecturer by implementing a two-dimensional tile map editor in Java. He was a great teacher, manipulated me to attend the classes and stay silent by providing helpful feedback when I got stuck. When I wasn't stuck, he stayed out of my way, as long as I passed the tests. I did, usually with the best grades. Our school could probably learn a thing or two of this way of teaching programming.

At some point I also learned PHP. I used it to write my first, self-written vulnerabilities. Fortunately my PHP-dabbling has happened with my own websites, which are to be expected to be of lower quality for being a playground for a newbie programmer.

By the end of 2012 C# and Java, those I had written all my desktop stuff in and had used professionally, began to feel a bit painful to write in. I asked why I have to write ten lines to just write "Hello world!" to console. I also asked if one could cheat the compiler to write some of the final code from a template. I also wondered why Visual Studio, the environment programmers tend to regard highly, leans so much on mouse. Are we not programmers, whose main tool is the keyboard!? If using a bloody mouse is so loved by many, why are we all not coding with Android-tablets?

I found Lisp. It answered my questions: you don't have to write a book to get a string to console. It's just (format t "Hello world!"). AST-manipulating macros of Lisp are templateish functions that generate and return new parts to AST in the compile phase. Emacs, the editor used by almost every Lisp aficionado, prides itself on not requiring mouse.

All the languages before the Lisp felt like work. They were almost the same language, with variable amounts of complexity and insanity thrown in. Lisp, however, was different. People who have designed it in the 50 years it has existed were not after pragmatism, which I think is a synonym for complexity in the proglang communities. They were university-folk making a tool that made them easier to do really smart things. That feels to be a major design principle in the language: keeping it simple, yet powerful.

Once I figured this principle out, I began to ask myself a lot of questions like "Why is this thing so complex?" and "Why isn't this thing half as powerful as it could be?". This, and better supported lisp-environments and emacs-packages, led me out of the world of Windows. Suddenly I realized I'm using Arch Linux, the operating system that optimizes best the axes of usability and simplicity. I'm crying literal tears every time I have to not be inside Emacs. In my ideal world, I'd be writing server-softaware in Lisp (META: probably Clojure) without foul things like X bothering me. Or possible some system-level stuff with C

In conclusion: after a decade I finally think I have some sort of idea how this thing called programming is done.

Also, in Finland, the promised land of Microsoft and Java, I fear I'm almost unemployable for not liking languages that aren't Lisp. (and to strengthen the joke here, let me add a smiley:) :D.

Thank you, any questions?

META:

It seems I have about 1400 words by now. Wish me luck in transforming this into an oral presentation.

Sunday 25 January 2015

Humen!

So, last year has gone, this year begun. I'm in Kotka, land is white with snow and everything seems ordinary. Unbelievably dull and uncreative environment for such a free spirit as me, don't you agree? Well, for starters, I don't. Last spring I tried to enhance the creativity of this dull-sounding environment by barricading myself in this flat. Results I've hopefully talked long enough already here. Last autumn I tried similar thing by participating in the startup-things. That worked out a bit better. I didn't produce anything concrete in them, but now I understand how my thinking has been flawed. I might be committing one of the deathly sins, but I think I'm scrapping the Lomaproosa, the original unreleased tale of my world of Kanariffa, to be just a (too) long-lived design document. Currently I have a prequel to that tale under development, in english this time, and once I have solid foundations, I'll rewrite the Lomaproosa in english too. It needs a rewrite, not only because of my arguably stupid dream of worldwide audience, but there is the whole middle-section I'd like to burn in eternal fires of oblivion.

Let's return to this world. Barricading myself in with the computer is supposed to be more creative than trying to be a bloody extrovert, isn't it? I mean, last spring I came up with the instant messenger-thingy, whereas last autumn I didn't create anything, as I just said. If we value our actions only by concrete creations, then yes, last spring was infinitely better, but if we value also well-being and have some long term vision, autumn was better. It pains me to say this, for I know what a PITA people can be, but creativity is not something that is found within oneself. Or at least not within me. I actually do require people to be able to think at all. There would be no Kanariffa without me and a few friends abusing caffeine in the middle of the long summer nights. There could be MERPG if I interacted with any designers face-to-face in my daily life (thanks KyAMK for keeping them in the north and us in the south!). Fortunately though I don't, for if such a thing existed, its biggest asset, the story, would be a disappointment.

But past is past, and I must face this newish year bold. Shall I also perish with it boldly? That remains to be seen.

I don't remember if I have announced this here yet. I'm in our local student association's board. I don't have (at least yet) any real responsibility, so pedagogically I'm just trying to infer how these organization thingies are ran. There's also some space to influence things, and I see a WTF in a need of fixing, I wont hesitate to do so. But the best thing I enjoy there? The general feeling of insanity. Days are long, but people seem to enjoy each other. This is nice, for this kind of environment boosts creativity. The organization has existed for thirty years, so there's some culture I need to get familiar with. So, more things to inspire from.

I'm interested if it's only the company of diverse people that has creative results in things I do, or being out of the comfort zone in general. I'm very close to applyin as a tutor. This sounds like the complete opposite of what I like doing, what with a billion familiar and unfamiliar people to interact with, and no absolute, correct answer to solve the whatever problem tutors are trying to solve.

There are serious human-related thingies (not neccessarily problems) that I'm looking forward to pondering on. Now, with clock 1:30am and alarm set up at 8am, I fare thee good night and merry last day of GGJ tomorrow.