[Adventuron] Graphic layers

The ability to use graphic layers is really great and useful. I don’t know if it would be possible to build the image in a buffer before displaying it. If there is a little bit of latency in the display, it can give clues to the player. But it’s already very good like that.

It will be possible to do this, the current implementation was put together very quickly, so I’ll record this as an issue.

It will help if you can show me the graphics latency in an image.

I wonder if this is not only about the display of the first image of the game.

Code
start_at = lakeside
locations {
   lakeside      : location "You are by the side of a beautiful lake." graphic = "fond" {
      on_tick {
         : if (is_beside "boot") {
            : set_true "is_boot_here" ;
         }
         : else {
            : set_false "is_boot_here" ;
         }
      }
   };
   my_location : location "You are in a room." ;
}
booleans {
  is_boot_here : boolean ;
}
objects {
   boot          : object  "a boot"  at = "lakeside";
}
on_render {
   : if (is_boot_here) {
      : overlay "boot_img" x = "72" y = "21";
   }
}
on_post_tick {
    : update_graphic ;
}

assets {
   graphics {
      fond : base64_png "iVBORw0KGgoAAAANSUhEUgAAAIAAAAAoBAMAAADEX+97AAAAG1BMVEU9Ly8oNEgQDQixoo2WHIJtXVvx8etHaHODq6Jj09WdAAACqUlEQVRIx42WS27jMAyGBQE9gLXwbC3aQbyWbhDMAQoDPoA33jcbryeb+tjDhyTLz4QoglQ1P/4/SQtVf/fxKPL4M00A0P7Ib832YfUGgKnA0f77GNDYJRvm+SUAuLMG07wFPEzKn+f5CSnufGjeAlJ9M09sP8V8ZOIK8Mvl8Usk/BxIUKcdhJbz7TgOEfD8EABi4JeTynEco4S7PQcAhE9bgLKpPgKKcvHw2jdBhfS+bx4ASgEYhQCsL4ACBZTDSsIeAOAdAiqFUemKAb9TyEcLwxAJBx6wJHhPAKB8pRUCNAJS/XEohtRHu/OgfO0pbn2VA9opTGAcEYIqiqwJIgGaAHAMcAmg8ROkAzQBzC1sGSdhowTsWrcBdAxAAUhqp2cQIFNEQuiCEcBDaTQtgOghAVCC5h6WaJ8Qhryv51CpWy+EBHABoJlBU7TjYOxYDMsaxG1EAAro+29ggNsC8If2iEpzG1cAWtMGHXwrISSAhxyg9NPy7KgHQ05AD4CAGz1LLhAQPHioQhN4ki/LlbEP2dtEANRgHlJMffV9BvCuWiQsgI0J7mKlEoEAwQN+CTZIAhU6ArQrgPpaAZINEgLxbS7KlYdimozKwmceoghKVmH5MXlZIwbwC3sKIBGalqTSCcAbkV+tO4DLAd5Rft9FBSa71mqS+BawIsRZyCqjvtrTfQVrwDaEkAHkVag93x2W0qnZdHYMEAJLKJcB1A7kjzIkDVSlOgYIYQ3wLvTaifTg8wTAhC4HkPt83fh1xLMzQCTYtAIhOVxebKDDk1MAExJg2RSgu0fuk66+BBChk0WC/LjGC7jTJI+pFwAk8D2e16fTGqvfyL57owCfnSTqg+7EjlwDIG/gchz6xx25BsT/FDbnKCGJugT4u1h47pX5zwBwrCCP/w2ByaLuMTD7AAAAAElFTkSuQmCC";
      boot_img : base64_png "iVBORw0KGgoAAAANSUhEUgAAAAoAAAAICAMAAAD3JJ6EAAAAZlBMVEUAAAAAAABjCyS3KRnydQb9xjA9Hh6FPTLLdTf3un3dblIMND0TaUdZtCzU50gbs5YSZnAjHGofSakImNpI5dxEEFyWHILxX4T6tKg9Ly9tXVuxoo3x8euDq6JHaHMoNEgQDQj///8toNKYAAAAAXRSTlMAQObYZgAAACpJREFUCNc9i8EJAEAMg4QM4v5blruS+jJgACnGszzX1ejufGzS3rP9wABxwgKQAouMEwAAAABJRU5ErkJggg==";
   }
}

Excellent example !

I see the boot appear.

I have an answer.

The reason for this is that Adventuron draws the image before it executes the on_tick {} block (which follows on_pre_describe {} and on_describe {}).

When the player redescribes or enters a location, the on_pre_describe {} event block is called, followed by the on_describe{} event block, then Adventuron renders the layout (in the theme) screen elements, usually header, then graphic, then description, then object list, then exit list.

After the entirely of the screen is rendered, then Adventuron executes the on_tick {} event block followed by the on_post_tick {} event block.

In your game, the game starts off with “is_boot_visible” having a false value, therefore when the first screen is entered, it renders the screen without the overlay (it does execute on_render {} every time the graphic is rendered).

Adventuron then renders all the other items discussed above, and in your initial on_tick {} block, you set ‘is_boot_visible’ to true. Following that, in your on_post_tick {} you trigger an update of the visible location graphic, which then calls on_render {} again, and this time the boot is visible, and that’s when you notice it appear over the blank image.

The flicker that you see is the time between rendering the image, and running the update_graphic (which triggers on_render {} ) in on_post_tick {}…

The solution to this is simply to make sure that any state that the on_render {} logic uses is available the first time the location is entered. To do this, either set up your state in on_pre_describe {} (not demonstrated below) or to use direct expressions in your .on_render (evaluate the boot at the time of the render).

on_render {
    // Now this will always be up to date at time of rendering.
   : if (is_at "lakeside" && is_beside "boot") {
      : overlay "boot_img" x = "72" y = "21";
   }
}

Alternative solution:

      fond : base64_png "iVBOR.........." {
         : if (is_beside "boot") {
            : overlay "boot_img" x = "72" y = "21";
         }
      }

Both of these techniques will stop the flickering of the boot.

Don’t remove the on_post_tick { : update_graphic; } command, as this is useful for re-rendering the scene as the state changes. The cost of this is two identical initial renders, but on modern PCs it’s not even 1% of the GPU, so it’s fine. I may detect this scenario and optimise it out at system level in the future.

I hope this explains things sufficiently.

2 Likes