Solarus 1.3 is out, now with a sprite editor!

UPDATE: a bugfix version 1.3.1 was just released. It fixes an error when opening a newly created sprite, and improves the sorting of resources with numbers in their id in the quest tree.

A new release of Solarus is available: version 1.3!

The main improvement of Solarus 1.3 is the graphical sprite editor integrated in Solarus Quest Editor. You will no longer have to edit sprite sheet data files by hand!

Sprite Editor

Screenshot of Solarus Quest Editor 1.3, modifying the sprite of an enemy in ZSDX.

The sprite editor was primarily developed by Maxs. You can create and edit sprite sheets. A tree shows the hierarchy of animations and direction of your sprite. And below the tree, you can edit the animation and direction that are selected in the tree.

The main changes of this release are in the quest editor. Another important improvement is that tile patterns can now be identified by a string instead of auto-generated integers. This allows to more easily maintain different similar tilesets.

There are also a few new features in the engine and in the Lua API, like more customizable switches, but nothing that breaks compatibility of your scripts.

As always, our games ZSDX and ZSXD were also upgraded to give you up-to-date examples of games. In ZSDX, there is also a new world minimap made by Neovyse.

Here is the full changelog.

Changes in Solarus 1.3

Lua API changes that do not introduce incompatibilities:

  • Add mouse functions and events (experimental, more will come in Solarus 1.4).
  • Add a method sprite:get_animation_set_id() (#552).
  • Add a method sprite:has_animation() (#525).
  • Add a method sprite:get_num_directions().
  • Add a method hero:get_solid_ground_position() (#572).
  • Add a method switch:get_sprite().
  • Allow to customize the sprite and sound of switches (#553).
  • Add a method enemy:get_treasure() (#501).

Bug fixes:

  • Fix the write directory not having priority over the data dir since 1.1.
  • Fix pickable/destructible:get_treasure() returning wrong types.
  • Fix custom entity collision detection when the other is not moving (#551).
  • Allow to call map methods even when the map is not running.

Changes in Solarus Quest Editor 1.3

New features:

  • Add a sprite editor (#135). By Maxs.
  • Add a zoom level of 400%. By Maxs.
  • Add keyboard/mouse zoom features to sprites and tilesets. By Maxs.
  • Add Lua syntax coloring (#470). By Maxs.
  • Add a close button on tabs (#439). By Maxs.
  • Rework the quest tree to show the file hierarchy and Lua scripts. By Maxs.
  • Add specific icons for each resource type in the quest tree.
  • Move the entity checkboxes to the map view settings panel. By Maxs.
  • Allow to change the id of a tile pattern in the tileset editor (#559).
  • Don’t initially maximize the editor window.

Bug fixes:

  • Fix converting quests to several versions in one go.


These improvements involve changes that introduce slight incompatibilities in the format of data files, but no incompatibility in the Lua API. Make a backup, and then see the migration guide on the wiki to know how to upgrade.

Changes in Zelda Mystery of Solarus DX 1.9

New features:

  • New world minimap. By Neovyse.
  • Make cmake paths more modifiable. By hasufell.

Bug fixes:

  • Fix direction of vertical movement on joypad in menus (#85). By xethm55.
  • Clarify license of some files.

Changes in Zelda Mystery of Solarus XD 1.9

New features:

  • Make cmake paths more modifiable. By hasufell.

Bug fixes:

  • Fix direction of vertical movement on joypad in menus.
  • Clarify the license of some files.

English tutorial!

More and more people are interested in creating games with Solarus. However, there was a lack of tutorials to explain how to do it.

There is a video tutorial in French, and a written tutorial also in French, but so far there was nothing in English. You guys were expecting it, here it is: the official English video tutorial!

I uploaded chapter 1 today, and more chapters will come in the next few days. The French tutorial has 55 episodes for now (and is not over!) so there is a lot of work! To get the updates, you can follow me on Twitter (@ChristophoZS) or subscribe to the YouTube channel.

We hope that you will enjoy these videos and more importantly, that you will be able to create lots of great games now :)

Bugfix release 1.2.1

A bugfix release named Solarus 1.2.1 is available!

It addresses a few issues with recent features that were not working correctly, like custom entities, and a problem of corrupted image when creating a new quest with the editor.

Changes in Solarus 1.2.1

  • Fix entity:is_in_same_region() giving wrong results (#500).
  • Fix custom_entity:set_can_traverse() giving opposite results.
  • Fix custom_entity:on_interaction() not always called.
  • Fix custom_entity sprite collision issues with some entities (#536).
  • Fix a crash in enemy:restart() when the enemy is dying (#558).
  • Fix hero:set_tunic_sprite_id() resetting the direction to right (#511).
  • Fix timer:get_remaining_time() always returning 0 (#503).
  • Fix declaring global variables from a map script (#507).
  • Fix the hero sometimes moving while no keys are pressed (#513). By xethm55.
  • Fix on_joypad events not always working (#519). By xethm55.
  • Add an error when a hero sprite animation is missing (#485). By Nate-Devv.

Changes in Solarus Quest Editor 1.2.1

  • Fix corrupted image in quest created by Quest > New quest (#548).
  • Fix tiles created on invisible layer (#508). By Maxs1789.
  • Fix crash when an NPC sprite does not have 4 directions (#510). By Maxs1789.

Custom entities

If you are developing a quest with Solarus, you will definitely be interested in lots of new features of Solarus 1.2. But the most important one is probably custom entities!

Assume that you want to block the entrance of a dungeon with a big rock. To create your big rock on your map, you have to choose the type of map entity that best fits your needs. But each type of entity (non-playing character, enemy, door, destructible, dynamic tile, etc.) implements some built-in behavior that you don’t want for this particular need. Each type of entity corresponds to a common use case that is not necessarily yours in this situation. Sometimes, you can hijack an entity to avoid its built-in behavior: for example, you can implement the rock as a non-playing character that does not talk. Or you can make an enemy that does not hurt the hero. This is weird at best.

Another example is creating weapons that are not included in the engine. The engine implements a bow with arrows, the boomerang and the hookshot, similarly to Zelda: A Link to the Past. But how to create the hammer? More difficult: how to create the stakes that can be pushed using the hammer? How to shoot ice when using the ice rod?

Custom entities are the answer to these challenges. Custom entities are a new type of map entity introduced in Solarus 1.2.

Their main feature is to have no special feature! Indeed, they are fully scripted. Your script can define the size, the sprite (if any), the movement (if any) and the exact obstacle and collision rules. You can set callbacks to be executed when a collision is detected with another entity. In short, they are very powerful.

Lots of other built-in entity types could even be reimplemented as custom entities. Yet, we keep them because they are commonly used in games.

Let’s see how we could implement our big rock to block the entrance of a dungeon. From the editor, create on your map a custom entity called “rock_entrance”, set its size, for example 32×32, and its sprite to “entities/rock_entrance”. Indeed, common properties like the size and the sprite can be set from the editor. This is also possible from the Lua script of your map, but using the editor to create entities is easier. Then, edit the map script to define the other properties:

rock_entrance:set_traversable_by(false)  -- Don't allow other entities to traverse the rock.

-- Destroy the rock if there is an explosion.
rock_entrance:add_collision_test("overlapping", function(rock_entrance, other)
  if other:get_type() == "explosion" then
    -- The rock explodes."secret")

This is a basic example of custom entity. To implement the hammer and hammer stakes, you will need two custom entities: the hammer itself (created dynamically when the player uses the item) and the hammer stakes. The hammer will test collisions with enemies and with hammer stakes. Hammer stakes will become traversable (and their sprite animation will change) when they collide with the hammer.

An interesting fact is that there will a lot of hammer stakes in your quest, and they will appear on different maps. In other words, you need a reusable custom entity. To solve this problem, we provide models: each custom entity can have an optional model. A model the name of a Lua script that will be applied to all custom entities that refer to it. Actually, this works exactly like the breed of enemies. You can have several enemies ruled by the same enemy script. Similarly, if you need multiple instances of identical custom entities, you can use a model.

Solarus 1.2 is out!

After six months of development, we are proud to announce the release of the Solarus 1.2!

Solarus now uses SDL2. Graphics are GPU-accelerated if available. Switching to fullscreen is faster, does not change the resolution and keeps the correct pixel ratio.  And the window is resizable. There are new pixel scaling filters, including hq4x which is great to play on big screens.

We now support LuaJIT, the just-in-time Lua compiler. Combined with the accelerated graphics of SDL2, we obtain better performance than ever.

But if you are a quest maker, you will especially be interested by custom entitiesstreams (the new name of conveyor belts), metatables and repeatable timers. I will give more details about these new features in future posts, but you can already see the documentation.

The quest editor was greatly improved. You can now resize multiple entities at once. The map view can be dragged with the middle mouse button and can be zoomed with Ctrl+wheel. Copy-pasting is more intuitive now, and works much better between different maps.

Our games ZSDX and ZSXD were also upgraded to give you up-to-date examples of games. ZSXD is now available in Spanish (beta). Thanks Xexio!

Here is the full changelog. 153 github issues were resolved for Solarus 1.2 (this is a new record!) and 20 more for ZSDX and ZSXD 1.8.

Changes in Solarus 1.2

New features:

  • Upgrade to SDL 2 (#262). Thanks Vlag.
  • Accelerate video operations in GPU if available. Expect huge speedups.
  • Add the hq2x, hq3 and hq4x pixel filter algorithms as new video modes.
  • Make the window resizable (#338).
  • Use LuaJIT if available instead of vanilla Lua for better performance.
  • New map entity type: custom entities, fully scripted (#323).
  • Conveyor belts are now called streams and can be non-blocking (#288).
  • Collision rules of streams (conveyor belts) are now like holes.
  • Rewrite the main loop with a constant timestep (#351).
  • Show a dialog box in case of fatal error.
  • The “wide” video modes do not exist anymore. SDL2 does the job now.
  • Make stairs sounds optional (#364).
  • Make more checks in sprite files to avoid crashes (#357).
  • Set the default speed of StraightMovement to 32 instead of 0 (#343).
  • The size of all map entities must be a multiple of 8 (#358).
  • Thrown entities (pots, bombs…) can now fall to a lower layer (#349).
  • Running into a crystal or a solid switch now activates it (#193).
  • The hero can now jump over distant crystal blocks (#42).
  • The shield no longer protects while using the sword or carrying (#192).
  • Languages: New syntax of strings.dat easier to read and parse (#170).
  • Maps: The world property is now optional (#128).
  • Maps: Teletransporters transition property is now a string (#402).
  • Maps: Walls have a new property “stops_projectiles”.
  • Sounds: Running into a wall now plays a sound other than “explosion” (#297).

Lua API changes that introduce incompatibilities (see the migration guide):

  • Video mode names have changed: no more wide, fullscreen ou windowed names.
  • no longer changes the fullscreen flag.
  • surface:set_transparency_color() no longer exists. Use surface:clear().
  •“none”) is replaced by
  • on_key_pressed() and on_character_pressed() are now both called (#344).
  • Destructible objects no longer show hardcoded dialogs (#270).
  • map:create_destructible() has no hardcoded subtypes anymore (#270).
  • map:create_teletransporter(): the transition is now a string (#402).
  • map:create_shop_item() is replaced by map:create_shop_treasure().
  • map:create_conveyor_belt() is replaced by map:create_stream() (#288).
  • The state “conveyor belt” no longer exists in hero:get_state() (#288).
  • The built-in strength of the sword has changed (#426).
  • Bosses are not initially disabled anymore (#448).
  • Call enemy:on_hurt() before enemy:on_dying() (#325).
  • enemy:on_hurt() no longer takes a life_lost parameter (#426).
  • The built-in defense of the tunic has changed (#428).
  • enemy:get/set_magic_damage() no longer exists (#428).
  • hero:start_hurt() no longer takes a magic parameter (#428).
  • hero:start_hurt() now hurts the hero even when enemies cannot.
  • Enemies have now a default size of 16×16 and origin of 8,13 (#354).
  • The size of enemies must be a multiple of 8 (#358).
  • item:on_pickable_movement_changed replaced by pickable:on_movement_changed.
  • pickable:get_treasure() now returns the item instead of the item’s name.
  • Timers: returning true in the callback now repeats the timer (#152).
  • sol.timer.start() now always returns the timer, even if its delay is zero.

Lua API changes that do not introduce incompatibilities:

  • New Lua type and methods for custom map entities.
  • New API of destructible objects, fully customizable now (#270).
  • Colors now take an optional alpha value as fourth component.
  • New functions
  • New method surface:clear().
  • Add loop and callback features to (#280).
  • New function sol.main.get_metatable(), allows to implement shared behaviors.
  • The lifetime of a menu can now be another menu.
  • New method menu:is_started().
  • Attempt to stop a menu already stopped is no longer an error.
  • New method map:get_hero() (#362).
  • map:get_world() can now return nil because the world is now optional (#128).
  • map:create_wall() accepts a new property “stops_projectiles”.
  • Entity names are now auto-incremented to simplify their creation.
  • New method entity:get_game() (#363).
  • New methods entity:bring_to_front() and entity:bring_to_back() (#273).
  • entity:test_obstacles() now takes an optional layer parameter.
  • New methods enemy:get_attack_consequence(), get_attack_consequence_sprite().
  • The event entity:on_created() is now called for all types of entities.
  • New event enemy:on_hurt_by_sword() to customize the sword strength (#426).
  • New event enemy:on_attacking_hero() to customize attacks (#356).
  • New event enemy:on_hurting_hero() to customize hurting the hero (#428).
  • New event hero:on_hurt() to customize the defense of the equipment (#428).
  • hero:start_hurt() now takes an optional entity and sprite (#417).
  • New methods hero:is/set_invincible() and hero:is/set_blinking() (#418).
  • New methods hero:get/set_animation() to set custom animations (#155).
  • New methods hero:get/set_sword_sound_id() to change the sword sound (#155).
  • New methods to set custom tunic, sword and shield sprites (#155).
  • New functions to get/set the properties of teletransporters (#403).
  • New functions to get/set the properties of blocks.
  • New methods to simulate game commands, by mrunderhill (#382).
  • New event sensor:on_left() (#339).
  • New event block:on_moving() (#334).
  • New event teletransporter:on_activated() (#312).
  • New event destination:on_activated() (#312).
  • movement:on_position_changed() now takes x and y parameters (#342).
  • Check the parameter sign in game:add/remove life/money/magic (#416).
  • Check the parameter sign in item:add/remove_amount.
  • New methods timer:get/set_remaining_time.
  • New function sol.main.get_elapsed_time() to get the simulated time (#424).
  • New function sol.input.get_key_modifiers() to get the key modifiers state.

Bug fixes:

  • Fix enemy:on_hurt() that was wrongly called when immobilized.
  • Fix life and money exceeding the max when the max changes (#355).
  • Fix RandomMovement speed that was not taken into account (#361).
  • Fix collisions detected on disabled entities (#455).
  • Fix pixel collisions coordinates when sprites move (#372).
  • Fix a slowness when loading maps (#374).
  • Fix crash when accessing a map not active anymore (#371).
  • Fix crash when changing the movement of the hero (#392).
  • Fix crash when calling hero:start_treasure() with wrong parameters (#391).
  • Fix crash when calling game:has/get/set_ability() with wrong name (#408).
  • Fix a crash when creating two entities with the same name (#370).
  • Fix issues with unobtainable treasures.
  • Fix the starting location wrongly saved with special destinations (#375).
  • Fix map:set_tileset() sometimes moving the hero near the map border (#400).
  • Fix enemies stuck on blocks (#360).
  • Fix enemies stuck on crystal blocks (#41).
  • Fix human NPCs not automatically showing “walking” when moving (#336).
  • Fix the hero leaving the grabbing state even while the game is suspended.
  • Fix low walls in dynamic tiles behaving like normal walls.
  • Fix wrong collisions of right-up and left-down diagonal jumpers.
  • Fix jumpers that could be traversed sideways (#481).
  • Fix blocks no longer stopping when aligned on the grid since Solarus 0.9.3.
  • Fix entities not always shown when they have no optimization distance.
  • Fix movement:start() raising an error if the optional callback is nil.
  • Fix random_movement:get_max_radius() that was not working.
  • Fix timer:is_suspended_with_map() that was not working.
  • Fix crash when calling timer:set_suspended_with_map() without game started.
  • Call hero:on_removed() and stop hero timers when stopping the game (#421).
  • Don’t die if the map or destination saved no longer exists (#301).
  • Don’t die if a map has no destination. Show an error and go to 0,0 instead.
  • Don’t die if hero:teleport() attempts to go to a non-existing place.
  • Don’t die if attempting to start a game without map.
  • Don’t die if attempting to start a non-existing dialog.

Changes in Solarus Quest Editor 1.2

New features:

  • The editor is now built with Maven (#365).
  • Multiple entities can now be resized at the same time (#405).
  • Copy-pasting entities now pastes them at the cursor (#404).
  • The map view can now be dragged using the middle mouse button (#413).
  • Zoom in/out in the map view using the Ctrl + mouse wheel (rekcah1986).
  • Add buttons to edit or refresh the tileset from the map view (#425).
  • The tileset view can now be dragged using the middle mouse button (#427).
  • Selecting a tile now highlights its pattern in the tileset view (#290).
  • Ctrl/Shift+click even on an entity now starts a selection rectangle (#410).
  • Tile patterns can now be moved in the tileset editor (#422).
  • The id and name of a new resource and now asked in a single dialog (#321).
  • Show the old value in the dialog to change an id/name (#468) (rekcah1986).
  • The order of resources in the quest tree can now be changed (#319).
  • Increase the stepsize when scrolling the map view.
  • Center the dialog of editing an entity (#443).
  • Add a scroller to dialogs that are too high (#437) (rekcah1986).
  • Show the map or tileset name in the “do you want to save” dialog.
  • Show quest name and resource ids in the tree view (thanks rekcah1986).
  • Don’t place new tiles below other entities if there are some (#461).
  • Switches, crystals and crystal blocks now show their actual sprite (#376).

Bug fixes:

  • Fix hidden entities getting selected when clicked (#460).
  • Fix selected entities losing their order when changing the layer.
  • Fix NullPointerException when canceling the Open Project dialog.
  • Fix freeze if tiles don’t exist when changing the tileset of a map.
  • Fix the tree not refreshing when deleting a resource (#335).
  • Fix the tileset editor not always showing the save dialog on closing.
  • Fix the num_columns property of sprites wrongly parsed.
  • Fix wrong displaying of right-up and left-down diagonal jumpers.


These improvements involve changes that introduce some incompatibilities in both the format of data files (in particular strings.dat) and the Lua API. Make a backup, and then see the migration guide on the wiki to know how to upgrade.

Changes in Zelda Mystery of Solarus DX 1.8

New features:

  • Replace fixed8.fon by a TTF font due to an SDL2 regression (#59).
  • Switch fullscreen also with F11.

Bug fixes:

  • Dungeon 3 5F: fix falling too early in the hole due to incorrect layers.

Changes in Zelda Mystery of Solarus XD 1.8

New features:

  • Spanish translation (beta). Thanks Xexio!
  • Replace fixed8.fon by a TTF font due to an SDL2 regression (#59).
  • Switch fullscreen also with F11.
  • Make streams non-blocking in the crazy house.

Bug fixes:

  • Fix a typo in French dialogs.
  • Fix the position of some diagonal jumpers.

New design for the development blog

As the project grows and gets bigger, we thought it was important to get a new design for the development blog. Here it is ! We merged some pages to simplify navigation and changed the wordpress theme to a customized version of the very nice Vantage theme by SiteOrigin.

Solarus is about to be released in its 1.2 version, so let’s say the new design is to celebrate the soon-to-come event !

Solarus 1.1.1 released, fixed wrong teletransportation

An update of Solarus, Zelda Mystery of Solarus DX and XD was just released!

The main problem was a bug in Billy’s cave in ZSDX. You could be teletransported wrongly to a place that you were not supposed to see so early in the game, and more importantly, you could get stuck if you saved at that place. If you have this problem, just download the new version of ZSDX and your savegame will automatically get fixed.

Other annoying issues were fixed, including the heart meter not always updated and the game failing to detect the death of enemies falling into holes.

Changes in Solarus 1.1.1

  • Fix teletransporters activated while coming back from falling (#346).
  • Fix a libmodplug compilation problem due to wrong sndfile.h (#324).
  • Fix enemy death detection when falling into hole, lava or water (#350).
  • Fix a crash when changing the hero state in block:on_moved (#340).

Changes in Zelda Mystery of Solarus DX 1.7.1

  • Fix the heart meter not updated until the first save/reload (#67).
  • Fix wrong teletransportation in Billy’s cave after falling in a hole (#66).
  • Fix the debugging console no longer working after using F1, F2 or F3.

Changes in Zelda Mystery of Solarus XD 1.7.1

  • Fix Creepers never exploding after they are hurt (#16).
  • Fix a typo in English dialogs.
  • Fix the debugging console no longer working after using F1, F2 or F3

As always, you can install both games to replace any previous version and your savegames will continue to work.

Thank you for your feedback!

Android, Pandora and GCW-Zero ports!

Solarus 1.1 now officially supports three new mobile systems!

You have been waiting for a long time for the Android version. Thanks to Sam101, our games are now officially ported to Android. This Android port is in beta-testing though. There are a lot of different phone models so we need your feedback to know if there are problems. Please post any issue on the forum.

The Pandora and the GCW-Zero are two open-source consoles that are oriented to homebrew and retrogaming. Their communities are very active and thanks to their work, Solarus now also works on these two systems!

Therefore, the list of (offically) supported systems is now: Windows, Linux, Mac OS X, OpenBSD, Amiga OS 4, Android, Pandora, GCW-Zero.

See the download pages to get the games on the system of your choice.

We are also thinking of an iOS port with touchscreen gameplay but this will take time. Not only we have to upgrade the engine and the Lua API to handle the mouse and the touchscreens, but we also need to completely rework the gameplay in the case when no physical button is available. So how do we do right now for the Android version? We actually use a trick: the SDL 1.2 port of Android adds virtual buttons to the screen, that are mapped to SDL keyboard keys.

Solarus 1.1 released!

The new version of Solarus is available now!

The main change of Solarus 1.1 is that there are no more hardcoded menus in the engine: the dialog box and the game-over menu are now fully scripted in your quest with the Lua API. There are a lot of other new features and improvements, as well as bug fixes, so it is recommended to upgrade.

Our games ZSDX and ZSXD were also upgraded to give you up-to-date examples of games. ZSDX is now available in simplified Chinese and traditional Chinese (beta). Thanks Sundae and Rypervenche! Note that a Spanish version of ZSXD is also in progress (thanks Xexio!).

Solarus 1.1 also improves portability and performance. This allows us to release the Android and OpenPandora versions of our games. They will be available in the next few days!

Here is the full changelog. 80 github issues were resolved for Solarus 1.1 and 20 more for ZSDX and ZSXD 1.7 so this is a huge list!

Changes in Solarus 1.1

New features:

  • Add a very short sample quest with free graphics and musics (#232, #318).
  • Allow scripted dialog boxes (#184).
  • Allow a scripted game-over menu (#261).
  • Replace the old built-in dialog box by a very minimal one.
  • Remove the old built-in game-over menu.
  • Remove the old built-in dark rooms displaying (#205).
  • New entity: separators to visually separate some regions in a map (#177).
  • New type of ground: ice (#182).
  • New type of ground: low walls (#117).
  • Blocks and thrown items can now fall into holes, lava and water (#191).
  • Kill enemies that fall into holes, lava and water (#190).
  • Allow quest makers and users to set the size of the playing area.
  • Allow maps to have a default destination entity (#231).
  • A game can now start without specifying an initial map and destination.
  • Stairs inside a single floor can now go from any layer to a next one (#178).
  • The channel volume of  .it musics can now be changed dynamically (#250).
  • The tempo of  .it musics can now be changed dynamically (#250).
  • Allow Lua to manipulate files directly (#267).
  • New syntax of sprites, easier to read and parse (#168).
  • New syntax of project_db.dat, easier to read and parse (#169).
  • languages.dat no longer exists. Languages are in project_db.dat now (#265).
  • The quest archive can now also be named (#293).

Lua API changes that introduce incompatibilities (see the migration guide):

  • map:is_dialog_enabled() is replaced by game:is_dialog_enabled().
  • map:start_dialog() is replaced by game:start_dialog().
  • Remove map:draw_dialog_box(), no longer needed.
  • Remove map:set_dialog_style(): replace it in your own dialog box system.
  • Remove map:set_dialog_position(): replace it in your own dialog box system.
  • Remove map:set_dialog_variable(): use the info param of game:start_dialog().
  • Make map:get_entities() returns an iterator instead of an array (#249).
  • Replace map:set_pause_enabled() by game:set_pause_allowed().
  • Make the enemy:create_enemy() more like map:create_enemy() (#215).
  • Remove sol.language.get_default_language(), useless and misleading (#265).
  • Remove sol.main.is_debug_enabled().
  • Remove map:get_light() and map:set_light() (#205).
  • In game:get/set_ability(), ability “get_back_from_death” no longer exists.
  • Empty chests no longer show a dialog if there is no on:empty() event (#274).

Lua API changes that do not introduce incompatibilities:

  • game:get/set_starting_location(): map and destination can now be nil.
  • hero:teleport(): make destination optional (maps now have a default one).
  • map:create_teletransporter(): make destination optional.
  • Add a function
  • Make map:get_camera_position() also return the size of the visible area.
  • Add a method entity:is_in_same_region(entity).
  • Add a method entity:get_center_position().
  • Add methods entity:get_direction4_to(), entity:get_direction8_to() (#150).
  • Add a method game:get_hero().
  • Add methods hero:get/set_walking_speed() (#206).
  • Add hero:get_state() and hero:on_state_changed() (#207).
  • Add events separator:on_activating() and separator:on_activated() (#272).
  • Add methods enemy:is/set_traversable() (#147).
  • Add a method enemy:immobilize() (#160).
  • Add on_position_changed() to all entities, not only enemies (#298).
  • Add on_obstacle_reached() to all entities, not only enemies (#298).
  • Add on_movement_changed() to all entities, not only enemies (#298).
  • Add on_movement_finished() to all entities, not only enemies/NPCs (#298).
  • target_movement:set_target(entity) now accepts an x,y offset (#154).
  • Add a method game:is_pause_allowed().
  • Add a method map:get_ground() (#141).
  • Add a method map:get_music() (#306).
  • Add an optional parameter on_top to
  • Add sprite:on_animation_changed() and sprite:on_direction_changed() (#153).
  • Add a function sol.input.is_key_pressed().
  • Add a function sol.input.is_joypad_button_pressed().
  • Add a function sol.input.get_joypad_axis_state().
  • Add a function sol.input.get_joypad_hat_direction().
  • Add functions (#175).
  • Add a function (#146).
  • Add a function
  • Add a function
  • Add functions for .it files (#250).
  • Add functions for .it files (#250).
  • Return nil if the string is not found in sol.language.get_string().
  • sol.language.get_dialog() is now implemented.
  • Add a function game:stop_dialog(status) to close the scripted dialog box.
  • Add an event game:on_dialog_started(dialog, info).
  • Add an event game:on_dialog_finished(dialog).
  • Add functions game:start_game_over() and game:stop_game_over (#261).
  • Add events game:on_game_over_started(), game:on_game_over_finished (#261).
  • Add sol.file functions: open(), exists(), remove(), mkdir() (#267).

Bug fixes:

  • Fix map menus not receiving on_command_pressed/released() events.
  • Fix camera callbacks never called when already on the target (#308).
  • Fix a crash when adding a new menu during a menu:on_finished() event.
  • Fix a crash when calling hero:start_victory() without sword.
  • Fix an error when loading sounds (#236). Sounds were working anyway.
  • Fix a possible memory error when playing sounds.
  • Fix blocks that continue to follow the hero after picking a treasure (#284).
  • Fix on_obtained() that was not called for non-brandished treasures (#295).
  • Jumpers can no longer be activated the opposite way when in water.
  • Jumpers are now activated after a slight delay (#253).
  • Sensors no longer automatically reset the hero’s movement (#292).
  • Correctly detect the ground below the hero or any point.
  • Don’t die if there is a syntax error in dialogs.dat.
  • Show a better error message if trying to play a Solarus 0.9 quest (#260).
  • Remove built-in debug keys. This can be done from Lua now.
  • Remove the preprocessor constant SOLARUS_DEBUG_KEYS.
  • Call on_draw() before drawing menus.
  • Fix .it musics looping when they should not.
  • Log all errors in error.txt (#287).

Changes in Solarus Quest Editor 1.1

  • Add a GUI to automatically upgrade quest files to the latest format (#247).
  • Remove the initial prompt dialog to open a quest (#264).
  • Replace non-free images by new icons (#245).
  • Add tooltips to the add entity toolbar.
  • Simplify the add entity toolbar by showing only one icon per entity type.
  • Survive when images cannot be found (#256).
  • Create more content when creating a new quest (#258, #279).
  • Improve error messages.
  • Fix a crash when creating a destructible without tileset selected (#283).
  • Fix the sprite field disabled in the NPC properties dialog (#303).


These improvements involve changes that introduce some incompatibilities in both the format of data files (sprites, project_db.dat, languages.dat) and the Lua API (the dialog box and the game-over menu are scripted now!). Make a backup, and then see the migration guide on the wiki to know how to upgrade.

Changes in Zelda Mystery of Solarus DX 1.7

New features:

  • Add simplified Chinese and traditional Chinese translations (beta).
  • Replace .spc musics by .it ones (much faster) (#17).
  • Add an animated Solarus logo from Maxs (#57).

Bug fixes:

  • Fix savegames created with Solarus 0.9 but that were never run.
  • Fix a slight alignment issue with the hurt animation of the hero.
  • Fix a small breach in dungeon 9 4F in the timed chest room (#4).
  • Fix easy infinite rupees in the waterfall cave (#13).
  • Fix low health beeping playing at final screen (#56).
  • Add a teletransporter from south lake to the cave under the waterfall (#10).
  • Dungeon 7 boss: the player could get stuck in the boss room (#6).
  • Dungeon 7 boss: change the misleading hurt sound of the tail (#7).
  • Dungeon 7: help the player be aligned correctly to obtain the boss key (#8).
  • Dungeon 3 2F: fix two switches that disappeared when activating them.
  • Dungeon 2 boss: fix tile disappearing issue (#14).
  • Dungeon 9 2F: fix a minor graphical issue.

Changes in Zelda Mystery of Solarus XD 1.7

New features:

  • Replace .spc musics by .it musics (faster) and remove unused ones.
  • Add an animated Solarus logo from Maxs.

Bug fixes:

  • Fix savegames created with Solarus 0.9 but that were never run.
  • Fix a slight alignment issue with the hurt animation of the hero.
  • Dungeon 1 3F: fix “attempt to compare number with nil” in counter 36 (#3).
  • Dungeon 2 1F: fix an enemy not counting in WTF room.

Customizable game-over menu!

The last built-in menu is not built-in anymore in Solarus 1.1!

Now, when the life of the player reaches zero, an event game:on_game_over_started() is called. The game is suspended and you can show whatever you want. You can make a dialog that lets the player chose between “Continue” or “Save and quit”. Or you can make a more elaborate game-over menu like in our games, where a fairy saves the player if he has one in a bottle.

And if you don’t define the event, game:on_game_over_started(), then the engine just restarts the game.

The Solarus 1.1 roadmap is close to its end. 50 issues were solved and 1 is still open. Now I am testing both games (ZSDX and ZSXD) to check everything because there was some refactoring done to upgrade to Solarus 1.1, and some C++ code was replaced by Lua code (most importantly, the dialog box and the game-over menu).