Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

So now I have added a widget to store the canvas position and size. I am running into another problem though, by default the placement and size of that canvas will be the one defined in the prototype so I have put some logic in the prototype's view function to apply the stored data persistence to the contraption. That seems to be working correctly as: when I navigate to the card containing my contraptions and enter "Interact" mode, I see the canvas getting in place properly. However I would like this to happen without having to navigate to that card at all (it's not a card meant to be seen by the user), so I'm trying to send a "view" event to the widgets from the deck's script

me.cards.sprites.widgets.sprite1.event["view"]

or even from the listener, while sitting on any card

deck.cards.sprites.widgets.sprite1.event["view"]

 but this doesn't result in anything. It seems like the event never reaches the widget.

Here's the newer version of the prototype, for reference:

{contraption:sprite_maker}
size:[140,140]
resizable:1
margin:[0,0,0,27]
description:"make a sprite"
script:"sprite_maker.0"
attributes:{"name":[],"label":[],"type":[]}
{widgets}
sprite:{"type":"canvas","size":[134,107],"pos":[4,4],"locked":1,"script":"sprite_maker.1","show":"transparent","image":"%%IMG2AIYAawD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AOg==","scale":1}
hitbox:{"type":"canvas","size":[35,73],"pos":[47,16],"locked":1,"script":"sprite_maker.2","show":"transparent","draggable":1,"scale":1}
copy:{"type":"button","size":[109,20],"pos":[10,116],"script":"sprite_maker.3","text":"copy background"}
click_field:{"type":"slider","size":[100,25],"pos":[147,4],"show":"none","interval":[0,1]}
hb_persistence:{"type":"grid","size":[100,50],"pos":[147,35],"show":"none","value":{"x":[],"y":[],"width":[],"height":[]}}
{script:sprite_maker.0}
on init do
  me.show:"transparent"
  # if some hitbox is save -> load, otherwise -> leave as default
  if count (rows hb_persistence.value) > 0
    init_hb_pos[]
  end
end
on init_hb_pos do
  persistent_hb_infos:first (rows hb_persistence.value)
  hitbox.pos:(persistent_hb_infos.x, persistent_hb_infos.y)
  hitbox.size:(persistent_hb_infos.width, persistent_hb_infos.height)  
end
on view do
  init[]
end
on get_sprite do
  sprite.copy[(0, 0) sprite.size]
end
on get_hitbox do
  offset:hitbox.pos
  size:hitbox.size
  ("offset", "size") dict (list offset), (list size)
end
on get_hb_persistence do
  first (rows hb_persistence.value)
end
{end}
{script:sprite_maker.1}
on click pos do
  if click_num[] = 0
    set_ul_corner[pos]
  elseif click_num[] = 1
    set_br_corner[pos]
  end
end
on click_num do
  click_field.value
end
on set_hb_pos pos do
  hitbox.pos:pos
  hb_persistence.value:
    insert 
      x:pos[0] y:pos[1]
      width:hitbox.size[0] height:hitbox.size[1]     into 0 end on set_hb_size size do   hitbox.size:size   hb_persistence.value:     insert
      x:hitbox.pos[0] y:hitbox.pos[1]
      width:size[0] height:size[1]     into 0 end on set_ul_corner pos do   offset_pos:me.pos+pos   set_hb_pos[offset_pos]   click_field.value:1 end on set_br_corner pos do   offset_pos:me.pos+pos   hb_pos:hitbox.pos   size:offset_pos-hb_pos   if size[0] < 0     hb_pos[0]:hb_pos[0]+size[0]     size[0]:-size[0]   end   if size[1] < 0     hb_pos[1]:hb_pos[1]+size[1]     size[1]:-size[1]   end   set_hb_pos[hb_pos]   set_hb_size[size]   click_field.value:0 end on drag pos do end on release pos do end {end} {script:sprite_maker.2} on click pos do end on drag pos do end on release _ do   pos:hitbox.pos   hb_persistence.value:     insert       x:pos[0] y:pos[1]
      width:hitbox.size[0] height:hitbox.size[1]     into 0 end {end} {script:sprite_maker.3} current_card:deck.card on click do   pos:sprite.offset   size:sprite.size   card_background:current_card.image   cropped:card_background.copy[pos size]   sprite.paste[cropped (0, 0)] end {end}

As described in the v1.36 release notes, sending a "synthetic" event to a contraption instance would cause it to be handled by the contraption's "external" (per-instance) script.

The deck-level script, like most scripts, is not executed while Decker is not in Interact mode. The only opportunity for a Contraption's scripts to execute during editing is the code inside custom attribute handlers, which is capped within a very brief quota. In both cases, these constraints exist to prevent incomplete or malformed scripts from wedging Decker and rendering it unusable.

(1 edit)

got it! Thanks for replying my flurry of questions and giving me leads to overcome my issues :)

I'm documenting my fix here, in case someone has similar needs.

1. Adding a template script.

I have created a view function in the prototype's template script, calling me.init[], the function that uses internal widgets to restore persistent data

on view do
  me.init[]
end

2. Exposing the inner init function.

The init function is located in the prototype's script, so it cannot be reached from a contraption's script. It has to be exposed by creating a get_x function in that same script

on init do
  # here should be some logic to restore persistent data
end
on get_init do
  # expose init function, so that it can be called from outside the prototype's script
  init
end

With these two changes: every contraption made from that prototype is created with that view function, which lets me send "synthetic" view events & the way these events are processed is still relying on the prototype's functions.