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 - alexgleason

Pages: [1] 2 3
Your scripts / Pushable block reimplemented in Lua
« on: June 29, 2019, 05:15:32 pm »
Daniel and I wanted to create pullable/pushable entities that aren't blocks. Below is a Solarus block entity reimplemented in Lua. It's almost an exact copy, except that when pushing, the hero does not continually display the "pushing" animation (only between movements). It's a minor issue but I'd appreciate any help to solve it. Here's the code:

Code: [Select]
-- Lua script of custom entity block.
-- By Daniel Molina and Alex Gleason, licensed under GPL-3.0-or-later


local entity = ...
local game = entity:get_game()
local map = entity:get_map()

-- Moves an entity in the 16x16 grid
local function grid_movement(d4)
  local m = sol.movement.create("straight")
  return m

-- Event called when the custom entity is initialized.
function entity:on_created()
  self._cooldown = sol.timer.start(self, 0, function() end)

-- Handle the hero pushing/pulling the entity
function entity:on_update()
  local hero = game:get_hero()
  local d4 = hero:get_direction()

  if not self:can_move() then
    return -- skip

  if self:is_being_pushed() then self:push(d4) end
  if self:is_being_pulled() then self:pull(invert_d4(d4)) end

-- Push the entity
function entity:push(d4)
  log("Entity is being pushed")

  -- Set hero state
  local hero = game:get_hero()

  -- Move entity
  local m = grid_movement(d4)
  function m:on_obstacle_reached()
  m:start(self, function()
    entity:stop_movement() -- HACK: solarus-games/solarus#1396

  -- Move hero
  local m_hero = grid_movement(d4)
  m_hero:start(hero, function()

-- Pull the entity
function entity:pull(d4)
  log("Entity is being pulled")

  -- Set hero state
  local hero = game:get_hero()

  -- Move entity
  local m = grid_movement(d4)
  m:start(self, function()
    entity:stop_movement() -- HACK: solarus-games/solarus#1396

  -- Move hero
  local m_hero = grid_movement(d4)
  function m_hero:on_obstacle_reached()
    entity:stop_movement() -- HACK: solarus-games/solarus#1396
  m_hero:start(hero, function()

-- Check if hero can move the entity (boolean)
function entity:can_move()
  return not self:is_moving() and self._cooldown:get_remaining_time() == 0

-- Check whether the entity is currently being pushed/pulled (boolean)
function entity:is_moving()
  return entity:get_movement() and true or false

-- Check whether the entity is being pushed (boolean)
function entity:is_being_pushed()
  local hero = game:get_hero()
  return self:overlaps(hero, "facing") and hero:get_state() == "pushing"

-- Check whether the entity is being pulled (boolean)
function entity:is_being_pulled()
  local hero = game:get_hero()
  return self:overlaps(hero, "facing") and hero:get_state() == "pulling"

-- Cooldown between pulling/pushing by 1 tile
function entity:start_cooldown()
  self._cooldown = sol.timer.start(self, 500, function() end)

It requires some utility functions, found here:

Here's the upstream file:

This is a super awesome project using Solarus:

And it's heavily documented, making it even better!!

I'm surprised we'd never heard from this person before - I'm going to reach out to her.

General discussion / Discord <-> Matrix bridge status
« on: February 16, 2019, 05:17:11 pm »
Hey all,

Going forward I'm going to use this thread to update the status of the bridge in case anything happens.

Currently (Feb 16, 2019 @ 11am) the bridge is down. The developer was last seen about 12 hours ago saying:

I've updated the Telegram and Discord bridges. The Discord bridge looks to be taking a bit longer to actually apply the update though, and might be down for longer than expected.

This is the longest period of time the bridge has been down since we first set it up December 9th. The rooms are still accessible to Matrix users, they just aren't syncing messaging to/from Discord.

General discussion / 4-color CC0 tileset (8px tiles)
« on: February 16, 2019, 04:16:54 am »
This tileset looks very cool:

It's the first free 8x8 tileset I've seen that would be a good fit for Solarus. The only problem is that many prebuilt entities need to be 16x16 (including the hero). But you can probably get around this with a bit of hacking in the scripts. It would be interesting to see someone build a tiny game with this.

General discussion / testing 123 please ignore
« on: January 29, 2019, 11:55:41 pm »
testing RSS chatbot integration

General discussion / Solarus Discord/Matrix channel descriptions
« on: January 06, 2019, 11:24:00 pm »
In the Solarus chat, Clewdrew noted that many channels on the Discord side don't have descriptions. Here's our suggestion for descriptions:

  • Solarus - General community chat. Feel free to say hi and ask questions.
  • Solarus Dev - Developing Solarus itself.
  • Solarus Random - Off-topic discussion with the Solarus community.
  • Free Resource Pack - Creating a free resource pack for use with Solarus.
  • Vegan on a Desert Island - Cheeky adventure game about politics and animal liberation (WIP).

  • solarus-fr: Would the french version of the solarus channel description do?
  • new-website: Development of the new website.
  • solarus-[platform]: Porting the Solarus engine to [platform].

My game has several different types of grass and water. Is there a way to set ground1 and ground2 to a different sprite when entering a different area?

I'd also be curious if it's possible to set the direction of the ground based on the hero's direction. eg, when the hero faces left ground2 looks different.


General discussion / Solarus 1.6 snap release
« on: December 28, 2018, 02:36:43 am »
Hi everyone,

I've just put some finishing touches on the Solarus 1.6 snap release.

If you're on Ubuntu, you can search for "Solarus" in the software center and install it from there. That's it!

For other distros, you need to first install snapd. It's probably as simple as sudo <yourPM> install snapd, but you can click the link for more info.

Once you have snapd installed, just run sudo snap install solarus and you'll be good to go!

Known bugs are listed here:

Please report any you find to that. Thanks!

If sound doesn't work: Open Ubuntu Software > Installed > Solarus [ver] > Permissions > Audio Channel and give it permission to run PulseAudio. (thanks latchk3y!)

Development / How do you organize your quest data files?
« on: December 06, 2018, 11:11:09 pm »
Here's how badly disorganized I am:

It's becoming an actual blocker for me. I'm afraid to create new maps and experiment because I don't want to worsen to this mess.

I may solve this by writing documentation on how Vegan on a Desert Island's files are organized. But I'm curious if anyone has already done this, or has any insight to offer.

Some parts I'd like to cover:

  • Dialogs - when do you create folders? Do you categorize by area, by character, by time period? How do you organize branching dialog?
  • Maps - same as above.
  • Sprites - when do you create new a sprite sheet? what is the folder structure?
  • Scripts - same as above.

Development / Lua promises
« on: December 03, 2018, 06:24:02 pm »
I've been working on animating an intro sequence for my game, and running into callback hell with movements. Eg, one movement must happen, then the next movement happens, then a timer happens, then another movement happens, etc.

I found a few Lua promise libraries:

The top one looks very promising. Anyone have experience with this? Also just wanted to share in case others find it interesting.

Your scripts / "End Credits" script (rolling credits)
« on: November 15, 2018, 09:54:14 pm »
I didn't share this before because it'd likely need to be adapted and parts of the code aren't super nice, but I figure maybe this will benefit someone.

It requires a dialog called "end_credits", and it just rolls through it until it's done.
Code: ( lua) [Select]
-- ♡ Copying is an act of love. Please copy and share.

-- Game credits. Plays at the end of the game.

local end_credits = {}

function build_array(...)
  local arr = {}
  for v in ... do
    arr[#arr + 1] = v
  return arr

-- Called when the menu is started
function end_credits:on_started()
  local lh = 12 -- line height in pixels
  local speed = 24 -- scroll speed in px/s

  -- Credits dialog
  self.dialog = sol.language.get_dialog("end_credits")

  -- Break dialog text into a table of lines
  local lines = self.dialog.text
  lines = lines:gsub("\r\n", "\n"):gsub("\r", "\n")
  lines = build_array(lines:gmatch("([^\n]*)\n"))

  -- Box where the credits go
  self.credits_surface = sol.surface.create(
    160, -- center the surface on the screen
    (#lines * lh) -- surface is large enough to hold all lines
      + 144 -- surface scrolls in from the bottom, so has a padding top equal to the screen size
      + 16 -- room for 8px top and bottom padding

  -- Loop through all dialog lines and draw them
  for i, line in ipairs(lines) do
    local line_surface =  sol.text_surface.create({font="Comicoro", font_size=16, text=line})
    -- Draw the given line
      8, -- left padding
      i * lh -- bump it down by line number and line height
        + 8 -- top padding for whole box

  -- Animate the text box upwards
  local m = sol.movement.create("straight")
  m:set_angle(math.pi / 2)

  function m:on_position_changed()
    local credits_surface = end_credits.credits_surface
    local x, y = credits_surface:get_xy()
    local w, h = credits_surface:get_size()

    log(string.format("Credits text box: (%d, %d)  ;;  y+h = %d", x, y, y+h))

    if y + h < 0 then
      -- Credits are out of view, end the menu
      log("Credits animation finished.")


-- Called each frame
function end_credits:on_draw(dst_surface)
  self.credits_surface:draw(dst_surface, 48, 144)

return end_credits

It's a menu, so put it in a .lua file (eg scripts/menus/end_credits.lua) and use something like this:

Code: ( lua) [Select]
local end_credits = require("scripts/menus/end_credits"), end_credits)

General discussion / How loud should sounds be?
« on: November 04, 2018, 05:50:11 pm »
One thing I don't quite understand, is how loud to make each of my sounds/music so it meets the user's expectation based on the volume they've set on their computer.

For example, sometimes I'll mute my game while working and be listening to other music. Then when I unmute my game, I have to turn the volume down. This is because the music in my game is louder than the other music I'm listening to. The other music is usually an album played with VLC, or a YouTube video.

I'm aware of "the loudness wars." Where did we ever end up with that? Is there any sort of standard for loudness? Ideally, I want users to not have to turn the volume up or down when switching from other software to my game.

Development / Has anyone tried compiling Solarus for the web?
« on: November 02, 2018, 09:16:31 pm »
There are C++ to ES6 transpilers that seem to work reasonably well, like Emscripten:

For example, you can see the open source game FreeDink running in the browser: This game is written in C++ and ported to the web with Ecmascripten.

I think Solarus would have to be modified for this to work since it reads the filesystem to load the quest and write save data, but it might be possible.

General discussion / Puzzle design
« on: November 01, 2018, 03:48:52 pm »
I've seen some great resources here about creating beautiful maps, but what about designing puzzles? How do you even approach designing something that you yourself should not be able to easily solve?

I've found one great video series, starting here:

Curious if others have any more input or resources.

I'm experimenting with making NPCs shiver back and forth when I use my vacuum item on them. It's a pixel movement that jitters an entity left and right by 2px.

When I try it, it says: Error: Illegal direction 3 for sprite 'animals/seagull_trash2' in animation 'walking'

I'm guessing that using a movement on an NPC is "smart" and makes the NPC automatically change direction toward the movement and try to walk that way. Am I right? If so, is there an easy way to override it?

It's not a big deal, and I might just not do this in my game. It doesn't seem documented though, and kinda surprised me.

Pages: [1] 2 3