12 Mar

DOTween: How to append a tween to a sequence already playing?

I’m using the fantastic DOTween engine for creating and managing tweens on Unity, but the latest version cannot handle a specific case: how to append a tween to a sequence which is already playing? First a bit of background. After completing DragonScales 6, we’re focusing on a new game, a casual Match 3 with a traditional tile swapping gameplay. Our DragonScales games are created with Java and LibGDX. However, this new project will be built on Unity with C#, and we make intensive use of tweens.

In particular, we want the players to be able to keep playing and swapping tiles even if the game is simultaneously processing matches in other areas of the board. When a match is detected, tiles above those matched tiles will fall. We’re implementing this falling path with position tweens, via DOTween. However, new matches in other areas might alter the path of tiles which are already falling. In order to handle such cases we’ll be appending new tweens to the tweens which are already executing. The problem is that sequences in the current version of DOTween must be entirelly defined beforehand, which clearly does not suit our requirements.

Luckily, there’s a sound workaround published by user EvgenL in this pertinent and open DOTween issue. In short: use a queue of sequences. Here’s the class we’re using, completely based on the referred code:

public class TweenChain
{
    public Queue<Sequence> SequenceQueue = new Queue<Sequence>();

    public TweenChain()
    {
        // empty
    }

    public void AddAndPlay(Tween tween)
    {
        // Create a paused DOTween sequence to "wrap" our tween
        var sequence = DG.Tweening.DOTween.Sequence();
        sequence.Pause();
        // "Wrap" the tween
        sequence.Append(tween);
        // Add tween to queue
        SequenceQueue.Enqueue(sequence);
        // If this is the only tween in queue, play it immediately
        if (SequenceQueue.Count == 1)
        {
            SequenceQueue.Peek().Play();
        }
        // When the tween finishes, we'll evaluate the queue
        sequence.OnComplete(OnComplete);
    }

    private void OnComplete()
    {
        // Tween completed. Remove it.
        SequenceQueue.Dequeue();

        // Other tweens awaiting?
        if (SequenceQueue.Count > 0)
        {
            // Play next tween in queue
            SequenceQueue.Peek().Play();
        }
    }

    public bool IsRunning()
    {
        // Are tweens being processed?
        return (SequenceQueue.Count() > 0);
    }

    public void Destroy()
    {
        // Goodbye. Thanks for your hard work.
        foreach (var sequence in SequenceQueue)
        {
            sequence.Kill();
        }
        SequenceQueue.Clear();
    }
}

Hopefully future versions of DOTween will handle this use case in a straightforward fashion. We needed to append a tween to a sequence in execution and, for the time being, this class solves our requirement.

20 Feb

NagiQ on Steam

We’ll be releasing our game NagiQ on Steam πŸ™‚ The release date is set for March 5:

NagiQ is a family-friendly, word game. It’s a great game to practice English vocabulary, and you’ll have to think a lot to complete all the 100+ boards of the game. Here’s a trailer with the basic gameplay:

Basic gameplay: Type words and connect the mystic letters.

We’ve added 10 Steam achievements to the game, corresponding to the trophies you get for completing the following actions:

  • Capture 2 mystic letters in a single play.
  • Capture more than 2 mystic letters in a single play.
  • Length of a word greater or equal to 15.
  • Complete a board with an amount of words lower or equal to the number of mystic letters on the board.
  • Complete a board in less than 10 seconds.
  • 20 consecutive boards completed, without exit / reset.
  • 15 consecutive boards completed, without using hints.
  • Score >= 20,000
  • Score >= 100,000
  • Score >= 200,000

Updating NagiQ on Steam

NagiQ is the first game we released, back in 2011. The game was created with Ren’Py, and in hindsight those were really fun development times. In order to integrate Steam achievements I updated the game to use the latest Ren’Py version. In short, these are the changes I had to make:

Read More
16 Jan

16 bits COM Oddity

I can’t even pinpoint what a 16 bits COM Oddity really means, but I think the idea is therein, somehow. Previously, I explained how to code a simple a “hello, world” program using the DEBUG tool that was shipped with DOS. Revisiting this obsolete knowledge was unexpectedly fun. We’ll retrieve the hexadecimal version of “hello, world” (well, “hello, world!!”) from that post:

EB 13 0D 0A 68 65 6C 6C 6F 2C 20 77 6F 72 6C 64
21 21 0D 0A 24 B4 09 BA 02 01 CD 21 B4 00 CD 21

That’s all we need for our “hello, world!!” binary. 32 bytes exactly. We can create that file bit by bit but that’d be too excessive, I think. Let’s use the echo command instead. This is the full command I entered in my Windows 10 cmd.exe prompt:

echo|set /p="Γ™β€Όβ™ͺβ—™hello, world!!β™ͺβ—™$β”€β—‹β•‘β˜»β˜Ίβ•!1└═!">hello.com

After that you’ll get a 16-bit COM, hello.com, that will display the “hello, world!!” message. Funny πŸ™‚

What are those weird characters?

First a little explanation. We want our hello.com file to be, byte after byte, an exact representation of the hexadecimal sequence above presented. We’ll use cmd.exe commands to dump characters into the file and, if we choose our characters carefully in order to match the target hexadecimal values, we’ll end up with the exact representation we’re looking for. For instance, the first 2 bytes block, EB 13, is the “jmp 115” instruction. Then comes the newline (0D 0A), and so on. If we convert our hexadecimal to decimal, we get:

235 19 13 10 104 101 108 108 111 44 32 119 111 114 108 100 
 33 33 13 10  36 180   9 186   2  1 205 33 180   0 205  33

The first byte in hello.com must be EB, or 235 in decimal. In order to dump our characters from the command line, we’ll convert that decimal value to a character. I’m trying this on a Windows 10 (64-bits) machine, with cmd.exe using Code page 850 Multilingual Latin 1. In such code page, character 235 is Γ™. And 19 is β€Ό. And, luckily, 13 is β™ͺ and 10 is β—™. Those two characters are especially important because they represent the carriage return and the line feed, respectively, and some shells won’t convert them to characters. However, happily, cmd.exe with my default code page will handle them as we need. To input those characters you can type the usual ALT + decimal value.

There are a few important things to notice:

Read More
15 Jan

“Hello world” with DEBUG

Coding “Hello world” with DEBUG will be a blunt exercise on programming futility. Or an exercise on retro, old-school coding. More than two decades ago I used to code in x86 (Intel) assembly, almost daily. I remember the masochist approach to learning the opcodes and the hardware architecture. The famous RBIL (Ralf Brown’s Interrupt List) was, back then, my favorite “reference”. First painful steps were taken and first crashes happily followed. I remember trying to code, as expected, the traditional “hello, world!”, using a strange tool included in DOS, DEBUG.COM. I wrote a post about this “hello, world” with DEBUG.COM elsewhere, and yesterday I found the time to reread it: I verified, first with awe, then with horror, and finally, with relief, that I had almost completely forgotten how to code in assembly. So I’ll revisit this here, mostly as a self-imposed disciplinary measure, an exercise on programming, specifically, an exercise on programming futility. Heck, DEBUG isn’t even available on the Windows 10 machine I’m typing this on. However, DEBUG looked pretty cool back then: it could assemble, disassemble and dump hexadecimal output. You could create little programs, or inspect programs and peek memory areas.

Specifically what I want is to build a minimal “hello, world!” program using DEBUG.COM. I don’t have any use for this, but it comes as a “relaxing” post after several weeks focused on the release of “DragonScales 3: Eternal Prophecy of Darkness” on Steam and the localization of “DragonScales 5: The Frozen Tomb”. After we execute DEBUG.COM we’ll meet a prompt with a “-” symbol. Now we can input our commands. I want to assemble, i.e., I want to type assembly language instructions. The command for that is “a”, which might be optionally followed by a memory address. By default, instructions will be placed starting from CS:0100, so I’ll use that address. Equivalently, I could type “a 0100” or “a 100” to achieve the same result.

-a

Now we have to place the data in memory. For this little program I only need the characters for “hello, world!!”. Notice I want two “!!” at the end. That’s because I want the final program to occupy exactly 32 bytes; we’ll see the reason for this later on. I’ll use the pseudo-instruction “DB” to define our string. With DB I can neatly provide the string using ASCII values, like this:

 db "hello, world!!"

Those are 14 bytes. However, I want a prettier output, with a newline character before and after our string. A newline is in fact two characters: a carriage return (CR is ASCII 13) and a line feed (LF is ASCII 10). In hexadecimal, CR is 0Dh, and LF is 0Ah. OK. Now our DB would be modified to look like this:

 db 0d,0a,"hello, world",0d,0a

Those are 18 bytes. We are not done yet with our data. In order to effectively print the message to the standard output I’ll recur to the function 09h of INT 21h. Check RBIL D-2109. In short, I have to place the value 09h in register AH, and DS:DX should point to the beginning of our string. The function will print every character until finding a “$” character (i.e., β€œ$” acts as the “zero” in null-terminated C strings). ASCII value of “$” is 36, or 24 in hexadecimal. Therefore, we modify our DB instruction again:

 db 0d,0a,"hello, world",0d,0a,"$"
Read More
06 Jan

DragonScales 3 on Steam

We’ll begin 2020 by releasing our game DragonScales 3: Eternal Prophecy of Darkness on Steam. Here’s the game’s Steam widget:

Key features for the Steam version:

  • 150 levels.
  • Only for Windows platform.
  • 10 Steam achievements.
  • Languages supported: English, German, French, Dutch, Italian, Portuguese and Spanish.
  • Updated libraries.
DragonScales 3 on Steam
DragonScales 3 on Steam

DragonScales 3 was the first DragonScales game with Gravity Mode and falling skulls. Furthermore, the game showcases 5 boss battles combining a new gravity approach with the classic DragonScales tile-matching gameplay. DragonScales 3’s story is based on a sinister prophecy, the Eternal Prophecy of Darkness. There is a group of dark cultists who want this prophecy to come true. Their plan is to bring back Specktr to life. Specktr! The ultimate embodiment of malice! Rumor has it that Specktr, once resurrected, will grant immortality to his followers. One of such followers, incidentally, is the powerful Archmage Cedric. DragonScales 3 is also the first DragonScales 3 with references to a fantasy kingdom, the Gravity Kingdom.

Read More
17 Dec

DragonScales: The Story of Archmage Cedric

This is the background story for the Archmage Cedric of the DragonScales games. If you have not played DragonScales 3 or DragonScales 5 yet, the following text contains several spoilers. All the art of DragonScales was created by our artist XKlibur: check her portfolio here.

Archmage Cedric
Archmage Cedric

The Archmage Cedric was one of the most powerful mages of the Gravity Kingdom. His command of the DragonScales magic was sublime, and that raised him to great glory and fame. Other mages of the kingdom respected and even feared him. In a sense, the Archmage Cedric was the epitome of success in sorcery and he achieved all he ever dreamt of. Once these men achieve all the things they want, their ambition grows even bigger, and they start bordering madness. This occured to Archmage Cedric. Suddenly, he started regretting his human condition, pitying himself for the weaknesses of his mortal vessel, the ugliness of pain, and then yearned for the absolute immutability of his body: he wanted to become an immortal.

Read More
11 Dec

DragonScales 6 game: Solution for Level 5-8

Some players of the latest DragonScales game, DragonScales 6: Love and Redemption, have reached out to us asking about a solution for Level 5-8. That level might seem a bit intimidating at first look, but once you figure out the little tricks for several parts of the board you’ll agree it’s kind of easy. Let’s take a look at the initial configuration of the board.

DragonScales 6 game initial configuration of Level 5-8
Initial configuration

A typical DragonScales board. We have two goals only: capture the red and the green cross-scales. There are some novelties, though, specific to DragonScales 6: keys and doors. Cells with a door icon won’t accept scales on them, so you’ll first have to remove the doors. That means you won’t be able to clear the top-left red cross-scale, or the green cross-scale or activate the arrow until you manage to remove the respective doors. To remove a door just click on it, but you’ll obviously need to capture at least one key beforehand. To capture a key, just form a combination containing the cell with the key.

Read More
08 Dec

Inversion of Control in Software Engineering

What is Inversion of Control in Software Engineering?

Inversion of Control in Software Engineering (IoC) is essentially a strategy for decoupling software components. Basically, the purpose of IoC is to remove unnecessary dependencies (couplings) which might reduce flexibility and elegance of a system’s design. The term Inversion of Control in Software Engineering might sometimes appear applied to different design contexts. It is a term that comes from the 70s, when bottom-up parsing was considered an inversion of top-down parsing. It has roughly continued to be applied in multiple contexts. Some people think Inversion of Control in Software Engineering is a design strategy. For others, it’s a design pattern. After some articles dealing with OpenGL, in this post we will briefly discuss this topic of Software Engineering.

Read More
04 Dec

Render a Triangle with OpenGL

This post will discuss how to render a triangle with OpenGL. In the following, renderization of a triangle assumes modern OpenGL, i.e., the old, fixed-function pipeline is of no concern for us in this post, as we’ll be using OpenGL buffer objects and shaders.

A Simple Triangle

By following the tutorials in the previous posts (Setting up Eclipse CDT for OpenGL and the GLFW Example) we were able to create a minimal program displaying an empty window. Now we want to draw something with OpenGL on that window, specifically, a triangle. Why a triangle? Well, the geometric shape more frequently used to approximate surfaces is the triangle. Approximation of 3D surfaces in real-time graphics by means of simpler shapes is known as tessellation. For our tutorial purposes, a single triangle will suffice.

GPU Power

Modern GPUs are quite fast and can also have a considerable amount of dedicated memory. When rendering, we’d like for as much rendering data as possible to be read by the GPU directly from its local memory. In order to render a triangle with OpenGL we’ll need, obviously, to transfer the 3 vertices of the triangle to the GPU’s memory. However, we do NOT want our rendering to go like this:

  • read a vertex from our computer RAM
  • copy it to the GPU memory
  • let the GPU process that single vertex
  • and then repeat this whole process for the next vertex of the triangle.

Ideally, what we want is to transfer a batch of data to the GPU’s memory, copying all the triangle vertices, and then letting the GPU operate with this data directly from its local memory. In OpenGL we have the concept of Vertex Buffer Object (VBO) to represent these data placed on GPU’s memory.

The data to render the triangle in OpenGL

Normally, we think of a vertex as a point, which in 3D space leads to a representation with 3 coordinates, commonly designated by x, y and z. However, in this case I’d like to think of a vertex as a more abstract concept: a minimal data structure required to define a shape. Given a vertex, we can “link” attributes to it to further define our shape. Thereby, one of such attributes of a vertex can be its position (the “x, y, z values”.) Other attribute might be the vertex’s color. And so on. In this tutorial we will “link” two attributes to our vertices: position and color. For position we will have three coordinates, each a floating point value. If a float takes 4 bytes, then our position attribute would require 3 x 4 = 12 bytes. For the color attribute, we’d have 3 extra components, following the RGB model. Each color component would then take 4 bytes, and the color attribute would also require 12 bytes. In total, each vertex would take 24 bytes, 12 for its position attribute, and 12 for its color attribute.

Now we have to specify how to process these vertices.

Read More
03 Dec

GLFW Example

Here I’ll briefly discuss a tiny GLFW example. Previously, I explained how to setup Eclipse CDT to work with OpenGL, using GLFW and GLAD. However, I instructed to copy-paste the example code on GLFW Documentation page, without providing any details. In the following I’ll present some code that you can add to the little project of our setup post, and will include GLAD initialization too.

Read More