~eliasnaur/gio

12 3

Golab: an example game made with gio

András Belicza
Details
Message ID
<CAP-HBq=9pbBmX3GHk5j4k6HwTkaSfxU0oMjB+yRwWMUGuU2j3g@mail.gmail.com>
DKIM signature
pass
Download raw message
I made a simple, 2D labyrinth game with gio. I used gio's window and
input handling, layout, widgets, image drawing.

Since this is my first gio app, it may not be "idiomatic" gio code,
but other's might find it useful and interesting.

https://github.com/icza/golab

It's still not finished, but proves gio can be used for games like this.
Details
Message ID
<C0MS445E2USG.2G4GYSQLDPDR1@testmac>
In-Reply-To
<CAP-HBq=9pbBmX3GHk5j4k6HwTkaSfxU0oMjB+yRwWMUGuU2j3g@mail.gmail.com> (view parent)
DKIM signature
pass
Download raw message
On Fri Feb 14, 2020 at 10:29 PM, András Belicza wrote:
> I made a simple, 2D labyrinth game with gio. I used gio's window and
> input handling, layout, widgets, image drawing.
>
> 
> Since this is my first gio app, it may not be "idiomatic" gio code,
> but other's might find it useful and interesting.
>
> 
> https://github.com/icza/golab
>
> 
> It's still not finished, but proves gio can be used for games like this.
>
> 

Impressive. It works on both my Linux and macOS machines, except for an
overlapping problem on macOS:

	https://imgur.com/a/05jK507

-- elias
András Belicza
Details
Message ID
<CAP-HBqnchMSmm5px=pko=ccW6c2OPTuLHpC6nXW7R2ajcYaNoA@mail.gmail.com>
In-Reply-To
<C0MS445E2USG.2G4GYSQLDPDR1@testmac> (view parent)
DKIM signature
pass
Download raw message
I used a fixed 50 pixels height for the buttons panel. Looks like on
macOS the Y=0 is the top of the the window title bar, and on Linux
that is the bottom of the window title bar?

On Sat, Feb 15, 2020 at 2:42 PM Elias Naur <mail@eliasnaur.com> wrote:
>
> On Fri Feb 14, 2020 at 10:29 PM, András Belicza wrote:
> > I made a simple, 2D labyrinth game with gio. I used gio's window and
> > input handling, layout, widgets, image drawing.
> >
> >
> > Since this is my first gio app, it may not be "idiomatic" gio code,
> > but other's might find it useful and interesting.
> >
> >
> > https://github.com/icza/golab
> >
> >
> > It's still not finished, but proves gio can be used for games like this.
> >
> >
>
> Impressive. It works on both my Linux and macOS machines, except for an
> overlapping problem on macOS:
>
>         https://imgur.com/a/05jK507
>
> -- elias
Details
Message ID
<C0MU34S1Y3V6.10ACH2SRKFNXO@toolbox>
In-Reply-To
<CAP-HBqnchMSmm5px=pko=ccW6c2OPTuLHpC6nXW7R2ajcYaNoA@mail.gmail.com> (view parent)
DKIM signature
pass
Download raw message
On Sat Feb 15, 2020 at 15:26, András Belicza wrote:
> I used a fixed 50 pixels height for the buttons panel. Looks like on
> macOS the Y=0 is the top of the the window title bar, and on Linux
> that is the bottom of the window title bar?
>

That's the problem then: my macOS laptop is a retina screen and therefore
a different Dp to Px scaling (2x) than my Linux machine (1.5x). Control
dimensions are in Dp, not Px, so a constant 50 px won't work everywhere.

You could either use an offset in Dp and use gtx.Px to convert it at each
frame, or you could use gtx.Dimensions.Size to determine the size of the
controls after layout.

-- elias

> On Sat, Feb 15, 2020 at 2:42 PM Elias Naur <mail@eliasnaur.com> wrote:
> >
> > On Fri Feb 14, 2020 at 10:29 PM, András Belicza wrote:
> > > I made a simple, 2D labyrinth game with gio. I used gio's window and
> > > input handling, layout, widgets, image drawing.
> > >
> > >
> > > Since this is my first gio app, it may not be "idiomatic" gio code,
> > > but other's might find it useful and interesting.
> > >
> > >
> > > https://github.com/icza/golab
> > >
> > >
> > > It's still not finished, but proves gio can be used for games like this.
> > >
> > >
> >
> > Impressive. It works on both my Linux and macOS machines, except for an
> > overlapping problem on macOS:
> >
> >         https://imgur.com/a/05jK507
> >
> > -- elias
András Belicza
Details
Message ID
<CAP-HBqndTnCN-2q2uZWHFxbAN0gvwvY9YNJbgsi8np7QyBgVvA@mail.gmail.com>
In-Reply-To
<C0MU34S1Y3V6.10ACH2SRKFNXO@toolbox> (view parent)
DKIM signature
pass
Download raw message
Thanks, I stored the layed out height of controls, and use that as the
offset when drawing the labyrinth. Can you check if it looks good now?

Also a new question: how can I calculate the required window size now?
Previously I used fixed 50 pixels for controls and 700 pixels for the
lab view, but if the controls height is not static, how can I
calculate that in advance so I can use a sensible initial window size?

Thanks.

On Sat, Feb 15, 2020 at 4:16 PM Elias Naur <mail@eliasnaur.com> wrote:
>
> On Sat Feb 15, 2020 at 15:26, András Belicza wrote:
> > I used a fixed 50 pixels height for the buttons panel. Looks like on
> > macOS the Y=0 is the top of the the window title bar, and on Linux
> > that is the bottom of the window title bar?
> >
>
> That's the problem then: my macOS laptop is a retina screen and therefore
> a different Dp to Px scaling (2x) than my Linux machine (1.5x). Control
> dimensions are in Dp, not Px, so a constant 50 px won't work everywhere.
>
> You could either use an offset in Dp and use gtx.Px to convert it at each
> frame, or you could use gtx.Dimensions.Size to determine the size of the
> controls after layout.
>
> -- elias
>
> > On Sat, Feb 15, 2020 at 2:42 PM Elias Naur <mail@eliasnaur.com> wrote:
> > >
> > > On Fri Feb 14, 2020 at 10:29 PM, András Belicza wrote:
> > > > I made a simple, 2D labyrinth game with gio. I used gio's window and
> > > > input handling, layout, widgets, image drawing.
> > > >
> > > >
> > > > Since this is my first gio app, it may not be "idiomatic" gio code,
> > > > but other's might find it useful and interesting.
> > > >
> > > >
> > > > https://github.com/icza/golab
> > > >
> > > >
> > > > It's still not finished, but proves gio can be used for games like this.
> > > >
> > > >
> > >
> > > Impressive. It works on both my Linux and macOS machines, except for an
> > > overlapping problem on macOS:
> > >
> > >         https://imgur.com/a/05jK507
> > >
> > > -- elias
>
Details
Message ID
<C0MVYT1UJF5E.2HFI5M1A2NKUL@toolbox>
In-Reply-To
<CAP-HBqndTnCN-2q2uZWHFxbAN0gvwvY9YNJbgsi8np7QyBgVvA@mail.gmail.com> (view parent)
DKIM signature
pass
Download raw message
On Sat Feb 15, 2020 at 16:42, András Belicza wrote:
> Thanks, I stored the layed out height of controls, and use that as the
> offset when drawing the labyrinth. Can you check if it looks good now?
>

Looks good now, thanks!

> Also a new question: how can I calculate the required window size now?
> Previously I used fixed 50 pixels for controls and 700 pixels for the
> lab view, but if the controls height is not static, how can I
> calculate that in advance so I can use a sensible initial window size?
>

Note that dimensions passed to app.NewWindow are hints and may be ignored or
modified by the OS. In addition, users can resize your window after it is
created.

You can state the window dimensions in Dp, but that won't help if your
labyrinth is drawn in pixels. A quick fix is the ignore the FrameEvent's
configuration and specify a 1dp = 1px cfg to layout.Context.Reset
to disable widget scaling. The right fix seems to me to measure game
elements in dps as well. 

-- elias
András Belicza
Details
Message ID
<CAP-HBq=yKh9OmTkEixCvkXa30ScwOsLa-tXu_RPDTxUaxOgHvw@mail.gmail.com>
In-Reply-To
<C0MVYT1UJF5E.2HFI5M1A2NKUL@toolbox> (view parent)
DKIM signature
pass
Download raw message
OK, I managed to put up an online demo where one can try golab from the browser:

https://icza.github.io/golab/

One suggestion, Elias:

Registering Gofont and all variants using gofont.Register() adds
almost 3 MB to the output binary, be it a desktop binary or Webasm
target.
In most cases apps don't use all registered fonts, e.g. I only use
them for the buttons, the regular Gofont.

In order not to add 3MB to the binary (webasm), I don't use
gofont.Register(), but instead I "manually" register just the regular
font with a code like this (code taken from gofont.Register()):

    register := func(fnt text.Font, ttf []byte) {
        face, err := opentype.Parse(ttf)
        if err != nil {
            panic(fmt.Sprintf("failed to parse font: %v", err))
        }
        fnt.Typeface = "Go"
        font.Register(fnt, face)
    }
    register(text.Font{}, goregular.TTF)

It would be nice to have a similar alternative in your gofont package,
e.g. `gofont.RegisterLight()`, or `gofont.RegisterRegular()` which
would only register a single font for those who don't need all.
This saves like 2MB from the output binaries.

On Sat, Feb 15, 2020 at 5:47 PM Elias Naur <mail@eliasnaur.com> wrote:
>
> On Sat Feb 15, 2020 at 16:42, András Belicza wrote:
> > Thanks, I stored the layed out height of controls, and use that as the
> > offset when drawing the labyrinth. Can you check if it looks good now?
> >
>
> Looks good now, thanks!
>
> > Also a new question: how can I calculate the required window size now?
> > Previously I used fixed 50 pixels for controls and 700 pixels for the
> > lab view, but if the controls height is not static, how can I
> > calculate that in advance so I can use a sensible initial window size?
> >
>
> Note that dimensions passed to app.NewWindow are hints and may be ignored or
> modified by the OS. In addition, users can resize your window after it is
> created.
>
> You can state the window dimensions in Dp, but that won't help if your
> labyrinth is drawn in pixels. A quick fix is the ignore the FrameEvent's
> configuration and specify a 1dp = 1px cfg to layout.Context.Reset
> to disable widget scaling. The right fix seems to me to measure game
> elements in dps as well.
>
> -- elias
Details
Message ID
<C0NVRTDZ565C.2X6U03WZEI8SN@toolbox>
In-Reply-To
<CAP-HBq=yKh9OmTkEixCvkXa30ScwOsLa-tXu_RPDTxUaxOgHvw@mail.gmail.com> (view parent)
DKIM signature
pass
Download raw message
On Sun Feb 16, 2020 at 19:38, András Belicza wrote:
> OK, I managed to put up an online demo where one can try golab from the browser:
>
> https://icza.github.io/golab/
>
> One suggestion, Elias:
>
> Registering Gofont and all variants using gofont.Register() adds
> almost 3 MB to the output binary, be it a desktop binary or Webasm
> target.
> In most cases apps don't use all registered fonts, e.g. I only use
> them for the buttons, the regular Gofont.
>
> In order not to add 3MB to the binary (webasm), I don't use
> gofont.Register(), but instead I "manually" register just the regular
> font with a code like this (code taken from gofont.Register()):
>
>     register := func(fnt text.Font, ttf []byte) {
>         face, err := opentype.Parse(ttf)
>         if err != nil {
>             panic(fmt.Sprintf("failed to parse font: %v", err))
>         }
>         fnt.Typeface = "Go"
>         font.Register(fnt, face)
>     }
>     register(text.Font{}, goregular.TTF)
>
> It would be nice to have a similar alternative in your gofont package,
> e.g. `gofont.RegisterLight()`, or `gofont.RegisterRegular()` which
> would only register a single font for those who don't need all.
> This saves like 2MB from the output binaries.
>

Sounds good to me, I can use that for the demo on the gioui.org frontpage
as well. Do you want to prepare a patch?

-- elias
András Belicza
Details
Message ID
<CAP-HBq=20kT91L61jK+Qmbt0WpZRcvF-OUQmAqGVc8SpnLT-wA@mail.gmail.com>
In-Reply-To
<C0NVRTDZ565C.2X6U03WZEI8SN@toolbox> (view parent)
DKIM signature
pass
Download raw message
Yes, I try to.

On Sun, Feb 16, 2020 at 9:46 PM Elias Naur <mail@eliasnaur.com> wrote:
>
> On Sun Feb 16, 2020 at 19:38, András Belicza wrote:
> > OK, I managed to put up an online demo where one can try golab from the browser:
> >
> > https://icza.github.io/golab/
> >
> > One suggestion, Elias:
> >
> > Registering Gofont and all variants using gofont.Register() adds
> > almost 3 MB to the output binary, be it a desktop binary or Webasm
> > target.
> > In most cases apps don't use all registered fonts, e.g. I only use
> > them for the buttons, the regular Gofont.
> >
> > In order not to add 3MB to the binary (webasm), I don't use
> > gofont.Register(), but instead I "manually" register just the regular
> > font with a code like this (code taken from gofont.Register()):
> >
> >     register := func(fnt text.Font, ttf []byte) {
> >         face, err := opentype.Parse(ttf)
> >         if err != nil {
> >             panic(fmt.Sprintf("failed to parse font: %v", err))
> >         }
> >         fnt.Typeface = "Go"
> >         font.Register(fnt, face)
> >     }
> >     register(text.Font{}, goregular.TTF)
> >
> > It would be nice to have a similar alternative in your gofont package,
> > e.g. `gofont.RegisterLight()`, or `gofont.RegisterRegular()` which
> > would only register a single font for those who don't need all.
> > This saves like 2MB from the output binaries.
> >
>
> Sounds good to me, I can use that for the demo on the gioui.org frontpage
> as well. Do you want to prepare a patch?
>
> -- elias
Gregory Pomerantz
Details
Message ID
<f8c8a05e-8299-f435-0b08-04de15b7ed19@wow.st>
In-Reply-To
<C0MU34S1Y3V6.10ACH2SRKFNXO@toolbox> (view parent)
DKIM signature
pass
Download raw message
On 2/15/20 10:14 AM, Elias Naur wrote:
> On Sat Feb 15, 2020 at 15:26, András Belicza wrote:
>> I used a fixed 50 pixels height for the buttons panel. Looks like on
>> macOS the Y=0 is the top of the the window title bar, and on Linux
>> that is the bottom of the window title bar?
> That's the problem then: my macOS laptop is a retina screen and therefore
> a different Dp to Px scaling (2x) than my Linux machine (1.5x). Control
> dimensions are in Dp, not Px, so a constant 50 px won't work everywhere.
>
> You could either use an offset in Dp and use gtx.Px to convert it at each
> frame, or you could use gtx.Dimensions.Size to determine the size of the
> controls after layout.
This type of mistake seems very easy to make -- perhaps the API could 
use display pixels by default wherever possible to make it more likely 
for apps to be cross-platform portable. App writers that really need to 
work in true pixels could still do so but would need to do the 
conversions where necessary, and this would make it more explicit that 
they are doing something that may potentially break cross-platform 
compatibility.
Details
Message ID
<C0PAGYEF4N45.YB52AQF9U9GP@toolbox>
In-Reply-To
<f8c8a05e-8299-f435-0b08-04de15b7ed19@wow.st> (view parent)
DKIM signature
pass
Download raw message
On Mon Feb 17, 2020 at 13:49, Gregory Pomerantz wrote:
> On 2/15/20 10:14 AM, Elias Naur wrote:
> > On Sat Feb 15, 2020 at 15:26, András Belicza wrote:
> >> I used a fixed 50 pixels height for the buttons panel. Looks like on
> >> macOS the Y=0 is the top of the the window title bar, and on Linux
> >> that is the bottom of the window title bar?
> > That's the problem then: my macOS laptop is a retina screen and therefore
> > a different Dp to Px scaling (2x) than my Linux machine (1.5x). Control
> > dimensions are in Dp, not Px, so a constant 50 px won't work everywhere.
> >
> > You could either use an offset in Dp and use gtx.Px to convert it at each
> > frame, or you could use gtx.Dimensions.Size to determine the size of the
> > controls after layout.
> This type of mistake seems very easy to make -- perhaps the API could 
> use display pixels by default wherever possible to make it more likely 
> for apps to be cross-platform portable. App writers that really need to 
> work in true pixels could still do so but would need to do the 
> conversions where necessary, and this would make it more explicit that 
> they are doing something that may potentially break cross-platform 
> compatibility.

Can you elaborate your proposal? In particular, what is "the API" referring
to?

-- elias
Gregory Pomerantz
Details
Message ID
<e15903d7-e95d-3ce0-0828-e9d9b5eb8a69@wow.st>
In-Reply-To
<C0PAGYEF4N45.YB52AQF9U9GP@toolbox> (view parent)
DKIM signature
pass
Download raw message
On 2/18/20 7:29 AM, Elias Naur wrote:
>> This type of mistake seems very easy to make -- perhaps the API could
>> use display pixels by default wherever possible to make it more likely
>> for apps to be cross-platform portable. App writers that really need to
>> work in true pixels could still do so but would need to do the
>> conversions where necessary, and this would make it more explicit that
>> they are doing something that may potentially break cross-platform
>> compatibility.
> Can you elaborate your proposal? In particular, what is "the API" referring
> to?

By API, I'm basically thinking of everywhere a function or type accepts 
pixel values -- if these were always required to be display pixels 
(instead of true pixels) it would be harder to make this kind of mistake.

We could simultaneously aim for improved type safety in general -- i.e. 
throughout the Gio code base, don't just interpret int or float32 values 
as pixels, but have types so the programmer has to explicitly convert to 
what the particular function or struct is looking for. As an example, 
right now, TransformOp.Offset() has a single parameter, an f32.Point, 
which is a pair of float32 values. It is not easy to know whether these 
values will be interpreted as true pixels or display pixels. Instead, 
TransformOp.Offset() could take a type that is explicitly meant to 
contain display pixels, so offsets work the same visually on all 
platforms. If the programmer really wants a true pixel offset, they have 
to convert their true pixels to display pixels in their code before 
calling TransformOp.Offset().
Details
Message ID
<C0PCLRH7DE5R.FE0B2ZCH4HKJ@toolbox>
In-Reply-To
<e15903d7-e95d-3ce0-0828-e9d9b5eb8a69@wow.st> (view parent)
DKIM signature
pass
Download raw message
On Tue Feb 18, 2020 at 08:46, Gregory Pomerantz wrote:
> On 2/18/20 7:29 AM, Elias Naur wrote:
> >> This type of mistake seems very easy to make -- perhaps the API could
> >> use display pixels by default wherever possible to make it more likely
> >> for apps to be cross-platform portable. App writers that really need to
> >> work in true pixels could still do so but would need to do the
> >> conversions where necessary, and this would make it more explicit that
> >> they are doing something that may potentially break cross-platform
> >> compatibility.
> > Can you elaborate your proposal? In particular, what is "the API" referring
> > to?
>
> By API, I'm basically thinking of everywhere a function or type accepts 
> pixel values -- if these were always required to be display pixels 
> (instead of true pixels) it would be harder to make this kind of mistake.
>
> We could simultaneously aim for improved type safety in general -- i.e. 
> throughout the Gio code base, don't just interpret int or float32 values 
> as pixels, but have types so the programmer has to explicitly convert to 
> what the particular function or struct is looking for.

Note that bare ints and float32 are *always* pixels. Dps (and Sps) only ever
appear in unit.Values.

> As an example, 
> right now, TransformOp.Offset() has a single parameter, an f32.Point, 
> which is a pair of float32 values. It is not easy to know whether these 
> values will be interpreted as true pixels or display pixels. Instead, 
> TransformOp.Offset() could take a type that is explicitly meant to 
> contain display pixels, so offsets work the same visually on all 
> platforms. If the programmer really wants a true pixel offset, they have 
> to convert their true pixels to display pixels in their code before 
> calling TransformOp.Offset().

I wanted to use Dps everywhere (perhaps doing Sps as a simple dp scale), but it
turns out that sometimes you do need pixels. A good example is font rendering,
where correct hinting and anti-aliasing depend on being able to align to the
underlying pixel grid. A similar example is layout, where using whole pixels
(int, not float32) is what avoids problems when two widgets meet on a
fractional pixel. See for example

	https://github.com/flutter/flutter/issues/15035#issuecomment-370028740

You could imagine using unit.Value everywhere in low-level graphics primitives
but I think that's overkill and will complicate the APIs and underlying code
too much compared to the gain.

-- elias