The figure-rectangle-quad fetish.

dsp2017-1.png

The inheritance pattern was always like an assumption of the best, one and only solution of creating groups of concepts. In the workplace, on the university, in hobby projects, in books. Because if quad is a rectangle, then it’s afolso a figure. So it’s a perfect candidate for an inheritance design.

IS A, IS A, IS A

One of the guidelines taught on the university and in some books about c++:

  • Q: ‘When should you use composition and when inheritance?’
  • A: ‘When the relationship is more like ‘IT IS’, use inheritance. If the ‘IS COMPOSED FROM’ is more accurate, use composition.’

Whatever project I’ve seen, most of them had an impressive inheritance tree. Sometimes it seemed that multiple level of classes was just for the source code to look smart. In the advanced stage of the project, the whole designed structure was turning out to be flawed. In the result it was bent in an ugly way to fit the new requirements. Not to mention about the journey through all the ancestors to figure out how the youngest class is really behaving.

We have a BehaviorA, BehaviorB and BehaviorC. Then we have a concept, which should behave using A and B, and another concept which should behave using B and C. Inheritance says: make base class with A behavior. And then add two classes: one for B and one for C separately. Both of them should inherit from A. Think about it: what’s the point of that? What if another concept is introduced, which should have A,B,C,D behavior? Why not use a factory function which will know A, B, C, D and then just compose those behaviors into a needed concept? Ok, it’s not so sophisticated as inheritance. But isn’t that just simpler?

Inheritance locks groups of behaviors into permanent concepts. Shouldn’t those behaviors be freed and used as the building blocks?

BEHAVES LIKE, BEHAVES LIKE, BEHAVES LIKE

Recently I was relieved, that what intuitively seems to me as a winning solution was backed in this video:

I don’t see the point of using the inheritance at all. I don’t think it’s a good pattern. I don’t think it should be used.

Also the author of the ‘You Don’t Know Js’ series strongly encourages to not to try to simulate the inheritance in Javascript. Even despite the class keyword being introduced in ES6! The prototype mechanism fits the composition perfectly. As the common behavior can be delegated to another object. Not copied and locked into an inelastic structure.

Another article, this time from Eric Elliot: https://medium.com/@_ericelliott/what-you-were-taught-was-not-prototypal-inheritance-f853ce3db00e#.cgs1zt2di

“Favor composition over class inheritance” – the Gang of Four

‘Composition over inheritance’ and yet the second one seems to reign in majority of the projects.

written in Emacs with org2blog mode

Cubicforest models.

dsp2017-1.png

Introduction

How the Cubicforest models will be created? It will be an isometric game with models made from cubes. What tools are involved in the process:

  • Blender software
  • Python scripts
  • Cube’s sprites in different colors.

Blender models

As it’s a sin to write tools, which already exist, I’m using Blender software to create 3d models, which are exported to JSON files. By starting with a position [0.0, 0.0, 0.0], cubes are added in Blender one by one, to create a final effect. Positioning is important: as the cubes have constant dimensions, when added next to each other, the exported file gives positions without fractions. It’s important later to easily indicate the order of the cubes for 2d rendering.

Python script. Json.

Blender allows to interact with the scene with a help of Python scripting. I’ve used it to export model’s data to JSON files. What is exported:

  • cubes’ positions
  • cubes’ colors

Script will be discussed in another post.

Colors

I’ve came up with a simple idea of exporting predefined colors. I didn’t succeed with coloring sprites in LibGDX, so I created ready, colored textures. List of colors includes ‘pink’, ‘dark pink’, ‘green’ etc. To keep everything simple the cubes have assigned named materials according to the color they should represent in the game’s world. Later the material names are associated with the according cube sprites.

2d sprites

atlas.png

First the 3d positions are sorted into 4 groups: for every angle of the future 2d sprite’s model. Depending on the angle, the group starts with the cube which is farthest (from the camera) and ends with the nearest one. 3d Positions are then mapped into isometric ones and painted onto texture one by one.

From the bottom layer of the model to the top. After that the sprite is saved: the final look is ready.

Effects

The person saying ‘A picture is worth a thousand words’ has just been shot.

Blender models:

wolf.jpg

pig.jpg

Rendered sprites:

wolves.png

pigs.png

written in Emacs with org2blog mode

You Don’t Know English

dsp2017-1.png

Post written in polish. But it’s not 100% a technical one.

Po co tłumaczyć książki programistyczne na język polski? Tzn. w sumie znam odpowiedź. W końcu się sprzedają i na pewno jest uwarunkowane to ekonomicznie. Może nie znam jakiegoś kruczka prawnego, który pozwala otrzymać ulgę podatkową, jeśli książka jest polskiego wydania? Może być.

Angielski jest jednym z podstawowych narzędzi w pracy programisty. Nie trzeba w nim płynnie mówić czy pisać. Ale większość dostępnych materiałów jest właśnie w tym języku. Im więcej się czyta, tym czyta się sprawniej, aż w końcu w tym drugim języku zaczyna się myśleć i niezauważalnie staje się tak samo przyjazny jak polski.

Aboslutnie rozumiem dlaczego bloguje się po polsku. W natywnym języku pisze się łatwiej. Ten post piszę 3 razy szybciej. Dalej: treść przekazana w natywnym języku jest atrakcyjniejsza dla polskiego odbiorcy. Maciej Aniserowicz (organizator DajSięPoznać) posiada grupę czytelników godną pozazdroszczenia. Co jest dowodem, że można dużo osiągnąć koncentrując się na mniejszej grupie. Ale jednak, jak sam napisał: zastanawia się, czy technicznych postów nie pisać jednak po angielsku. Ok, ten akapit to taka chwilowa dygresja na tematy językowe. Wracam do meritum.

Bohaterem pogadanki jest polskie wydanie You Don’t Know JS. Na recenzję polskiego wydania natknąłem się na pewnym polskojęzycznym blogu. Autor raczej koncentrował się na treści książki, niż tłumaczeniu, ale napisał, że woli książki w języku polskim, bo po angielsku czytać to tak nie bardzo. I sądząc po jego postach, jest na pewnie dobrym programistą, którego umiejętności zasługują na szacunek. Ale jeśli ktoś ma do wyboru oryginał po angielsku i wybiera polskie tłumaczenie, to robi błąd. Jeśli nie ćwiczy czytania po angielsku: znów błąd.

Książki techniczne to nie beletrystyka. Tej to nie wiem, czy byłbym w stanie czytać po angielsku. Na pewno spróbuję. Ale to inna para kaloszy: mam ogromną przyjemność z czytania polskich tłumaczeń książek Phillpa Dicka, Lovecrafta czy Diuny Herberta. Polskie tłumaczenie dostarcza mi rozrywki, której szukam. Ale w przypadku programowania: tutaj ma cholerne znaczenie każde słowo. Przekręcenie zdania to nie przekręcenie imienia bohatera czy spalenie dowcipu, który brzmi zabójczo w oryginale. To wprowadzanie czytelnika w błąd, który może pociągnąć za sobą lawinę błędnie rozumianych koncepcji do końca lektury.

Nie mogłem uwierzyć:

“(…) Put slightly differently, it’s said that bar() closes over the scope of foo(). Why? Because bar() appears nested inside of foo(). Plain and simple.” “(…) Ujmując rzecz inaczej, można powiedzieć, że funkcja bar() zostaje zamknięta przez zakres foo(). Dlaczego? Dlatego że funkcja bar() wydaje się zagnieżdżona wewnątrz foo(). To powinno być jasne i oczywiste”

Wydaje się, to do dupy wydawnictwo Helion. To powinno być jasne. I oczywiste.

Ten błąd wypala mi oczy. Za każdym razem. I ktoś sobie pomyśli: ‘Aha! Więc w JS niektóre funkcje się wydają, a inne nie! Figlarny ten język, nie ma co.’ Tak w ogóle, jak coś może się jednocześnie ‘wydawać’ a jednocześnie być ‘jasne i oczywiste’?

Do cholery: to tłumacz, czy Helion przepuszcza książki przez translator? A może siedzi w piwnicy licealista, któremu wydawca podrzuca pod drzwi kawałki pizzy, by biedak nie opadł z sił, tłumacząc w bieżącym tygodniu już piątą książkę? Na tym opiera się model biznesowy wydawnictwa? Wydać książkę, byle wydać? Helion i jego tłumacze z premedytacją wypuszczają na rynek szkodliwie przetłumaczone pozycje.

Programuje się po angielsku. Dokumentację czyta się po angielsku. Książki programistyczne wydane po angielsku, najlepiej czyta się po angielsku. Oryginał jest po polsku? Super, cieszmy się, że w tym piękniejszym języku również jest coś porządnie napisane. W tym przypadku to nie ma znaczenia. Liczy się zaufanie do profesjonalizmu treści.

Żałuję, że wydałem na tą przetłumaczoną serię 120 złotych. Tak, wiem że to cholernie mało, polskie wydania mają boskie ceny. Ale wolałbym wydać dwa razy tyle i dostać oryginał, albo po prostu przelać pieniądze autorowi, udostępniającemu książki za friko, bo napracował się przy tej świetnej serii. W przeciwieństwie do pewnych partaczy.

Nie bądźmy programistami, którym “nie bardzo” czyta się po angielsku. Bądźmy lepsi, niż tłumacze Helionu.

Rzekłem.

written in Emacs with org2blog mode

A look into the past.

dsp2017-1.png

Introduction

I’m going to use whatever I can from the previous project. I’ll list some of the know-how which will be useful in Cubicforest.

cubic.png

The gameplay

I’m now 100% sure if I’ll use the original idea of the rules (You can check them here: http://adam.skobo.pl/?p=697). Anyway I have tested some variants and now I have some knowledge about do’s and dont’s for what the game could be about. Although idea is not complicated, I’ll look for ways to simplify it even more.

Tiled levels

I have ready recipe on creating maps in Tiled. It may seem as something easy: jut put elements on the map, export to the file, load the file. But: You have to decide how to organize the layers, how to name them, how to smuggle other level-data needed (like available player tools). Maybe even Java source code for loading that data (organizing in data structures) will be useful. Old post: http://adam.skobo.pl/?p=537.

Cubic models

And now an absolute time saver. How to build 3d models, export them to the .blend file, convert it to JSON and then make an import to the game. Little Python magic involved, as it’s a native language for the Blender.

blender.jpg Blender models examples. Their 2d representations visible on the previous screenshot.

How to build a 2d sprite is an another interesting topic. Depending on the 2d perspective, cube’s texture should be drawn in the right order to recreate model in the isometric projection.

Old source code

Not sure if the source code itself will be useful: it does not have some complicated algorithms and neither the noteworthy code structure. But it’s good to have a look on the old files. Maybe something interesting will be noticed.

Solver

Ok, one component is definitely worth of attention: levels solver. Previous version has a component which recursively checks all the possible player’s decisions and gather the winning ones. The way to do it, taking into account level’s structure, is not so obvious.

So in the end: I’m glad that the abandoned project will have a second chance. A Javascript one.

written in Emacs with org2blog mode

Why it’s not finished?

dsp2017-1.png

Introduction

As the present contest app is a rewrite of the Cubicforest-java project, I would like to write about my thoughts, why it wasn’t finished. Nonetheless, I’m happy with the results: what I’ve learned is mine. It wasn’t only a software development lesson, because writing a project requires also other skills.

Write small (not)

I think it’s a quite common reason of failure in finishing any vision. Not adjusting the available resources to the project’s requirments. And by that I mean mostly the number of developers, which in case of a home projects is one. That, plus the available time and patience. How long will You endure, writing the same project on and on, after hours and during the limited time on weekends? Will the desire of implementing Your vision be enough?

We’re starting too big, dreaming about creating something original and recognizable. Risking not finishing anything. Not realizing that finishing something smaller will give us enough satisfaction and fun to start something new very soon.

So yes: Cubicforest turned out to be too big to finish before burnout. I would say it’s finished in 60%.

Still learning and always will.

I’ve read somewhere, that rewriting projects could be a good exercise. The best way to learn is to write, write, write. We’re learning new things, getting back to our old source code and rolling our eyes, thinking ‘how could I ever write something like that’. And that’s the thing: the bigger the project, the harder is to perform the desired refactoring. Of course if it’s an extremely important project, we’re agreeing on compromises by doing only some of the needed changes: generally because of the lack of time. Or motivation.

And one more time: that’s why writing smaller hobby projects is better. We can start over without the luggage of bad assumptions. I wasn’t completely dissatisfied with my code. Once I even wanted to continue the project. But right now I’m too tempted to write it better. With the new language I’m learning, new blog posts read, new practice. I want to use experience from that project and mix it with new things I’ve learned lately.

Not doing it fast.

Hm. I thought this post will be longer, but I’m finding only two mentioned reasons.

Too big project.

Want to and will write it better.

I will add another one, pretty similar to the first. Don’t let yourself to work on something too long. You’re losing impetus.

written in Emacs with org2blog mode

Dajsiepoznac2017 contest app.

dsp2017-1.png

New edition of Dajsiepoznac contest has begun. It’s the new era for my blog (hopefully) and I’m going to write here only about concretes. Without story telling or unnecessary ‘blah blah blah’ (am I the only one annoyed by the ‘blah blah blah’ on the blogs?): let me begin.

I’m going to reactivate my unfinished Cubicforest game project (https://github.com/adamskopl/cubicforest-java). Written in Java using LibGDX library. Extremely enlightening experience, lots of work, lots of learning. Why it’s not finished: that’s a topic for the next post.

tiled-cubic.png Early version with sprites.

For the new version I’ve chosen my current main language: Javascript. I’m going to use my experience with the previous version: mainly the way of building and displaying models. The rules of the game are not ready yet, the previous ones seems to be over complicated. For now it does not matter. Despite of the fact, that gameplay details are not known, current basic assumptions will not change:

  • world is built out of one-sized cubes
  • world is isometric
  • gameplay is turn based
  • game world is built from tiles (like on screenshots)
  • characters are moving from tile to tile

cubic.png Late version with all objects built from single cube sprites. Based on 3d models made in Blender

Until I’ll reach that moment, I’ve got a lot of work to do. Mentioned points are my main concern right now. I’ve taken approach to which I’m not fully convinced, but intuitively I’m suspecting that it will not blow in my face. I will concentrate on the display. I will not begin gameplay development until the way of displaying cube-based models will not be ready. Without them my vision has no meaning. Displaying cubes, moving them dynamically, changing their colors, displaying models, destroying them: these are my main concerns.

With cubic engine ready, I’ll try to finish a simple turn based game. 3 month deadline is very cruel. But also very motivating.

Cubicforest gameplay.

written in Emacs with org2blog mode

No Title

dsp2017-1.png

Testing setup for the Get Noticed! contest. Not a contest post.

// testing source code
// font color is shitty and we have to deal with it.
const some = 10;
for (let i = 0; i < 10; i++) {
    window.console.log('blah blah blah');
}
switch (some) {
    case 10:
        window.console.log('blah blah blah');
        break;
    default:
        window.console.log('blah blah blah');    
}

written in Emacs with org2blog mode

Collisions trouble.

dp-300x70.png

About lately occurred collision problems.

At first I was satisfied with a first solution for collisions resolving: checking collisions after one movement iteration. What is a movement iteration: a constant time during which objects change their position, normally by moving to the next tile. If an object has a different speed, than it moves at that time a different number of tiles. This ‘movement iteration’ concept gives me more control about game flow: one movement iteration, one positions change for every object.

But lately more situations started coming up. So here are those situations with collisions check implementation explanation.

coll_mov.png

First situation shows a variant which was mistakenly assumed to be the only one. Both objects end their movement on one tile. Both are reported to CollisionHandler:

var GAME_POS = GAME_OBJECT.mov().gamePosTo;
prepareArray(this.tilesToHandle, GAME_POS.x,
        GAME_POS.y);
var ARR = this.tilesToHandle[GAME_POS.x][GAME_POS.y];
(...)
var TILE = this.tilesManager.get(GAME_POS.x, GAME_POS.y);
ARR.push(TILE);

And later every tile is used to make an every to every collision test.

Second situation shows that collisions can occur during movement iteration: when objects are passing each other during normal movement or when one object has bigger speed and passes other object during position change. This forced me to implement something I wanted to avoid: checking collisions on every update(). And this means to get all objects and check every vs every if there are no collisions.

var collObjects = this.gameObjectsManager.getAllWithout(
[GOT.ROAD, GOT.VOID]);
for (var i = 0; i < collObjects.length; i++)
        for (var j = i + 1; j < collObjects.length; j++) {
                this.game.physics.arcade.overlap(
                collObjects[i].sprite,
                collObjects[j].sprite,
                this.onCollision, null, this);

After that, collected colliding pairs have to be merged in collision groups: one group represents objects which are colliding at the exact moment of time in the same spot. So in the end these groups can be passed to CollisionHandler and handled in the same way as collision between objects ending their movement on the same tile.

Third situation: when object is starting movement from the same position as the position of an another object. It’s not a collision, because collision between those objects was already handled. The difference between those objects positions is calculated: if it’s small enough, it means that during collision check, this collision will be ignored.