Wednesday, December 16, 2015

Postmortem - 7 hours of hell

If you remember my 7 hours of hell post  you probably wonder why postmortem.

To give you introduction to this you need to know that I recently done port to Visual Studio 2013 (I used vs2010 till now). This migration was planned for some time already. I even started it in the past. But never finished because rebuilding of external libraries was pain in the a.. . Now I fixed this issue by automated building script and without bigger problems I was able to compile everything with Microsoft compiler ver: 12.0.

If this was good idea I still don't know but for sure I know that I still fixing bugs and issues that shown in meantime. I don't mind it so much because some of stuff I do right now were also in plan for future.

Probably you are curious what my one button plugin postmortem have to do with this changes ? Answer is simple I miss my one button plugin in Visual Studio 2013 ;(

I tried to use plugin without any modification but it didn't work and for now I work without it. I need to say you really can get used to this small improvement in workflow and after time I almost sure that I will bring this feature back into vs2013. Even if this will cost me another 7 hours of work :D

Greg



Sunday, November 22, 2015

Generated code

When two months ago I created generator for RTTI code I didn't realize how this one script will change so much in my programming style.

Right now I have already four of generators in my code base:
  1. RTTI - Generate part of my RTTI code.
  2. SID - Generate CStringID with already calculated hash
  3. Pimpl - Generate interface class.
  4. Enum - Generate toStringID, fromStringID functions.
So what changed for me after writing this one generator that make difference ? I try not to do monkey job. To show you how this improve my workflow let's look on generator I wrote today: Generator of Enumerator functions: toStringID, fromStringID.

This is simple problem where for some enumerators we want to have conversion from value to some verbose type. Some people may claim that this is not issue. You write functions once and they work. Later you just need to modify them when you do some changes in enum. This take like about half minute work 

... if we don't do mistake there. Then this is one extra compilation time. In some code base this can be counted in minutes. I would really love to see how much time of our programmers life we spending of stuff like that :) 

In my case I just have one macro: WR_ENUMGEN(EnumType, InvalidValue). Which look like this:
#   define WR_ENUMGEN(E, D)    \
        const CStringID&        toStringID(E a_value);                   \
        E                       fromStringID(const CStringIDa_value);
And is used like this:
    namespace EConstantsBuffers
    {
        enum Enum
        {
            CBPerFrame,
            CBPerView,
            Count,
        };
 
        typedef Enum Type;
 
        WR_ENUMGEN(TypeCount);
    };
The rest is generated :] So on top of this one line I just need to generate projects and that's all. No extra programmer steps to do. Thanks to that:

  • Adding/modifying of enumerators is simple
  • Generate code is easy to debug (what may be tricky with some macros).
  • Not slowing down my compilation. 
  • There is almost no place for any mistake  (always in sync with enum) .
  • There is unified code convention between enums.
  • Expanding of functionality need only modification of macro and/or generator.
So I don't know about you but personally with time I will probably use more and more generated code. I don't have a lot of spare time for monkey job I prefers to leave it for computers.

Greg

Thursday, November 12, 2015

Tools Design

Variable Set Editor - Main view
Continuation of previous post :] this time with real examples :D

Real tools design 

This may look like joke but this one window took me ~3 days to do. This include all it's features and communication:

Editor <-> Engine.

But this is reality. Creating good tools require time and I wasn't joking in Summary from previous post:
"As you can see creating of good tools is not easy. You often need go back and forth to create something really useful. You don't want to modify everything by scripts in which you can make easily mistake. Good tool will for sure save you a lot of work and return effort that you spend on it." 

Tuesday, November 10, 2015

Few words about tools design

Once again I will return to topic of tools. Mostly because right now this is the part of code I spend most of my time in. 

I will focus in this post on one dialog: Variables Set Editor This one dialog may sound simple but if you start thinking more about it it's really complex tool. 

So let's start with short description what Variables Sets are then lets move what we want achieve and in the end look on real implementation of this problem.

Variables Set

This is really simple system which allow you to specify some kind of properties. Right now I support only values of types: 

  • StringID
  • Float
  • Vec4.
Whole system may be use to store values like: life, attacks parameters, movement speed etc. In my case to this data have also access animation system which may request some kind of information which later may be use to control blends and generally its behavior.


Because this is simple list of variables you want to be able to have some kind of hierarchy. i.e:
NPC object contain [local set] which inherit values from [Clones set] which inherit values from [enemies set]. Change in inherited variables will be apply to all not override values. 

Dialog requirement

Short: You should be edit this stuff in nice UI.

Implementation 

Firs approach
Thanks to Qt designer this was really easy. As you can see on right everything look really nice you have section for name, you see right away type of variable are able to modify value and see what value you inherit :] If you want to add variable you using context menu (under Right Mouse Button). 

Of course this wouldn't be so easy if I ended here:P I forgot my dependencies list so I done small upgrade and finished :] Final result bellow:

Final dialog

Summary

As you can see creating of good tools is not easy. You often need go back and forth to create something really useful. You don't want to modify everything by scripts in which you can make easily mistake. Good tool will for sure save you a lot of work and return effort that you spend on it. And the tool you seen on screenshots are for sure not good one.


Saturday, October 24, 2015

7 Hours of hell

This will be story, my story based on true events.

Hour 0

Recently I start using project generator not only to generate makes, projects and solutions but also to generate some code. Because of that from time to time I need to run one python script. This is not big problem but I decided to make my life easier and add button in Visual Studio 2010 (I'm working slowly on progression to new one) which will trigger this task. Sound simple right ? 


Tuesday, October 20, 2015

My biggest problem: I try to do things right ...

In last weeks I done a lot of work on animation system. In the same time I did not code too much of it. Right now I still struggle with some basic thing: edition of blend tree. And this is not that I'm not able to code it. It just my current prototype fell somehow wrong.

I don't like forcing myself to do stuff. If I do this is the worst possible situation. Code will be messy without any clean goals and in the end it will feel somehow wrong each time there will be need of modifying it.

To not loose time I do other things completely unrelated to animation system. Leaving this problem hanging somewhere in "background". When I have time I try to find in my head a way to improve my design of editor to make my changes nicer. When I will know how I want to do it I will just sit down and code it: quicker, better and with a lot more fun.

Of course some may see all of this as excuse for not doing stuff I should :] And if somebody saying that it just mean that he don't know what programming is about. 

This is not about writing code this is about resolving problems. Code is just medium which allow us to present our solution to other people.

Greg

Tuesday, September 29, 2015

Namespaces hell

Welcome in namespace hell. In this place you will find annoying code and the best part: it is on demand. So lets start another topic base on one of my horror stories which ended with hours spend to straight things up.

But let's start from begin. This words probably don't mean a lot for you: s2d, s3d, world2d. world3d, fs, sound, physics, math, navmesh, utility, resources, game, editor, lba, wre, wr.

Personally I know them really well. All of this are namespaces that I used or using in my code. This is collection from 7 years of development and they are probably not all of them. When I start writing engine I wanted to do stuff right. So I created modules which then I encapsulate in namespaces. This was naive and stupid because I ended with annoying code. Who want to write physics::CPhysics for physics class? This is duplicated information. But well with time I got smarter and removed most of them using simple method : Find and replace all.

This was my first sin. After this operation I left with code where you could find stuff like this:

namesace wre
{
    class A : public wre::class B
    {
        ...
    }
}

The second sin is my mistake of using prefixes for basics types and functions which were outside of namespace. So I had wrVec3, wrQuat, wrMtx44 and functions with similar convention. Why I call it sin ? Because I ended with inconsistent code standard which is not something good and create really a lot of issue. For what you use prefix for what namespace?

So right now I'm decided to clean all of my past mistakes. There will be only one simple convention. Everything will be in one main namespace wr (stands for White Rabbit) and helpers wr::math. I will cleanup naming convention, remove prefixes and put everything related to engine in this namespace.

If somebody think that namespace is useless in he can always use : 


using namespace wr; 


to remove need of using it explicit. I think that this change will only result in simpler and easier to understand code. But well there are no sure things.

What do you think about namespaces ? You would recommend them or rather burn them using fire ?

Greg

Sunday, September 27, 2015

Commit comments


Now that I thought about this is interesting topic:

How your comments for commits look like?

In my case you probably think that they are poor because I do project myself. But here I will surprise you (and myself to) because most of the time I do full summary what I done in given change list. So bellow you will find few of my comments from different commits across last 3 years (I use not modified git logs) :

* 13/11/2012

* 25/02/2013

* 30/12/2013

* 05/09/2014

* 21/09/2015

I really like my current form because its simple and easy to understand. Especially with my tendency to submit multi issue change lists. I need to do something about this because this may save me a lot of troubles later. But sometimes you just starting one thing which require something else and before you notice you have overlapping changes. 

What is yours format of check-in comments. ?

Greg

Sunday, September 20, 2015

Animation System Changes: Part 1

After weeks of work (probably I could even say months) and hundred resolved tasks and bugs new animation system finally start working ;] Check final effect:


If you think that it is look no different from my old animations then you are almost right :D Currently this new system have even less functionality than old one. Because of that I needed to disable big part of gameplay.

Was it worth it ? 

Short version: I think that: YES. 

Saturday, September 19, 2015

Playing games and Dreams


Normally I don't play too much games but there are days when I just want to relax and play. Sometimes even a little too much for one day but well this have it's charm (till the next day when you need to wake up).

This week I finished playing PS3 Uncharted games and Zone of the Enders. I feel inspired by their style. I really liked Uncharted 2 graphics would it be cool if Little Big Adventure remake had this level of graphics :D Well I need to return to development I still need do few things to make dreams became true.


Tuesday, September 15, 2015

RTTI: Changes for better

As some of you may know White Rabbit Engine use it's own Run Time Type Information system. And well like with everything else sometimes come time when you need to upgrade stuff. Recently I had another occasion to do iteration over this system.

In this post I will try to give you a little bit insight how m RTTI look is engine, what changed and what are plans for future. But well let's start from begin.

Saturday, September 12, 2015

Weird thoughts

Let's start this from some thoughts about who I'm (yes I will be talking about myself).
I'm not seeing myself as somebody really intelligent I would say that I'm event think that I'm stupid. Funny thing is that with time I see that even then I'm more intelligent than a lot of people :|
Question is where this bring us and why I'm in such a position? I thought about this and my answer is: "learning". 

I like to learn new stuff, discover things that I didn't know about. This is for me something incredible and in current time we can do this really simple. Sadly because of that I see how small my knowledge is and how big the sea of possibilities is. There is always ways to growth. 

On other hands we have people who don't really want to learn. They do it only when they are forced by situation. They think that what they know is enough.

I don't know which way of thinking is good or right. The thing that I know is the fact: I don't want to stop learning. I'm where I'm because of things I done right and also all my mistakes. Thanks to all of them I'm different person today than I was yesterday and tomorrow I will be different person too.

Greg

Short Term Memory

Funny thing about doing your own tech is that you sometimes need to do some funny stuff. This week I needed done Short Term Memory Manager. My comment in code describe it like this:
Short Term Memory Manager (STM Manager). STM is memory which you want to use for short one-shot tasks:             Create->Execute->[GetResult]->Destroy It is limited by capacity so you never can use more than you pre-allocated for it. Right now it's use to transfer resource data CPU->GPU and in animations tasks.
For me this is temporary memory which I use for example to load texture data and then passing it to GPU upload (which will remove it). There are also other usage where I think using normal allocation would be a little bit overkill.

So my short term memory manager use my new memory ring buffer which look like this:

wrMemoryRingBuffer.h

wrMemoryRingBuffer.cpp

After creating this code the rest was easy:

    //////////////////////////////////////////////////////////////////////////
    uint8* CShortTermMemoryMgr::cpuAlloc( uint32 a_Nbytes, uint32 a_alignment )
    {
        // memory is HEADER + ALIGNMENT_MEMORY(ALIGNMENT-1) + HEADER_OFFSET(+1) + a_Nbytes
        uint32 memorySize = sizeof(SHeaderCPU) + a_alignment +a_Nbytes;

        uint8* memory = nullptr;

        {
            CMutexAutoLock lock(m_cpuMutex);

            memory = (uint8*)m_cpuMemory.alloc(memorySize);

            if (!memory)
            {
                if (cpuRecoverMemory(memorySize))
                {
                    memory = (uint8*)m_cpuMemory.alloc(memorySize);
                }
                else
                {
                    WR_ERROR(false, "There is not enough memory for this allocation.");
                    return nullptr;
                }
            }
        }

        // Create memory header
        SHeaderCPU* header = (SHeaderCPU*)memory;
        header->isUse = true;
        header->size = a_Nbytes;

        // Fill offset info
        uint8* data = wrAlignAdress(memory + sizeof(SHeaderCPU)+1, a_alignment);
        data[-1] = static_cast<uint8>(data-memory);

        return data; 
    }

    //////////////////////////////////////////////////////////////////////////
    void CShortTermMemoryMgr::cpuFree( uint8* memory )
    {
        if (memory)
        {
            CMutexAutoLock lock(m_cpuMutex);
            SHeaderCPU* header = (SHeaderCPU*)(memory - memory[-1]);
            header->isUse = false;
        }
    }
    //////////////////////////////////////////////////////////////////////////
    bool CShortTermMemoryMgr::cpuRecoverMemory( uint32 a_memoryNeed )
    {
        const void* memory = nullptr;

        while(m_cpuMemory.getBiggestAllocSize() < a_memoryNeed && (memory = m_cpuMemory.peek()))
        {
            const SHeaderCPU* header = (const SHeaderCPU*)memory;

            if (!header->isUse)
            {
                m_cpuMemory.free();
            }
            else
            {
                break;
            }
        }

        return m_cpuMemory.getBiggestAllocSize() >= a_memoryNeed;
    }
I added also two helper functions:
    
    template<class t="">
    T* CShortTermMemoryMgr::cpuAllocT( uint32 a_alignment )
    {
        if (uint8* memory = cpuAlloc(sizeof(T), a_alignment))
        {
            return wrNewExt(memory) T;
        }

        return nullptr;
    }

    template<class t="">
    void CShortTermMemoryMgr::cpuFreeT( T* a_memory )
    {
        if (a_memory)
        {
            a_memory->~T();
            cpuFree((uint8*)a_memory);
        }
    }


And this finalized my work :] Personally I really like how this came out. Its simple and pretty efficient but well I'm curious what you think about this? Maybe you have some betters idea how to resolve problems like this?

Greg

Sunday, September 6, 2015

Hunting of memory corruption

This is the story of memory corruption hunting and what I learned thanks to it.

So the story started when after one of many big changes in component system I needed to re-save all maps and objects templates :] Because I'm lazy bastard some time ago I created processes which loading each of it and re-save. All this after pressing one "magic" button. Great idea and in the same real stress test how object system works.

Sadly after all this time I didn't use it, whole process failed. And in worst possible way: memory corruption. Everybody who have occasion to deal with at leas one not trivial one know that this are not nice bug. Especially in multi-threaded environment:/ In my case normal corruption wasn't enough and sometimes even my callstack was corrupted. Fun :|

So well my hunt begin because I couldn't left this issue without fix.

1st approach: Debugger
The first approach was the most trivial one check what happening when app crashed. Simple and useful but not in this place. The debugger stop when it's already too late. I tried to find some pattern in memory which is corrupted and nothing there :/ I failed.

2nd approach: Enabling all my memory debugging options. 
Yeah in all this years I accumulate some memory debugging tools like: full tracing what memory is allocated, memory guards, validation if memory is not release second time and full allocation/releasing logging. Final result: another defeat :/ 

Non of this tool helped. I only found that my guard sometimes get replaced from "WREGUARD" to "WREGWARD" :/ and it's happening in TiXML node memory (I using XML right now for storing RAW version of map which is use in editor. But let's return to this topic in next approach).

3rd approach: Checks on memory release (Desperation begin somewhere here)
Microsoft _CrtCheckMemory(..) is so nice thing. But well after I done that I can say: I was stupid. XML and full memory check on memory release. Heeeee heeee heee hee he (laugh of crazy person). I started process and started play Uncharted 2 on PS3 and after more than hour later it was still releasing the first map. 

This as bad idea as idea to use XML for project:/ My To-Do task for replacing it with Jason gain higher priority after this.

4th approach: Decoding of callstack from stack memory.
Yep I was so desperate that I learn how to decode callstack from memory for win32 (In the fact it's really easy :D but well. Right now I know how to decode PowerPC, x86 callstack so only x64 left). 

After reading corrupted stack I learned: nothing more than I already know. Releasing of xml again :/

5th approach: Luck
And this one was in the fact funny because I noticed that very often memory which is released is not managed by my memory tools. So after short check I find out sad truth: Allocating memory in one module and releasing it in another is not the best idea :/

Another funny side story:
To be sure that I removed the issue I installed even Valgrind on my Linux computer but it was crashing in initialization of libGlew. First thought: well probably Valgrind do something that glew crash. Because I didn't want to spend too much time into it I just ignored. 

This was mistake. One simple check: run game without Valgrind would show me that the problem was in my changes that I done on Windows not tool itself. But well :/ Day later I figure out this and will soon run full check of editor using Valgrind (This is one of reason why its worth to have Linux build :) )

Summary 
This one issue shown me so much problems with my code. After it I properly secured my code for releasing of memory from other module, guess what ? I found more of similar problems :/ 

But well right now everything what I found is fixed but this is not the end. I decided that after animations it will be good occasion to spend some time on improving my memory system: make it quicker, allow better control over it and add more tools for checking stuff (just in case). 

From things I will do I will for sure switch on explicit use of dlmalloc and switch on memory tags stack:
 MemStack memstack(EMemTag::System); int32* memory = wrNew int32 [32]
Which will coexist with my existing system:
 int32* memory = wrNewEx(EMemType:System) int32 [32];
Do you have some recommendations what you would want to see in your memory system? How you would trace stuff like that? Do you have maybe some nice secret tool that can help? Or maybe some nice trick in your slave that could help me with future issues ?

Greg

Sunday, August 30, 2015

Return from overseas

Finally I have my stuff from Canada :] There is a lot of them but one of the important ones are my computers. Thanks to that I return to normal programming but well before that I needed to sync my projects.

There was a lot of changes in projects in last three months so I expected problems and well there were :)

  • First is my lack of normal internet connection :/ yep I still waiting for it. So right now I try to use hotspot option in android to be able exchange code between Linux laptop <-> PC.
  • Second was broken Windows build :/ I tried really hard to have working version of windows but without continuous compilation it's hard to switch systems all the time just to check if I didn't broke something. But well hour later the build worked.
  • Third were missing manifest generations (TBD) which allow me to hold plugins to editor in separate folder. Because of that I needed to do some changes manually.
  • My continuous compilation is still dead I need to recover it (I missing it).


There were also things that went well:
  • New project generator works great :D I needed to do some improvement which took like one minute. Right now I'm adding support to vs2013 and I'm really happy how easy it is.
  • Compilation time - better computer and I don't have time almost on anything between pressing compiling and starting tools.
  • After fixing compilation errors everything works again.
  • I started using sharing of keyboard and mouse (I using Synergy) and this allow me on quicker switching between systems :) 
So as you see I'm not laying around and doing nothing. Return of my hardware should be boost for me in development and allow me on quicker iteration time and there is a lot to do :/ But well, such a life.

Greg

Sunday, August 16, 2015

Am I good programmer?

After some break in posting I returning with another weird topic :D

Am I good programmer ? 

This is one of this topics that is simple: I'm the best programmer :D so we all came to this nice conclusion and we can end all discussion ...

If only real life was so simple :) Some time ago I spend whole evening with friend discussing if I am good in what I do. Funny thing is that in this discussion I was the person who claimed that I'm still not skilled enough. Because what in the end mean that I'm good programmer?

I think that this is tricky question because of multiple reason:

  1. It depend who you compare to.
  2. It depend what kind of work you do/done.
  3. It depend what you expect being good in.
  4. It depend what you mean by being good.
So lets start in order:
Follow and be followed

After all this year I spend on programming I still seeing that there are people who are better than me and in the same time I see people that are not so good as me. It don't mean that they are good or bad. 

It just happen that in current time we are in this configuration. Few years later situation may change I can be better than all of them. Nothing may change and there exist possibility that I will be the worst of them. This is the reason why we programmers can never stop learning. In this world everything changing and if won't change with it we will be left behind.

Look what I done

This one is tricky because what mean that I done something? This most of the time mean that:
  • This task was assigned to me,
  • There was need for it,
  • There is no similar system in code base,
  • I sacrifice my own time to do something after work.
All of this mean that not everybody can do great, big stuff in work. There is army of people which do small changes, bug fixes and support. This not mean that they are worse than the people who done big systems.

I'm good in what I do

In this world there are specialist, generalists and stupid people like me. 
  • Specialists - are people who are awesome in what they do but they knowledge behind their specialization is often really limited. 
  • Generalists - are people who know a little bit of everything but they don't have tight specialization.
  • There are also this stupid people who want to be specialists in everything. Always trying to have big knowledge in everything they touch.
No mater which kind of people you want to be it won't be easy.

I'm who I'm 

If you see me as good programmer I'm appreciate this. If not then tell me why you think so. I will try my best to fix this. In the end I'm just another programmer who do the best it can to be the best in what he do. Thanks to that I know that I still have infinite possibilities for growth and this is what I love in this work: 

I can learn new stuff all the time so it's never really boring.

This is also reason why in my eyes you need to deserve for being good programmer you don't gain it just because you done something or you have a lot years of experience. You need to prove it to me and do this all the time.

Greg




Monday, July 27, 2015

Bug in rendering of editor

Week ago I wrote post about porting editor to linux. I was mentioning there this weird bug :
Editor works (Yes I know that drawing area is shifted to right. This is one of bugs that I still don't know why happening and I already spend on it like two days :/)
Which is really nicely visible on this screen shoot:


I spend on it like three days and still wasn't able to figure out why it happening or find any trace of it. I tried to ignore it but after noticing similar issues with blender and chrome I decided on desperate step. 

From my experience I know that upgrades of system never ending good. This is the reason why I try avoid them as much as it possible. But well sometimes you need to do stupid things so I decided to update my Linux (Ubuntu 14.04) and graphics card drivers (fglrx-14.301) to newest versions.

What went good: I was nicely surprised that system upgrade went without bigger problems. There were two steps 14.04 -> 14.10 -> 15.04 which took some time but except that I cannot complain.

What went wrong: Update of graphics card drivers. This is sad that after all this years you are not able to install driver without any problems. It took me half day of work, checking a lot of pages and in the end modifying source code of driver to make it work. This was just one line of code but still :/

Final result: Well decide yourselves:


It work how it should work but well I hate bugs like this. If I knew update of system would fix that I would spend 1 day on update not 3 days searching blindly what I doing wrong.

But well this is our developers reality: dealing with our bugs and bugs of others.

Greg

Saturday, July 18, 2015

Scripting language in game ....

I know I know I stepping on thick Ice. Some people love scripting languages other hate and other don't care. Personally I still don't know to which group I belong.

I somehow understand all sides:

  • Scripting language:
    • [+] Have quick iteration time
    • [+] Non programmer can do some simple stuff
    • [+] It's easier than native code
    • [+] Separate game from engine
    • [-] Can be slow (most of the time is)
    • [-] Use garbage collector so it was more user friendly 
    • [-] Can be tricky to debug.
  • Native code:
    • [+] Can be really efficient
    • [+] Give you access to everything
    • [+] You have full control
    • [+/-] No garbage collector
    • [-] Can get easily messy
    • [-] Easy thing can take really a lot of time
    • [-] Slow iteration time
    • [-] You need really good programmers to utilize it
Because I'm not 100% sure about using scripting language in game I will try to create some add-on to engine so you could use scripts but you weren't forced to do this if you want. 

And here start my dilemma and request for advice: 

Which script language you would like to use create game and why ? 

There is big choice of them C#, Lua, Python, Java Script (This one I would like to avoid) or maybe something completely different? I will be happy to hear your opinions.

Greg

Friday, June 19, 2015

Understanding of problem

This topic came to my mind in meantime of resolving linking problem on Linux. When I build dynamic library my app missed some of the symbols. 

And no I didn't forget to compile *.cpp file which contain it. If it was so easy I wouldn't spend hours on resolving it. But this won't be topic of this post. The topic is about understanding of problem that we try resolve. I talking especially about this weird situations when something happening and we don't know why.

I know different schools how to deal with this hard problems :] 

Conclusion 1: It's for sure not in my code. 

And this issue wasn't in my code :]  I didn't believed that this code was wrong from start. It was my fault for sure. Question only where. 

Of course I'm not always was this way. In my younger days very often after hour of searching I were deciding it's for sure not my fault. Of course in 99% of time I was finding out later that I was wrong. Well privilege of being young.

Conclusion 2: Let's shuffle code and it will work.

Not literally but point of this is to do some change which we think will fix issue but we don't understand why. After this we run application if it work we are happy. To give example we have crash in application because of NULL value so we add check if it is null.

Sadly this way of resolving problems is one of the worse I can imagine. There is nothing worse than changing randomly code because we try to resolve some issue. This is just bad idea because very often this "fix" hide real problem. With time passing finding steps to reproduce it became harder and harder.

Conclusion 3: Let's understand what happening.

I think is the best solution but have one bottleneck: it consume time. But I will add from my experience: that very often it save time later. Issue is resolved properly, we understand what we done to make it work and finally if it will reported again most of the time it's some other problem.

Conclusion 4: I understand what happening but don't know why.

This is my current situation where I know that my issue is because of linking of static libraries (*.a) inside dynamic (*.so). Static library missing virtual table symbols because one of virtual function is not in the same *.cpp. So I know why this issue happen I expect that there are some missing flags of linking to resolve it. I just need to find which one :]

Summary

Of course all this sound easy :] but its not. There are situation where you need to do null check because there is no time. You need to ship something in hour and there is no choice. Of course good approach is to look into the problem deeper after sending build to find real issue.

Other thing is that life showing that sometimes problem is really in some external library or not your code. This happening but still safer is to assume that you done something wrong. And if you really don't know what you could do wrong prepare some solid test case and contact person responsible for this piece of code.

Finally, approach to understand problem is not something we are born with (in most cases). This is for sure not the easiest way of dealing with problem and we need to put a lot of effort into it. But with time it start to being natural approach which bring only benefits.

Greg

Saturday, June 6, 2015

Lets play : Good code / Bad code

If you try to find answer what good/bad code is, you won't find it in this post. I don't try to sell my beliefs and I'm sure you wouldn't like them anyway. To show you that, check this simple pieces of code:

//////////////////////////////////////////////////////////////////////////
void CAnimationResource::releasevoid )
{
    SAFE_DELETE(m_privateData);
}

I use void when function don't use any arguments. I know this useless and do nothing but I just like look of it (Personal preference). Other example:

//////////////////////////////////////////////////////////////////////////
CAnimationResource::CAnimationResourceconst wrResourceIDa_idIResourceManagera_manager )
    : CResource(a_id)
    , m_manager(a_manager)
{
}

I using prefix a_ for arguments of functions and use this style of organizing initialization in constructors. This is my way of coding. You probably have your own style this is perfectly fine. We shouldn't fight over some conventions details. Everybody is different and everybody code differently. This is sometimes not easy to accept (even for me) but we just need to live with it. 

So let's not focus on programming style and move to the main topic:

Good code

So what good code really mean ? Some time ago I would probably give answer right away. It would be long and boring talk how to write code, what to do and what not to do. But right now I'm doubt I could easily answer this question.

Lets assume that we have piece of code which resolve some issue. Code is really messy with hacks all over it. Because of all this we cannot call it good code, great candidate to refactoring. Sadly without rewriting half of other big system it's hard to create better solution. People with commercial experience know that in production environment you not always can rewrite everything.

Following all this thoughts we can have bad code in which we have bad code which in given situation is the best possible code. So probably we could call it good code which don't make sense at all :| I'm lost in my thoughts.

So is this mean that bad code is good ?

I think it's just like problem mentioned in this presentation. The same gray tiles looks brighter  in shadow but in light area they look darker. I think this is accurate description of code. Our way of code perception is affected by code we know. Bad code may look pretty good if you deal with even worse code all the time.

So what bad code mean ?

Everybody recognize bad code when they see it. But defining it is not easy. For me there are few points which make code bad for me (this is my subjective opinion):
  1. If you spend more than hour to understand small piece of code and still fail to do it.
  2. Code show no understanding of problem it should resolve.
  3. Code with weird dependencies which are hard to follow.
  4. Duplicating of functionality that can be simple achieve by modification other piece of code.
  5. Overusing allocations.
  6. Not strict access rights to class members.
There is probably hundred more points which I missed. But this are the one that came to my mind right now.

Conclusion

So Good and Bad code is hard to define. Some "good" code that I wrote few years ago look for me crappy right not. Sometimes it's really bad piece of code and it's perfectly fine. If I'm saying this then it mean I'm better now and I can see flows in what I done. At some point when I will find time or need I will try to improve this bad code.

If in work somebody telling me that my code is bad. It mean that it's bad no matter how I see it right now. I will ask why he think so, we will discuss this mater and I will try to fix it. There is point in arguing who is right and who is wrong. It's about understanding why other person see my code as bad and dealing of source of problem.

Of course it's easier to talk about it then do it. We are often stuck in our boxes which are comfortable and don't try look outside. But there is outside world and we cannot forget about this. That's why I learned that I need to experience as much as I can. Different code, different technologies, different languages, different opinions, different approaches. I'm not always succeeding in that but I try and this is what allow me to grow.

What you think about this problem? And how to deal with it?

Greg

Sunday, May 24, 2015

Project generator

I like to experiments and have fun doing that. Right now I work on another crazy idea. You know because developing of game and technology behind is not enough. Don't worry this is just another side project connected with this one. 

Project generator.

I know that I could use some existing solutions (i.e CMake) but this wouldn't be so fun as doing it myself in python :] Well I started doing ... some time ago and returning to it whenever I had some time. Right now I'm at the level where Linux make support is better than previous generator I use. Sadly Microsoft Visual Studio support not exist there right now :D

Well I fix this in future. But lets move to some details about new project generator which is wrote in python.


Sunday, May 17, 2015

Singleton pattern

Singleton pattern... People love it or hate it. There are also group of people who don't mind them.

I'm still try figure out which I'm :] I'm for sure not the one who love them. I'm also cannot say that I rally hate them because I still use them in code (It is like with my Facebook account. After I created one I try not complain about fb. ). So probably I'm best fit to don't mind group.

But my past experience showing me that I have bigger tendency to removing them from code than adding new one. And probably some colleagues from work will be happy about this because we spend a lot of time discussing about problem.

I remove them because I put even more effort in good design of systems. In a lot of cases thanks to changes I just don't need global objects. Which is good. It allow me to better utilize multithreading thanks to encapsulation.

Today sadly I had problem where I still don't know cleaner solution than global state:

//////////////////////////////////////////////////////////////////////////
template<> bool write<CResHandle>( ISerializerWritera_writerconst CResHandlea_value )
{
    return a_writer.serialize(a_value.isValid() ? a_value->getId() : wrResourceID());
}

//////////////////////////////////////////////////////////////////////////
template<> bool read<CResHandle>( ISerializerReadera_readerCResHandlea_value )
{
    wrResourceID id;

    if (!a_reader.deserialize(id)) return false;

    if (CResource::isValid(id))
    {
        a_value = getResMgr()->createResource(id);
    }
    else
    {
        a_value = nullptr;
    }

    return true;
}

Function getResMgr() return global resource manager. I don't want to pass it around inside arguments because this is ugly and I would need to do the same with each manager I want to use. This would increase my arguments list and each new manager would recommend changes in all write/read functions.
I thought maybe about storing inside ISerializerReader/ISerializerWriter function like setData()/data() in some Qt classes. This way it will be really easily to extend list of available data even by game (which may add some new write/read functions). 

I'm still not sure about this solution and how nice it is. I will spend some time thinking about it but for now I will leave getResMgr() use with nice macro call right before it : 

WR_TODO("gwojciechowski""Think about way to not use global getResMgr().");

If you have any idea, thoughts or you just want to comment this. I'm open on opinion how to make this nice and clean :]

Greg 

Sunday, May 10, 2015

Sculptures gallery moved

To make my life simpler I moved my sculptures gallery to my deviant art account. You can find link in Arts page or here :

http://angelusda.deviantart.com/

UI

It's funny that only with time and experience you start to understanding how hard UI code is. I remember a lot of situations when UI freeze in meantime of doing something. Whole window is locked and you just prying that its still alive.

First version of my tools were similar: everything happening in one thread which was block when I was doing some longer operation. Because there was not too much to process it was not so painful. With time this changed, amount of data grow. To fix the issue I started adding progress bars to some operations and was happy.

Sadly I was still wrong. This solution is still messy. I block whole UI and just update progress bar when some operations may be processed in background. Recent change of threading taught me beaut of asynchronous operations.

Right now all my communication Engine <-> UI is happening by events which cleaning my design of whole tools. All code where I mix UI with mechanics changing in creation of event and processing of it later. Bellow you can see code creating event:

if (autoevent = m_appCtx->createEventT<CEditorEventGetLevelProperties>())
{
    event->setLevelSessionID(m_levelID);
    event->setUserData((size_t)a_properties);
    m_appCtx->submitEvent(eventfuncEventCallback()
                                 .connect(this, &QWrPropertiesEngine::onRequestTreeEvent));
}

Later I just need to process returned callback:

void QWrPropertiesEngine::onRequestTreeEventCEditorEventa_event )
{
    if (EErrors::isFailed(a_event->getErrorCode()))
    {
        return;
    }

    QPropertiesWidgetproperties = (QPropertiesWidget*)a_event->getUserData();

    Q_ASSERT(properties);

    autoevent = WR_RTTI_CAST_PTR(IEditorEventPropertiesa_event);

    Q_ASSERT(event);

    properties->clear();
    ...
}

I like this approach so much that I will probably switch in game UI on the same basics. How it will go we will see but for now I fell that this is good decision.

Greg

Monday, April 27, 2015

Dancing with code ?

I'm thinking if "dancing with code" could accurate describe my current situation with project. I started to think about it because I feel a little like student of dancing classes. You know this where they say you some things like:

Three steps forward, two steps back, Three steps ...

I'm still not sure if this is good phrase and also what kind of dance I would learning. But I know that with time it start to look better. So its my code. Sadly with each  new element I see there is still a lot for me to learn/do.

Sunday, April 19, 2015

Code review story ...

Last week I took small break from project. I get out of town, visited friend, meet new people and talk in meantime of drinking beer. Big part of this talks were about game programming (Yes I'm a geek and even after work I still talk about games and programming).

But why I telling all this ? Because this one week proved me how much I changed in last years and also how much I need to change in incoming ones.

This post will be be story about : How I thrown childish pride and became who I am. 

Wednesday, March 25, 2015

Alien and painted Link.

I updated my sculpture gallery with new two pictures :



I have also two other sculptures in progress :] more info about them coming soon.

Saturday, March 14, 2015

Coffe Monster page Update and new sculpture

Let's start with forwarding info from Little Big Adventure progress. There were update of :


There were two new post.

Except that I was able to started new clay sculpture :


This is base frame of it :] you can try to guess what is this. In rest of post you can find pictures how it look with clay on it.


Thursday, March 5, 2015

Hydralisk is finished

Finally after more than 18 hours of work I finished Hydralisk sculpture. Final result you can judge for yourself :


Additionally I updating my collection with Broom sculpture I done for one of my friend:


Thursday, February 26, 2015

Prison Stories and Clay figures

There are few things I would like to share with you :]

The first one is that I added new post about LBA: Prison stories.

The second one is new clay figure project: Hydralisk for StarCraft. It's still work in progress so it's not ideal but well I think it's already look cool.


The other one is that I finally finished painting Dino Fly :

Before painting

Painted version
I think it's look nicer this way :]

Greg

Saturday, February 21, 2015

Changes ...

Each day bring changes sometimes bigger sometimes smaller. Today bringing change that probably not a lot from you expected but well : after 4 years there will be no more posts about Little Big Adventure Remake development on this blog.

But don't worry about this :] I moving officially development news on new blog:

http://coffemonsters.com/
This is also day when I switch on using Coffe Monsters™ name for game production.

So probably you wonder what about this blog ? It will still exist, but it will change a little bit it content. From now on you will be able to find here:

  • Sharing knowledge about programming, 3D modeling, digital drawing.
  • Information about my personal works : modeling in clay, painting and other weird hobbies.
  • Some weird post about other things :]
I want believe that this is next step in developing Little Big Adventure which will result in better contact with all people who are interested in project.

Greg Wojciechowski

Monday, January 19, 2015

Progress page

Killah pointed out in comment of previous post nice thing:
"Why don't you post an map progress of the mod, like percentage of level done, animation, scripting, on what you need help etc"
So this state is already fixed. There is new page with progress of work. Right now I put there things I'm currently working on and I will update it with the future one when I will start them.

Full road map will need to wait a little bit more because right now preparing it would take me a little bit to much time but still I want to believe you will like this new idea from "Killah" (thanks for it).

Greg

Sunday, January 11, 2015

New year, new problems, new announcements.

Lets start with the best wishes for year 2015 :]

2014 Summary

I'm still alive still active and I will do short summary of previous year :

  • Looking back on all my posts in 2014 I need to say "I suck in writing posts" :| I didn't done too much of them. I will try to fix this this year :)
  • I failed to release the demo which I announced - Sorry here :/ "Mea culpa"
  • Company where I work: Ubisoft Montreal released Far Cry 4
In project itself changed a lot. Git statistics told me that I: 
  • Done 440 commits
    • Average in month:    40
    • Minimum in month:  11
    • Maximum in month: 83
  • Modified 247328 lines (without added/deleted files)
    • added:     137386 
    • removed: 109942
  • Modified 742856 lines (including added/deleted files)
    • added:     288150 
    • removed: 454706
This commits  included:
  • New UI system.
  • New resource system. 
  • Switching to component objects.
  • New serialization of data.
  • AI use nodes to define behaviors.
  • Partial port on Linux (I'm still working on it).
  • Switching on SDL 2.
  • And a lot smaller changes which I don't remember.
What this commits don't include are:
  • New GUI graphics.
  • Creating some development scripts.
  • Configuring continuous builds machine (I still working on this)
  • And probably few other things I don't remember.
New problems

This year didn't started too well for me. The 2nd January my hard drive broke. I needed to recreate whole working setup. If this wasn't enough my copy of data was on external HDD which after connecting ask me if I want to format it because file system is corrupted. So I had fun.

Finally after few days I was able to recover most of data from hard disk and repair file system from external one. I could finally work normally, but well few days lost. Good thing that I use this occasion to improving the way of configuring new computer for project.

New announcements

There will be few announcement this year. I know some of them already and some are still prepared but about them later. 

The fist one is with this year Little Big Adventure Remake will get new logo : 


And wit this I will finish this first 2015 post. To the next time.

Greg