I finished translating Re-Hoard’s code from Lua to Chaiscript.

I am surprised at how few days I took after my vacation.

Then again, I was riding the additional hard work I did before the vacation.


Honestly, I still need to write a function that sets the language variable (which would decide whether the game would be in English, Spanish, or Esperanto). While I had the idea of a language-select screen, I also wonder if I could simply have the game read the language setting from Libretro. (After all, does no ChaiLove explicitly target Libretro?) After that, I need to actually draw the Spanish and Esperanto version of the title logo. Then there is the implementation of the priority queue and, subsequently, replacement of the Breadth-First search with the A* algorithm.

However, I would rather debug the game, first. At the current state, the game should run normally. If I debug now, I would have to worry about less possible places where something went wrong.

I am going to ask Mr. Loach again…

Advertisements

I guess I answered prematurely…

After I woke up today, I got the urge to work on Re-Hoard again. I did… but got “enough” after a few hours.

I guess I just needed a slower pace.

However…

…I got that same feeling when I was working on my Master’s Project 2 years ago. At that point, not only was I “running on empty,” but, after the trimester was over, I could not do any work until a month later.

Re-Working, Re-Thinking

You are probably wondering what has happened to me during this silent period.

After I left Lua, I assessed my current options. Because a job opportunity already led me to learn JavaScript, a rather delightful language, I decided to first use melon.js, then Phaser. I later realized, though, that not only would me needing to use a web server be a problem with the turnaround when working on the game, but there is also the risk that way too many people would try to play my game at once, causing server overload (and high costs). Meanwhile, I worked on a ChaiLove version. The problem is that ChaiLove does not have that much documentation – the only ones that were helpful to me were the cheatsheet and this tutorial – which meant that I had to request Rob Loach’s aid… which would be the first time. Despite that, ChaiLove seems to be a great alternative, what with the ease of use and better functionality. I mean, not only can I use actual classes, but the audio system has more control.

The tricky thing, however, is re-thinking how the game should work in ChaiLove… especially given that some algorithms are specific to the pico-8.

I may have to go back to being silent, though, because the concentration on this work is intense.

My hoard is nil.

if ecs_single_entity["actor"] == "fireball" or "arrow" and ecs_single_entity["location"] ~= nil then
    if ecs_single_entity["location"][1] > 1 and ecs_single_entity["location"][2] > 1 then
        if ecs_single_entity["sprite"] == sprite_fireball_up or sprite_arrow_up then
            if {ecs_single_entity["location"][1], ecs_single_entity["location"][2] - 1} == value then --the location is nil
                ecs_single_entity[key] = nil
            end
            elseif ecs_single_entity["sprite"] == sprite_fireball_down or sprite_arrow_down then
                if {ecs_single_entity["location"][1], ecs_single_entity["location"][2] + 1} == value then
                    ecs_single_entity[key] = nil
                end
            elseif ecs_single_entity["sprite"] == sprite_fireball_left or sprite_arrow_left then
                if {ecs_single_entity["location"][1] - 1, ecs_single_entity["location"][2]} == value then
                    ecs_single_entity[key] = nil
                end
            elseif ecs_single_entity["sprite"] == sprite_fireball_right or sprite_arrow_right then
                if {ecs_single_entity["location"][1] + 1, ecs_single_entity["location"][2]} == value then
                    ecs_single_entity[key] = nil
                end
            end
        end
    end
end

re-hoard_still-nil

Even after I explicitly checked if the location is nil, I get this error.

In fact, my main issues are how Lua and pico-8 deal with nil values. They always seem to come up and cause big problems every step of my way, no matter how close I get.

I think that my game cannot handle Lua.

I was prepared in case this happened. I am aware that C, being a lower-level language, invites more problems, but I do not think that I can profitably go farther using Lua at this point.

I am not quitting Re-Hoard. However, right now, I shall search for a different game engine. Meanwhile, I shall take a look at the underlying algorithms that run Re-Hoard. Even if this issue is just another algorithm problem, I still plan on switching languages because Lua is just giving me too much grief.

Hoarding on the Dragon

(Disclaimer: a lot has happened here quite some time ago, which means that I have forgotten details here. While the order of the text and the order of the pictures is correct, the pictures might not accurately reflect the state of the game at their point of time in the text.)

 

I was wondering why all of the opponents were knights instead of the variety of emotions I planned. I decided to check the value of the name of one of the opponents.

That value was nil.

In fact, all of the opponents had nil components set to nil values!

The entity-component system that I used is actually a couple of functions that run over tables (the entities) that have a set of keys and values (the components). Other functions (the systems) run on those keys. Because tables are the basis of this entity-components system, I figured that I had two solutions:

  1. Turn the component keys into integers instead of strings. I might also switch from pairs() to all(), which requires a gapless sequence of integers but runs the components in order and had a bigger guarantee of working.
  2. Rewrite the entities, components, and systems in a way that gets rid of syntactic sugar.

I picked the 2nd option, other than my run with Scheme making me distrustful of syntactic sugar, because making the underlying structure more apparent should make the game work better.

That did not work, though the whole thing is actually more understandable.

I then found that the populator accidentally overwrites the dragon entity. I fixed that.

re-hoard_half-opponents

…”local ‘c’ “? That variable did not exist in the code!

After some struggling with online searching and looking at the code again, I found that my conversion to the new format was incomplete. Aside from the table-related deletions still using syntactic sugar, the string keys, by virtue of being strings instead of numbers, needed quotation marks, plus the key/value pairs needed commas at their ends. I did all these fixes.

re-hoard_full-opponents

Everyone is there now! The game actually looks playable!

…”looks”. Nobody could move!

The code seemed fine, but the dragon’s movement values were nil! This time, the dragon was completely empty (excluding one entity that had the value of… an empty table)! I tried manually setting the value of the dragon’s movement, but the dragon moved in place once then stopped. I ended up writing a lot of debugging code that printed the value of both the dragon’s vertical movement and position after I manually set the movement, but the movement seemed to go nowhere.

Turns out that everyone still used the old components which split the movement and positions into horizontal and vertical parts. I updated them to the new components that used its own table. In the meantime, I also got rid of some redundant code that checked the current phase in some modules, even though the modules themselves only run in their respective phases.

re-hoard_gang-up

While the opponents can move, they were supposed to touch the dragon if the dragon was next to them. Moreover, the dragon was supposed to lose after one of the opponents touched the dragon, but the game keeps going…

Hoarding Opponents

Shortly after I wrote my previous post, I wondered if I made a mistake when drawing the map. After all, while testing the game, I hard-coded the dungeon plan, which meat that the dungeon-builder was not at fault. Sure enough, I found that the mset() functionality merely says which sprite goes where in the map but does not actually draw the map itself.

I added actual drawing-code.

re-hoard-unbuilt_dungeon

The dungeon actually drew itself. From what you (cannot) see, though, the treasure is gone. Even after I replaced the dummy data with the actual dungeon-generator, the treasure is still invisible. I messed with the treasure’s location.

Turns out that the game draws the treasure before the dungeon, hiding the treasure. I only noticed that because, when the treasure was moved behind a brick tile, I could see part of the treasure. (Black is equivalent to transparent in the pico-8. I saw the treasure through the black lines of the brick tile.) I rearranged the order of the drawing code.

re-hoard_stuck-knights

One thing is that, not only does the dungeon-builder actually work in practice, but I also can see every opponent and the dragon! The problem, though, is that just about everyone is stuck inside the walls. Looking into the code revealed that the sprite-drawing code positioned everyone off by 2 pixels. That worked, but some were still stuck in walls. I then realized that the dungeon-building code had the internal cell-order of “vertical, then horizontal” instead of the more intuitive “horizontal, then vertical” order I used. I switched the order of the opponent-placer to “vertical, then horizontal”.

re-hoard_free-knights

Everyone is now located properly!

(You can see that I restored the original color of the treasure’s metal part.)

Despite these fixes, there are a couple of problems. The first is that they are all of the knight sprite when there is supposed to be only one knight. The second part is that no one, not even the dragon, is moving. I thought that may have to do with the entities not having a variable that declared what opponent they are. (After all, the knight sprite is the default sprite.) However, had the opponent-declarer not worked, neither would the opponent-locator worked either because both are functions! Trying to access the details of the world was fruitless, either.

I let go of this problem right now.

That’s my Hoard!

At this point, I am incredulous to any feeling I have that I would never finish my game. After all, every time I get that feeling, I get a success that deals with the cause of that feeling.

The first part was that I realized that mset() from the pico-8 API merely alters the map data but does not actually draw the map. The second part was that, out of some reason, I wrote code inside the dungeon-building function that explicitly does not run during the setup phase. (Between those two, I ended up fixing a lot of other bugs and even simplified the code a lot. That was a happy side-effect of figuring out the problem with the map not drawing.)

After those fixes, I got this:

re-hoard_single-treasure

That screen was blank yesterday.

I have never been so glad at seeing a single treasure chest.

Cleaning up my Hoard…

After struggling with finding out a possible entry point in solving my problem, I wondered if the dungeon that has the array was too big. I did a couple of dungeons: one normal-sized and one half-sized.

No.

I then wondered if the opportunities were at fault, since the game runs out of memory after printing the opportunities.

No.

I then wondered if what was at fault was the function that runs at an intermission, since everything prints right before running out of memory. After selectively commenting out sections, I found that the music-handling system was at fault.

I looked the code itself.

music_stop = function()
 music_stop()
 music_playing = false
end

…doh. I meant to write music(-1), instead. The game was stuck in an infinite loop.

I fixed that, but I got a new problem:

re-hoard_too-big

I read about that restriction a lot, but this is the first time this has happened to me.

I got rid of the commented-out debugging code in testing the dungeon, but the fact that I am extremely close to hitting that restriction is surprising and frightening.

 

Despite this, the game still does not go to regular gameplay. I wonder what now?