Menu

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.

Show posts Menu

Topics - Diarandor

#21
Game art & music / Did you know about ZREO?
July 28, 2016, 07:18:36 AM
Greetings!

I'm pretty sure that many of you have already heard about ZREO ("Zelda Reorchestrated"), which is a team of many people that make covers and orchestrated versions of the music of Zelda games. I thought they deserved to be mentioned here since we all are Zelda fans here. If you are interested, you can listen to their music in their official website and their youtube channel:

http://www.zreomusic.com/
https://www.youtube.com/user/ZREOTeam/
https://twitter.com/zreomusic
#22
Hi pals! Just by curiosity, I would like to know if you prefer screen-sized overworld maps like in Zelda games of the gameboy, or bigger overworld maps like in A Link To The Past. I mean overworld maps, not for levels/dungeons. I may take into account these opinions when I start mapping someday; but that will be in the far far future (probably Mercuri's Chest will be finished before then, hahah). Anyway, this may be interesting info for new developers too. You can put your opinion and discuss about this.

PS: I personally have preference for small overworld maps that are screen-sized and very dense (i.e., with many things on them: entities, secrets, easter eggs, etc), like in Link's Awakening. However, I prefer bigger maps for dungeons, like the oracle games did. I may change my mind depending on your opinions.

Let the poll and discussion begin! :D
#23
General discussion / chip music vs non-chip music?
June 18, 2016, 03:46:14 AM
Hi comrades!

Some time ago I made a few compositions with Famitracker. These are 16-bit music.
I was wondering if it would be better to try to remake these songs with LMMS (so the sounds would have "higher quality", i.e., it will be non-chip music).

Well, 8/16-bit music was a limitation of old consoles, but it is nowadays a style with a lot of charm (in the same way pixel art is for the graphics). There are impressive compositions made with 16-bit style in recent games (you can listen to Shovel Knight OST for instance), so chip music should not be considered bad quality music. (Unfortunately, many people do not understand this style of music of video games nowadays.)

Since I need to take a decision, I opened this poll. You can change your vote if you change your mind.
I will post later some of my few and rudimentary compositions. :P
#24
Hi pals! I am a very curious person, and I was wondering which elements of the gameplay of a Zelda-like game are more important for most of the players (which is quite subjective to each one's opinion), so I created this poll.

The result can be useful to quest makers in order to make a game with balanced gameplay/mechanics according to what most of the people want.

You can vote for 2 options, to choose the 2 options you think are more important. I think it is a bit hard to choose since all elements are very important in my opinion.

PS: do not vote random, please! :)
#25
Hi, here is part of a script I made to (re)define some functions of the metatable of the hero. In this piece of code a few functions which allow fixing direction and walking and stopped animations are defined. The trick I am using was an idea that MetalZelda posted in an older topic (http://forum.solarus-games.org/index.php/topic,448.0.html). It was not possible until now that Christopho has improved solarus in the development version of 1.5.

My custom functions:
-The direction fix allows to walk sideways, which is useful for some weapons. The following functions are defined:
Code (Lua) Select

hero:set_fixed_direction(direction)
hero:get_fixed_direction()

-The fixing animation function allows to simplify some code in case you are changing the stopped/walking animations of the tunic of the hero for some purposes. In my case, I was changing to a jumping tunic (for a custom jump) and a carrying tunic (for a custom carry that allows carrying custom entities). This now can be done without changing the tunic sprite, using the functions:
Code (Lua) Select

hero:set_fixed_animations(stopped_animation, walking_animation)
hero:get_fixed_animations()


The code can be put in some script apart. Be careful since it may override some function or event of the hero metatable in case you have defined it elsewhere. The code is here:
Code (Lua) Select

local hero_meta = sol.main.get_metatable("hero")

-- Function to set a fixed direction for the hero (or nil to disable it).
function hero_meta:set_fixed_direction(direction)
  self.fixed_direction = direction
  if direction then
    self:get_sprite("tunic"):set_direction(direction)
  end
end
-- Function to get a fixed direction for the hero.
function hero_meta:get_fixed_direction()
  return self.fixed_direction
end
-- Function to set fixed stopped/walking animations for the hero (or nil to disable it).
function hero_meta:set_fixed_animations(stopped_animation, walking_animation)
  self.fixed_stopped_animation = stopped_animation
  self.fixed_walking_animation = walking_animation
end
-- Function to get fixed stopped/walking animations for the hero.
function hero_meta:get_fixed_animations()
  return self.fixed_stopped_animation, self.fixed_walking_animation
end

-- Initialize events to fix direction and animation for the tunic sprite of the hero.
-- To do it, we redefine the on_created and set_tunic_sprite_id events using the hero metatable.
do
  local function initialize_fixing_functions(hero)
    -- Define events for the tunic sprite.
    local sprite = hero:get_sprite("tunic")
    function sprite:on_animation_changed(animation)
      local fixed_stopped_animation = hero.fixed_stopped_animation
      local fixed_walking_animation = hero.fixed_walking_animation
      local tunic_animation = sprite:get_animation()
      if tunic_animation == "stopped" and fixed_stopped_animation ~= nil then
        if fixed_stopped_animation ~= tunic_animation then
          sprite:set_animation(fixed_stopped_animation)
        end
      elseif tunic_animation == "walking" and fixed_walking_animation ~= nil then
        if fixed_walking_animation ~= tunic_animation then
          sprite:set_animation(fixed_walking_animation)
        end
      end
    end
    function sprite:on_direction_changed(animation, direction)
      local fixed_direction = hero.fixed_direction
      local tunic_direction = sprite:get_direction()
      if fixed_direction ~= nil and fixed_direction ~= tunic_direction then
        sprite:set_direction(fixed_direction)
      end
    end
  end
  -- Initialize fixing functions when the hero is created.
  function hero_meta:on_created()
    initialize_fixing_functions(self)
  end
  -- Initialize fixing functions for the new sprite when the sprite is replaced for a new one.
  local old_set_tunic = hero_meta.set_tunic_sprite_id -- Redefine this function.
  function hero_meta:set_tunic_sprite_id(sprite_id)
    old_set_tunic(self, sprite_id)
    initialize_fixing_functions(self)
  end
end

#26
Game art & music / Original art
February 06, 2016, 03:02:41 PM
Greetings! I'm gonna upload some of my (unfinished) sprites to devianart.
It may take between 1 and 3 years of work until I have finished all of this since I am doing this in my free time as a hobby.
You can download them from here: http://diarandor.deviantart.com/
but you need to have a devianart account and login there to see images.

At present I have only uploaded a few sprite sheets, but I will keep uploading things from time to time. These sprites will probably be used for the game "Children of Solarus" of the Solarus Team.
#27
Development / Unfinished scripted boots
January 15, 2016, 10:00:26 AM
Hi! I want to share my script for the boots item. It's not finished yet, but it can help others.
The aim of this script is to allow to combine the boots with other non built-in items, like a custom jump/feather, a custom sword, and maybe others. The behaviour will be the same as in Link's Awakening, and fully customizable.

It remains to add the collision detection with custom entities that can be broken with the boots,
which can be easily done by using the new functions
map:get_entities_in_rectangle(x,y,width,height)
entity:has_collision(collision_test, other_entity)

when Solarus 1.5 is released.

Code (Lua) Select
--[[
Unfinished script for the boots item.
The aim is to allow to combine the boots with other non built-in items,
like the jump/feather and the sword, and maybe others.
--]]
local item = ...

local speed = 250

function item:on_created()
  self:set_savegame_variable("possesion_feather")
  self:set_variant(1)
  self:set_assignable(true)
end

function item:on_obtained()
  local hero_index = item:get_game():get_hero():get_index()
  local inventory = item:get_game():get_inventory()
  inventory:add_item(hero_index, item)
end

-- Function to start the running sequence before the movement.
function item:on_using()
  local game = self:get_game()
  local hero = game:get_hero()
  -- Get slot associated to this item.
  local command = "item_1"
  if game:get_item_assigned(2) == item then command = "item_2" end
  local can_start_run = false
  -- Start running animation.
  hero:set_animation("running")
  -- Timer to check if the command button is being pressed enough time to use the boots.
  local timer = sol.timer.start(item, 1000, function() can_start_run = true end)
  -- Check if the command button is being pressed enough time to use the boots.
  sol.timer.start(item, 1, function()
    if not game:is_command_pressed(command) then
      timer:stop()
      hero:set_animation("stopped")
      item:set_finished()
      return false
    elseif can_start_run then
      item:start_running()
      return false
    end
    return true
  end)
end

-- Function to start the running movement.
function item:start_running()
  local game = self:get_game()
  local hero = game:get_hero()
  local dir = hero:get_direction()
  local dirs = {[0]="right",[1]="up",[2]="left",[3]="down"}
  local command_dir = dirs[dir] -- Current direction.
  -- Create movement and check for collisions with walls.
  local m = sol.movement.create("straight")
  m:set_speed(speed)
  m:set_angle(dir*math.pi/2)
  m:set_smooth(true)
  function m:on_obstacle_reached()
    item:smash_wall()
    return 
  end
  m:start(hero)
  -- Check for commands pressed to interrupt movement or use weapons.
  local is_using_other_item = false
  sol.timer.start(item, 1, function()
    -- Stop movement if some direction command (different from
    -- the current direction) is pressed.
    local interrupt = false
    for _,str_dir in pairs(dirs) do
      interrupt = interrupt or
        (game:is_command_pressed(str_dir) and command_dir ~= str_dir)
    end
    if interrupt then
      m:stop()
      hero:set_animation("stopped")
      item:set_finished()
      return false
    end
   
    -- TODO: Check if custom items (feather, sword,...) are used, for a combined use.
    --[[
    if game:is_command_pressed("attack") and (not is_using_other_item) then
      is_using_other_item = true
      game:simulate_command_pressed("attack")
    end
    --]]
   
    -- Keep checking.
    return true
  end)
end

-- Function for the crash effect against walls.
function item:smash_wall()
  -- Crash animation and sound.
  local hero = self:get_game():get_hero()
  sol.audio.play_sound("boots_crash")
  hero:set_animation("hurt")
 
  -- TODO: detect collision with custom entities (to break them). To do
  -- when some functions (like map.get_entities_in_rectangle and hero.has_collision)
  -- are made in Solarus 1.5.
  --[[
  -- Call a collision event if the hero crashes with a destructible entity.
  local x, y, width, height = hero:get_bounding_box()
  for e in map:get_entities_in_rectangle(x, y, width, height)
    if hero:has_collision("facing", other_entity) then
      if other_entity.on_boots_crash ~= nil then
        other_entity:on_boots_crash()
        break
      end
    end
  end
  --]]
 
  -- Create bounce movement.
  local dir = hero:get_direction()
  dir = (dir+2)%4
  local m = sol.movement.create("straight")
  m:set_speed(75)
  m:set_angle(dir*math.pi/2)
  m:set_smooth(true)
  m:set_max_distance(12)
  m:start(hero)
  function m:on_obstacle_reached()
    hero:set_animation("stopped")
    item:set_finished()
  end
  function m:on_finished()
    hero:set_animation("stopped")
    item:set_finished()
  end
end
#28
Hi! I was trying to script a weapon menu like the one in Link's awakening (but with 3 slots and any weapon could be assigned to each of them). I wanted to make it possible to unassign the sword of the attack button (with the possibility of assigning other items to the attack button), but also I want the possibility of assigning the sword to other buttons, is it possible? The problem that I have is that I don't know how to start the built-in sword attack from an item script...

(Note that calling the command "game:simulate_command_pressed("attack")" is not a solution since the sword would be already unassigned from the attack command.)

Could this be possible with solarus 1.5 using some access to the sword sprite? And in that case how?
#29
I would like to know if I could use some weapons/items like the Roc's Feather and the Pegasus Boots in my own game without copyright infringement. I am creating from scratch my own art, which is completely different from the art of Nintendo (although the style has some influence sometimes), so there would not be any infringement from the art part.

But still, I am not sure if using a similar weapon/item that has the same name could be considered a copyright infringement. Also, do you think that I could use the names "Roc's Feather" and "Pegasus Boots" for my game? (I suppose that I can because Roc and Pegasus were mythological beings after all, and not invented by Nintendo...)

Probably there will be no problem and this is all legal, but  I want just to be sure. It's just that I have not seen these items in non-Zelda games (which is probably normal because they do not need them and game players would claim they copied that). Sorry if these are silly questions, it's just I am quite paranoid.
#30
How can I choose the order to draw the sprites of a custom entity? I mean, how can I draw a sprite above/below other sprites of a given custom entity?

Until now, the only way I found to simulate this was to create a new custom entity with the new sprite, set it to draw on Y-order, and put it in position (x,y+2,z), where (x,y,z) is the position of the original entity; also we need to update the position to follow the original entity. I don't like to have to use this trick each time I want to draw a sprite avobe... Is there some other way to do it at present?

EDIT: just in case, I opened an issue for this, here: https://github.com/christopho/solarus/issues/809
#31
Hi, I am not completely sure of this but I think that the function
Code (Lua) Select
hero:set_invincible([invincible, [duration]])
is not working correctly. It is very strange for an important method like this not to be working, and that makes me think that I am doing something wrong. I have tried to use
Code (Lua) Select
hero:set_invincible(true)
when a switch is activated, but the hero is still being hurt by enemies.

Could someone confirm that this function is not working or that I am doing something wrong?

(Just in case, I have opened an issue for this in github, here: https://github.com/christopho/solarus/issues/805)
#32
Hi! I made scripts to replace built-in teletransporters by custom entities (custom teletransporters). This is done using a function when the map has changed, which replaces automatically all built-in teletransporters of the map by the custom ones.

The point of this is that custom teletransporters, unlike the built-in ones, can interrupt teleportation if some condition is satisfied, for instance if the hero is jumping (usually over them). So this allows jumping over teletransporters, which would not be possible otherwise because built-in teleporters cannot be aborted at present. (Remark: I am using a custom jump, not the built-in one.) The scripts are very easy to use.

This is the script for the custom entity teleporter (entities/teleporter.lua):
Code (Lua) Select

--[[
Custom entity to teleport the hero to other map. These entities, unlike the built-in
teletransporters, allow to abort the teleportation if some condition is satisfied.
In our case, we abort the teleportation if the hero is jumping over the teleporter.
Important: in all the maps we create usual built-in teletransporters, to ease the creation
of teletransporters in the editor. Then, a scripted function defined in the map metatable
is used at runtime to replace built-in nonscrolling teletransporters with custom teleporters
when the map is loaded. The jumping state of the hero must be a boolean stored in hero.is_jumping.
--]]

local entity = ...

local sound_id, transition_style, destination_map, destination_name

function entity:on_created()
end

function entity:teleport()
  if self.on_activated then self:on_activated() end -- Teleporting event.
  local hero = self:get_map():get_hero()
  -- Repair destination name obtained from side scrolling teletransporters.
  if destination_name == "_side" then
    local dir = (hero:get_direction()+2)%4
    destination_name = "_side" .. dir
  end
  -- Teleport.
  hero:teleport(destination_map, destination_name, transition_style)
end

function entity:set_sound(sound_id) sound_id = sound_id end
function entity:get_sound() return sound_id end
function entity:set_transition(transition) transition_style = transition end
function entity:get_transition() return transition_style end
function entity:set_destination_map(map_id) destination_map = map_id end
function entity:get_destination_map() return destination_map end
function entity:set_destination_name(destination) destination_name = destination end
function entity:get_destination_name() return destination_name end


And this is the main script (scripts/.../custom_teleporters.lua) which defines the replacing function:
Code (Lua) Select

--[[
Function to replace built-in teletransporters with custom teleporters.
This is called when the maps are loaded. Custom teleporters, unlike the built-in
teletransporters, allow to abort the teleportation if some condition is satisfied.
In our case, we abort the teleportation if the hero is jumping, so we avoid the use
of the teleporter if the hero is jumping overt it.
Important: in all the maps we create usual built-in teletransporters, to ease the creation
of teletransporters in the editor. Then we replace the non-scrolling ones with custom
teleporters.
---
Use:
1)Load the file from the game manager or other script using.
write sol.main.load_file("scripts/.../custom_teleporters.lua")(game)
2) The function game:customize_teleporters() must be called when loading any map.
This can be done using the event game:on_map_changed(map).
3) Change the value of the variable hero.is_jumping to true/false
when the hero starts/ends jumping, so that the custom teleporters can
know if the hero is jumping or not.
--]]

local game = ...

function game:customize_teleporters()
  local map = game:get_map()
  -- Replace non-scrolling teletransporters.
  for e in map:get_entities("") do
    if e:get_type() == "teletransporter" then
      -- Get general properties.
      local x,y,layer = e:get_position()
      local name = e:get_name()
      local enabled = e:is_enabled()
      local origin_x, origin_y = e:get_origin()
      local w, h = e:get_size()
      -- Get teletransporter properties.
      local on_activated = e.on_activated
      local sprite = e:get_sprite()
      local animation, animation_set
      if sprite then
        animation_set = sprite:get_animation_set()
        animation = sprite:get_animation()
      end   
      local sound_id = e:get_sound()
      local destination_map = e:get_destination_map()
      local destination_name = e:get_destination_name()
      local transition = e:get_transition()
      -- Replace teletransporter with custom entity.
      e:remove()
      local properties = {name = name, x = x, y = y, layer = layer,
        direction = 0, model = "teleporter"}
      local t = map:create_custom_entity(properties)
      t:set_enabled(enabled)
      t:set_origin(origin_x, origin_y)
      t:set_size(w, h)
      -- Mimic initial properties.
      t.on_activated = on_activated -- On activated event.
      if animation_set then
        local new_sprite = t:create_sprite(animation_set)
        new_sprite:set_animation(animation)
      end
      t:set_sound(sound_id)
      t:set_destination_map(destination_map)
      t:set_destination_name(destination_name)
      t:set_transition(transition)
      -- Add teleportation collision test with hero. This requires the hero not to be jumping.
      local test = "center"
      if transition == "scrolling" then test = "facing" end
      t:add_collision_test(test, function(teleporter, other)
        if other:get_type() == "hero" then         
          -- Condition to teleport: hero is not jumping.
          if not other.is_jumping then
            t:teleport() -- Activate teleportation.
          end   
        end
      end)

    end
  end
end


It's tested and works perfectly. Usage explanations can be found in the comments of these scripts.
I hope someone finds this useful.

EDIT: updated to solve a small problem.
#33
Hi! I need help/advice for this problem:

I would like to abort teletransportation if some condition is satisfied.

In particular, what I want is that if the hero is jumping over some teletransporter, then he should not be teleported. This is the purpose I had in mind, and until now I was disabling all teletransporters of the map before the jump for 1 second and then enabling them with a timer, which is not a clean solution in my opinion because you have to get all the teletransporters of the map.

Note that we have to avoid using the method "teletransporter:on_activated()" because we could be overriding it when it is defined, so we should not use it to teletransport the hero to the same map and position (also that would play the teletransporter sound...).

My ideas:

From the engine part: I suggest/request to add an optional method "teletransporter:teleportation_test()" returning a boolean (this would be similar to custom collision test functions). If this method is not defined, then the behaviour would be as usual. Otherwise, the engine would use that method as a test to know if the teletransporter can be used or not.

Another solution could be to use sensors or custom entities as teletransporters, but I think that the engine should give a cleaner solution allowing to use built-in teletransporters.

What do you recommend me to do? Do you have some better idea?
#34
Development / Problem to detect sword collision
August 26, 2015, 04:14:15 AM
Hi! I am having problems to detect a custom entity (a plant) when it is cut by the sword. The code I am using is something like this:

entity:add_collision_test("sprite", function(entity, other_entity, sprite, other_sprite)
  -- Do nothing if the animation is not "sword", or if the sword is not close enough.
  if other_sprite == nil then return end
  if other_sprite:get_animation() ~= "sword" then return end
  -- cut the plant!
end)

I realized that when the hero was in down direction, he could cut a plant that was in the up direction, and I didn't know why that did happen until now (because the sword sprite was not colliding with the plant).

I found that the problem is that, when the hero attacks, both the hero and the sword have an animation called "sword", so if the hero sprite touches the plant during the attack, the plant is cut too (even if the sword does not touch it). I also tried using the method get_type, but the collision with the sword sprite seems to return "hero" as the type of the entity (I suppose that the sword is just a sprite of the hero).

Is there some way to deal with this problem quickly? As a last option I would change the sword item by a custom entity sword, but I want to keep the sword item if possible, for simplicity.
#35
Development / How to configure the joypad?
August 21, 2015, 11:43:36 PM
Hi! I am using a joypad of microsoft (of the Xbox360). I would like to set a default configuration like this:
A = "attack", B = "action", X = "item_1", Y = "item_2", Start = "pause", Analog-stick = directions.

The start button and the analog stick work by default as I want. What should I do to set the behaviour of the other keys to call the corresponding commands? Is there already some example to do this? (I would like to associate the buttons of the joypad to the commands, avoiding to define a casewise function on_key_pressed(key), if possible.)

I have read the Lua API but I did not find a short way to do it. Also, I don't know which "keys" are the ones associated to the buttons A,B,X,Y. Could you help me?  :-\
#36
I requested for this feature in https://github.com/christopho/solarus/issues/743. Anyway, I got an easy idea that I will try to use to simulate this, as a workaround, using a script. I want to share the idea:

First, we create a function game:add_custom_collision_test(entity, collision_test_type, callback), which adds all the info of the collision test to the list "entity.custom_collision_tests = {}" (storing the variables collision_test_type and callback), and at the same time creates the collision test with the function of the engine. This function would return the "key" of the list where the info of this collision test is stored (so we can recover the info of the collision test with "entity.custom_collision_tests[collision_test]" where collision_test is the "key").

Then, with other function called game:clear_custom_collision_test(entity, collision_test) we would first clear all collision tests, set to nil the info of the collision test (with "entity.custom_collision_tests[collision_test] = nil"), and re-create again all the other collision tests with the info which remains in the list.

Anyway, if this function is implemented someday in the engine, I will delete my script.
#37
Hi, I am trying to use the event custom_entity:on_interaction(), but nothing happens. I put a sound inside the event but it is not played when I press action command facing the custom entity. I have tried with traversable and non-traversable custom entities. I am aware that this was in the list of fixed bugs in version 1.2.1, so maybe I am doing something wrong (but it still could be a bug).

Also, since the hud does not show any dialog when the hero is facing the custom entity (which is probably intended since the action is not neccesary "talking", it could be anything, so I suppose that the engine does not change the effect of the action command), it would be nice to have a function to notify the hud that the event custom_entity:on_interaction() can be activated. This could be done with an event called "custom_entity:on_interaction_possible()", which is called when the hero can interact with the custom entity.

I point out that using collision tests to notify the hud that the hero can interact with the custom entity would not be perfect, since the test would not be the same that the engine uses, so it could happen that the hud is notified when the interaction is not possible or that the hud is not notified when interaction is possible.

PS: I have created two issues on Github:
https://github.com/christopho/solarus/issues/741
https://github.com/christopho/solarus/issues/742
#38
Zelda Return of the Hylian SE / Some small "bugs"
August 13, 2015, 03:00:36 PM
Hi! I am playing the remake Zelda Return of the Hylian SE and it's great (I never played the original before). I didn't know you were working on this game, a nice surprise. Nice work! :)

I am still in dungeon 4, but I have found two things that could be fixed, although nothing important:
-In temple 3 I think, there is an "up" arrow missing in the map (in the right-down corner).
-In temple 4, when the boss transforms you into a rabbit, the "up" direction of the animations look like the down ones. Also, when you push a wall the rabbit becomes transparent (I guess there is no pushing animation in the sprite, but the walking one can still be used).
#39
Bugs & Feature requests / Bug freezing hero?
August 07, 2015, 06:36:48 PM
Hi! I am using this code in the script of a map

local map = ...
function map:on_started()
  map:get_hero():freeze()
  sol.audio.play_sound("ok")
end

but the hero does not freeze (the sound plays, so the event is initialized). I suspect this could be a bug of the map:on_started() events. I have tried even with empty maps and nothing happens. This is very strange. Can anyone confirm this is not just me?

EDIT: I was trying to use this to make a cutscene for the intro. But since I don't need to display the hero I will use hero:set_enabled(false) instead of hero:freeze(). Anyway, this could be a problem to make cutscenes where the hero appears and we need to freeze him.
#40
Game art & music / Recommended free dialog fonts?
August 07, 2015, 12:40:05 PM
Hi! Could you recommend some free small pixeled font, with CC-SA or GPL3 license, allowing commercial use, and similar to the ALTTP one?

(I don't trust much on free font websites, and some of them may have ripped fonts, that I want to avoid to be legal.)
I need a small one for dialogs and another slightly bigger for the menus.