Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - Diarandor

Pages: [1] 2 3 4
Hi! Although I'm not active these days, I have a question about the default blend mode.

The engine v1.6.x currently uses the following as default blend mode (called "blend"):
"blend" (default): This drawable object is alpha-blended onto the destination surface.
dstRGB = (srcRGB * srcA) + (dstRGB * (1 - srcA))
dstA = srcA + (dstA * (1 - srcA))
Link to the Lua API:

Why was this blend mode chosen? I do not like it because it is not associative, which is a bad property because this is not what happens in the real world. Let me explain this. In our real world, when you overlap 3 semitransparent surfaces A, B and C, the associative property
Code: [Select]
(A * B) * C = A * (B * C)is satisfied, where "A * B" means putting or drawing A above B.

However, the "over" blending mode ( does satisfy the associativity, and is given by
Code: [Select]
newA = srcA + dstA - dstA * srcA      // This is equivalent to the current alpha in "blend".
newRGB = ( srcA * srcRGB + (1 - srcA) *  dstA *  dstRGB ) / newA.
Note that if newA is 0, the denominator in newRGB should be replaced by 1 (or whatever, because the new surface becomes transparent) to avoid a NaN error.

So these are my suggestions:
1) Add a new blend mode to the engine, called "over".
2) Set the "over" blend mode as default, if this does not produce incompatibilities with the old "blend" mode.

If you like the idea, we could open an issue for this. If there is a reason to keep "blend" as default, I would like to know, just by curiosity.

General discussion / We have moved
« on: September 20, 2018, 11:50:26 AM »
Just to inform people who may be interested in asking questions in the chat: the team has left Gitter and moved to Discord (#solarus chanel). Also recall that we left the Github repos and we are working on Gitlab.

Your scripts / New "debug_dialogs" script
« on: March 08, 2018, 01:45:16 AM »
I made a useful script to debug dialogs in our projects: debug_dialogs.lua
I tested it and it works perfect with dialogs without extra info/variables.
I haven't tested it with dialogs that need extra info/variables, so there may be issues in those cases, and I don't know how we could avoid those errors, although I think that does not matter so much.

Game art & music / Free tileset by DragonDePlatino
« on: March 04, 2018, 01:46:40 AM »
There is an unfinished artwork (tilesets) by @DragonDePlatino that is free and looks very charming:
Someone could be interested in this art to make a game with Solarus.

Development / Diagonal directions for hero
« on: March 02, 2018, 10:38:27 AM »
Some devs may be interested in this. I think that it is possible (not tested yet) and easy to code directly from Lua scripts the feature of allowing animations for the movement of the hero in 8 directions (that is, including diagonal animations). The idea is as follows:

1) Use the event "hero:on_movement_changed(movement)" to get the movement, and calculate its direction from its angle.
2) Use a modification of my "direction fix" script to include all directions.

This feature could be used with all animations/actions/weapons of the hero. This includes the animations for walking/stopped, swimming, sword attacks, etc. Our hero Eldran does not have art for diagonal animations yet (so we cannot use this feature), but that may change someday. :)

General discussion / Some Zelda-like games
« on: February 14, 2018, 07:45:21 PM »
I found some interesting projects of other devs working on Zelda-like games. Some info here:

-The waking cloack (this looks a lot like Link's Awakening in style, very charming):

-This man (, a.k.a. baranot3nshi, seems to be working on a Zelda-like game too, and the art is really awesome:
but his project seems not to have a name yet.

Let's hope these Zelda-like games, and many others, get finished someday and they become as good as they seem.

Your projects / Children of Solarus [official thread]
« on: January 16, 2018, 03:08:21 PM »
Project CHILDREN OF SOLARUS (by the Solarus Team)

I think this project deserves its own topic where we, the Solarus Team, can post our progress and some screenshots, and anyone can post their comments and suggestions about it. The project "Children of Solarus", still not very known, is intended to become a 100% free (as in freedom) remake version of "Mystery of Solarus DX", which will improve its predecessor in many ways. Feedback is always welcome (testing, bug reports, translations, suggestions, etc).

This project, led by Christopho, was started millions of years ago (before the dinosaur extinction), and hopefully will be finished before the incoming apocalypse in 2023. Much progress has been done so far, including the hero sprites, 95% of the overworld tileset (still a bit experimental), some the first overworld maps (remapped recently by Chris), some NPCs and enemies, most part of of the music (composed by Eduardo DueƱas), most part of the sounds, new scripts, and much more.

This is a list of the new work that is planned to be finished for this year 2018: completion of the overworld mapping (at least the light overlworld for now, and maybe the dark overworld too), all remaining NPCs sprites, many more new enemies (art and scripts), the indoor houses tileset, the first dungeon tileset (with color variants for other dungeons), and hopefully much more (including more mapping).

News and screenshots will be posted in the Official Website:
[Some members of the Solarus Team are now secretly working on a new version of the website. Please, keep the secret.  ;)]

General discussion / Okami on Steam
« on: December 16, 2017, 01:13:56 AM »
The game "OKAMI HD" is finally available on Steam!!! People say this is one of the best non-Zelda Zelda games, and it even has a bark button!!! ;D I tried it once with an emulator but it ran too slow on my computer and was unplayable... but now I will definitely buy it on Steam when I get some free time to play it.

Your scripts / New rain script
« on: November 10, 2017, 09:40:39 AM »
You can download from here an updated version of my rain script:

This new version does not use custom entities anymore. It draws all rain drops on a surface, and only 1 single sprite is used for all the rain. There is also the storm mode, which is more spectacular. And the best of all is that the transition between the 3 modes ("rain", "storm" and nil) is smooth.

General discussion / DreamTales, a Zelda-like videogame
« on: October 12, 2017, 12:50:08 AM »
Hi! Some news here:

It seems that some devs are working on a new Zelda-like game called DreamTales, where the main mechanic is about turning enemies into chocolate (and then they can be eaten, or pushed like statues). The graphics seem very close to ALTTP, and the plot has a lot of influence from LA too (the hero is inside a dream).

Links here (the second link is in Spanish):

EDIT: it seems that they need 25.000$ for their kickstarter before the end of this month, so it seems to me that this project will never be finished.

General discussion / What do you prefer for a shield?
« on: July 17, 2017, 07:50:49 AM »
For the project Children of Solarus, which kind of shield would you prefer?

General discussion / Easter eggs in Link's Awakening
« on: July 13, 2017, 04:38:52 AM »
I found a video that shows some easter eggs of Link's Awakening:
I know that there are tons of videos showing bugs and secrets of this game, but the easter eggs of this video are really interesting and some of them are not so well-known (like the one of the walrus, which I found quite surprising).

General discussion / Some selective outlining tutorials (pixel art)
« on: April 26, 2017, 09:38:16 PM »
Hi! I am posting here some links of tutorials that explain the technique of "selective outlining", also known as "selout" or "broken outlines", which is just a type of anti-aliasing in the borders of the sprites. I am still learning this useful technique, which seems complicated to master, and it may be bad to abuse too much from it.

Selective outlining is used to show borders in a good way independently of the background color. For instance, if all borders of an NPC are black, these will not be seen over a dark ground, which may make ugly "saw" borders to appear. To avoid this problem, we use color borders with a darker color very close to the inner one; some artists also use some kind of "dithering" in these darker borders, but others say that this is not very clean and bad. My guess is that if this is done in the wrong way, the result may be bad, but if done correctly and in the correct proportions, the result is impressive. Using this technique is also a choice for the pixel artist.

My current personal choice will be just to keep it simple, with just a slightly darker color border, close to the inner color (but without discontinuous color alternance in the borders because my sprites are too small and also to avoid extra-work). I don't know if color borders really are or not considered as selout (maybe that depends on the definition each artists give to the concept), but I think that using color borders, without color alternance, is good enough for very small sprites.

General discussion / Design of graphs of dungeons
« on: April 17, 2017, 05:58:19 PM »
This video explains a bit how to make a dungeon graph, which is useful to design a dungeon. It is not exactly a tutorial, but it is interesting.

Hi @Christopho! I need some help. I have a problem with my rain script. I don't kow if this is a bug or something I did wrong. I think the problem started when I began refactoring my code, but I am not sure. My (unfinished) rain script is this one:

Code: (Lua) [Select]
-- Rain manager script.
To add this script to your game, call from game_manager script:

The functions here defined are:
    game:set_rain_type(world, rain_type)

Rain types: nil (no rain), "rain", "storm".

-- This script requires the multi_event script:
local rain_manager = {}

local game_meta = sol.main.get_metatable("game")
local map_meta = sol.main.get_metatable("map")

-- Default settings. Change these for testing.
local rain_enabled = true -- Do not change this property, unless you are testing.
local lightning_enabled = false
local rain_speed = 100 -- Default drop speed 100.
local drop_max_distance = 300 -- Max possible distance for drop movements.
local drop_delay = 10 -- Delay between drops, in milliseconds.
local drop_sprite_id = "test/rain"

-- Initialize rain on maps when necessary.
game_meta:register_event("on_map_changed", function()
  if self ~= nil then
    local map = self:get_map()

-- Get the raining state for a given world.
function game_meta:get_rain_type(world)
  local rain_type = self:get_value("rain_state_" .. world)
  return rain_enabled and rain_type
-- Set the raining state for a given world.
function game_meta:set_rain_type(world, rain_type)
  -- Update savegame variable.
  self:set_value("rain_state_" .. world, rain_type)
  -- Check if rain is necessary: if we are in that world and rain is needed. 
  local current_world = self:get_map():get_world()
  local rain_needed = (current_world == world) and rain_enabled and rain_type
  if (not rain_needed) then return end -- Do nothing if rain is not needed!
  -- We need to start the rain in the current map.
  local map = self:get_map()

-- Create rain if necessary when entering a new map.
function rain_manager:update_rain(map)
  -- Get rain state in this world.
  local world = map:get_world()
  local rain_type = map:get_game():get_rain_type(world)
  -- Start rain if necessary.
  if rain_type == "rain" then
  elseif rain_type == "storm" then

-- Define function to create splash effects.
-- If no parameters x, y are given, the position is random.
local function create_drop_splash(map, x, y)
  local max_layer = map:get_max_layer()
  local min_layer = map:get_min_layer()
  local camera = map:get_camera()
  local cx, cy, cw, ch = camera:get_bounding_box()
  local drop_properties = {direction = 0, x = 0, y = 0, layer = max_layer,
    width = 16, height = 16, sprite = drop_sprite_id}
  -- Initialize parameters.
  local x = x or cx + cw * math.random()
  local y = y or cy + ch * math.random()
  local layer = max_layer
  while map:get_ground(x,y,layer) == "empty" and layer > min_layer do
    layer = layer - 1 -- Draw the splash at the lower layer we can.
  -- Do not draw splash over some bad grounds: "hole" and "lava".
  local ground = map:get_ground(x, y, layer)
  if ground ~= "hole" and ground ~= "lava" then
    drop_properties.x = x
    drop_properties.y = y
    drop_properties.layer = layer
    local drop_splash = map:create_custom_entity(drop_properties)
    assert(drop_splash ~= nil)
    local splash_sprite = drop_splash:get_sprite()
    function splash_sprite:on_animation_finished() drop_splash:remove() end

-- Define function to create drops.
-- If no parameters x, y are given, the position is random.
local function create_drop(map, x, y)
  local max_layer = map:get_max_layer()
  local min_layer = map:get_min_layer()
  local camera = map:get_camera()
  local cx, cy, cw, ch = camera:get_bounding_box()
  local drop_properties = {direction = 0, x = 0, y = 0, layer = max_layer,
    width = 16, height = 16, sprite = drop_sprite_id}
  -- Initialize parameters.
  drop_properties.x = x or cx + cw * math.random() + 30
  drop_properties.y = y or cy + ch * math.random() - 100
  drop_properties.layer = max_layer
  local drop = map:create_custom_entity(drop_properties)
  local m = sol.movement.create("straight")
  m:set_angle(7 * math.pi / 5)
  local random_max_distance = math.random(1, drop_max_distance)
  function m:on_finished() drop:remove() end
  function m:on_obstacle_reached() drop:remove() end
  function drop:on_removed()
    local x, y = drop:get_position()
    create_drop_splash(map, x, y)

-- Start rain in the current map.
function rain_manager:start_rain(map)
  local max_layer = map:get_max_layer()
  local min_layer = map:get_min_layer()
  local camera = map:get_camera()
  local drop_properties = {direction = 0, x = 0, y = 0, layer = max_layer,
    width = 16, height = 16, sprite = drop_sprite_id}
  -- Initialize random seed for positions.

  -- Start timer to draw rain drops.
  sol.timer.start(map, drop_delay, function()
    -- Create drops on random positions.
    -- Repeat loop.
    return true

-- Stop rain in the current map.
function rain_manager:stop_rain(map)


-- Return rain manager.
return rain_manager

The problem appears when leaving a map with rain to another (where there is no rain, but this is probably not important). The bug appears in the console (no crash) at lines 92-93, because the entity "drop_splash" does not exist in that moment. I know that this can be fixed with an extra condition "if drop_splash ~= nil then blablabla end", but I'd like to know why does this happen.

I had the same problem at lines 31-32, because the "self" variable does not exist sometimes, and the condition "if self ~= nil then" fixed this. Why do not these variables exist when these events are called? Is this a bug?
Thanks in advance for the help.

Pages: [1] 2 3 4