Skip to content

Alexey Anufriev Posts

Split Git Repository

“organizations which design systems … are constrained to produce designs
which are copies of the communication structures of these organizations.”
M. Conway

Mono-repository in software development is a very popular way of organizing the source code and collaboration around it. It has some pros, like easy refactoring or dependency management, but it also has some cons, like a very high level of coupling between components (of course these statements are debatable but this is not the point of the current post). Some IT giants, like Google, Twitter or Facebook are still using mono-repository but this costs them quite a lot, just look at the new build systems like Bazel or Buck, they were invented to minimize the effort required to manage a huge pile of code.

At the same time, there is an alternative approach of making big products still having the projects distributed across multiple repositories. One of the benefits here is “loosely coupling” that leads to very easy scaling.

Practically not much of the projects are started already being split into modules and stored separately. In most of the cases it is a single repository that is growing until some point in time when the decision to split is made. But until this moment it is already a lot of work has been done. In case if the previous history is not relevant and can be neglected it is quite a simple task to make a split: move modules to the new location and tune CI accordingly. But in case if there is a need to preserve changes history and have it relevant to the content of each new module it becomes a non-trivial task, but (spoiler!) still possible to be performed quite fast.

Here is an abstract project with two logical modules: user-related and guest-related. Both are represented by four directories inside the repository. Ideal plan to separate those modules would be following:

So, how to do this?

Leave a Comment

Debug with Git

Testing shows the presence, not the absence of bugs.
Dijkstra

Apparently, software regression is a very nasty situation in the development process. It usually means that the last delivery contains something breaking. To overcome the situation the whole release must be analyzed. A developer has to write tests, rollback the changes, run tests, and … it is still there, one more step back in the VCS history and the error is still reproducible. And now this bug just got another additional label “legacy”.

Actually, it turns out that this functionality has not been used for a while thus the bug could be introduced not just with the last commit or two but quite some time ago. In case if the codebase is big enough it may lead to some significant amount of time to find an exact change that introduced this bug.

In practice, there is a way how to automate this search. Below there is an example of this operation within the Git repository.

Leave a Comment

HTTP Verbs in REST. POST vs PUT.

REST is a very flexible and at the same time, powerful methodology used for software architecture design. But this flexibility gives more space for design mistakes. Unlike SOAP that can transfer data via multiple protocols, REST interaction is done completely via the HTTP protocol. It uses HTTP verbs (or methods) to express the intention of operations.

Most commonly used verbs in the REST world are:

  • GET
  • POST
  • PUT
  • DELETE

In many cases, developers have to map those verbs on CRUD operations. Honestly, this mapping is quite a difficult task itself and moreover has no single definition from the REST side. The first and the last verbs are pretty obvious and self-explanatory: data retrieval and data removal. But one very popular problem is related to the remaining POST and PUT. In general, very often there is a decision problem: which operation to use for data insert and which – for data update.

Leave a Comment

Camera Shake Effect in Unity

One of the most important things in every game, that gives each player a feeling of diving into gameplay, is a feedback. Game feedback can be expressed in many different ways but the main idea behind is the same – the player must feel that the game reacts on any action or event that happens. Feedbacks can be different, starting with a sound or visual effect and ending with narrative or storyline changes.

A couple of real examples where the feedback is missing:

  • FPS. The player shoots but the gun stays frozen on the screen. To add some realism the gun can simulate kickback with an appropriate animation.
  • Horror game. The player goes through the typical “dangerous” tunnel and at the end of it meets the creature and begins a fight. And game turns into “hack and slash”, but having creepy sound effects in the tunnel can make a real horror-like atmosphere.

Usually, a good feedback does not need to be difficult or complex. It is even vice versa, very often it is enough to play a simple sound or shake the camera in some concrete moment and it already can contribute a lot to the gameplay. One very popular example when the player expects to have a feedback is damage infliction. When someone hits you, you want to know this. This feedback is usually implemented as a camera shake, that simulates a head shake after hit. From the first sight it seems not very clear how to simulate this but in Unity it can be done in one line of code!

Leave a Comment

Using multiple cameras in Unity

Game Development is full of surprises. Completely different problems can be solved with the help of a pretty similar solutions. Let’s take two examples:

  1. Post Effects. This is a very powerful mechanism of adjusting the rendered picture right before displaying it on the screen. Using the effects it is pretty easy to add the fog or increase the brightness, etc. But in case if the game screen displays not only the environment but also some UI elements (health bar, number of points, etc) it turns to be a problem to apply the effects only to the particular part of the picture skipping UI.
     
  2. First Person Shooter. Having first person view in the game the player always sees own gun. This gun is usually attached to the player’s model. The model itself has a collider that interacts with the environment (detects collisions and prohibits passing through the walls, etc). In case if the player has to come up to the wall very closely it can happen that the gun can pass through the wall. Having a separate collider attached to the gun would not solve the problem since it would block the player from coming close to the wall.

But how to deal with these, at first sight, different problems?

Leave a Comment

Unity Transform* methods explained. Part I – TransformDirection.

In general, game engines deal a lot with geometry. Everything like point, vector, line or 3D model can be represented as a set of Coordinates. Each Coordinate must be related to some Coordinate Grid.

Usual Coordinate Grid is represented by its origin (starting point) and a set of axis.

Unity supports two types of Coordinate Grids (also called Spaces):

  • World – single for the whole scene with the fixed origin bound to the scene center.
  • Local – one per each object within the scene but with the origin bound to the object pivot.

Very often it is required to transform a coordinate from one space to another. To do this operation Unity provides a set of methods:

  • TransformDirection
  • TransformPoint
  • TransformVector
  • InverseTransformDirection
  • InverseTransformPoint
  • InverseTransformVector

The first 3 methods do a transformation from the local space to the world space and the last 3 do the opposite operation. The reason why there is not only one method but a set is following: different types of transformation can be dependent on different factors like rotation, position or scale of the coordinate’s owner (the owner of the local space). The documentation for each method is quite short but the transformations behind are not so trivial.

The goal of this set of articles is a detailed explanation with illustrations of each transformation. This should give a clear understanding of each method and allow to do a wise choice during development.

For better comprehension, the explanation of all three transformation types is divided into parts: one for each type. Current post is about TransformDirection method 1 .

Leave a Comment

Can C# struct be assigned to null?

Types in C# are divided into two groups:

  • reference types (classes);
  • value types (primitives, structs).

The variables of the first group contain the references to the object instances. That is why these variables can be null, means pointing to nothing, or not initialized. But as for the latter group, the variables of it are stored directly as values without references. In this case, null cannot be assigned.

At the same time, C# allows to wrap value types into Nullable struct to make them “optional” and capable for later initialization.

This can be done in the following way:

Nullable<int> value = null;

besides, there is a short notation for the same part of code:

int? value = null;

Nice. But wait a second, Nullable is a struct and structs are value types. How come that it can be assigned to null?

Leave a Comment

GrabPass Blending

The color palette is very important for games. It allows to percept the action on a screen more naturally. But it also brings additional complications during development. For example, due to similar tint, the background can mask foreground elements.

This problem can be solved by the designer having those elements properly painted (not just a solid color but also adding some gradients, etc.). But this solution can be applied to the elements that are static. Whenever the background shifts the result becomes broken.

At this moment the most suitable solution would be blending of colors controlled in time. In Unity Game Engine this can be done via shader.

Leave a Comment