zethra

Godot + Sugarizer = profit?

So I hear you want to make a game for Sugarizer. For HFOSS we want to port some older Sugar games to Sugarizer. Many of the games were created using pygames, which is not available on the web. So we're going to need to use a different “game engine” for these games. Now a reasonable person might say “using a full on game engine for games this simple is overkill” and “using a few simple web libraries is perfectly sufficient”. But where's the fun in that?

The Godot game engine is pretty cool, and just so happens to be able to export games to html+js+wasm. Which means we can, theoretically, make a Godot game run in Sugarizer. So how do we do this? First, I downloaded the Godot sample game, Dodge the Creeps, to try to embed. I configured the Godot project to be able to export to HTML5 and uploaded it to Github[1]. Then I created a new Sugarizer activity based on the activity template. I cloned the Godot game as submodule into the activity folder and took to embedding it. I wrote a build script to export the game and HTML5 and save to a folder called out. In this form the game works by just opening in the browser. So I modified the activity html file the load the web page as an iframe in the remainder of the activity page under the top bar. It took a bit a finagling to get the frame to be the right size, but after that it worked! See the finished product here [2].

This turned out surprisingly easy to do. However there are a few drawbacks and things to improve. Sugarizer as is doesn't seem to have any sort of build step, being that it's all scripts, but having to run a build script for just my activity is less than optimal. I could save the output web game in git but it's more of a build artifact than source code so that doesn't feel right. Also the wasm file is ~20M (~14 after running wasm-opt). Also the activity has some load time. It's not terrible but it's more than the other activities.

[1] https://github.com/zethra/dodge-the-creeps [2] https://github.com/zethra/sugarizer-lite/tree/godot/activities/DodgeTheCreeps.activity

commarch rust

Rust is a programming language empowering everyone to build reliable and efficient software. Rust tries to provid the benefits of lower level languages like C and C++ while avoiding many of their pitfalls. Rust can be compiled for most major operating systems and CPU architectures, with primary support for Windows, macOS, and Linux on x86. I'm specifically analyzing the Rust compiler project, however the organization that manages the development of Rust also oversees many other related projects. The Rust compiler, like most compilers for systems languages, is bootstrapped and therefor is written in Rust.

My bug fix project was bitwardenrs, which is a Rust implementation of the Bitwarden server. Bitwarden is a FOSS cloud password manager. These projects are on different orders of magnitude of size. Rust has ~748,463 lines of code whereas bitwardenrs ~25,152 lines of code. Rust has about ~30x more code. Rust has 2,655 contributes according to GitHub to bitwardenrs's, 53. I'm not sure exactly how many users each project has, but Rust definitely has a lot more users that bitwardenrs.

Rust is older than people realize. It'll be 10 years old in July; bitwardenrs is 2 years old. Rust, while incomplete in some places, is a fairly polished product that closer to being “done”, whatever that means for a language, than it is from its inception. bitwardenrs is a young project. It's not a complete implementation yet and is lacking in polish, like comprehensive documentation.

Rust has a somewhat unorthodox governance system. Rust's original creator, Graydon Hoare, explicitly did not want to be a BDFL and left the project several years ago, to work on other things. Graydon worked at Mozilla Research at the time. Mozilla has since taken over the project. While most of the people who work on Rust do not work for Mozilla, it has paid for a lot of Rust's development. Partly due to Mozilla's interest in using Rust to rewrite parts of Firefox. The Rust trademark is also owned by Mozilla. The Rust project is governed by a core team made of some people who work full time on Rust and some volunteers. There are several other groups that manage various parts of Rust development, from the language and compiler to the documentation and community teams. There are also working groups to handle more specific and concerted efforts like embedded and game development. Changes to Rust are proposed, discussed, and accepted through an RFC process.

bitwarden_rs, as far as I can tell, follows a BDFL model, being owned by Daniel García. The project does not have any governance documentation but it's under Daniel's personal GitHub account, and he makes most of the commits.

Sources: https://www.rust-lang.org/governance/ https://github.com/aturon/rfcs/blob/rust-governance/text/0000-rust-governance.md https://github.com/dani-garcia/bitwarden_rs https://github.com/rust-lang/rust

Quiz 1

1.1 internet relay chat 1.2 free and open source software 1.3 one laptop per child 1.4 free software foundation 1.5 pull request

  1. git 2.b subversion

  2. sugar

  3. XO

  4. guthub

  5. gitlab

  6. source hut, savanna

  7. d

  8. a

  9. c

  10. e

  11. b

13.1 read 13.2 redistribute 13.3 run 13.4 repair

Bug for bitwarden_rs

I needed to find a bug to fix for the bugfix assignment so I scrolled through repo on the GitHub trending Rust repos page. I looked at topgrade, a system upgrade utility I use, but all of it's issues where a bit more than I wanted to take on. Then I looked at bitwarden_rs; a Rust implementation of the bitwarden server. I looked through their issues and found one mark as “good first issue”. Someone wanted help and version cli flags added to the binary.

So I replied to the issue say I'd fix it [1]. After looking at the code I ask what command line argument paring library I should use, some people have strong options on this kind of thing, and we decided on structopt. structopt is an declarative API over clap, the most popular command line argument paring library in Rust.

I implemented the feature, try to keep to their code style. I was fairly easy to write, but I did have to ask how they wanted me to get the version string. The maintiner said I should print bitwarden_rs $git_verson if $git_verson is set and bitwarden_rs (Version info from Git not present) if it's not. I got it working and I submitted a PR [2]. The maintainer asked me to change the version short flag from “V” to “v” so I made that change. There was a bit more discussion around the flag, but the maintainer decided to take the patch in that state.

[1] https://github.com/dani-garcia/bitwarden_rs/issues/816 [2] https://github.com/dani-garcia/bitwarden_rs/pull/888

Adventures in Sugar Part 1

Why? Because!

So this my be entirely pointless but I want to see if I can get Rust code, and maybe even Rust+Qt to run on Sugar. To do this I'm going to need to figure more about how Sugar activities work. This blog post will be a log of how this goes.

My virtual manager vm has decided to stop working. An error with the networking driver. Possibly a rolling issues. Either way, I'm going to set up virtual box.

I got virtual box setup and I'm now trying to install the guest extensions. I found I guide for Debian 10, so we'll see if that works.

I got the guest extensions installed and sugar failed to boot all the way. Next I'm going to try xrandr.

xrandr worked! I was able to change to screen size by putting xrandr --size 1920x1140 before the sugar command in .xsession. I tried making the size 2560x1600 but that made the screen black.

I want to see if I can build and run Poki Launcher on sugar. I installed rustup to get a recentent enough version of the compiler and I install the Qt development libraries. I compiled successfully but had errors upon running.

I tried modifying the Hello world activity. I tried to get it to launch Firefox by adding setting the exec option to firefox. This didn't work; it just hung for a while. I think sugar require the app it interact with it's API in some way. I might try to write a Python Sugar activity that starts Firefox next.

Literature Review 2

It's true, the term “free software” is misleading. Most English speakers will think you mean free in cost, not free as in freedom. This is to some degree an unfortunate quirk of the English language. If I was around in 1997 I would have agreed with Peterson that a better term was needed. Open Source is a good attempt, but it does quite capture essence of what's meant by free software. Practically speaking, source code availability is a big piece free software but open source doesn't describe what you should be allowed to do with that software.

It my very well be impossible to express the meaning behind free software in a few words, in a way that a lay person would understand. Open source is better than many other attempt at this that I have heard. And the term in entrenched enough now that we couldn't getting rid of it even if we wanted too. “Free and open source software” is a decent compromise albeit a bit long.

As to Hill's criticisms of the Open Source Initiative's mission statement, I generally agree with what he said. While in 2020 that is true of many high profile FOSS projects it's not true broadly, and it'd be unreasonable to expect it to be. It's not even always true of high profile FOSS projects. The heart bleed bug in OpenSSL was a least partly caused by a lack of man power dedicated to code review. I'm not trying to criticize the OpenSSL project, but it illustrates Hill's point. Just because a project is FOSS, or even widely used, doesn't mean it's bullet proof, and it's problematic to assume otherwise.

I agree with Hill that by focusing on just the functionality of the code we loose the thread of free software. Free software vs proprietary software is a philosophical and ethical debate. Having software that works for you is important but that's not the point. Focusing solely on functionality is to ignore the philosophical reason to prefer free software, even when it's functionality is less than that of proprietary alternatives.

I've heard people say that “open source has won”, I may have said it myself. They mean that open source software has become the prevailing option in many key areas. I don't deny that open source software is much more prevalent than it once was. But I think it is foolish to believe that the philosophy of free software is anything more than a niece. Companies don't care about you freedom. Don't forget it.

Linux, Icons, Pain, and Triumph

A few months ago I was working on Poki Launcher[1], my application launcher for Linux. An application launcher needs to enumerate all of the installed apps on the system. The way this is done is described by the Free Desktop desktop entry specification. While researching this and working on my app I realized that, since I wanted to display app's icons in my launcher, I would also need an implementation of the Free Desktop icon theme specification[2].

I don't want to go too deeply into what the Free Desktop icon theme specification is, but briefly, it allows an app that wants to display an icon for an app to find an icon of the right size, for some value of right, and find an icon from a given theme. Most apps ship with their own icons, it's part of their branding. But having all of the app icons on you system having been created by different people with different design sensibilities can be vary dissonant visually. This is why we have icon themes. Icon themes are a groups of icons for various apps that all look good together and have a similar design. The icon theme specification describes how these themes are structured and installed so they can override the default icons.

Getting back to the story, I needed a way to look up these icons and I couldn't find a Rust library to do so. So I endeavored to write my own implementation in Rust. Following the free desktop spec and looking at gnomes implementation I decided I needed to cache a bunch of data about these themes to make look ups FAST. I needed to parse these index files to find out where the icons I wanted where. They where basically ini files so I pulled in an ini parser I was using in Poki Launcher. I parsed all of the index files and created efficient lookup structures of all of the icons and cached them to disk using Cap'n Proto which serialized and de-serialized instantly! I wrote benchmarks and everything. This was going to be fast. And it was horribly slow. Now, loading the cache files and doing the look ups was fast, but generating the cache files took several seconds for larger themes. And the cache files where huge, tens of megabytes.

Discouraged I looked for other solutions and eventually I figured out how to get Qt's icon lookup functionality to work from Rust and used that for Poki Launcher. But now, a few months later and the problem is still nagging at me. The frontier yet untamed. There was still no Rust library for doing icon look ups on Linux. So about two weeks ago I decided to take another crack at the problem. This time with a different design in mind.

I still wanted it to be fast, but I wanted to take a different approach to it. This time I decided to forgo caching all together, at least initially, and just try to do the look up as fast as I could. I decided to write my own ini parser that was would only do what I needed it to and avoid coping a lot of data around. I also tried memory mapping the index files. The rest was fairly straight forward and I'm happy to say I got the library work. And it is pretty fast! I haven't done any formal benchmarking yet but using the time command on Linux it can find all the icons for Firefox in around than 0.01 on average. Obviously this isn't very scientific and I'll need to do more work to really optimize it but I feel good about the work thus far.

If your interested I've dubbed the library linicon[3] and put it on crates.io I've also written C ffi bindings for it[4].

[1] https://git.sr.ht/~zethra/poki-launcher [2] https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html#context [3] https://git.sr.ht/~zethra/linicon [4] https://git.sr.ht/~zethra/linicon-ffi

Lit Review: Programming is Forgetting: Toward a New Hacker Ethic

For this blog post I will be discussing Allison Parrish's keynote at Open Hardware Summit 2016. The talk titled “Programming is Forgetting: Towards a New Hacker Ethic” is a critic of “hacker culture” as described in “Hackers: the hero of the computer revolution” by Steve Levy. “Hackers” presents a very computer-centric view of the world; saying that do be a hacker means believing computing is the most important thing in the world. She goes on to explain that Levy's examples of the hacker ethic in play don't live up to his own standards and how the hacker ethic's core principles are flawed. Specifically, Parrish explains how the hands on imperative, a core piece of Levy's thesis make unfounded assumptions about the world that can lead to harmful conclusions.

I agree with this section of her talk. It baffles me that anyone would believe that computing is the most important thing in the world. In practice, the hacker ethic also seems to be a rather self centered ideology, prioritizing one's own curiosity and learning over other's needs.

Parrish goes on to describe how one of Levy's core assumptions is that the world can be perfectly modeled in a computer system, which I agree isn't the case. In fact, I'd argue it's impossible. This talk helped me future understand that computer systems can have biases.

However I did take issue with a few thing. I think the title, “Programming is Forgetting” is confusing. “You can't model the world” or “Not everything is a Computer System” might have made better titles. I think she should have spent more time explaining and defending her “Hacker Questions” and possibly less time on her explanation of digitization. While I appreciate posing posing questions as opposed to declaring ethical rules, I think there is still value in prescribing what we want to see in our communities. Asking what biases we're introducing is great but that doesn't help us figure out if though biases are bad. I would enjoy seeing a follow up talk.

http://opentranscripts.org/transcript/programming-forgetting-new-hacker-ethic/

Rust is Not Production Ready (Yet)

A bit of a bold title, I know, but I think I can make a good case. Weather Rust is production ready depends on your use case. The issues holding the Rust language from being production ready for all use cases are as follows: compile times, lack of a stable ABI, the lack of a specification, and the rate of change in the language. If you are working on a sizable project, compile times really start to become a drag on productivity. You can mitigate them by breaking up your crate and reducing your use of procedural macros but these are just band-aids. The lack of a stable ABI is only a problem in certain use cases but it's alloying I can't use Rust shared objects without exposing a C API. Having a stable ABI would also mean we could package common Rust libraries like we do C libraries; which would also help with the binary size problem. The lack of a specification and the rate of change in the language means it's very hard for other implementations of Rust to exist; which help witch help to mature the ecosystem. I think all of these issue can and will be solved and I don't think the rate of change in Rust right now is bad. But, for Rust to really be production ready they will have to address. Rust just need more time to mature.

Rust's crate ecosystem is also immature. While we do have many solid crates; there are still a lot of holes. We still don't really have a de facto web framework, we don't really have any GUI libraries that are “there yet” or don't come with serous caveats (like linking to C++), and the entire networking stack is in flux. Until Rust stabilizes more the crates ecosystem will be in constant flux. The addition of futures and async/await, while welcome, mean that all of the networking libraries need to be reworked. And there are more of these changes to come. Non of this is to say futures are a bad thing. I think having a solid low level futures system will be great. But I can understand why people hesitant to use Rust yet.

Rust is great, and I like the new features but the language needs to calm down and stabilize more before it's really production ready.

Qt and Rust

For the past few months I've been working on an application launcher for Linux[1]. This has been my first foray into writing desktop apps for Linux so I didn't have a go to tool set. I wanted to use my current hobby language Rust, so I looked into the existing GUI libraries available on crates.io and looked at existing Rust GUI apps.

The most popular library of the bunch was gtk-rs[2], the Rust bindings for the GTK toolkit. I'd never used GTK before so there was a learning curve, but I got something working. GTK worked but I found it hard to use, possible due to my lack of experience with the library, so I decided to try something else. Most of the other Rust GUI libraries were very new and unstable, which is a non-starter for me.

The other major GUI framework used besides GTK is Qt; so I looked into that. The first Qt library I found for Rust was rust-qt-binding-generator[3]. With this, I'd write my application logic in Rust, my UI in QML and write a JSON file to define the objects shared between the two. With this library I was able to get my app working but it was far from perfect. Having to maintain two definitions of my UI object was a pain and I couldn't access the parts of Qt the library didn't expose. The later of which was a problem because I needed a mechanism to load icons by name from the icon cache, which Qt provided but I couldn't access.

Enter qmetaobject-rs[4]. A library the exposed, at least part, of the the Qt API using the cpp crate and a lot of marcos. This library had a few advantages over rust-qt-binding-generator: It had a nicer API, I didn't have to maintain a separate definition of my UI object in JSON, and most importantly to me, I could access the part of the Qt API I needed even though it wasn't exposed through the library. This still wasn't perfect, as I needed to write some C++ code and fork qmetaobject to do what I needed but I was able to do it. I plan to try to upstream my changes at some point but I need to polish them up first.

So if you are interested in writing a desktop app in Rust I recommend checking out qmetaobject.

[1] https://git.sr.ht/~zethra/poki-launcher [2] https://gtk-rs.org/ [3] https://github.com/KDE/rust-qt-binding-generator [4] https://github.com/woboq/qmetaobject-rs/