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.


Messages - alexgleason

Pages: [1] 2 3
1
Your projects / Re: Ocean's Heart
« on: Today at 08:31:34 pm »
Anyway, I've definitely gotten a wonderful dose of having to reassess my preconceptions from talking about you, so just know I appreciate that

I know! Orange you glad we had this conversation??

I really like the way you think, Alex : )

Likewise!

I think the stance I've been taking in my head- that it's possible my game would do so well that the value of my assets would be considerable- is less optimistic, and honestly more egotistical. So thanks for bringing it up, because that attitude, even when not consciously embraced, hurts the potential value of what I create as a shared resource, so I'd like to let it go. Maybe the individualistic mindset of valuing one's own creations as personal brand assets above the value they have as a shared resource is probably symptomatic of undervaluing our community, and that's a shitty thing to realize about myself. But realizing it is necessary to addressing it! And will help me be more compassionate toward my community going forward.

I agree, this is the same realization I came to. I started out as an artist, and the open source software thing really shook up my ideas about intellectual property. Now I mostly write code, but I always feel really satisfied to share my other creations. I have gone through great lengths to reorganize my life around giving. And I've been burned by people many times who want to take advantage of that, but I try to focus on the people who are giving back.

We've built a society where the default option is to not give. You quite literally have to go against the grain of society and become a "free thinker" or whatever to see an alternative path. But maybe if we all gave, we'd all have so much more.

Even though some people will burn me, I'm still indebted to all the people - dead or alive - who gave me things I didn't ask for. To Bach, da Vinci, Linux, Solarus, and now you. Nintendo never game me anything that didn't come with a price tag and a EULA, but I don't live for them. I would choose for Ocean's Heart and Children of Solarus to become notorious even at the cost of A Link to the Past being totally forgotten.

On that note, I'd like to introduce you to Nina Paley. She's a professional artist and copyright abolitionist:


Needless to say, she's a personal hero of mine, lol. If you click any of these links and ignore the rest, please choose the first one.

I still think about the potential negative impacts of releasing assets designed around a specific scenario and setting.
And I'm not a teacher, trying to nourish and refine some creativity muscle.

Kinda seems like you addressed your own point. I get your concern, especially because throughout the creation of my game I've been repeatedly making stupid novice mistakes. And I realize these things, and ask myself, "hasn't someone already figured this out before?" But unless you want to be a teacher, I wouldn't worry too much about this. I think it's a separate problem. My concern with freely-licensed assets is that people have been deprived the freedom to copy and share, and I want to take steps to counteract that. To hopefully foster a culture around giving.

But if you wanted to, you could be a teacher. Why not? Include some advice with your assets, or write some blog posts about things you learned about game design. People who are eager to learn will learn. For the rest, we might just have to accept they will be creating mushroom forests.

There are multiple ways you could present your game assets. If you present them all in the context of "Ocean's Heart graphics" rather than "generic zelda-like tileset" then at least people can recognize it as a part of a whole project, which might make them more considerate of the way the use it.

Anyway, thanks for having a real discussion on the internet! You've actually changed my mind on a lot of things.

Totally, and likewise! I feel kinda hopeful for humanity now, hooray!

2
Your projects / Re: Ocean's Heart
« on: Today at 07:18:24 pm »
A full half of them have weird sidequest about finding a stolen orange with just the peel as a clue, or a specific NPC that only eats oranges. After some thought... this alternate timeline has almost no measurable downsides. The people of the alternate future have you to thank, Alex.

Glad we're finally on the same page. ;)

https://vimeo.com/295845034 password: naranja

Vegan on a Desert Island officially takes place in the same fictional universe as Ocean's Heart! This is canon.

3
Your scripts / Re: Script to save the state of hundreds of objects
« on: October 17, 2018, 10:00:07 pm »
I created a far superior version. It's encapsulated entirely within the custom entity script itself:

Code: Lua
  1. -- ♡ Copying is an act of love. Please copy and share.
  2.  
  3. local entity = ...
  4. local game = entity:get_game()
  5. local map = entity:get_map()
  6. local hero = game:get_hero()
  7.  
  8. -- Name of the savegame variable for this map and model
  9. local valname = string.format("entitystate__%s__%s", map:get_id(), entity:get_model())
  10.  
  11. -- Takes in a trash_state and converts it to a string for
  12. -- storage into a savegame variable
  13. local function state_tostring(state)
  14.   local string = ""
  15.   for i, v in ipairs(state) do
  16.     string = string .. tostring(v)
  17.   end
  18.   return string
  19. end
  20.  
  21. -- Takes a state string and returns a table
  22. local function state_fromstring(str)
  23.   if str == nil then return {} end
  24.   local state = {}
  25.   for i=1, #str do
  26.     local n = tonumber(str:sub(i, i))
  27.     state[i] = n
  28.   end
  29.   return state
  30. end
  31.  
  32. -- Event called when the custom entity is initialized.
  33. function entity:on_created()
  34.  
  35.   -- Initialize the properties of your custom entity here,
  36.   -- like the sprite, the size, and whether it can traverse other
  37.   -- entities and be traversed by them.
  38.   entity:set_traversable_by("hero", false)
  39.  
  40.   -- Initialize some variables in the map
  41.   if map._trash_count == nil then map._trash_count = 1 end
  42.   if map._trash_state == nil then
  43.     map._trash_state = state_fromstring(game:get_value(valname))
  44.   end
  45.  
  46.   -- Add an ID to this entity by the order it was created
  47.   self._id = map._trash_count
  48.   map._trash_count = map._trash_count + 1 -- increment counter
  49.  
  50.   -- Initialize the trash state
  51.   if map._trash_state[self._id] == nil then
  52.     map._trash_state[self._id] = 1
  53.   end
  54.  
  55.   -- Remove this if it was already sucked up
  56.   if map._trash_state[self._id] == 0 then
  57.     self:remove()
  58.   end
  59. end
  60.  
  61. -- Like remove(), but not called when the map ends
  62. function entity:destroy()
  63.   if self.on_destroyed ~= nil then
  64.     self:on_destroyed()
  65.   end
  66.   self:remove()
  67. end
  68.  
  69. -- Update the trash state table and save
  70. function entity:on_destroyed()
  71.   map._trash_state[self._id] = 0
  72.   local state_string = state_tostring(map._trash_state)
  73.   print(state_string)
  74.   game:set_value(valname, state_string) -- Save the trash state
  75. end
  76.  

This custom entity can now be placed in any map, and calling entity:destroy() will cause it to save the state of that entity for that map.

Best of all, it requires not a single loop over the map entities!

4
Development / Re: Multi-events as the default?
« on: October 17, 2018, 09:56:13 pm »
I was able to achieve what I wanted by manipulating the map from the context of an item script. I ended up with way less code (and cleaner code), so I'm wondering if my suggestion here is bad practice? I'm not really sure.

5
Development / Multi-events as the default?
« on: October 17, 2018, 08:41:47 pm »
I was just having this moment of great realization for why Lua is a powerful programming language, then I hit a wall again.

To give an example, I have a script which does get_metatable("map"):register_event("on_started", ...)

The problem is, Solarus Quest Editor creates every map script with an empty on_started defined. So I'll need to edit all my maps and change it to map:register_event("on_started", ...) in order to make both functions run.

Basically, I'm trying to have events in "layers". Every map will always call the same "on_started" function in the metatable, but it will also call the "on_started" function of the specific map itself.

So I'm wondering if there should be a push towards using multi-event functions in Quest Editor instead. Eg, creating a new map might look like this:

Code: Lua
  1. -- Lua script of map test_map.
  2. -- This script is executed every time the hero enters this map.
  3.  
  4. -- Feel free to modify the code below.
  5. -- You can add more events and remove the ones you don't need.
  6.  
  7. -- See the Solarus Lua API documentation:
  8. -- http://www.solarus-games.org/doc/latest
  9. require("scripts/multi_events.lua")
  10.  
  11. local map = ...
  12. local game = map:get_game()
  13.  
  14. -- Event called at initialization time, as soon as this map becomes is loaded.
  15. function map:register_event("on_started", function()
  16.  
  17.   -- You can initialize the movement and sprites of various
  18.   -- map entities here.
  19. end)
  20.  
  21. -- Event called after the opening transition effect of the map,
  22. -- that is, when the player takes control of the hero.
  23. function map:register_event("on_opening_transition_finished", function()
  24.  
  25. end)

This would offer a lot more flexibility, because you could disable the default behavior by switching to an empty function. This seems like a more common use-case. I can't think of a use-case where it's better off the way it currently is.

The only real issue I see is that Quest Editor would have to assume you have a multi_events script. So then it makes me think... maybe package that into the engine itself? I mean, it's an essential tool for quest development.

6
Your scripts / Script to save the state of hundreds of objects
« on: October 17, 2018, 08:49:55 am »
Video of this in action: https://vimeo.com/295527145

This is basically solving the problem of Banjo Kazooie's music notes (or Donkey Kong 64's bananas) - how do you save each individual banana/music note separately so that once you picked it up once, it is gone forever?

This script is unfinished, and it's only in a single map for now, but I wanted to share my progress. Later I'll clean it up and abstract it into a proper separate lua module.

My game has hundreds of pieces of trash on the map. When you load the map, the "beach_trash" savegame value looks like this:

Code: [Select]
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
After vacuuming 2 pieces of trash:

Code: [Select]
1111111111111111111111100111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
After vacuuming 6 pieces:

Code: [Select]
1111111111111110011111100111111111111111111111111111111111111111110011111111111111101111111111111111111111111111111111111111111111111111111111111111111111111111111110111111111111111111111
Essentially, when the map loads, it finds all the trash entities, loops through them, and gives them an ID based on the order they're returned from map:get_entities(). So the first piece of trash returned from get_entities() would have an ID of 1 and so on. A "state" table then keeps track of every piece of trash. The trash's ID is used as a key for the state table, and the value is 1 if existing, and 0 if removed. The state table is converted into the above binary string when saved. Here's the full code:

EDIT: Better version in the post below. Also, someone pointed out that this is basically a bitmap. Pretty much - it's like removing all the gaps between the entities and then creating a bitmap over that.

Code: Lua
  1. -- ♡ Copying is an act of love. Please copy and share.
  2.  
  3. local map = ...
  4. local game = map:get_game()
  5. local trash_state = {}
  6.  
  7. -- Takes in an entity state table and converts it to a string for save
  8. local function state_tostring(state)
  9.   local string = ""
  10.   for i, v in ipairs(state) do
  11.     string = string .. tostring(v)
  12.   end
  13.   return string
  14. end
  15.  
  16. -- Takes a state string and returns a table
  17. local function state_fromstring(str)
  18.   if str == nil then return {} end
  19.   local state = {}
  20.   for i=1, #str do
  21.     local n = tonumber(str:sub(i, i))
  22.     state[i] = n
  23.   end
  24.   return state
  25. end
  26.  
  27. -- Get all trash entities for a map
  28. local function get_trash_entities()
  29.   local trash_entities = {}
  30.   local custom_entities = map:get_entities_by_type("custom_entity")
  31.   for entity in custom_entities do
  32.     if entity:get_model() == "trash" then
  33.       table.insert(trash_entities, entity)
  34.     end
  35.   end
  36.   return trash_entities
  37. end
  38.  
  39. -- Assign ID's to all trash entities.
  40. -- Add on_removed event.
  41. local function process_trash()
  42.   trash_state = state_fromstring(game:get_value("beach_trash")) -- load from save
  43.   local entities = get_trash_entities()
  44.   for i, entity in ipairs(entities) do
  45.     entity.id = i -- Assign id to each piece of trash
  46.     if not trash_state[entity.id] then
  47.       trash_state[entity.id] = 1
  48.     end
  49.     function entity:on_removed() -- Update the trash state table
  50.       trash_state[self.id] = 0
  51.       local state_string = state_tostring(trash_state)
  52.       game:set_value("beach_trash", state_string) -- Save the trash state
  53.     end
  54.     if trash_state[entity.id] == 0 then
  55.       entity:remove()
  56.     end
  57.   end
  58. end
  59.  
  60.  
  61. function map:on_started()
  62.   process_trash()
  63. end
  64.  
  65. -- Remove the on_removed event, otherwise trash_state will be set to all zeros when the map is left
  66. function map:on_finished()
  67.   for i, entity in ipairs(get_trash_entities()) do
  68.     entity.on_removed = nil
  69.   end
  70. end
  71.  

7
Your projects / Re: Ocean's Heart
« on: October 17, 2018, 07:46:09 am »
Nice! I appreciate your thoughtfulness. You seem like a nice person. I'll just address the parts I have counterarguments for. I agree with a lot of what you wrote.

Quote from: Max
As a small point, look how many Zelda fan games include a rooster statue in their village's central square, just because it's a nice looking asset to take from Link to the Past.

I realize you're using this as an example to illustrate a larger point, but I'm gonna talk about this literally for a sec. The rooster statue is a meme. I don't think reusing it is uncreative, it's just a cultural reference. But even if you don't think that, this isn't a Creative Commons asset anyway, it's an asset being copied without permission, which Nintendo could sue for.

People feel some ownership over old Nintendo graphics (rightly so). It was a part of a lot of people's childhoods. It's common for people to copy these graphics and use them in fan creations. It took us 26 years to get to that point with the rooster statue, though. Nintendo is a big company, and they can afford to prevent fans from spreading their work. As indie creators, I'm not sure we can afford not to encourage people to share and reuse our work. 26 years is too long.

I want to believe my game will become very popular. But the truth is that it probably won't. It has potential, but this is a competitive industry. Freeing the assets will at least give it a fighting chance for notoriety. It would be a worse mistake for me to spend so much time creating something that is relatively obscure and locked away from reinterpretation and reuse.

Quote from: Max
Or on a bigger scale, have an ice-themed area instead of a rainforest-themed area, just because that's the assets they have. If I want to encourage creativity, I don't think all my assets would benefit those who would use them.

These people are ignoring copyright anyway, so they have the whole world in their hands in terms of assets they could use. If they wanted to creatively reuse assets, there is virtually nothing standing in their way. They could have combined assets from Super Mario Bros and Portal. Most of them didn't, but the creator of mari0 did, and it certainly reinforced the cultural affection for both series.

I don't think being creative is an innate quality of a person, but there is a trend I can't ignore: some people are creative, and some aren't. A creative person can start with any arbitrary pool of resources and create something awesome. I do think we can teach people to more creative, but it would be a deep change in modes of thinking, not altering a resource pool. I mean, jack-o-lanterns involve literally carving a giant piece of fruit with a knife and look at what some people can do with that.

Quote from: Max
If I'm thinking about re-using assets in future games, and assuming the best case scenario where I release graphics freely and a whole damn genre sprouts out around them, my next game might get lost?

This sounds like a great problem to have. I guess you'd just have to rise to the challenge and create a far more innovative game than before. :)

Quote from: Max
So, obviously,  my logic isn't foolproof, but that's at least part of my rationale behind keeping a few assets out of any resource I create and share freely.

It sounds like you're a bit afraid to let go of the main character, and maybe the game's identity. Keep in mind that it can go both ways. If someone created a sequel to my game and I didn't have to lift a finger, I'd be thrilled. The only reason someone wouldn't is because of an egoistic attachment to the creation. It can be hard to separate the creation from the self, but doing so can be even more personally satisfying in the long term.

Quote from: Max
pile of orange peels

I dunno, I've searched for some very specific terms for free graphics ("trash bags", "vitamin") and was bummed there were no free graphics to go off of. I can't imagine that having more options would be a bad thing as long as sites like OpenGameArt.org are properly searchable and curated. You never know, maybe someone really needs a pile of orange peels, haha. I'd love a situation where everything you could think of has at least one free graphic online. Doesn't mean you have to put that graphic front-and-center, though. You could present generic graphics on a curated sprite-sheet, and just let people dig into your game's data to pull out whatever else they want. Up to you.

EDIT: Since we just had a whole conversation about a pile of orange peels, it has some cultural significance now, and I want to hide your pile of orange peels in my game somewhere only so the few people reading this thread can understand the inside joke.

EDIT2: Oranges are vegan.

8
Your projects / Re: Ocean's Heart
« on: October 16, 2018, 06:23:38 am »
My reasoning is I'd like to be able to maintain some identity for my game visually that's unique and marketable

I can definitely understand the concern - you don't want the art to become diluted and used in ways you didn't intend. I wouldn't want that, either. I've been thinking about this for a few minutes and I keep finding counterarguments, though. Like, if someone used your graphics in a crappy game nobody ever plays... oh well? Like, it might make me cringe, but realistically there's not much loss there. But if someone uses your graphics in a game that becomes very popular, then it's like "by the way, all these graphics were actually created for this great original game Ocean's Heart." Then there becomes a context and a history, your art spreads, and becomes imbued in culture.

I guess I just don't think spreading art around defiles its virginity. On the contrary, it helps it learn and grow. It frees it, and this is what free culture is all about.

The third possibility is that your art is proprietary and someone copies it and profits off it without giving you credit. This is always a possibility because some people don't follow the law. So, would you actually sue? The answer is "it depends" I'm sure, but nobody wants to sue. It's an extremely stressful and exhausting thing and most of the time you're better off just letting it go so you can continue to focus on building your own life up rather than tearing down enemies. Not to mention the public controversy of a lawsuit - nobody wants to join the ranks of Nintendo by suing over IP, not even indie game devs. If I'm totally misreading the situation, I apologize, I'm projecting my own situation onto this argument. But if you wouldn't sue if someone copied, and there's a lot to gain from people copying, and not much to lose from it, I personally am very much in the CC-BY boat. Anyway, that's my argument haha. Just wanted to share, but I respect your decision to do whatever you want. ;D Looks like it's gonna be a great game either way.

9
Your projects / Re: Ocean's Heart
« on: October 16, 2018, 01:25:46 am »
Wow, I just clicked through this, and your game looks amazing! Super exciting to see this much work put into a custom Solarus game.

Are you planning on freely licensing the game's graphics and code?

10
You have this behavior because game:on_command_pressed() is called before the on_command_pressed() of game menus.

Okay, so it is intended behavior! Thank you for replying.

I thought the game is "below" the menu, and therefore it wouldn't be called. So is game:on_command_pressed() always called first no matter what when there's an active game?

11
Okay, freezing and unfreezing the player was a bad solution because the hero must be unfrozen in order to brandish a treasure. So what I did instead to work around this is simply add this to game:on_command_pressed:

Code: Lua
  1. function game:on_command_pressed(command)
  2.   -- Don't handle any of this stuff when a dialog box is open
  3.   if game:is_dialog_enabled() then
  4.     return false
  5.   end
  6.   ...
  7. end

I'm getting the feeling that a "dialog box" is not simply just a normal game menu. It must have some additional behavior.

12
I noticed something weird today: my sword can be activated during a dialog box. It goes to the first frame of animation and then is frozen until the dialog box finishes.



When I first opened the dialog box I checked "hero:get_state()" and it says "free". When I press the item button assigned to my sword, it says "sword activated". Keep in mind my sword is an item assigned to item_1 (using hero:start_attack() internally), so it's not surprising that I have strange behavior. But I did think it was strange the dialog box doesn't freeze my hero. I can fix this issue by calling hero:freeze() when the dialog box starts, and hero:unfreeze() when it finishes.

Okay, I understand that some menus (like a HUD) shouldn't freeze the player. But it raises a question: how exactly are button events handled? My dialog box has this:

Code: Lua
  1. function dialog_box:on_command_pressed(command)
  2.   -- "action", "attack", "up", and "down" are handled here. I'm using "item_1" and not pressing any other buttons.
  3.   ...
  4.  
  5.   -- Don't propagate the event to anything below the dialog box.
  6.   return true
  7. end

It returns true, so it shouldn't propagate. The context of dialog box is "game", and "game:on_command_pressed" is where the hero swings her sword.

In main.lua,

Code: Lua
  1.   -- I've simplified my code, but it shouldn't matter. This function shouldn't be called in the first place.
  2.  
  3. function game:on_command_pressed(command)
  4.  
  5.   print("you've reached me") -- This prints in the console when I perform the action in the screenshot, confirming that this function is called
  6.  
  7.   -- Makes the sword swing
  8.   local item = get_item_for_command(command)
  9.   item:on_command_pressed(command) -- this code calls hero:start_attack() internally
  10.  
  11.   return true
  12. end

Any ideas why the event is propagated to game:on_command_press?? Thank you!

13
Development / Re: User properties (key, value) ??
« on: October 15, 2018, 07:15:26 pm »
Looks like a new feature in Solarus 1.6: http://www.solarus-games.org/doc/1.6/lua_api_entity.html#lua_api_entity_get_property
Quote
User-defined properties are arbitrary key-value pairs that you can set to any entity. The engine does nothing special with them, but you can use them in your scripts to store extra information.

14
General discussion / The perfect controller
« on: October 15, 2018, 04:27:37 am »
I spent today working on controller input for my Solarus game, and it sparked me to write about my decades-long yearning for the perfect video game controller. Just wanted to share, article here:

https://blog.alexgleason.me/the-perfect-controller/

15
Bugs & Feature requests / Re: Improve gamepad support
« on: October 14, 2018, 10:03:14 pm »
SDL_gamecontroller sounds like magic. Did this pull request ever happen?

Pages: [1] 2 3