A person is being lazy if he is able to carry out some activity that he ought to carry out, but is disinclined to do so because of the effort involved. Instead, he carries out the activity perfunctorily; or engages in some other, less strenuous or less boring activity; or remains idle. In short, he is being lazy if his motivation to spare himself effort trumps his motivation to do the right or expected thing.
+
+
Don't avoid discomfort.
+
+
+
+
+
+
+
diff --git a/favicon.ico b/favicon.ico
new file mode 100644
index 00000000..3eaf504f
Binary files /dev/null and b/favicon.ico differ
diff --git a/index.html b/index.html
new file mode 100644
index 00000000..ec8da4b8
--- /dev/null
+++ b/index.html
@@ -0,0 +1,283 @@
+
+
+
+
+
+ Philipp Hansch - Ruby, Rust and more
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 👋 Hi, I'm Philipp Hansch, a full stack developer currently focusing on Rust where I have contributed over 200 pull requests to Clippy and associated tooling. I appreciate clean and well tested code and enjoy playing with new technology.
+ Feel free to take a look at my writings and resumé as well.
+
+
+
+
Recent
+
You can find my in-progress Rust work in this GitHub project.
+Below is a list of my last 10 merged pull requests.
I decided I want to write more on here, but I also don't want the pressure of writing a full blog post every time I get the urge to write. So I set up this notes section that gives me a separate space to dump my current thoughts without much editing.
+
So here goes my first note.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
I've removed the link to my sponsor page, because I haven't taken sponsors
+since 2021. The reality is, I've been burnt out of tech for a while now,
+website updates didn't have priority, and I don't see myself taking money for
+OSS work in the foreseeable future.
+
I have a more detailed post on my burnout coming up. Maybe this week - I've been
+slowly crawling out of my burnout recently.
There's probably a full blog post in here somewhere. For the past few months
+I've been using VSCode for work and private projects. I grew tired of
+breaking plugins and changing configs all the time. I'm a big fan of robust
+tech and my neovim experience has been very far from that. I want to spend as
+little time as possible thinking about configs. The majority of my computer
+time should not be spent working on my dotfiles.
+
VSCode solves this problem by having plugins that almost always just work.
+Especially when it comes to Language Server plugins, there's a world of
+difference. So around 9 months ago I started using VSCode as my main editor.
+
Fast-forward to today, there are two main reasons I'm now switching back to
+neovim:
+
+
VSCode ended up being a memory hog on my Dell XPS 13 from 2018. I ran out of
+memory multiple times.
+
The UI of VSCode is distracting and annoying to use.
+
+
Now I'm using LazyVim to take care of my LSP setup and hope that it doesn't
+break as often. I essentially outsourced most of my neovim configuration. I can still
+configure neovim to have a distraction-free UI, be resource-friendly and most
+important, not break on every plugin update.
+
Let's see what it looks like after another 9 months.
Over the past couple of days I've spent some time to update the website. Maybe it's a sign that my burnout is getting manageable.
+
+
Links underlined for improved accessibility.
+
New link list on the home page (Inspired by @muan).
+
Removed the 'Reading' page and added a link to my Storygraph page.
+
I can write notes now. The most recent are listed here
+
Using CSS custom properties for variables - I'm very much behind on frontend tech. commit
+
+
I'm still not 100% happy with the home page, so I will continue working on it this week. I want to improve the look of the timeline as well as update references to my Rust involvement (I'm not involved anymore, for now).
I decided I want to write more on here, but I also don't want the pressure of writing a full blog post every time I get the urge to write. So I set up this notes section that gives me a separate space to dump my current thoughts without much editing.
I've removed the link to my sponsor page, because I haven't taken sponsors
+since 2021. The reality is, I've been burnt out of tech for a while now,
+website updates didn't have priority, and I don't see myself taking money for
+OSS work in the foreseeable future.
+
I have a more detailed post on my burnout coming up. Maybe this week - I've been
+slowly crawling out of my burnout recently.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
There's probably a full blog post in here somewhere. For the past few months
+I've been using VSCode for work and private projects. I grew tired of
+breaking plugins and changing configs all the time. I'm a big fan of robust
+tech and my neovim experience has been very far from that. I want to spend as
+little time as possible thinking about configs. The majority of my computer
+time should not be spent working on my dotfiles.
+
VSCode solves this problem by having plugins that almost always just work.
+Especially when it comes to Language Server plugins, there's a world of
+difference. So around 9 months ago I started using VSCode as my main editor.
+
Fast-forward to today, there are two main reasons I'm now switching back to
+neovim:
+
+
VSCode ended up being a memory hog on my Dell XPS 13 from 2018. I ran out of
+memory multiple times.
+
The UI of VSCode is distracting and annoying to use.
+
+
Now I'm using LazyVim to take care of my LSP setup and hope that it doesn't
+break as often. I essentially outsourced most of my neovim configuration. I can still
+configure neovim to have a distraction-free UI, be resource-friendly and most
+important, not break on every plugin update.
+
Let's see what it looks like after another 9 months.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Over the past couple of days I've spent some time to update the website. Maybe it's a sign that my burnout is getting manageable.
+
+
Links underlined for improved accessibility.
+
New link list on the home page (Inspired by @muan).
+
Removed the 'Reading' page and added a link to my Storygraph page.
+
I can write notes now. The most recent are listed here
+
Using CSS custom properties for variables - I'm very much behind on frontend tech. commit
+
+
I'm still not 100% happy with the home page, so I will continue working on it this week. I want to improve the look of the timeline as well as update references to my Rust involvement (I'm not involved anymore, for now).
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Hi there! In 2018 I decided to set up this little thing where I track my
+progress of learning Rust and contributing to its ecosystem. In March 2019 I
+completed the first 100 pull requests and I wrote about it
+here.
+
Why 100?
+
It's low enough to feel reachable but it also requires a significant amount of
+commitment.
+
What counts?
+
I decided to only count contributions to other projects because it prevents me
+from cheating the count by creating dozens of small pull requests to my own
+projects. It also means that pretty much every PR will benefit the Rust
+ecosystem in some way.
+
+
+
+
+
+
+
+
+
+
+
+ 2021-02-15: Made a contribution to rust-clippy
+
+
+
+ ⧽ Upgrade compiletest-rs to 0.6 and tester to 0.9
+
On any given day I find myself with at least 2 rails consoles open at the same time. One for local development and one for the testing or production environment.
+All share the same prompt.
+
In development:
+
[1] pry(main)> User.destroy_all
+
+
In production:
+
[2] pry(main)> DataCollector.collect
+
+
It would be really good to know what environment each rails console is operating on. While it is printed on the start of the rails console session, it usually quickly scrolls off the screen.
+
What if we accidentally removed the users on the wrong system? Sure, everyone has working backups, database replication and is also testing them regularly, right?
+
Even if we have working backups, we can still work on preventing accidents. Luckily we have complete control over the pry prompt through the .pryrc configuration file.
+
The solution
+
A closer look at the documentation shows that we can easily make text bold and colored in the prompt:
+
Pry::Helpers::Text.red('I am red.')
+Pry::Helpers::Text.bold('I am bold.')
+
+
We get the project name using:
+
File.basename(Rails.root)
+
+
The pry prompt can be overridden in the .pryrc with a custom proc:
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Ich werde zunächst einige Einträge über meine ersten Blogversuche schreiben. Das Blog benötigt noch etwas Feintuning. Wobei sich mir hier eine wichtige Frage stellt:
+
"Das Blog" oder "Der Blog"?
+
Über diese Frage scheint es im Netz wohl eineendloseDiskussion zu geben. Ich lege mich hier einfach auf "Das Blog" fest.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
As you can see, I sadly didn't get around to update the blog with new posts. That is, first and foremost because I recently moved to Berlin. It's an exciting city and there's so much to see. There's also stuff to be done for university which takes up some time.
+
Lastly I'm not going to continue to use XNA for future projects. XNA is a good toolset that can teach the very basics of game programming. But as far as I can tell, it's not really a tool set that is common in the industry. For now, I am only writing down some game ideas. Eventually I'll get a hold of C++ and actually finish some games that deserve a place on my portfolio. Until then, I'm playing around with the RIFT addon system. Their addons are based on Lua, which is a scripting language I don't want to miss out on.
+
Ah, yes: From now on, every post will be in English. I am not sure if I get around to buy an English domain name, so the .de will have to stay for now. As to the old German posts: Right now I don't have the time to properly translate them to English. However, Christmas is near and I will be visiting my parents in North Rhine-Westphalia, so I might find some time to translate them. :)
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
+
+
+
+
+
+
+
+
+
diff --git a/posts/are-you-the-princess-or-the-knight/index.html b/posts/are-you-the-princess-or-the-knight/index.html
new file mode 100644
index 00000000..7935183b
--- /dev/null
+++ b/posts/are-you-the-princess-or-the-knight/index.html
@@ -0,0 +1,93 @@
+
+
+
+
+
+ Are you the princess or the knight?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
When things get dark and tough, and you don't know what to do, you can either sit down and do nothing but wallow in self-pity and doubt, or you can stand up and decide that even if you don't know what you're going to do, you're going to take life by storm. In the end, you can decide if you're going to be the princess waiting to be rescued, or the knight fighting the dragon.
+Reddit User Jehosh. Source
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
We went to the Naturpark Westhavelland, which is a 90 minute drive away from Berlin. The weather looked really promising and since no one of us has been at that place before we were all excited to get there. The Naturpark Westhavelland is located about 50km west of Berlin and is one of the few places in Germany with a natural night sky.
+
We met at a car-rental place at about 18:30 and packed up our stuff. Some of us, me included, didn't have any astronomy equipment and just brought something to eat. We got moving 30 minutes later and started making our way West. One hour later we were already in rural Brandenburg, leaving Berlins nightly glow behind us. We started looking for a place to set up our stuff and first stopped on the side of a small road between two small villages.
+
The moment we stepped out of the car was the best thing ever and I will probably never forget that moment. Looking back at it, I think most of us didn't expect to see so many stars.
+
It is hard to describe the feeling you get when seeing it for the first time. It is a humbling experience. You really have to see and experience it for yourself.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Ich möchte an dieser Stelle kurz die lange Pause entschuldigen. Falls sich jemand über die Ruhe gewundert hat:
+
Die letzten paar Monate habe ich für die Schule viel zu tun gehabt. Das hat sich nun auch mit einem erfolgreichen Abschluss bezahlt gemacht. Ich bin nun Staatlich geprüfter Informationstechnischer Assistent mit FHR.
+
Mein persönliches Ziel für diesen Blog war es, zumindest am Anfang des Jahres, jede Woche einen Blogpost zu veröffentlichen. Das wären nun noch 51 Blogposts über die verbleibenden 6 Monate dieses Jahres. Ich weiß nicht ob ich dieses Ziel noch erreichen kann, aber ich habe auf jeden Fall schon einige Blogposts vorbereitet die verteilt über die nächste Woche erscheinen werden.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
um mir die Arbeit zu erleichtern, werde ich meinen gaming Blog mit diesem Blog zusammenführen.
+Dies wird der letzte Artikel auf phansch.de sein. Alle neuen Artikel sind auf plyturon.net zu finden.
+Da vermutlich einige Links auf meinen Blog verweisen, wird er so lange wie möglich weiterhin under blog.phansch.de erreichbar sein. Für phansch.de habe ich schon andere Pläne. Im übrigen wird plyturon.net komplett Englisch sein.
+
Danke an alle treuen Leser,
+
Philipp
+
+
Hi there,
+
in an effort to make things easier for me, I decided to merge my gaming blog with this blog.
+From now on, you will find all new posts over at plyturon.net.
+blog.phansch.de will continue to lead to this blog, but there won't be any new posts. I have other plans for this domain.
+
Thanks for following me through all the years,
+
Philipp
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
While I was working on a new version of Jou, I suddenly stumbled across a roadblock.
+
+
+
+> What?! Expectation equals result, so why would it fail?!
+
That was my first thought.
+
It might be useful to know what the test and get_recent look like.
+
Here's a breakdown of the spec:
+
before do
+# Create a basic temporary journal file
+ @journal_file = Tempfile.new('jou_test')
+ @journal = Journal.new(@journal_file.path)
+
+ @today = Date.today.strftime("%y.%m.%d")
+end
+
+it "returns a string with entries from today" do
+ @journal.add("hi!")
+ @journal.add("ho!")
+ @journal.get_recent(1).should == "### #{@today}\n * hi!\n * ho!\n\n"
+ends
+
+
And get_recent:
+
def get_recent(limit = 5)
+ out = ""
+
+self.each_pair do |date, entries|
+break if limit == 0
+
+ out << "### #{date}\n"
+ entries.each { |entry| out << " * #{entry}\n" }
+ out << "\n"
+ limit -= 1
+end
+
+ out
+end
+
+
My first guess was that the failing test was caused by using ==. Luckily I've heard about
+different equality matchers in rspec before. I looked them up and it turns out that using == is
+indeed the right choice to compare the values of two different objects.
+
Then I decided to run the test on the command line instead of using RubyTest inside Sublime Text. Maybe, for whatever reason, it would show something that RubyTest doesn't.
Well, how did that hyphen get there and why didn't it show up in Sublime Text?
+First, let's see if the hyphen is actually in the file and not just present on the command line.
+I'm using the HexView plugin to check the actual content of the file.
Well there it is. c2ad. In Unicode that's U+00AD - the soft hyphen. You can see a demonstration of the soft hyphen on wikipedia.
+
Now that I found the character, I was able to remove it and the test succeeds. But that doesn't answer the two questions from above.
+
+
How did that hyphen get there and why didn't it show up in Sublime Text?
+
+
I frankly have no idea how the hyphen got there but I can make some guesses on why it doesn't show up. Firstly, it could be the font that doesn't support the soft hyphen. However, since I'm using the same font (Ubuntu Mono) for Sublime Text and urxvt, that's not possible. After all, the soft hyphen was displayed on the command line. My guess is that Sublime Text treats the character as an invisible character as the unicode standard suggests:
+
+
Despite its name, U+00AD - soft hyphen is not a hyphen, but rather an invisible format character used to indicate optional intraword breaks. As described in Section 16.2, Layout Controls, its effect on the appearance of the text depends on the language and script used.
+The Unicode Consortium. The Unicode Standard.
+http://www.unicode.org/versions/latest/
+
+
Was it worthwhile?
+
Yes. I think that sometimes it is worth digging deep instead of reverting to a previous commit.
+I'm still new to testing so looking into equality matchers surely didn't hurt. I also learned a lot about Unicode, which might come in handy at some point.
+
What about you? Do you revert to save time or do you prefer to get to the root of the issue?
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Vorwort: _Für diese Reihe wird Visual C# Express 2008 oder MonoDevelop benötigt. Screenshots, Codesnippets und Solutions werden vorerst nur für Visual C# Express verfügbar sein.
+
Schiffeversenken ist ein tolles Spiel. Jeder kennt es und jeder mag es.
+Da liegt es eigentlich nur nahe, das Spiel als Programmieraufgabe zu verwenden.
+
Wenn wir uns das Spiel genauer anschauen, stellen wir fest dass es vieles zu beachten gibt.
+
+
Die Spielfeldgröße
+
Art und Anzahl der verfügbaren Schiffe
+
Schwierigkeitsgrad des Computergegners
+
Verschiedene Spielvarianten
+
+
Mit ein bisschen Fantasie lässt sich das Spiel noch erweitern:
+
+
Sonar, zum aufdecken eines Feldes.
+
Radar, um festzustellen von wo gefeuert wurde.
+
Superwaffen, die mehrere Felder treffen.
+
Zeitliche Begrenzung
+
+
Zunächst werden wir nur ein einfache Version entwickeln, in der sich, abgesehen vom Schiffeversenken, nur die Spielfeldgröße ändern lässt.
+
Das erste was wir Programmieren werden ist also das Spielfeld.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Note: Die ZedGraph Website existiert leider nicht mehr, deshalb habe ich die links entfernt.
+Für die Darstellung von Graphen und Diagrammen in einer Form gibt es verschiedene Werkzeuge. Der Großteil der Angebote ist allerdings nicht kostenlos oder nur gering konfigurierbar. Auf der Suche nach weiteren Bibliotheken bin ich auf ZedGraph gestoßen.
+
ZedGraph ist eine freie Bibliothek zum Erstellen von flexiblen Diagrammen und Graphen. Mit ZedGraph lassen sich alle Formen von 2D Diagrammen darstellen. Die Diagramme bieten Optionen zum Zoomen, drucken, kopieren und speichern.
+
Während die ZedGraph Wiki bereits viele Beispiele bietet, werde ich ebenfalls die Grundfunktionen von ZedGraph anhand eines kleinen Beispiels erläutern.
+
Darstellung von zufälligen Zahlen als Streudiagramm
+
Um ZedGraph benutzen zu können, muss die aktuelle Bibliothek hier heruntergeladen und entpackt werden.
+Wir erstellen zunächst ein neues Windows Forms Projekt. Als erstes fügen wir einen Verweis zur ZedGraph.dll hinzu. Dazu kopieren wir zunächst die ZedGraph.dll in das bin/Debug Verzeichnis unseres Projektes.
+
+
Anschließend fügen wir im Projekt-Explorer einen Verweis zur ZedGraph.dll hinzu (how-to).
+
Mit
+
using ZedGraph;
+
+
können wir jetzt auf sämtliche Funktionen von ZedGraph zurückgreifen. Um das ZedGraphControl nutzen können, müssen wir das Element noch der Toolbox hinzufügen. An dieser Stelle werde wir das Formdesign nicht näher betrachten. Wir gehen direkt in den Code.
+
Zunächst haben wir zwei Klassen auf die wir zurückgreifen:
+
Random rNum = new Random();
+ PointPairList randomData = new PointPairList();
+
+
Random ist Teil des .net Frameworks und gibt uns eine zufällige Zahl zurück.
+PointPairList ist eine Klasse der ZedGraph Bibliothek und ist eine Liste von PointPair Objekten.
+
Nun die Methode zum Erzeugen von 200 zufälligen Zahlen:
+
private void button_update_Click(object sender, EventArgs e)
+{
+ randomData.Clear(); //Remove old data
+
+ int i = 0;
+
+ do
+ {
+ i++;
+
+ //Add random new data to the PointPairList
+ randomData.Add(rNum.Next(1, 255), rNum.Next(1, 255));
+ }
+ while (i < 199);
+
+ //Update the chart
+ CreateChart(zedGraphControl1);
+}
+
+
Und die Methode CreateChart:
+
private void CreateChart(ZedGraphControl zgc)
+{
+ GraphPane myPane = zgc.GraphPane;
+
+ //Needed for redrawing the chart, to remove old curves
+ myPane.CurveList.Clear();
+
+ //Add the data
+ LineItem myCurve = myPane.AddCurve("Random Values", randomData,
+ Color.Black);
+
+ //Customize the graph
+ myCurve.Line.IsVisible = false; //Hide line-connections
+ myCurve.Symbol.Type = SymbolType.Circle;
+ myCurve.Symbol.Size = 2f;
+ myCurve.Symbol.Fill.Type = FillType.Solid;
+ myCurve.Symbol.IsAntiAlias = true; //Makes the circles smoother
+
+ //Refresh the graph in order to show the new data
+ zgc.AxisChange();
+ zgc.Refresh();
+}
+
+
Zunächst erstellen wir einen Verweis auf das ZedGraphControl. Mit myPane könnten wir auf die zahlreichen Properties zugreifen.
+Wir nutzen es in diesem Beispiel aber nur um alte Daten im Falle einen Updates zu entfernen.
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Der Konstruktor der abgeleiteten Klasse Answers legt sämtliche Properties fest und ruft die Methode PopulateArray() auf. Außerdem wird das Array initialisiert und selbiges in RadioButtons konvertiert.
Die Anpassung der Form ist recht einfach. Wir fügen der Methode Form1_Load() folgende Zeile hinzu:
+
this.Controls.AddRange(a.ArrAnswers);
+
+
+
Weiterhin soll man den Weiter-Button nicht benutzen können, bevor eine Antwort ausgewählt ist. Dazu wird die Eigenschaft enabled des Buttons button_next zunächst auf false gesetzt.
+
Wenn nun eine Antwort ausgewählt wird, soll der Button aktiviert werden. Dazu müssen wir jedem unserer RadioButtons einen EventHandler zuweisen.
+
Der EventHandler aktiviert den Button button_next wieder. Außerdem werden wir im letzten Teil dieser Reihe an dieser Stelle die Antworten sammeln.
+
In der Methode Form1_Load fügen wir jedem RadioButton einen Click-Eventhandler hinzu:
+
//Add an eventhandler for each radiobutton
+foreach (RadioButton rdb in a.ArrAnswers)
+{
+rdb.Click += Handler;
+}
+
+
Die Methode Handler aktiviert den Weiter-Button wieder wenn ein Click-Event von einem der RadioButtons ausgeht.
Um zu verhinden, dass nach der letzten Frage die Antworten angezeigt werden, müssen wir die Methoden EndReached() und Restart() erweitern:
+
private void EndReached()
+{
+//.
+//. //Skipped some lines here
+//.
+
+//Set all Answers invisible
+foreach (RadioButton rdb in a.ArrAnswers)
+ {
+rdb.Visible = false;
+ }
+}
+
+private void Restart()
+{
+//.
+//. //Skipped some lines here
+//.
+
+//Set all Answers visible
+foreach (RadioButton rdb in a.ArrAnswers)
+ {
+rdb.Visible = true;
+ }
+}
+
+
Das war's auch schon. Wir können nun beliebige Fragen und Antworten ausgeben lassen und den Test wiederholen. Damit haben wir schon über die Hälfte unserer Anforderungen an das Programm erfüllt. Nun fehlt nur noch eine grafische Darstellung der Testergebnisse.
+
Die bisherige Lösung als .zip Datei: Nicht mehr verfügbar.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Im vorherigen Tutorialteil haben wir die Grundlagen für das Auswerten der Fragen programmiert.
+
Ein kurzer Blick auf unsere ToDo Liste sagt uns, dass wir nur noch eine grafische Liveauswertung der Ergebnisse implementieren müssen.
+
Meine Wahl für ein passende Auswertung habe ich mit ZedGraph bereits getroffen. ZedGraph ist einfach zu benutzen und sehr flexibel was die Darstellungsformen angeht.
+
Wir stehen jetzt vor 2 Teilproblemen:
+
+
Sammeln der Ergebnisse
+
Erstellung des Diagramms
+
+
Sammeln der Ergebnisse
+
Das sammeln der Ergebnisse ist überraschend einfach.
+
Wir legen eine neue Membervariable an:
+
private double[] answerCount; //Contains the choices
+
+
Diese wird dann in der Methode Form1_Load initialisiert:
+
//Initialize the array (size = total possible answers)
+answerCount = new double[a.Count];
+
+
Der Gedanke ist recht simpel:
+Das Array hat eine Größe die der Anzahl der Antworten entspricht. In unserem Fall wäre das 4.
+Wenn nun eine Antwort bestätigt wird (button_next_Click) können wir den Wert des entsprechenden Arrayfeldes erhöhen.
+
Wir erweitern nun die IF Abfrage in der Methode button_next_Click():
+
if (rdb.Checked == true)
+{
+//Save the answer
+int answerID;
+answerID = Convert.ToInt32(rdb.Name);
+answerCount[answerID] += 1;
+
+//Set the answer to unchecked and break
+rdb.Checked = false;
+break;
+}
+
+
So können wir für jede Antwortmöglichkeit bequem die Anzahl der Antworten feststellen.
+
Erstellung des Diagramms
+
Für den letzten Schritt müssen wir ein paar Vorbereitungen treffen.
+Um ZedGraph benutzen zu können, brauchen wir einen Verweis auf die ZedGraph.dll und das entsprechende Steuerelement in der Toolbox.
+Wie das geht kann in diesem Blogeintrag nachgelesen werden.
+
Als nächstes verbreitern wir unsere Form und fügen das ZedGraphControl hinzu.
+In etwa so:
+
+
Initialisierung des Diagramms
+
Soweit zur Vorbereitung des Diagramms. Nun fehlen uns noch 2 Methoden und entsprechend die Aufrufe.
+Der erste Schritt ist die Initialisierung des Diagramms. Hier werden sämtliche Startattribute festgelegt.
+
private void InitChart(ZedGraphControl zgc)
+{
+ GraphPane myPane = zgc.GraphPane;
+
+//Set a title
+myPane.Title.Text = "Auswertung";
+myPane.Title.FontSpec.Size = 30;
+
+//titles and axislabels
+myPane.XAxis.Title.Text = "Antwortmöglichkeiten";
+myPane.XAxis.Title.FontSpec.Size = 25;
+myPane.YAxis.Title.Text = "Anzahl";
+myPane.YAxis.Title.FontSpec.Size = 25;
+
+//Set labels for the x-axis
+string[] XLabels = a.arr_data;
+myPane.XAxis.Type = AxisType.Text;
+myPane.XAxis.Scale.TextLabels = XLabels;
+myPane.XAxis.Scale.FontSpec.Size = 15;
+
+//Set labels for the y-axis
+myPane.YAxis.Scale.FontSpec.Size = 20;
+myPane.YAxis.Scale.FontSpec.IsBold = true;
+
+//Refresh the graph
+zgc.AxisChange();
+}
+
Wenn wir das Programm so ausführen erhalten wir folgendes Bild:
+
+
Update des Diagramms
+
Nun fehlen nur noch die Balken, welche die Anzahl der Antworten repräsentieren.
+
private void UpdateChart(ZedGraphControl zgc)
+{
+ GraphPane myPane = zgc.GraphPane;
+
+//Needed for redrawing the chart, to remove old curves
+myPane.CurveList.Clear();
+
+//Add the actual bars
+ BarItem myBar = myPane.AddBar("Antworten", null, answerCount,
+Color.Red);
+
+//Refresh the graph in order to show the new data
+zgc.AxisChange();
+zgc.Refresh();
+}
+
+
Aufgerufen wir UpdateChart() im button_next_Click-Eventhandler:
Das war es auch schon. Leider ist die fertige Lösung nicht mehr als Download verfügbar.
+
Ich hoffe, dass meine erste Blogreihe eine gute Hilfestellung, auch für C# Anfänger, bietet.
+Anregungen und Wünsche können gerne in den Kommentaren geäußert werden. :)
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Im vorherigen Tutorialteil haben wir das Fragebogenformular gebaut. Nun wollen wir die Fragen auslesen lassen.
+
Bevor wir die Fragen auslesen und darstellen können, müssen wir uns die Frage stellen, ob wir bei einem einfachen Textformat bleiben wollen. So hat das .xml Format den Vorteil, dass es sich leichter in andere Formate umwandeln lässt. Eine Datenbank hätte den Vorteil, dass man Fragen und Antworten an einem zentralen Ort speichern kann.
+Dass das .xml Format und eine Datenbank einige Vorteile gegenüber einer einfachen Textdatei haben, liegt klar auf der Hand. Doch für welches Format sollte man sich entscheiden?
+
Mit dem .net Framework 3.5 gibt es eine neue Möglichkeit zur Abfrage von Datenquellen wie XML-Dateien oder Datenbanken: LINQ. Mit LINQ ist es möglich .xml Datenquellen und SQL Server Datenbankobjekte auszulesen und zu bearbeiten. Da ein SQL Server deutlich mehr Konfiguration und Wartung bedarf als eine einfache .xml Datei, werden wir für dieses Projekt .xml Dateien verwenden.
+
Zunächst müssen die Fragen also in eine XML Struktur umgewandelt werden.
+(Der Download zur Fragen.xml wurde entfernt, da die Datei nicht mehr existiert)
+
Die Klasse Questions
+
Nun brauchen wir eine Klasse, die die Fragen ausließt.
+
Diese Klasse hat zunächst folgendes Grundgerüst:
+
using System;
+using System.Xml.Linq;
+using System.Linq;
+
+namespace CSharpQuiz
+{
+class QuizXml
+ {
+public string Path { get; set; }
+public XName xmlElement { get; set; }
+public XName xmlSub { get; set; }
+public string[] arr_data { get; set; }
+
+/// <summary>
+ /// Returns the number of questions wich are stored in the .xml file
+ /// </summary>
+public int Count { get; }
+
+/// <summary>
+ /// Fills the array with the questions, found in the.xml file
+ /// </summary>
+public virtual void PopulateArray() {}
+
+/// <summary>
+ /// Expands the array by one
+ /// </summary>
+private void ExpandArray() {}
+ }
+class Questions : QuizXml
+ {
+public Questions() { }
+
+/// <summary>
+ /// Contains the questions in string format
+ /// </summary>
+private string[] arr_questions;
+
+/// <summary>
+ /// Returns a question
+ /// </summary>
+ /// <param name="index">Index of the question to be returned</param>
+ /// <returns>string question</returns>
+public string this[int index] { get; }
+ }
+}
+
+
Der Konstruktor der abgeleiteten Klasse Questions legt sämtliche Properties fest und ruft die Methode PopulateArray() auf. Außerdem wird das Array initialisiert:
Die Methode PopulateArray() liest die Fragen mittels LINQ to XML aus:
+
/// <summary>
+/// Fills the array with the questions, found in the.xml file
+/// </summary>
+public virtual void PopulateArray()
+{
+ XDocument xdoc = XDocument.Load(this.Path);
+
+var query = from xml in xdoc.Elements(this.xmlElement).Elements(this.xmlSub)
+select xml;
+
+foreach (XElement el in query)
+ {
+ExpandArray();
+int _id = Convert.ToInt32(el.FirstAttribute.Value);
+string _question = el.Value;
+
+//Add the question the array
+this.arr_data[_id] = _id + ". " + _question;
+ }
+}
+
+
Damit das Array nicht überläuft, wird die Methode ExpandArray() aufgerufen. Die sorgt dafür, dass das Array um ein Element vergrößert wird.
+
/// <summary>
+/// Expands the array by one
+/// </summary>
+private void ExpandArray()
+{
+//Creates a temporary array wich is +1 bigger than the original questions array
+string[] tempArray = new string[this.arr_data.Length + 1];
+
+//Original array gets copied to the temporary array
+this.arr_data.CopyTo(tempArray, 0);
+
+//Temporary array gets assigned to the original array
+this.arr_data = tempArray;
+}
+
+
Die Eigenschaft Count gibt nur die Größe des Arrays zurück:
+
/// <summary>
+/// Returns the number of questions wich are stored in the .xml file
+/// </summary>
+public int Count
+{
+get
+ {
+return arr_questions.Length;
+ }
+}
+
+
Zuletzt brauchen wir noch den Indexer:
+
/// <summary>
+/// Returns a question
+/// </summary>
+/// <param name="index">Index of the question to be returned</param>
+/// <returns>string question</returns>
+public string this[int index]
+{
+get
+ {
+return arr_questions[index];
+ }
+}
+
+
Anwendung der Klasse im Fragebogen
+
Aufgrund des Indexers können wir die Frage 1 mittels
+
Questions q = new Questions();
+label_frage.Text = q[1];
+
+
aufrufen. Der übergebene Wert steht für eine ID aus der Fragen.xml Datei. Deshalb müssen wir nicht bei 0 anfangen, sondern können die erste Frage auch mit f[1] ausgeben lassen. Wir benötigen auch einen FragenIndex, der zu Anfang auf 1 gesetzt wird.
+
Die Methode ShowQuestion() lässt eine bestimmte Frage ausgeben und erhöht danach den FragenIndex. Wenn das Ende erreicht ist, wird die Methode EndReached() aufgerufen.
Dazu brauchen wir die zwei EventHandler Form1_Load und button_weiter_Click. Diese beiden EventHandler werden die Methode ShowQuestion() aufrufen.
+
Wer den ersten Teil gelesen hat, wird sich an unsere definierten Anforderungen erinnern. Wir wollen den Test wiederholbar gestalten.
+Dazu müssen wir einen neuen Button in der Form hinzufügen:
+
+
Den Wiederholen Button setzen wir zunächst über die IDE auf Visible = false.
+
Jetzt brauchen wir nur noch die Methode Restart():
Restart() wird über das Click-Event des Restart-Buttons aufgerufen.
+
Wir haben nun eine dynamische Lösung zum Auslesen von .xml Dateien die entsprechend formatiert sind. Die Fragen können auch beliebig geändert werden. Im nächsten Teil dieser Reihe werden wir schauen, wie wir die Antworten bereitstellen können.
+
Die bisherige Lösung als zip-Datei: Nicht mehr verfügbar.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Vorwort: Für diese Reihe wird Visual C# Express 2010 oder MonoDevelop benötigt. Screenshots, Codesnippets und Solutions werden vorerst nur für Visual C# Express 2010 verfügbar sein.
+
In der Schule hatten wir in Programmieren ein C#-Quiz zu erstellen. Dies war durchaus eine anspruchsvolle Aufgabe mit mehreren Hürden die es zu meistern galt.
+
Die Aufgabe
+
+
Es soll ein Fragebogen entwickelt werden, welcher der schulischen Selbsteinschätzung dient. Dazu wird ein Fragenkatalog bereitgestellt. Dieser Fragenkatalog enthält 23 Fragen zu verschiedenen Themen, z.B. Lernkonzentration, Aufmerksamkeit im Unterricht und Fleiß.
+
+
Es stehen vier Antwortmöglichkeiten zur Auswahl: „Fast immer“, „Oft“, „Manchmal“ und „Ganz selten“. Die Darstellung der Ergebnisse erfolgt grafisch. Das Programm soll in der Programmiersprache „C#“ realisiert werden.
+
Fragen und Antworten sollen sich anschließend anpassen lassen.
+
Fragebogen im Textformat: Nicht mehr verfügbar.
+
Planung
+
Anforderungen an das Programm
+
Vordefinierte Anforderungen:
+
+
Änderbare Fragen und Antworten
+
Programm passt sich automatisch an geänderte Fragen/Antworten an
+
Grafische Darstellung der Testergebnisse
+
+
Selbstdefinierte Anforderungen:
+
+
Test wiederholbar
+
Zwischenergebnisse anzeigen
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Nun, nachdem die Planung abgeschlossen ist, können wir mit dem Programmieren beginnen.
+
+
Zunächst wird das Projekt in Visual Studio 2010 erstellt. Wir benötigen eine Windows Forms Anwendung und nennen sie "CSharpQuiz". Jetzt können wir die Form entsprechend unseren Bedürfnissen anpassen.
+
+
Wir brauchen nur ein Label und einen Button. Das Label kommt links oben in die Ecke und wird "label_fragen" genannt.
+Der Button wird links unten platziert und bekommt den Namen "button_weiter". Außerdem können wir unserer Mainform den Titel "Quiz" geben.
+
Die bisherige Lösung als zip-Datei: Nicht mehr verfügbar.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Together with @detrumi I posted a proposal for cargo lint configuration files
+over at internals.rust-lang.org.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
How is character diversity achieved in Guild Wars 2? How can each player customize their character? What's the link between character diversity and dynamic events? Musings after the break.
+
In previous games, character diversity was mainly achieved through the character creation. You choose a race, a class, the appearance and then name the character. But character customization doesn't end at character creation. There are different playstyles that determine what you actually do in-game. In recent MMO's, you can switch playstyles on-the-fly, change armor colors, complete achievements and earn titles.
+
How previous MMO's fostered character diversity
+
Firstly, I wanted to get the old things out of the way. You stumble about these things in pretty much every MMO and these are part of Guild Wars 2 as well. In character creation, you choose a race, a profession, your appearance and the character name. The next things are Dungeons, titles and achievements. At endgame you have the usual build choices and improving your skill and knowledge of the game mechanics. So, what is new to Guild Wars 2 that allows for further character diversity?
+
+
Character Creation
+
Let's start with the character creation as this is what every player has to do. Apart from race/profession choice and character appearance, Guild Wars 2 character creation offers preliminary story choices. Depending on race and profession, you get to choose different character backgrounds, flavor items and personality traits. Personality affects the way NPC's will interact with you in your personal story and in the world. The character background also affects certain cinematics and NPC interaction.
+
Distinguishable playstyle
+
Some people might argue, that after the character creation is done, character customization is done as well. That certainly isn't true for Guild Wars 2. Have you heard about traits? No? Then I recommend reading ArenaNet's latest post (note: link broken) on that topic. Traits are a way to offer late-game customization to your character. They allow you to alter attributes and even modify some of your skills. For example, if you are into earth magic as an Elementalist, you have the option of choosing the corresponding trait line. What's great about that is that it allows for deep diversity even in the same class.
+
Another thing that plays into the character diversity in Guild Wars 2 is the actual playstyle. By that I mean how you actually play. You can constantly switch between weapons or prefer to use environmental weapons. You can be a hit-and-run thief or a front-line guardian who thinks that dodging isn't necessary. You can be the front-line Elementalist that knows his class to heart and switches between attunements when needed or you are the back-line support Elementalist who always uses the water attunement. The choice is entirely yours. This is very special about Guild Wars 2. The combat system allows for a lot of different playstyles that can be very distinguishable.
+
+
Stories told by the players
+
In previous MMO's, every player was experiencing the same story as every other player around them.
+This is where Guild Wars 2 truly innovates. Character choices, gameplay and mechanics aside, the dynamic event system allows each player to have a very different experience. If you rescued a town then another player that is walking by later on, will find the rescued town not knowing that you rescued it. When you meet the player later on and ask him about his experience, it would be entirely different from yours. Another example would be exploration, where you can find stuff no other player has experienced before. I really love that players do not experience the same content over and over again.
+
The same holds true for World vs World. And while the concept of World vs World and Large Scale PVP is certainly not new, I wanted to talk about it as it's one of my favorite topics. The things we experience in WvW will certainly be worth writing down, because they have an impact on the world and are meaningful to those who were there. If you conquer a keep it is yours. If you want to keep it, you have to form friendships so it doesn't get taken over the next night. There will be hundreds of players roaming the mists and that is awesome. There is so much freedom in WvW, it's almost a sandbox setting.
+
The things players experience will define the stories those players can tell and those will define their characters. Everyone is able to tell his own story of what he experienced in the world. This is what character diversity means for me.
+
+
This is my entry for GuildMag's blog carnival.What does character diversity mean for you?
+Leave a comment or write your own article for GuildMag's blog carnival. ~Ply
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
I managed to finish PiDefender almost a week in advance after I decided to exclude a lot of features. The last thing I worked on was a giant AOE that kills all enemies. Here's a gif that shows an older work in progress.
+
I'm now planning to use #1gamcrunch to create a prototype for my February game. So, expect another blog post on Sunday.
+
What is PiDfender?
+
PiDefender is a top-down space shooter. The player controls a cannon by moving the mouse around. The goal is to hold out as long as possible by killing the enemies.
On Linux, use love /path/to/game.love to run the game.
+
On Windows use love C:\path\to\game.love, double click the file, or drag the .love file onto love.exe
+
On Mac use open -n -a love "/home/path/to/game" or drag the .love file onto the Love.app application bundle
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Fire, Air, Earth and Water. I can deal with any of them.
+
+
The Elementalist is one of the professions that is easy to get into but hard to master. Due to the sheer number of skills and weapon combinations there is a lot to keep in mind when trying to master the four elements.
+
+
This introduction will give you an overview over the Elementalist profession. I will talk about the basic playstyle as well as attributes and weapons.
+
Please note: I won't go into detail about which attributes to choose or what weapon to pick. That will be entirely your choice. This is not a guide to a cookie-cutter-omfg-pwnage Elementalist build. It's only general information that you need to know if you want to start experimenting yourself.
+
The basics
+
The Elementalist is a caster-type profession that is mainly focused on damage-dealing over a distance. However, certain weapon and attunement combinations allow for entirely different playstyles. As an Elementalist you can switch between the four different attunements Fire, Air, Earth and Water on the fly. Each attunement comes with an entirely different set of skills. Unlike other professions you can't switch your weapon during combat.
+
As an Elementalist you are wearing light armor, the least protective armor type in Guild Wars 2. That means you are mainly fighting from the backline to avoid taking damage.
+
+
Attributes
+
The four basic attributes in Guild Wars 2 are:
+
+
Power: Increased attack damage.
+
Precision: Increased critical strike chance.
+
Vitality: Increased health.
+
Toughness: Increased defense/armor.
+
+
In addition to these four basic attributes, ArenaNet recently introduced 6 new attributes that are split up into three offense, two support and one profession-specific attributes.
+
Offense
+
+
Prowess: Improves the damage multiplier on critical strikes.
+
Malice: Improves the damage done by conditions like burning, poison, confusion, and bleeding.
+
Expertise: Improves the duration of all conditions inflicted by the character.
+
+
Support
+
+
Concentration: Improves the duration of all boons applied by the character.
+
Compassion: Improves all outgoing heals that your character does, including self heals.
+
+
Profession-specific
+
The Elementalist can reduce the recharge time of the four elemental attunements by putting points into the new Intelligence attribute.
+
+
Weapon combinations
+
Staff
+
The staff comes with a lot of AOE ground targeted abilities. It will probably require a lot of aiming practice and ability timing to master this weapon.
+
Scepter/Focus
+
The Scepter/Focus combination offers powerful close range abilities and control abilities. This might be a better choice for PVP than PVE, due to the control abilities like Blinding Flash and Dust Devil.
+
Scepter/Dagger
+
Due to the lack of control abilities, this combination is not very useful in PVP. However, the mix of ground targeted abilities and close range abilities makes this combination shine in PVE short and mid range combat.
+
Dagger/Dagger
+
If you like hit and run tactics in PVP and face-to-face combat, this might be your choice. The off hand dagger also grants the control ability Earthquake.
+
Dagger/Focus
+
Focus comes with two protective abilities and therefore could be seen in PVP quite often. For PVE, there are too many defensive abilities. The main hand dagger adds a lot of close range abilities as well as control abilities like Ring of Earth.
+
+
In addition to the different weapon skills, keep in mind that there are four different attunements. That makes 21 different skill sets, not even including utility skills and trait customization. Also, please keep in mind that all this stuff is based on beta information. Furthermore I should note that I have never played the game myself to form a proper personal opinion on the abilities and weapon combinations.
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
This video from NecroBator and TenTonHammer shows some of the jumping puzzles that we started to hear about after the press beta event.
+
+
This area is part of the open world and is not instanced. At the end of the puzzle there is a boss waiting for you to be killed and a chest to be looted. Note that there are different types of traps, obstacles and environmental effects on the way to the top. As this takes place in a level 15 area, we can safely assume that there are more riddles and puzzles spread across the entire map.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Coming from a web development background, lower level things can sometimes feel very
+foreign, especially when your code only ever runs in a languages VM.
+
I was in the audience for James Munns' (@jamesmunns) talk about Embedded
+Development at the Berlin Rust meetup last year. At the time of this
+writing that was 9 months ago and I've now decided to give embedded development
+a try. I'm going to write this post as I go along.
+
Since I don't really have a project that I want to work on, my initial goal is
+to find out how it is like to work on embedded systems and how approachable the
+documentation is. I've worked with a Rasperry Pi briefly and got an LED
+blinking, but that was 5 years ago, using Processing.
+
Getting Started
+
Searching the internet for 'rust embedded book' gave me the
+rust embedded book as a result. Before going through this book
+though, I'll re-watch James Munns' talk and make some proper notes of it.
With the notes done, it's time to grab another coffee and start reading the
+book. The 'Assumptions and Prerequisites' section makes me think that I'm not
+the perfect target audience for this book, because apart from the Rasperry Pi,
+I've never debugged any embedded system.
+
+Luckily I found the [Discovery book][discovery-book] via the bookshelf which is
+linked in the table on the first page. It seems that this is the book one should
+work through first. I've [opened a PR][book-pr] to mention the discovery book a bit more
+prominently.
+
As it seems like the discovery book works with the hardware immediately, I'm
+going to jump back to the QEMU section of the embedded book. Once my
+hardware arrives I'll return to the discovery book.
+
Following the installation instructions worked without problems. It seems like
+the majority of the tooling so far consists of QEMU, GDB and only a handful of cargo
+crates.
My device arrived and following the included instructions worked without
+problems until I tried using the USB interface. It turned out that my old Mini
+USB cable didn't work. I'm not sure why but I think it might be because it
+doesn't support data transfer.
+
I went to the local electronics store, bought a new one and opened another
+PR (already merged 🧡) to mention the data transfer requirements for the cables.
+After that I also opened another issue which proposes a
+Glossary for the embedded book. I'm hoping to get to that by the end of January,
+unless someone else is faster.
+
I think this is a good point to wrap up this post as I won't be able to get back
+into it for a few days. In the next post I'm going to try writing my first embedded
+Rust program following the discovery book.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
The last two months were kinda dull, as I was visiting my family and helping with their house renovation. The past few weeks I spent playing Guild Wars 2 with my friends, but we are done with that for now.
+Here is a summary of what happened more recently and what I'm working on right now.
+
Since university hasn't started yet, I signed up for two courses at Coursera. Coursera is offering hundreds of courses covering all kinds of topics; from biology to computer science. Interactive programming in python was the first course I signed up for. The second is Social Network Analysis (SNA), which has already started.
+
Social network analysis already turned out to be really interesting and now I'm looking forward to python as well. Coincidentally, the SNA course allows me to use python for creating and analyzing network graphs, which turned out to be really fruitful - More about that in a future blog post.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Things changed a lot but I didn't feel in the mood to really keep the blog up-to date. Now I'll have to pay for it. This will be quite a lengthy post. I'll go over the recent website changes first, then go on with my second foray into Guild Wars 2. I also started learning Ruby, so I'll go into more detail further down. And there's also an update about my netbook experience. Here's what happened in chronological order.
+
One Game A Month
+
I haven't finished any new games after February. I had a side-scroller in the works but that project is still way too over ambitious in terms of content creation. I'm not sure if I will get around to finishing that one. I might start a new game from scratch instead.
+
Guild Wars 2
+
This topic is really hard for me to talk about because it really messed with my goals and plans for this year. Let this be a warning for future me. After finishing the winter semester at university I lost interest in creating games and started playing games instead. I was caught up in Guild Wars 2 again. The last time was crazy too. I even had a blogdedicatedtothegame before it came out.
+
This time it took up 5 months of the year. I slowly grew more and more attached to my character. Until there was a point where it only made sense to keep playing. "Otherwise the time I spent playing before that would have obviously been wasted", I reasoned. Meeting a group of nice players and slowly starting to carry responsibility for in-game stuff made it worse.
+
Luckily there came a point where I grew sick of it. That was at at the end of August. I still remember that moment. I wish I knew what triggered it. It might have taken a few minutes, but I slowly lost all sense of attachment to my characters. It's as if there was a dense cover of fog suddenly removed from my vision. A few days after that I brought myself to delete my Guild Wars 2 characters as well as all my EVE Online characters. I never want to touch MMOs again.
+
Ruby
+
It took me a week to get things going again. I started learning Ruby. Because, why not? The first tutorial I took was the one at Codeschool. After that I stuck with Codeschool and continued with the Ruby courses. However, I felt as if those tutorials skipped a lot of Ruby fundamentals.
+
After the first month I un-enrolled from Codeschool to continue with Projects. Projects is a GitHub repository consisting of over 100 programming projects compiled by GitHub user thekarangoel. I'm not done with Projects yet but I decided it was about time to give Test Driven Development a try: Learn Ruby (Solutions) from testfirst.org/learn_ruby. I never wrote tests before, so this was a really fun learning experience.
Jou is a simple command line utility that helps with maintaining a journal file in markdown syntax.
+
+
I'm using a journal file to keep track of what I did each day. Like writing a blog post or making changes to the website. It's part of my gtd process. At some point I got sick of locating and opening my journal file in a text editor, so it only made sense to make life easier. Feel free to give it a try by installing it with gem install jou.
+
Website changes
+
As you might have noticed, the website underwent quite some changes:
Feedburner RSS feed has been replaced with a simple atom.xml
+
+
Netbook / Toolset changes
+
So, this is the third and last part of my netbook experience. My requirements have changed a lot since I first wrote about it. I also modified the setup I described in the second post a bit.
+
After using it for roughly two years, my netbook felt very underpowered. The processor was weak and watching HD videos was a thing of the past. The battery was dead and the touchpad was broken. Coupled with the fact that I'm not seriously playing games anymore, I want to get rid of my PC as well.
+
What I want
+
+
A simple, minimal and lightweight system
+
Keyboard-heavy interface as it's faster
+
As much screen real estate as possible
+
Long battery life
+
8G memory and a SSD
+
Hardware fully supported by Linux
+
2 Monitor support
+
+
The solution is the Dell XPS 13. It's going to replace my netbook and my PC. And it will be able to run my current Linux environment.
Finally, here's a setup script to install everything from a basic Linux Mint installation. (Use at your own risk.)
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
At the end of January, I started working on a sidescroller game. That was a mistake. I have never written a sidescroller before. So there were a lot of unexpected problems. First I got stuck on the camera system. I looked at other games and their implementations until I finally got a camera system working. Then I got stuck with collision detection. And how on earth would I implement the parallax scrolling? What about level design, animations, audio and story?
+
Additionally, I started learning for my upcoming university tests.
+
I knew I wasn't going to finish it in time for the February deadline of OneGameAMonth.
+
The solution
+
The solution was simple, literally.
+
Here's the Connect-Four clone I worked on in the past two days. It's not impressive or pretty, but I finished it in time.
+
Screenshots
+
+
+
Running the game
+
+
If you don't have Love2D installed, download it here and install it first.
On Linux, use love /path/to/game.love to run the game.
+
On Windows use love C:\path\to\game.love, double click the file, or drag the .love file onto love.exe
+
On Mac use open -n -a love "/home/path/to/game" or drag the .love file onto the Love.app application bundle
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Hi, this post is going to be part of a series about productivity,
+procrastination and how to form better habits around open-source work.
+
I can be a terrible procrastinator. Sometimes it's productive procrastination,
+other times it's just browsing Reddit or watching YouTube videos. With these
+posts I want to share some of my approaches to keep my procrastination at a
+non-destructive level.
+
In retrospect, one key part of this battle has been to move my procrastination
+away from the computer and internet and to only use my computer for
+non-procrastination things. This post describes the key parts that are working
+for me right now.
+
Firefox Extensions
+
I'm using two Firefox extensions to limit some of my procrastination:
+
+
+
Youtube Unhooked is a small extension that will block the more useless parts
+of youtube, such as recommendations, related videos and of course, the
+comments. I found this useful mostly for hiding the related videos section.
+
+
+
Facebook News Feed Eradicator is another very focused extension that will
+hide the Facebook news feed. This is useful because I pretty much only use
+Facebook for the events part.
+
+
+
You have probably already heard of LeechBlock. It worked for me for a
+few weeks but I got into the habit of just going to about::addons and
+disabling it... Which brings me to my current solution for blocking websites.
+
/etc/hosts blocklist with cronjob
+
As a replacement for LeechBlock, I've been utilizing my /etc/hosts file for
+some time now. Editing it requires me to enter my sudo password which makes it a
+bit more difficult to unblock blocked sites. However, it was not difficult
+enough. I ended up removing sites from the file and never got around to
+add them again.
+
To solve that problem, I now have an Ansible playbook that
+creates a cronjob which runs every 2 minutes. The cronjob resets the /etc/hosts
+file to the contents of a /etc/hosts_base file where all of my go-to
+procrastination sites are blocked.
+
I have found this to work surprisingly well.
+
Of course, this has potential to fall apart if I start editing /etc/hosts_base but
+so far that hasn't been the case.
+
An ongoing fight
+
I don't claim to have found a perfect solution here. It's more the case that I
+think that fighting procrastination is a never ending battle. I will always find
+some way to procrastinate. However, by at least limiting some of the bad habits
+on my computer, I think that I'm more likely to produce something of value when
+I'm using it without distractions.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
3 weeks ago I set out to fix a crash in Clippy, this is what I learned along the
+way. I hope this blog post will be useful for other people diving
+into Clippy and maybe serve as motivation if things get difficult.
The crash has been reported in this Clippy issue.
+It is demonstrated with the following valid Rust program:
+
trait Foo<'a, A> {}
+
+impl<'b, T> Foo<'b, T> for T {}
+
+fn func<'b, S: Foo<'b, ()>>(_item: S) {}
+
+fn main() {}
+
+
When executed with rustc, it compiles, but it produces the following ICE when it
+is executed with Clippy:
+
error: internal compiler error: librustc/ty/relate.rs:700: impossible case reached
+thread 'main' panicked at 'Box<Any>', librustc_errors/lib.rs:554:9
+stack backtrace:
+<snip>
+
+
Traits.. generics.. lifetimes!? Oh no
+
The crashing snippet from above shows why I have been.. not so quick with fixing
+this. I have been avoiding dealing with explicit lifetime annotations since I
+started with Rust almost a year ago. Further, I have never been in a position
+where it made sense to implement my own traits, especially not generic traits,
+so it was pretty easy to avoid.
+
It's safe to say that, at this point, I don't really understand what this
+program means. Let's figure it out step by step.
+
trait Foo<'a, A> {}
+
+
This is a trait called Foo with no associated items. Foo is also generic
+over any type A and it declares a lifetime parameter 'a. By itself, this
+does not mean anything, but it allows for potential implementers of this trait
+to use the lifetime 'a and the generic type A.
+
impl<'b, T> Foo<'b, T> for T {}
+
+
Here we define an implementation of our trait Foo for any type T. Again, we
+declare a lifetime 'b and a generic type T so that we can use them to implement
+Foo. This impl also declares no associated items.
+
// func takes item of type S which has to implement `Foo`
+fn func<'b>(_item: impl Foo<'b, ()>) {}
+
+
The last line contains the cause of the Clippy crash. Again we declare that the
+function is going to use a lifetime 'b. We then define a parameter that can
+be any type that implements Foo with the lifetime of 'b and a type of ().
+
The backtrace
+
The backtrace contains some first pointers where we can have a further look.
+
error: internal compiler error: librustc/ty/relate.rs:705: impossible case reached
+
+thread 'main' panicked at 'Box<Any>', librustc_errors/lib.rs:599:9
+stack backtrace:
+// snip
+13: rustc::util::bug::bug_fmt
+14: <rustc::ty::subst::Kind<'tcx> as rustc::ty::relate::Relate<'tcx>>::relate
+15: <&'a mut I as core::iter::iterator::Iterator>::next
+16: <smallvec::SmallVec<A> as core::iter::traits::FromIterator<<A as smallvec::Array>::Item>>
+ ::from_iter
+17: <core::result::Result<T, E> as rustc::ty::context::InternIteratorElement<T, R>>::intern_with
+18: <rustc::ty::sty::TraitRef<'tcx> as rustc::ty::relate::Relate<'tcx>>::relate
+19: rustc::infer::InferCtxt::commit_if_ok
+20: rustc::traits::select::SelectionContext::match_impl
+21: rustc::infer::InferCtxt::probe
+22: rustc::ty::trait_def::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::for_each_relevant_impl
+// snip
+34: rustc::ty::query::__query_compute::evaluate_obligation
+35: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for
+ rustc::ty::query::queries::evaluate_obligation<'tcx>>::compute
+36: rustc::dep_graph::graph::DepGraph::with_task_impl
+37: rustc::ty::context::tls::with_related_context
+38: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>
+ ::force_query_with_job
+39: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
+40: rustc::traits::query::evaluate_obligation::<impl rustc::infer::InferCtxt<'cx, 'gcx, 'tcx>>
+ ::evaluate_obligation
+41: rustc::traits::query::evaluate_obligation::<impl rustc::infer::InferCtxt<'cx, 'gcx, 'tcx>>
+ ::predicate_must_hold
+42: clippy_lints::utils::implements_trait::{{closure}}
+ at clippy_lints/src/utils/mod.rs:258
+43: rustc::infer::InferCtxtBuilder::enter::{{closure}}
+ at librustc/infer/mod.rs:472
+// snip
+56: clippy_lints::utils::implements_trait
+ at clippy_lints/src/utils/mod.rs:258
+57: <clippy_lints::needless_pass_by_value::NeedlessPassByValue as rustc::lint::LateLintPass<'a, 'tcx>>
+ ::check_fn::{{closure}}
+ at clippy_lints/src/needless_pass_by_value.rs:178
+58: core::iter::iterator::Iterator::all::{{closure}}
+ at libcore/iter/iterator.rs:1680
+59: core::iter::iterator::Iterator::try_for_each::{{closure}}
+ at libcore/iter/iterator.rs:1559
+60: <core::slice::Iter<'a, T> as core::iter::iterator::Iterator>::try_fold
+ at libcore/slice/mod.rs:2490
+61: core::iter::iterator::Iterator::try_for_each
+ at libcore/iter/iterator.rs:1559
+62: core::iter::iterator::Iterator::all
+ at libcore/iter/iterator.rs:1679
+63: <clippy_lints::needless_pass_by_value::NeedlessPassByValue as rustc::lint::LateLintPass<'a, 'tcx>>
+ ::check_fn
+ at clippy_lints/src/needless_pass_by_value.rs:175
+
+
Let's go through the backtrace from top to bottom.
+
error: internal compiler error: librustc/ty/relate.rs:705: impossible case reached
+
+
This tells us where the crash was reported from inside rustc. I'm noting this
+down to have a look at the code later.
For now, I think all these lines are irrelevant to the crash in Clippy.
+
Further down we find more useful information:
+
56: clippy_lints::utils::implements_trait
+ at clippy_lints/src/utils/mod.rs:258
+57: <clippy_lints::needless_pass_by_value::NeedlessPassByValue as rustc::lint::LateLintPass<'a, 'tcx>>
+ ::check_fn::{{closure}}
+ at clippy_lints/src/needless_pass_by_value.rs:178
+
+
This tells us from where Clippy invoked the chain of methods that caused the
+Crash. In other words, one of these places is probably using rustc internals
+incorrectly.
+
It also shows which lint caused the crash to happen.
+
needless_pass_by_value checks for functions that take arguments by value and
+don't consume those arguments. Clippy should suggest to pass these arguments by
+reference instead:
And indeed, in our crashing example, we pass the argument by value:
+
fn func<'b, S: Bar<'b, ()>>(_item: S) {}
+
+
We are now sure that this code should trigger the needless_pass_by_value lint
+but it crashes instead. Next, we are going to try and find out more about what's
+going on internally.
+
First steps to fixing a Clippy bug
+
The first thing we are going to do is making the crash easily reproducible by
+creating a test case. Luckily someone already provided a minimal crashing
+example in the issue. A minimized example is always super helpful.
+
We are going to add the code to the run-pass test suite of Clippy. The
+run-pass suite will fail if any of the code inside fails to compile.
+
Here's our failing code:
+
// tests/run-pass/ice-2831.rs
+#![allow(dead_code)]
+
+trait Bar<'a, A> {}
+impl<'b, T> Bar<'b, T> for T {}
+fn funk<'b, S: Bar<'b, ()>>(_item: S) {}
+
+fn main() {}
+
+
We can now run the test easily using:
+
RUST_BACKTRACE=1 TESTNAME=run-pass/ice-2831 cargo test --test compile-test
+
+
As expected, this fails to compile and crashes with the backtrace from above.
+Good!
+
Debugging with println!
+
Now that we are able to quickly run the test, we can start to debug the
+crash. I usually use plain println! calls to get all the possibly relevant
+values printed to stdout.
+
In this case we want to know what we pass through to rustc before
+predicate_must_hold is called:
+
/// Check whether a type implements a trait.
+/// See also `get_trait_def_id`.
+pub fn implements_trait<'a, 'tcx>(
+cx: &LateContext<'a, 'tcx>,
+ty: Ty<'tcx>,
+trait_id: DefId,
+ty_params: &[Kind<'tcx>],
+) -> bool {
+let ty = cx.tcx.erase_regions(&ty);
+let obligation = cx.tcx.predicate_for_trait_def(
+ cx.param_env, traits::ObligationCause::dummy(), trait_id, 0, ty, ty_params
+ );
+ println!("cx.param_env: {:?}", cx.param_env);
+ println!("ty: {:?}", ty);
+ println!("obligation: {:?}", obligation);
+ println!("ty_params: {:?}", ty_params);
+// NOTE: Crash happens after `predicate_must_hold` is called
+ cx.tcx.infer_ctxt().enter(|infcx| infcx.predicate_must_hold(&obligation))
+}
+
+
Using the command from above, this will recompile the changed code and execute
+our test. Here is the result:
+
cx.param_env: ParamEnv { caller_bounds: [
+ Binder(TraitPredicate(<S as Bar<'b, ()>>)), Binder(TraitPredicate(<S as std::marker::Sized>))
+ ], reveal: UserFacing }
+ty: &S
+obligation: Obligation(predicate=Binder(TraitPredicate(<&S as Bar<()>>)),depth=0)
+ty_params: [()]
+
+
Understanding the context
+
Maybe you can spot something in the debug output already. However, I first want
+to find out what all these new types mean.
+I have dealt with ParamEnv before, but Binder, TraitPredicate and Obligation are new to me.
+It looks like it's time to learn about some rustc internals. Nice!
+Learning about rustc internals usually means searching around in the
+rustc-guide and in the rust compiler documentation
+and putting all the information together.
+
+
ⓘ New concepts
+
ParamEnv
+
+ ParamEnv is short for Parameter Environment. It contains information about the
+ trait bounds. It can be used to check whether a type implements a certain
+ trait, for example.
+
+ As I understand it, a `Binder` associates variables with arguments where they were defined. For
+ example in the closure `|a, b| a + b`, the `a` and `b` in the `a + b ` are bound to the closure,
+ and the closure signature `|a, b|` is a binder for the names `a` and
+ `b`.
+ This also applies to lifetime parameters.
+
+ A predicate related to traits. A predicate in the rust type system describes
+ something about the given type. For example, whether it is well formed, object
+ safe or a subtype with another type.
+ As far as I understand it, a TraitPredicate is a predicate that says whether a
+ type implements a given trait.
+
+ An Obligation represents some trait reference (e.g. int:Eq) for which the
+ vtable must be found. The process of finding a vtable is called "resolving"
+ the Obligation. This process consists of either identifying an impl (e.g.,
+ impl Eq for int) that provides the required vtable, or else finding a bound
+ that is in scope.
+
+ A vtable is a struct that contains the function pointers to the trait's
+ associated functions. The pointers point directly to the concrete machine code
+ for each method in the implementation.
+
With all that in mind, let's review our debug output again:
+
cx.param_env: ParamEnv { caller_bounds: [
+ Binder(TraitPredicate(<S as Bar<'b, ()>>)), Binder(TraitPredicate(<S as std::marker::Sized>))
+ ], reveal: UserFacing }
+ty: &S
+obligation: Obligation(predicate=Binder(TraitPredicate(<&S as Bar<()>>)),depth=0)
+ty_params: [()]
+
+
What's especially interesting about our debug output is that the Obligation
+contains a TraitPredicate that is different to the Obligation in the
+ParamEnv:
+
// Our self-built TraitPredicate:
+TraitPredicate(<&S as Bar<()>>)
+
+// The TraitPredicate in ParamEnv:
+TraitPredicate(<S as Bar<'b, ()>>)
+
+
The reason for that is probably that we build the Obligation in the lint code
+ourselves, while the ParamEnv is the one of the actual test case.
+
+
At this point I have been looking into this bug for more than two weeks in my
+free time. I have to say thanks to @arielb1 who pointed me in the right
+direction after I improved the output of this ICE in rust.
+
+
Fixing the bug
+
@arielb1 confirmed my suspicion: The TraitPredicate in the
+Obligation should contain the lifetime, too:
+
+
It calls input_types, which drops the lifetime parameters out of Bar,
+turning an OK <S as Bar<'b, ()>> trait-ref into a not-OK <&S as Bar<()>>
+trait ref. The not OK trait-ref has its indexes wrong because it's missing a
+lifetime - at index 0, it should have a lifetime, not a type. So you get an
+ICE.
+
+
With that information, the fix was only a few hours away and turned out as a 9
+line change:
You may wonder how this is fixing the issue exactly. We first removed the
+input_types() call. This means we have to find a replacement to
+get the collection of lifetimes and type parameters for the given trait
+reference t.
+
Let's have a look at the source of input_types() and see how it gets the type
+parameters of the trait reference:
+
pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
+// Select only the "input types" from a trait-reference. For
+// now this is all the types that appear in the
+// trait-reference, but it should eventually exclude
+// associated types.
+self.substs.types()
+}
+
+
Substs is what we're looking for. It contains the different parameters
+of the type, including lifetimes. For example the substs of a HashMap<i32, i32> would more or less look like this: &[tcx.types.i32, tcx.types.i32].
+
In our example, S: Foo<'b, ()>, that would be [S, ReEarlyBound(0, 'b), ()].
+The first element is the name of the type parameter, S. The second one is the
+name of the lifetime, 'b. The last one is unit.
+
Calling substs.types() on S: Foo<'b, ()> will result in [()]. However,
+using substs directly, gives us what we want: [S, ReEarlyBound(0, 'b), ()].
+Instead of calling types() on substs, we just iterate over the substs
+directly and avoid the crash.
+
With the crash fixed, this concludes the post. I hope you were able to learn
+something new from this. Maybe I also inspired you to have a go at working on
+Clippy. If that's the case I encourage you to look through the good first
+issue label, pick one that seems easy to you and dig in =)
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
As the footer says, it is inspired by a Chrome extension. But I can't remember the name of it. If you happen to know the extension, let me know.
+
Using IndexedDB
+
This project was my excuse to practice some Javascript as well as applying the principles of OfflineFirst.
+I decided to use IndexedDB, because it seems to be the simplest solution for persistent offline storage. There is also localStorage which has limits on the maximum size of data. If you are looking to sync your data to a server, maybe give hood.ie or PouchDB a try.
+
An IndexedDB primer
+
IndexedDB is an object storage for Javascript objects. Each IndexedDB database stores a collection of key-value pairs. Each value can be a Javascript object of any complexity. The key can be a property of such an object. You can also create indexes of any properties for quicker searching and sorting. Furthermore, instead of using SQL, in IndexedDB you use a cursor to iterate over a result set.
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
+
+
+
+
+
+
+
+
+
diff --git a/posts/for-everyone/index.html b/posts/for-everyone/index.html
new file mode 100644
index 00000000..ae13116c
--- /dev/null
+++ b/posts/for-everyone/index.html
@@ -0,0 +1,117 @@
+
+
+
+
+
+ This one is for everyone
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
When I moved to Berlin two years ago I moved there with the intention of becoming more outgoing and becoming less anxious in social settings. I was never very popular in class and I pretty much never went out to parties before. In school, I got picked on and bullied. Before Berlin, I was very insecure. So, for me, moving to Berlin was about starting anew. I also moved here to study applied computer science at HTW Berlin.
+
I am a software developer and I love to learn. Usually I learn about new languages, algorithms, frameworks or general programming concepts. But recently I have learned a lot about myself.
+
If you take a look at the archive, you will see a huge gap between March and October. Same for my GitHub history with a huge gap of nothing between March and September:
+
+
What happened there, was Guild Wars 2. Guild Wars 2 is an MMORPG — Short for Massively Multiplayer Online Role-Playing Game. Those types of games can be very addictive. I knew what I was getting myself into. I have been playing MMORPGs for more than 5000 hours since I was 16. It was a world where I could be what I wanted myself to be. There were no critics and it was easy to make friends.
+
Unsurprisingly, I got addicted to Guild Wars 2 as well. I wrote about it before. I had played the game before already and even had a dedicated blog running — Some of the articles are in the archive. I played it for a month straight and quit after I reached max-level. I focused on university for the winter semester 2012/2013 and managed to make it through the required tests.
+
At that point I wasn't very sure what I wanted to with my life. In my free time I had been developing small video games. And I had been thinking about getting into the games industry since I moved to Berlin. Eventually I gave up on that dream. I learned that video game developers are often exploited and expected to work for very long hours. That's not what I was really looking for.
+
So, I decided to go back to Guild Wars 2 again. This time I had found a group of very nice people. The social element plays a huge factor in MMORPGs. By design, Guild Wars forces you to play together with other people, so eventually you will get to know them. And maybe join a guild together.
+
Friends can keep you in the game even if you don't like the game anymore. Additionally, the more time you invest, the more likely you are to stay. If you help with organizing ingame events you will have a certain responsibility to not just quit without saying anything. This went on for about 5 months.
+
+
In that period I pretty much neglected everything else in my life. And in the end I dropped out of university for stupid reasons. But eventually, things started to get better.
+
Three months ago I wrote:
+
+
Luckily there came a point where I grew sick of it. That was at at the end of August. I still remember that moment. I wish I knew what triggered it. It might have taken a few minutes, but I slowly lost all sense of attachment to my characters. It's as if there was a dense cover of fog suddenly removed from my vision.
+
+
After that, I went on and deleted all my characters. Not only in Guild Wars 2, but also in Eve Online which I had played before. I wish I had better advice on dealing with gaming addiction, but I don't. If you are looking for some motivation to quit, maybe the next part is for you.
+
Maybe everything isn't hopeless bullshit
+
After I was done with video games, I wrote about learning Ruby:
+
+
I started learning Ruby. Because, why not?
+
+
It is amazing how this decision shaped my life in the last two months and I still can't quite believe it. As I dropped out of university, I was looking for job opportunities in Berlin. That was the point where I decided to get out of my comfort zone and go outside to meet people. I went to a ton of meetups. I learned that I have to force myself to get outside in order to become more comfortable around people.
+
Then I learned about Hackership. Since I wrote a gem to automate some of my journal tracking, I got invited to the organizers meetup. This was a first as well. When I arrived at the location I wasn't sure if I was at the right bar. An overwhelming voice inside me told me to turn around and just go home. I did that before on other occasions. But driving an hour to this place and just turning around was not an option this time. So I stepped in. The rest is history (and available in the archive).
+
In retrospect, this has taught me to welcome every opportunity to get better in social settings. You don't get more comfortable around people by sitting at home alone.
+
Hackership ended before Christmas and it was the best thing that could happen to me this year.
+
Thank you to everyone I've met in the last two months. You are all amazing!
+
+
If you read through this incredibly long blog post, I want to thank you for taking the time to read it. You might also like what I post on Twitter.
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
It's been a few months since I've written here and it's time for an update.
+
The idea to learn another programming language than Ruby was on my mind the majority of 2017.
+I know Ruby pretty well and have been doing it for over 4 years now, and I feel like my learning has slowed down a lot in the past year.
+
Last November, after playing around with Elixir, I decided that it would be better to learn Rust if I want to learn things more deeply.
+
I really think Elixir and Erlang have their place and I enjoyed doing Elixir. However, the reach of Elixir and Erlang doesn't seem to go far beyond web development and communication technology. Furthermore, I felt like being on the same abstraction level as Ruby where I didn't learn as deeply as I could.
Rust gives me much more freedom but it still allows me to build sensible abstractions that keep me productive.
+The language itself covers many new concepts that I didn't have to deal with in Ruby. Especially the type system and borrow checker.
+
How am I learning Rust
+
At the beginning of December I started with Advent of Code. It was fun, but AoC was a bit tough with time constraints and the fact that I never really did Rust before, contributed to me giving up. After partly finishing the first week I decided not to continue.
+
Instead, I started with the Exercism exercises for Rust. Currently I'm about halfway done with all the exercises.
+Almost all of them have a focus on mathematical problems and algorithms, which makes them perfect for learning about iterators and collections.
+
While doing these practice exercises can be fun, I was also looking to contribute something useful to the community and getting my hands on some real-world Rust code.
+
Clippy
+
I don't remember exactly how I found it, but I have now been contributing for about 2 months: Clippy.
+
Clippy is a bunch of lints that catch common mistakes and improve your Rust code.
+
Contributing to Clippy is awesome in many ways. It's an opportunity to teach users how to improve their Rust code while also preventing common mistakes at the same time.
+For me as a contributor, Clippy allows me to learn Rust while also learning about Rust internals.
+
My first lint was this one. It turned out much more tricky in the end because attributes in Rust are not at all what they look like on the surface. There were a hand full of bug reports after it got merged.
+
Not being a Rust expert certainly made it more difficult, but it's totally possible to do a deep dive into a very specific area of Rust internals and coming out alive.
+
I am also regularly going to the Berlin Rust Hackers/Learners Meetup and the last time it happened during the Rust All Hands 2018. The atmosphere that day was exciting to say the least. I got to meet some of the people working on Clippy and everyone was super welcoming.
+
The end result of that day was that I'm now part of the clippy team! While I wasn't super productive that day, I left with many ideas and lots of enthusiasm.
+
What's next
+
For Clippy I want to personally focus on fixing existing bugs and lowering the open PR count. I also want to improve the contribution instructions to make it easier for new people to contribute.
+
In order to do that I need to learn more Rust. I haven't finished my copy of 'Programming Rust' by Jim Blandy and Jason Orendorff, yet. Once finished, I want to get some practical experience writing my own thing from scratch.
+
I started a GNU Typist rewrite last year but didn't continue because I didn't know enough Rust at the time: rtypist. I hope to pick it up again this month and use it to get some practical experience with traits, lifetimes and writing my own macros.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
This post is a rough translation from german to english and is based on this post: Mein Einstieg in C++.
+
In order to get started with C++ i decided to have a look at problem #2 on projecteuler.net.
+A description of the problem can be found here.
+
Basically, you have to find the sum of all even-valued terms in the fibonacci sequence which do not exceed four million. Sounds easy, doesn't it?
+
Here's how i solved it.
+
In order to get a specific fibonacci number I used a formula made by Moivre-Binet.
+
+
What is amazing about this formula, is that it uses three square roots and still returns integer numbers.
+Don't believe me? I couldn't really believe it either so i simply implemented it in C++:
The rest is relativley simple. Just check if the returned number is even-valued and less than four million.
+If that's the case, add the number to the sum variable.
While the formula of Moivre-Binet might not be very efficient it's quite interesting that it returns integer numbers.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
If you take a look at my repositories, you will see that a majority of them are small projects. Working on your own projects can teach you a lot, but working with others can teach you even more. You can learn a lot by reading someone elses code. I wanted to do this for some time now and last week I actually started doing that.
+
I thought about contributing to open source for some time now, but never did because most project were too intimidating. If that sounds familiar, then I might be able to give you some advice on starting out.
+
Finding a project you want to work on
+
The first step is to start looking for a project you want to contribute to. The advice I heard the most, was: "Start contributing to a project you already use". For, me this didn't work for a couple of reasons.
+
Looking at Firefox, Jekyll, Vagrant, Rails, Bundler and a couple others, I didn't know where to start. Issue descriptions sounded cryptic, were very platform specific or involved knowing about a couple dozen different source files.
+
But working on a tool that you actually use sounds really nice. You know how the tool is supposed to work. And maybe you already have a rough idea how it is put together. But if there's nothing you can contribute, you will have to look beyond projects that you use on a daily basis. That's what I did. I started looking for projects that I liked and that I would like working on. Additionally I came up with some criteria that the project should meet as well:
+
+
It is active. This includes time of the last commit and comment activity on issues or pull requests. If didn't merge any pull requests within a couple months, chances are, yours probably won't be merged either. If the last commit is 6 months old, that's also an indicator for an abandoned project.
+
Good documentation. There should be a guide on setting up the project. There should also be a guide on how to get your changes merged in.
+
Lots of issues to pick from. Maybe they also have a beginner tag for issues.
+
Manageable size. The bigger the project, the harder it will be to figure out where to change something in order to fix a bug. You will be able to contribute faster on smaller projects.
+
+
People won't be mad at you for contributing to their project
+
Before you start working on a feature or bug report, make sure you have read the available documentation on how to contribute. My biggest fear was that I would mess something up with my branching and the pull request as I never used pull requests before. Reading the documentation has helped a lot. Make sure you have read Creating pull requests and Using pull requests.
+
If you are stuck with something, just ask in the specific issue. More often than not people will help you with problems. Some projects also encourage to submit pull request early. This way you can get feedback on your work before making more changes to it.
+
Some projects also have an IRC channel or a mailing lists. Spend some time reading those and learn what everyone is working on. See how the atmosphere is in general. Are people encouraged to ask questions? If you find that there is a lot of bickering, maybe start looking for another project.
+
Your first contribution
+
If you have read through the available documentation on your project, then it's time to pick an issue you want to work on. You want to start out with simple issues, to get some experience with making pull requests and the issue system. Your first issue should be as simple as adding some documentation or adding a translation.
+
Contributing to open source projects really isn't as scary as I thought it would be.
+I hope this post contains some useful advice. If you have decided to contribute to an open source project, let me know!
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
+
+
+
+
+
+
+
+
+
diff --git a/posts/good-news-i-am-moving-to-berlin-and-getting-into-the-games-industry/index.html b/posts/good-news-i-am-moving-to-berlin-and-getting-into-the-games-industry/index.html
new file mode 100644
index 00000000..2cd547a9
--- /dev/null
+++ b/posts/good-news-i-am-moving-to-berlin-and-getting-into-the-games-industry/index.html
@@ -0,0 +1,93 @@
+
+
+
+
+
+ Good news: I am moving to Berlin! And getting into the games industry!?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Good news: I am moving to Berlin! And getting into the games industry!?
Just wanted to let you readers know, that I'm now on the move to Berlin.
+
+
I'll be studying Applied Computer Science (Angewandte Informatik in German) at HTW Berlin for at least the next 3 years.
+
For now, I am trying out some shared living and see how that works out. Unfortunately I won't have internet right off the start. But that's one of the things on my high priority list.
+
In order to keep this blog alive, I have scheduled a few posts about various topics for the next two weeks.
+
Future plans
+
During the time in Berlin I will be concentrating most of my efforts on getting a step into the games industry as a games programmer (C++/DirectX). I could have just chosen to study Game Design but I wanted to have a more general degree in case something goes wrong.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
When linking a publicly shared Google Drive folder or file, people are always forwarded to the Google Drive page, instead of the actual file.
+This makes it difficult to use Google Drive to host downloads or static blog-content. However, Google's introduction of Google Drive Site publishing made it possible to link directly to the resource, instead of the Google Drive page.
+
Google Drive setup
+
The first thing you want to do, is go to http://drive.google.com and setup a public folder somewhere.
+To make this folder public, change the visibility settings to Public on the web and make sure that you are the only one that can edit.
+
+
Now you will need to obtain the folder ID. Change to your public folder and you will see the ID in the address bar. The last part is the FolderID you are looking for:
+
+
The next step makes it a little bit more difficult than using Dropbox since this bit of information is quite hidden. According to the Google Drive SDK documentation, we can use an URL like https://googledrive.com/host/[FolderID]/path/to/file.type to link directly to publicly shared files.
If you prefer a shorter URL to your content, you can setup a redirect from a sub-domain to your public Google Drive folder. Since my domain is managed by Namecheap, I will illustrate the process with their service. It should be similar for other services.
+
Go to Account -> Your Domains and select the domain where you want to setup URL forwarding. Then go to All Host Records.
+
Here you setup the URL Redirect to the Google Drive URL from above: https://googledrive.com/host/[FolderID]/
+
+
Now you can use http://static.yourdomain.net/path/to/image.png to link to your static blog content.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Update: This giveaway is obviously no longer active.
+
Hi everyone, I still have about 150 Google plus invites to hand out.
+Simply drop me an email at hi@phansch.net if you want me to invite you to Google+.
+
Regards,
+Philipp
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
It’s almost here—the second Guild Wars 2 Beta Weekend Event begins this Friday! For three days, players from all over the world will experience the wonders and dangers of Tyria—and a ton of cool new content!
+
+
+
ArenaNet just published a new blog detailing what changes we can expect for BWE #2.
+
Here are my personal favorites:
+
+
Improved Overflow Servers
+
Key Bindings
+
Chat Bubbles
+
Resizable Map
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
I can't believe how fast the time flew by during Hackership. It is almost holiday time. And by the time this post is published I will be visiting my family already. This week at Hackership, I moved my authentication system to devise and made everything look nice.
+
On Monday I began to setup devise. I wanted to move to devise at some point because it also comes with its own mailing system. This way I don't have to figure out too many things at once. Setting up devise went more smoothly than I anticipated. However there were a lot of failing test - leftovers from the railstutorial. Some of them were still useful. But most of the test cases are now covered by devise.
+
Sadly I had to stay home on Tuesday because I didn't feel very good. I spent a lot of time on Typeracer to further improve my typing speed. I also changed a few vim shortcuts to make things easier. (Feel free to check out my .vimrc!). I also managed to get devise working properly but still had a few failing tests.
+
Luckily I didn't catch the flu, so I was back on Wednesday. I got a lot of stuff done on Wednesday. The first half of the day I worked on fixing the rest of the failing tests for devise. When I was done with that, it was time for our last Rails Q&A. This time we talked about how to connect your Rails application to an external web service. We actually set up a basic proxy API with the Wordnik service.
+
Once we got that working, it was time to part again and continue working on our own projects. Since my work on the tests was done, I began working on the design of my application. As I already did that before, I had a basic design going after another two hours. Here is a screenshot:
On Thursday I spent a little more time on the look. I made sure all the forms for user authentication are looking nice. The default devise views don't come with the Bootstrap look by default.
+
At about 3 pm we went to the big presentation room of betahaus. Since we were going to use it for the graduation ceremony later on, it was nice to get accustomed to it. I wasn't a big fan of public speaking when I started Hackership. Maybe this has changed a little bit by now. Since we were doing daily stand ups and weekly demo sessions, I had a lot of practice.
+
Anyway, this last time our internal demo session was held on a proper stage. I don't think anyone had a finished project to show. We have learned a lot, but 6 weeks aren't enough to learn a new language/framework and have a ready product to present.
+
After our demo session, it was time to walk through the plans for the graduation ceremony. We basically staged everything beforehand so that there would be no surprises during the actual ceremony. And then it was time for the actual graduation ceremony. It took a little while until everyone arrived, but eventually every seat was taken.
+
Ben started by giving a short introduction to Hackership and the philosophy behind it. Then it was panel time. I also signed up for the panel and so I found myself sitting in front of 70 people together with 6 other graduates. We shared some of our experiences and answered questions from the audience. People seemed to be genuinely interested. After the panel, we were given our certificates. Below is mine. It also includes code from everyones Hackership project, but it's not included in the picture.
With the certificates given out, our organizers announced the crowdfunding campaign for the next Hackership Batch. Hackership is on Indiegogo. Feel free to check it out and maybe help with the funding if you happen to like it. I already did. After the announcement of the crowdfunding campaign, the ceremony was over pretty much. It was time to meet the audience and talk about what we learned during Hackership.
+
It was nice talking about my project. I got some very valuable feedback for my touch typing teacher and will start measuring user performance on different typing lessons to figure out what lessons help the users the most. The more data the better. So it seems I still have a lot of things to learn. However, I'm not sure if that will help me with actually learning Ruby on Rails. Instead I might start to contribute to open source Rails projects, like Discourse or Open Streetmap.
+
So this is it. Hackership is officially over. A couple of us will continue to work together in the new year and help each other with their projects. Thanks to the organizers and Hackers in Residence and other people who helped to make this happen. Hackership introduced me to all kinds of awesome people and they helped me overcome my depression and social anxiety. But that's for another post. So this won't be the last post this year. If you have read this far, thank you for actually taking the time to read this!
+
Have a great holiday!
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Although I sort of talked about this on twitter already, I am happy to announce that I got accepted to Hackership.
+
What is Hackership
+
+
Hackership is a self-directed, hands-on learning programme for Coders, Programmers and Software Developers to acquire new skills or become better at what they already do.
+
+
+
It's like an apprenticeship. But for hackers. A Hackership.
+http://www.hackership.org/
+
+
The program offers a distraction-free environment where you are responsible for what you learn. There
+is no curriculum and no instructors. Instead there is a huge focus on self-directed learning, deliberate practice and reflective learning.
+There will be daily stand-ups and weekly demos. Additionally there will be experienced hackers around to help people with difficult problems and to dig deeper into the technology. This first batch will be hosted by betahaus.
+
Hackerschool New York is a very similar program and has been running for three years already.
+
What and how I want to learn
+
Primarily I want to learn Ruby on Rails and proper Test Driven Development. I already have an idea on how to get started with this. I will spend the first two or three days working through this Ruby on Rails tutorial. After that, I will start to work on the actual project where I can apply all the things from the tutorial. Additionally I am going to use Anki cards for stuff that is hard to remember. I will also try to maintain a learning journal to regularly review my learning progress.
+
The actual project
+
Once I'm done with the tutorial, I will start working on a website that helps people learn touch-typing. About a month ago I started to learn touch-typing on the German Dvorak layout. I tried all kinds of tools and websites but only a few supported the layout I chose. None of these were very fleshed out. I had a really tough time getting to my current 25 WPM.
Although I would love to share some more specifics, the project details aren't really fleshed out yet.
+
Looking forward
+
My goal is to get a position as a junior Ruby developer at the end of Hackership. However, I really need to put myself out there. I never did that until the beginning of this month. So apart from Hackership I will try to be at every event possible to deal with my social anxiety. While overcoming my anxiety might sound difficult, I am really looking forward to the times ahead.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Eventually I managed to find the right way out and arrived at Betahaus where we started out with breakfast and quick introductions at 9. We then had about two hours of workshops about how to approach learning. Starting with brainwriting, where we wrote down the first two words that came to mind after hearing the word learning. The brainwriting session was followed by an introduction to the psychology behind learning. We were introduced to three different perspectives on learning: Behaviorism, cognitivism and constructivism.
+Then we had a short video session followed by an open discussion about the video and learning in general.
+
After lunch it was time to get started.
+
I joined a group which was planning a booking system in Python/Django and I quickly joined their discussion about their database schema. We found a few more people interested in database design and organized a small meeting room to do some planning. After that, I started working on fleshing out some ideas for my own project.
+
Tuesday
+
The second day started off with a presentation about deliberate practice:
+
(Unfortunately the slides have been removed a few years later)
+
After that, it was my turn to give an introduction to learning journals and my tool jou. I decided to give reveal.js a try for that. I should have prepared a little better since the most important slide didn't show up at all. That caught me by surprise and I was lost for a moment. Also, I probably need more practice with public speaking. Anyway, the (now fixed) slides can be found here.
+
After lunch, I started working on the Railstutorials book. Since I already had a working Ruby environment, I just had to make sure to install rails properly. At the end of the day I found myself at the end of chapter five as I skipped a few things I already knew.
+
Wednesday
+
Compared to Tuesday, I didn't really make a lot of progress with the tutorial. I managed to finish chapter six, though. However, there were other things happening on that day. At around 10, Christoph showed up to give us a tour of Betahaus. He is pretty much the CEO of the place, although he doesn't really fancy that term. He started with their woodworking room and explained how Betahaus was just a group of friends originally. After that we went on to see the other parts of the space and then it was time for lunch already.
+
After lunch we had a Q&A about Rails and testing with one of our Hackers in residence. That really helped me to answer some basic questions about testing. I also learned how the different environments (testing, development, ...) work. For example in a production environment, rails is started with the --environment production switch. For testing it's a little bit different because rails is not really starting a new server to run the tests on. Instead, the server is mocked.
+
Thursday
+
Thursday started off with me forgetting about BetaBreakfast. Luckily, I was still on time to see the demos. The first one was Somewhere. On Somewhere you can Discover how interesting people around the world actually work. Their mission is to give people a glimpse into other people's work and give them an idea if they want to work there. The second demo was by Makeapoint which aims to provide an alternative to text-based discussion forums.
+The third was by tran.sl (link broken) which is was a platform that aims to be a marketplace for translators.
+
Once BetaBreakfast was over, I started working on the tutorial again. At some point I got stuck for an hour or two because the database was acting weird. I am still not sure about the cause. Eventually I rolled back to a previous commit where it worked again.
+At the end of the day I made it to chapter eight of the tutorial but was bored out of my mind. The book is very detailed and copying stuff over to the editor makes me feel like I'm not learning much. Which is probably true.
+For the next week I plan to start working on my own project. I will skim over the rest of the tutorial and see if there is anything left to learn.
+
Fast forward to 6 pm, it's demo time. This is where we show off what we accomplished during the week. If I were to compare my work to the other demos, they were really interesting and I kinda feel like I didn't learn as much as I could have. For next weeks demo I will try to share more of what I learned and focus less on what I did.
+
For my project I don't want to say too much because I don't have anything to show yet. All I can say is that it will be helping people to learn touch-typing.
+
I might have mixed a few things up in this weeks blog post - there was so much stuff that happened! This month is probably one of the most intense months in my life so far.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
So before I start to write about what I did, I want to talk about what I want to accomplish during Hackership. As I mentioned previously, i want to learn Ruby on Rails and Test Driven Development. That is my general plan. Last week I started working on the Railstutorial book by Michael Hartl and I got to the end of chapter 8 before the week ended. This week I want to start working on my own stuff.
+
A touch-typing teacher
+
I know some programs are out there that teach touch-typing for qwerty/z and other popular keyboard layouts, but there's really only a handful websites that offer lessons for less popular layouts like Dvorak Type 2. This is what I'm going to work on for the next couple of weeks.
+
My goals for the week were to setup a basic frontend, create a user login and to save the progress of the user.
+
Monday
+
On Monday I decided to put the tutorial away and start working on the project. I started out with some javascript stuff to get a very basic frontend done. This is what it looks like:
On Tuesday I started to set-up a basic Rails App. Some static pages here and there and including Bootstrap 3. I also gave Guard a try. Guard is a command line tool to easily handle events on file system modifications. You can use guard to automatically run tests when spec files are changed. I can definitely see how automated testing is superior over running test by hand. Most importantly, I don't have to switch to the console every time I want to run my test suite. Eventually I will get around to set up everything with Travis CI.
+
Wednesday
+
On Wednesday I continued working on the App and added a basic user sign-up - pretty much following the tutorial again.
+
Friday
+
While I wasn't there on there on Thursday, I showed up for the Hardware Accelerator Demo day. There were quite some interesting pitches to be seen but nothing that was really groundbreaking. The most interesting presentation was by DeMiFi which basically is a small mobile router.
+
And that's pretty much it for last week. I didn't get as much done as I wanted to, but that's fine.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
This week was a little bit less about rails and more about front-end stuff. I needed to get some Ajax to work. And that proved to be very difficult. Especially considering that I didn't know in what form rails is expecting PATCH data.
+
On Monday I continued working on the sign-in and sign-out system for the touch-typing website. Once I was done with that, I had to update the user model to include a new column which stores the WPM of users. The Rails guide for migrations was pretty useful to get that done. In the evening it was time to get to know our Hackers in residence.
On Wednesday one thing I was trying to figure out was: What exactly Rails is expecting from an Ajax request? I spent a lot of time in the development.log and tried to solve various errors. Eventually I got it working with the help of Ben. Once I got it working I was able to make a lot of progress. The WPM of a user is now automatically submitted once the lesson is finished.
+
Thursday started in the evening for me. I mainly did some CoffeeScript refactoring. Here are some interesting resources I found helpful:
This book contains a very helpful section on the syntax of CoffeeScript and also a short introduction to Classes.
+
Friday is not an official Hackership day, but there was a lot of interest in an Arduino Workshop. So, we started at 12. Since there was an Arduino Workshop the previous Friday which I didn't attend, I had to setup my environment first which went surprisingly smooth. Making the LED's blink was just a matter of about half an hour. I didn't stop at making one LED blink. There was a very difficult practice which required a lot of connectors and resistors. Making sure that everything is connected correctly was not an easy task. The task was to create an LED array to display a certain image. The image was set in a 2D array in the source file. This was a really fun exercise and eventually I got it to work, yay!
+
+
That's it for the third week of Hackership. Next week I'm going to work on the database model and some CoffeeScript refactoring.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
This week I worked on implementing the models for lessons and practices so that data is available for every single practice.
+I also tried to wrap my head around CoffeeScript but it seems that I should learn more about javascript first.
+
We started the week with our usual Monday morning breakfast and decided on our goals for the week. After the breakfast I started working on creating the
+models and migrations for Lessons and Practices. I spent an hour planning the initial database structure and then went on to create the models, associations and migrations.
+
The first thing I did on Tuesday was cleaning up the database model as there were a couple unused attributes. I then went on and re-organized my routes.rb as it was getting a little unwieldy with the new models. Me and a few other learners also got interviewed by @e_w about our Hackership experience. The interview videos will be part of a short video about the first Hackership batch. I also gave the shoulda Gem a try. This is a gem that allows for easy testing of model associations.
+
Once my tests were green, I started working on my Anki cards collection. When I started with Hackership, I wanted to see how spaced repetition could improve my learning. I started taking notes of things that I looked up again and again. One example would be unpacking bzip and gzip files on Linux: tar xvjf files.tar.bz2 - I had a really hard time remembering the arguments until I put it into my Anki collection.
+
On Wednesday I had to make up for not writing enough tests in the previous two days. I started learning more about FactoryGirl and also installed the database_cleaner Gem. Then I wrote some tests for a couple helper methods I've written before. We also had a 2 hour long Rails Q&A session where we talked about concerns and the devise Gem.
+
It was CoffeeScript time on Thursday. I tried. I tried really hard to understand CoffeeScript scoping. But it seems that without proper Javascript knowledge this is very hard. That makes refactoring very difficult and my current code is not very maintainable. I don't think that I have enough time to improve on it before Hackership ends. Another thing that happened, was an introduction to GitHub by @lstoll, @muanchiou, @vmg and @jdennes. They explained pull requests and a couple more features of GitHub, like commenting on specific lines on a commit.
+
+
I did get everything done that I had planned for this week. I also went to the Ruby Meetup on Thursday and met a lot of new people. Next week I'm going to work on displaying errors the user makes and jumping to specific lessons.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
I didn't have a lot of motivation to work on my project this week. However, I still got a lot of stuff done and learned a lot of new things.
+
Firstly, I started using vim this week. I got sick of having to use the mouse a lot with Sublime Text. My goal is to only use the keyboard when I'm working on code. I spent the weekend configuring it to my liking and created a cheatsheet with the basic movement shortcuts. It will take some time to learn all these new shortcuts, but I hope I will be faster with editing my code.
+
Another thing you might have noticed are the changes to the website. There's a new background color and the homepage has changed as well. It now shows the estimated reading time for each blog post. The website itself now also uses a slightly bigger font.
+
To start off the week, I started working on my CV/Resumè on Monday to prepare for the mock interviews the next day.
+
On Tuesday, I worked on the frontend part of my project. I managed to have the teaching text display only on one line and hide words that are outside of the box-width.
+I also tried to improve on my CoffeeScript code, but refactoring is really hard, when you don't understand the language properly.
+
The best thing of the day was the job search workshop by Soundcloud recruiter Jessica Hayden. Finding the right company to work for ain't an easy task. The workshop was followed by a mock interview session for which we had to sign up beforehand.
+
The next day, Wednesday, I added functionality to make it possible to directly jump to a specific lesson. This took some effort because it required changing the CoffeeScript code. As you can probably see by now, the CoffeeScript code causes a lot of pain for me. Even though I want to focus on Ruby on Rails I still have to work with Frontend stuff. So I will probably spend some time to properly figure out how Javascript and CoffeeScript work.
+
In the evening we had another presentation about finding a job. This time with a focus on the Startup environment.
+
On Thursday I decided to convert my CoffeeScript to JavaScript again. I started annotating it to make sure I understand what is going on. What's left so far is the concept of prototypes, which I don't understand yet. Converting to Javascript allowed me to solve a scope problem I had with the words-per-minute calculation.
+After getting a lot of feedback on my CV on Tuesday, I also managed to improve it a lot. I added a few new sections and added information about Hackership.
+In the evening a few of us went to a whiteboard talk at Soundcloud. It was an introduction to relational databases but also gave an overview over NoSQL databases.
+
This was probably my most eventful week during Hackership.
+
On Saturday I coached at the Railsgirls Berlin Hackday. It was my first time coaching and it turned out that teaching total beginners how to program is not easy. But it was very fun and in the end I got good feedback and my coachees learned a lot.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
The last few days have been quite a torture for me.
+The 22nd started with some major stomach ache for me. The pain was so intense, that I couldn't sleep the following night. So I called my dad and he brought me home the next day. The next three days I was on pain killers. But as the pain didn't go away I decided to go to the local hospital. Well, to make a long story short, it turned out that I have kidney stones. Right now I am half-way through with all the surgery stuff. The kidney stones are still there but don't cause as much pain as they did before. At this point I have a flexible tube between my kidney and my bladder to relieve my kidney.
+
The next step is to shatter the kidney stones so that they are small enough to eventually leave my body on their own..
+
So, what can be done to prevent kidney stones from forming? Turns out, not much. I live a somewhat healthy life. I drink enough water. I'm not smoking. I don't drink alcohol as regular as others do (I could be more athletic, tho..). Even my doctor told me there is nothing I could have done but going to the hospital a few days earlier to get some of the REALLY GOOD painkillers.
+
Please don't take take any of the above as a medical advice.Always go to a doctor rather than looking things up on the internet.
+
With not much left to say, I wish everyone a happy new year and all the best for the future. Keep checking out my blog for new stuff in the next year!
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Here's how to automatically setup SSL Certificates for HAProxy using certbot and Let's Encrypt, without having to restart HAProxy.
+
This article assumes that you have certbot already installed and HAProxy already running.
+
Certbot command
+
As we are using HAProxy, we can't just run sudo certbot --haproxy like for nginx because certbot doesn't officially support HAProxy, yet. Instead we have to use the certonly command and the --standalone option to run a standalone webserver.
+
We also want to include the certbot command in a script later on, so we need to supply all further options via the command line. The basic certbot command we will use, looks like this:
If you try to run the command on the machine where HAProxy is running, it will tell you that port 80 is already in use, because that's the port HAProxy is listening on.
+To circumvent that, we will have to tell the standalone server to use another port:
Be sure to validate the config with haproxy -c -f /path/to/your/haproxy.cfg to check for mistakes.
+
Now we can reload the HAProxy config and try to run the certbot command from above again. It should work, but we aren't done yet.
+
Putting it all together
+
The next step is to create a script that will execute the certbot command and copy the generated certificate to the directory where HAProxy is looking for it.
+
The script will be called cert_renew and it will take a list of domains as an argument.
+
#!/bin/bash
+
+# This script takes a list of domains as arguments
+# and will setup a single certificate for all of them.
+
+cert_name="generic_cert"
+haproxy_cert_dir="/etc/haproxy/ssl-certs"
+email="you@host.org"
+
+domains=""
+for domain in "$@"
+do
+domains+="-d $domain "
+done
+
+certbot certonly --standalone --agree-tos --non-interactive \
+-m $email --preferred-challenges http \
+--http-01-port 9785 --cert-name $cert_name \
+--renew-with-new-domains --keep-until-expiring $domains
+
+mkdir -p $haproxy_cert_dir
+
+# Combine the certificate chain and private key and put it
+# into the correct HAProxy directory
+cd /etc/letsencrypt/live/$cert_name
+cat fullchain.pem privkey.pem > "$haproxy_cert_dir/cert.pem"
+
+echo "Reloading haproxy"
+sudo systemctl reload haproxy
+
+
Using it like cert_renew domain1.org domain2.net will setup one certificate for both domains at /etc/haproxy/ssl-certs/cert.pem and reload HAProxy.
+
Setting up the Cronjob
+
Next, we will save the script at /usr/local/bin/cert_renew and setup the cronjob, so that it runs twice per day:
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
I came here after using Wordpress for over two years.
+I always want to keep stuff as simple as possible: I don't need a dashboard, plugins, a media library or a link database. Neither do I need a theme database, a user database or a WYSIWYG editor to create a blog post. That stuff is over-kill. And that was going through my mind the whole time.
+Today I pretty much dived head-on into github, jekyll and liquid to create this first post. And it was a blast. I learned so many useful things. But what I like most about this new setup is that, apart from the initial setup, there is almost no maintenance required. Whereas in popular blog software, you have to deal with frequent software updates, backups and broken plugins or broken themes.
+
I will try to write about my experiences with jekyll and liquid as I move on. Here's a summary of day #1:
+
Setting up github
+
This is not the first time I tried to get into using github. I admit that previously I had no idea what to use it for. But yesterday I stumbled upon pages.github.com and I was immediately intrigued. So today, I downloaded the github app for windows and created my first repository. This was pretty straightforward and right now I prefer the GUI over the command line.
+
Getting to know jekyll and liquid
+
The first documentation I found, was this one. It wasn't very helpful as it didn't explain how to actually create a page or even a blog. Turns out, I was looking in the wrong place. jekyllbootstrap.com (not existing anymore) was the biggest help, especially the introduction article.
+With the proper documentation at hand I quickly made progress and soon had my first template/page setup working. From there it was only a surprisingly small step to a blog.
+
How this blog works
+
This markdown file contains all the text for the blog post. The YAML front matter at the top specifies the layout for the blog post, the category, tags and a title. The layout file contains html and a content variable that is replaced with the blog post by jekyll. You might notice that the post.html layout file has a layout defined. The default layout will replace the content variable with the post layout.
+
Publishing
+
I'm using Sublime Text 2 to create the blog posts in markdown. Once I'm done writing a blog post I commit the file to the _posts folder in my repository. That's all there is to publishing. (It might take a few minutes until the changes show up.)
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
+
+
+
+
+
+
+
+
+
diff --git a/posts/how-gaming-could-make-a-better-world/index.html b/posts/how-gaming-could-make-a-better-world/index.html
new file mode 100644
index 00000000..60d68d4c
--- /dev/null
+++ b/posts/how-gaming-could-make-a-better-world/index.html
@@ -0,0 +1,92 @@
+
+
+
+
+
+ How gaming could make a better world
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Games like World of Warcraft give players the means to save worlds, and incentive to learn the habits of heroes. What if we could harness this gamer power to solve real-world problems? Jane McGonigal says we can, and explains how.
+
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Anmerkung: Screenshots wurden entfernt und der Artikel ist nicht mehr aktuell.
+
Vor kurzem hat mich unter Windows 7 zum ersten mal ein BSOD erwischt. Das ist, zumindest bei mir, eine sehr seltene Angelegenheit. Leider war ich beim auftauchen des Bluescreens so perplex und habe die Fehlermeldung nicht wahrgenommen. Was also machen?
+Es gibt verschiedene Möglichkeiten die Infos aus dem Bluescreen nachträglich einzusehen.
+
+
Eventviewer
+
WinDbg
+
+
EventLog
+
Die erste Möglichkeit besteht darin, das EventLog von Windows zu durchsuchen.
+
Das EventLog speichert verschiedene Arten von Ereignissen während des Windows Betriebes auf. Die Ereignisse sind in drei Kategorien aufgeteilt: Information, Warnung, Fehler. Diese Informationen werden ständig im Hintergrund gesammelt und im EventLog aufbereitet dargestellt. Aufgerufen wird das EventLog wie folgt:
+
+
Start -> Ausführen
+
"eventvwr" eingeben
+
Mit OK bestätigen
+
+
Ein Bluescreen sollte unter die Kategorie "Fehler" bzw. "Kritisch" fallen. Mit einem Doppelklick auf das entsprechende Event und einem nachfolgendem Klick auf "Details" erhält man folgende Ansicht:
+
+
Sowohl mit der Event-ID als auch dem BugCheckCode lassen sich über Google meistens weitere Informationen finden.
+
WinDbg
+
Wenn die gefundenen Informationen nicht reichen und der Bluescreen nicht beseitigt werden konnte, gibt es noch eine weitere Möglichkeit um der Ursache auf die Spur zu kommen.
+Mit WinDbg lassen sich sogenannte Minidumps analysieren. Minidumps werden im Falle eines Bluescreens unter C:\Windows\Minidump angelegt.
+Natürlich ist WinDbg sehr komplex. Für unser Problem reicht es jedoch, wenn wir die Schritte kennen um einen Bluescreen-Minidump zu analysieren.
+
WinDbg installieren
+
Für WinDbg werden die Windows Debugging Tools benötigt. Bei der Installation muss allerdings nur WinDbg installiert werden.
+
Bei der Installation ist es wichtig, die Debugging Tools auszuwählen:
+
+
WinDbg kann anschließend über das Programmmenü gestartet werden:
+
+
WinDbg benutzen um Minidump auszulesen
+
Zunächst ist es nötig die Windows Symbols herunterzuladen welche das debuggen überhaupt erst ermöglichen.
+Dazu gehen wir in WinDbg auf "File -> Symbol File Path.." und geben folgendes ein:
Nun sollten wir den Workspace speichern um den Symbolpfad beim erneuten Start des Programms nicht nochmal eingeben zu müssen.
+Um den Workspace zu speichern gehen wir auf "File -> Save Workspace".
+
Als nächstes lokalisieren wir den zu analysierenden Minidump. Normalerweise wird dieser unter %systemroot%\Minidump gespeichert. Der Minidump ist nach dem Datum, einer zufälligen Nummer und einer fortlaufenden Nummer benannt.
+
In meinem Beispiel heißt der Minidump "111010-27456-01.dmp".
+
Um den Minidump auszulesen öffnen wir ihn in WinDbg über "File -> Open Crash Dump". Bei der Frage, ob wir den Worksapce speichern möchten, wählen wir "No".
+
Nun befinden wir uns in der Debugging Ansicht. Es wird zunächst eine weile dauern bis die Symboldateien heruntergeladen wurden.
+Wenn der Download abgeschlossen ist, sieht das Debuggingfenster so aus:
+
+
Wir können bereits sehen wodurch der Fehler ausgelöst wurde: "Probably caused by : ntkrnlmp.exe"
+Um weitere Informationen zu bekommen, geben wir unten in der Kommandozeile den Befehl !analyze -v ein.
+
Dies analysiert den Fehler bis ins Detail:
+
BAD_POOL_CALLER (c2)
+The current thread is making a bad pool request. Typically this is at a bad IRQL level or double freeing the same allocation, etc.
+Arguments:
+Arg1: 000000000000000b, type of pool violation the caller is guilty of.
+Arg2: fffffa8005338728
+Arg3: 0000000005338720
+Arg4: fffffa8005338f38
+
+Debugging Details:
+
+FAULTING_IP:
+nt!ExDeleteResourceLite+199
+fffff800`02c690f9 eba0 jmp nt!ExDeleteResourceLite+0x13b (fffff800`02c6909b)
+
+ BUGCHECK_STR: 0xc2_b
+
+CUSTOMER_CRASH_COUNT: 1
+
+ DEFAULT_BUCKET_ID: VISTA_DRIVER_FAULT
+
+PROCESS_NAME: System
+
+CURRENT_IRQL: 0
+
+LAST_CONTROL_TRANSFER: from fffff80002daf6b8 to fffff80002c7c740
+
+STACK_TEXT:
+[...]
+
+STACK_COMMAND: kb
+
+FOLLOWUP_IP:
+nt!ExDeleteResourceLite+199
+fffff800`02c690f9 eba0 jmp nt!ExDeleteResourceLite+0x13b (fffff800`02c6909b)
+
+SYMBOL_STACK_INDEX: 2
+
+SYMBOL_NAME: nt!ExDeleteResourceLite+199
+
+FOLLOWUP_NAME: MachineOwner
+
+MODULE_NAME: nt
+
+ IMAGE_NAME: ntkrnlmp.exe
+
+DEBUG_FLR_IMAGE_TIMESTAMP: 4c1c44a9
+
+FAILURE_BUCKET_ID: X64_0xc2_b_nt!ExDeleteResourceLite+199
+
+BUCKET_ID: X64_0xc2_b_nt!ExDeleteResourceLite+199
+
+Followup: MachineOwner
+
+
Mithilfe der eingerückten Informationen können wir zum Beispiel über Google weitere Infos bekommen. In diesem Fall hat ein neuer Audiotreiber das Problem behoben.
+
Ich hoffe dieser Post war einer Hilfe und konnte eventuelle Probleme beheben.
+*[BSOD]: Bluescreen of death
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
I need to write.
+I initially planned to split this over a few posts, but my notes kept growing and now I'm at a point where I have to get rid of all the notes and formulate a proper blog post.
+So, the past few months were kinda crazy.
+
I'm pretty much done with playing video games for the time being. My last big game was Guild Wars 2. I even had a small ambitious blog project which I took care of for 5 months. I gave Planetside 2 a try and played with friends for a few days. It was fun but after a while it was all the same. I think that was the case with every MMO I've tried.
+
##When I started simplifying##
+
It wasn't after I quitting Guild Wars 2 when I started to realize that I kept refreshing social networks and news all the time. Looking for new blog posts, insightful videos and ted talks.
+I constantly got disrupted doing whatever I really wanted to do. Looking at Twitter or watching an hour-long ted talk. In the end I came to realize that I was wasting time while I neglected important university stuff. This was a major life-changer for me: Realizing that I cannot read every single news story, lifehacker article and blog post out there. Someone pointed me to a post from Leo Babauta on zenhabits.net which talks about letting go of that stuff.
+
From there on, I pretty much started re-evaluating my behavior. One information source replaced the last one and then removing the new information source. This has led me to a point where I only check Hacker News, reddit and email for half an hour in the morning and half an hour in the evening. On a similar note, I also got rid of my TV but I must admit that I wasn't watching TV anyway (German TV is terrible).
+
##My personal toolbox##
+My next step was creating a small set of programs to do work for university. So, I sat down and came up with some requirements for my toolbox:
+
+
I want to have my documents in a single location, available everywhere and easy to backup.
+
Initial setup should be as simple as possible.
+
Every tool should allow online synchronization, so I can continue working wherever there's internet available.
+
Programming and tinkering environment should be running on a virtual machine to allow easy backups and easy installation.
+
+
This is where it got complicated. First, I cut down on redundant software. I got rid of Wunderlist in favor of Evernote. I'm now using GTDFH to organize my projects in Evernote. I also got rid of Microsoft Office. Instead I'm using a combination of Evernote, impress.js for presentations and Google Docs.
+I also made the switch from Firefox to Google Chrome to keep my browser in sync.
+
My programming environment is running on a Windows 7 virtual machine right now. That machine has a local jekyll server, netbeans for java programming, python and a simple xampp server. My second virtual machine is running Linux Mint with a database client for my postgres class. My university is also providing git repositories, so I'm using these instead of of a public GitHub repository, to keep my programming assignments private.
+
##Call me minimalist, if you want##
+After slowly gaining control over my online life, I started devoting my time to the place I live in. I've always been rather tidy. My mom taught me to always clean up on the go. But I didn't really do that until I moved away from my parents. Having my own place changed that. It also made me reconsider keeping all the stuff I own.
+
Having less stuff, makes cleaning a lot easier. Buying less stuff saves a ton of money. Owning only the clothes you really like, makes picking clothes in the morning really easy. And, after all, having less stuff makes moving very easy. I donated half of my books to friends and family and I'm now using a Kindle. One third of my clothes went to charity. I digitized old photos and sold my games collection to a local video game shop. Having less stuff freed my mind.
+
So where do I go from now? I'm happy with where I am now. I can focus on the most important stuff (university), get it done and then focus on personal projects without getting distracted.
+I still have a few things to write about. I hope to be able to publish them this year.
+This blog also needs some updates to the theme. But that's for another blog post.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
With my move to Berlin, I wanted to change things around. Being a total computer nerd, I would sit at the computer most of the time. I always knew that it wasn't healthy, but there was always something to do at the PC. Things didn't really change until I was done with my kidney treatment at the end of March. But when I left the hospital that day, I went to the city center and enjoyed the sunshine at the Reichstag.
+
A few days after that, I was still in my old habits. However, two weeks later or so, I was browsing Reddit and stumbled upon r/GetMotivated.
+
Here's what r/GetMotivated is about:
+
+
Welcome! We’re glad you made it. This is the subreddit that will help you finally get up and do what you know you need to do. It’s the subreddit to give and receive motivation through pictures, videos, text, music, AMA’s, personal stories, and anything and everything that you find particularly motivating and/or inspiring.
+
+
So browse around, ask questions, give advice, form/join a support group. But don’t spend too much time here; you’ve got things to do.
+
This subreddit is one of the greatest starting points in terms of getting motivated. Seeing the stories of other people on their way to a better life really helped me getting motivated.
+
+
I started geocaching not so long ago. Check out my profile on geocaching.com here.
+
Thanks to r/c25k I started running and doing push-ups. I will post about my weekly progress here, on this blog and on Reddit.
+
I also decided to start a list of things I want to achieve at some point in my life. These things may or may not include, going to outer space or visiting every continent. (This post was really helpful with starting such a list)
In the past months something changed in my perception of life. I'm not sure what exactly caused that change, but I know that Reddit's r/GetMotivated helped a lot!
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
+
+
+
+
+
+
+
+
+
diff --git a/posts/including-the-directx-sdk-libraries-into-your-visual-cpp-game-project/index.html b/posts/including-the-directx-sdk-libraries-into-your-visual-cpp-game-project/index.html
new file mode 100644
index 00000000..c4fff2bb
--- /dev/null
+++ b/posts/including-the-directx-sdk-libraries-into-your-visual-cpp-game-project/index.html
@@ -0,0 +1,110 @@
+
+
+
+
+
+ Including the DirectX SDK libraries into your Visual C++ game project
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Including the DirectX SDK libraries into your Visual C++ game project
Fortunately, solving this problem is relatively straightforward.
+
Downloading the DirectX SDK
+
You will need the DirectX SDK Libraries from Microsoft. These contain the aforementioned header files and libraries. Download the latest DirectX SDK from here.
+When the download is complete, proceed by installing the DirectX SDK. Make sure you remember the installation location as you will need this later.
+
Installing the DirectX SDK
+
+
Add references to your project settings
+
+
In order to tell Visual Studio that your game requires DirectX, you will have to add the DirectX libraries and header files to your project.
+
+
Open your project setting
+
Navigate to VC++ Directories
+
On the right, select Includepaths
+
A new window will open, that lets you new include paths. Add a new include path by hitting the New Row button in the top right.
+
Now you will have to navigate to your DirectX SDK installation directory and select the Include folder.
+
+
+
Do the same for the library path and you project should compile properly.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Recently the German government is pushing the rollout of new identity cards for citizens as well as an alien-card for foreigners. While those new identity cards come along with a whole set of new security features, German privacy advocates criticize that those new identity cards are a further step into the direction of a surveillance country.
+
With the introduction of the new identity cards it will be possible to store the fingerprint on the identity card. While this feature is optional, it can be used as identity verification. Fingerprints are a good way to identify a person. In fact, they are unique to each individual. This feature could be used in a variety of applications. For instance, it could be used as an additional key for online banking, aside from a username and a password.
+
In addition to the optional fingerprint, all identity cards can optionally be loaded with a digital signature which is more secure. This signature can be used online to sign legally binding contracts. Currently many websites that require age verification will ask the visitor s to send-in a copy of their identity card. The new signature will make it possible to just “plug-in” your identity card and send the signature to the provider.
+
Furthermore the new identity cards are smaller. While the old identity cards are twice as big, the new ones are of the size of a credit card or a driver’s license. This makes it possible to put them into the purse easily.
+
Although it is true that the new identity card contains new security features, this has some downsides as well.
+
Firstly, the new identity cards are more expensive than the old ones. While the fee for old identity cards was 8€, the new cards will cost 28,80€.
+
Another significant point is that the new identity cards were said to be secure, while they aren’t anymore. White-hat hackers have already proven the insecurity of the new identity cards. They were able to completely erase the data that is stored on the electronic chip. For instance, this could be a problem when you don’t notice that someone has erased the data on your card. You would be charged the fee for a new one and eventually get in trouble with the law.
+
Finally, the new cards are vulnerable to identity theft. The data that is send to the computer is usually cryptographically secured. But some parts of the connection aren’t encrypted. White-hat hackers have been able to read the data, when the card was used in conjunction with a computer that was not running up-to-date anti-virus software. For instance, think of a situation where fraudsters would replace the card reader at a bank with an insecure one. They would be able to read all the sent data.
+
In summing up it can be said that the new identity cards were meant to be more secure but turned out to contain a host of vulnerabilities. I am most concerned about how it will look like in 10 years, when people will still use the new identity card. Eventually there will be a dozen of publicly known security vulnerabilities. Data theft will probably occur every day.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Hier ein kleines Tutorial wie man einen Linux Webserver auf einer Virtuellen Maschine erstellt.
+
Es hat viele Nachteile, Projekte auf einem Produktivsystem zu entwickeln. Es macht daher Sinn, ein Testsystem aufzusetzen. Am sinnvollsten ist hier ein virtueller Webserver.
+
Als Software benutze benutzen wir VirtualBox und Ubuntu.
+
Das Hostsystem ist Windows 7 x64.
+
VirtualBox kann hier heruntergeladen werden und das .iso Image für Ubuntu 9.10 hier.
+
Die Installation und Konfiguration von VirtualBox ist zum Großteil selbsterklärend und die Schritte zum erstellen einer neuen Maschine sind sehr gut erläutert.
+
Für unseren Test-Webserver wird ein 20GB Volume erstellt und 350 MB Arbeitsspeicher zugewiesen.
+
Wenn die virtuelle Festplatte erstellt ist, muss man festlegen, dass die .iso Datei zum ersten Start eingebunden wird.
+
Dazu wählt man die zu ändernde Maschine aus und öffnet das Einstellungsmenü.
+
Dort lässt sich das entsprechende .iso image auswählen.
+
+
Danach wird die Maschine gestartet und Ubuntu kann installiert werden.
+
Bevor man sich an die Apache Installation macht, sollte man alle verfügbaren Updates installieren.
+
+
Wenn alle Updates erfolgreich installiert sind, sollte die Maschine neu gestartet werden.
+
Nun kann man den eigentlichen Webserver installieren.
+
Apache
+
sudo apt-get install apache2
+
+
Überprüft werden kann die apache Installation, indem man im Browser "localhost" eingibt. Wenn "It Works!" ausgegeben wird, war die Installation erfolgreich:
+
+
PHP
+
sudo apt-get install php5 libapache2-mod-php5
+
+
Jetzt den Apache neu starten um die Änderungen zu laden:
+
sudo /etc/init.d/apache2 restart
+
+
Um zu überprüfen ob PHP erfolgreich installiert wurde geben wir folgendes in das Terminal ein:
Es sollten nun umfangreiche Informationen über PHP im Browserfenster erscheinen. Wenn das klappt, funktioniert also der Apache und PHP auf unserem Ubuntu!
Zu guter letzt noch ein paar nützliche Tipps im Umgang mit dem neuen Testsystem.
+
Apache/MySql starten und beenden
+
Um Apache zu starten folgenden Befehl benutzen:
+
sudo /etc/init.d/apache2 start
+
+
Zum beenden:
+
sudo /etc/init.d/apache2 stop
+
+
Zum neustarten:
+
sudo /etc/init.d/apache2 restart
+
+
Status ausgeben:
+
sudo /etc/init.d/apache2 status
+
+
Für MySql einfach "apache2" durch "mysql" ersetzen.
+
Speicherort der Dateien
+
In /var/www/ können jetzt die Dateien und Skripte abgelegt werden, die auf eurem Webserver verfügbar sein sollen.
+
Userverzeichnisse
+
Jeder Nutzer hat die Möglichkeit in seinem Homeverzeichnis eigene Websites abzulegen.
+
Diese Websites lassen sich über http://localhost/~username abrufen.
+
By Default gibt es diese Möglichkeit leider nicht.
+
Zunächst erstellen wir in unserem Homeverzeichnis ein Verzeichnis mit dem Namen "public_html".
+
cd
+mkdir public_html
+
+
Jetzt laden wir das Apache Modul userdir:
+
sudo a2enmod userdir
+
+
Wobei userdir der Name des Moduls ist und nicht der Name des Userverzeichnisses!
+Nun muss der Apache neu gestartet werden damit die Änderungen angewandt werden.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Jon Peters is going to be on a live Q&A with MMORPG.com this Thursday at 10am PST (6pm GMT).
+
As if that wasn't good enough, you will be able to post your questions, both in their forum thread as well on the twitter hashtag #gw2qna.
+
+
MMORPG.com has partnered with the Guild Wars 2 team for an exclusive Live Stream Q&A; with Jon Peters at 10:00 a.m. PST (1:00 p.m. EST) about professions and traits in Guild Wars 2. Post your questions on these topics and we’ll choose 10-15 to ask during the interview. All questions must be in by Wednesday at Noon EST. We will be hosting the Guild Wars 2 Live Interview on the MMORPG.com Live Stream page (www.twitch.tv/mmorpgcom).
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
This was my first time participating in a game jam. The jam was a blast, although I didn't like the theme: You are the villain. I spent the first hour brainstorming ideas for the theme and ended with a space shooter where you shoot at defenseless transport ships.
+
The source, the timelapse. I didn't publish a playable version, yet. You can get it from github and swap out the music that's missing, to make it run.
+
+
What was good
+
+
This is my first game that I pretty much finished. On a single weekend! I did pacman, breakout and pong clones in C# and Lua before, but I never really created a game on my own in such a short amount of time.
+
I learned a ton! (See below)
+
+
What went wrong
+
Too many firsts
+
+
Only played around with Lua and Love2D for a week
+
Never did a screenlapse before
+
When the jam started, I had no idea how to create a good game soundtrack or where to get them
+
I also added a new library for managing game states on Saturday. I had to move a lot of code around.
+
Particle Systems in Love2D.
+
+
At the end I lost my motivation to finish it
+
Therefore, the last sequence isn't implemented and the game doesn't really end. I am not sure how to stay motivated until the end, next time.
+
I focused too much on the story instead of making the game work
+
I want to blame this on the topic for this Ludum Dare. I had a story in mind where the player controls an alien spaceship, shooting at humans.
+It turned out, that it was difficult to distinguish between aliens and humans. Therefore, I put in a lot of text that explains who you (the player) are.
+
Maybe there are better way to do this, but a space shooter where you are the villain was probably a bad idea in the first place.
+
The overall gameplay and mechanics are lacking
+
Admittedly, I am not a game designer - rather a programmer. But I should put some more effort into this area next time.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Für meinen Einstieg in C++ habe ich mir das Problem #2 von [projecteuler.net](http://projecteuler.net) herausgesucht. Die Problembeschreibung befindet sich [hier](http://projecteuler.net/index.php?section=problems&id=2).
+
Für die Lösung muss man zunächst die Fibonacci Zahlen bestimmen. Dafür verwende ich die Formel von Moivre-Binet:
Der Rest ist relativ simpel. Es wird geprüft, ob die Zahl kleiner als 4.000.000 ist und ob sie eine gerade Zahl ist.
+Wenn das der Fall ist, wird der Variable sum die Zahl hinzuaddiert.
Das ist weder die schnellste, noch die eleganteste Lösung aber ich konnte mir zunächst nicht vorstellen, dass die Formel wirklich immer ganze Zahlen ausspuckt.
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
They have been supporting all kinds of open source Rust contributors this past
+year and are a huge boon to the Rust community. I'm exited to work with them to
+bring more Clippy features on the way!
+
I also want to thank the following people for continued sponsorship of my open
+source work this past month: @repi, @oli-obk and @yaahc.
+
If you like what I'm doing and want to support my work as well, please consider
+sponsoring me on Patreon or via other
+means 🧡
Of those, the most rewarding work was rewriting Clippy's internal
+'update-reference' scripts. These scripts are used by contributors to update the
+reference files when test output has changed. Rewriting the scripts in Rust
+should make contributing from Windows much easier.
+
Reflections
+
Working from home during the lockdowns really messed with my daily routines and
+habits. Now that there is hope for an end to the pandemic I have been able to
+fix my lack of motivation that plagued me in the past months. I didn't get a lot
+done from July to November. Outside of work I didn't have the energy to touch
+any more code at all.
In October I also removed myself from the reviewer rotation for Clippy
+and handed my pending reviews to the other members of the team. In retrospect, I
+should have done that much earlier. This break from open source was something I
+really needed and I won't hesitate to do this again in the future.
+
Goals
+
My primary goal for January is to make Clippy's UI test blessing work from the
+rustc subtree checkout. I have a working prototype locally but as I have not much
+experience with the rustc tooling, I expect some edge cases will be uncovered
+once my code is being reviewed.
+
This work will enable rustc contributors to update the Clippy UI test reference
+files without any issues and with their familiar tooling.
+
Apart from that I'm going to re-add myself to the reviewer rotation for Clippy
+and start reviewing larger pull requests again.
+
+
+
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
I'm incredibly thankful to the following people for sponsoring my open source
+work this past month: @repi, @oli-obk and @yaahc.
+
If you like what I'm doing and want to support my work, please consider sponsoring ♥
+
What I've worked on
+
If you're familiar with how this website looks, you can probably tell that it
+has a slightly new look. Also, if you were to look into my personal documents
+directory, you could most likely tell that it had been recently cleaned and
+organized …again. Hello procrastination!
+
Looking at the November
+review, I have to
+admit that I didn't follow through with all the goals I wrote down:
+
+
I absolutely did not continue with the tiny compiler. I'm currently stuck on
+implementing the visitor and I'm honestly not sure if it's worth it to
+continue
+
I reviewed some Clippy PRs, but I've felt a lack of motivation in reviewing
+for some reason. I also didn't contribute as much as I used to
+
+
I did a few other things, though:
+
I now have a Patreon page! Setting up
+Patreon required a lot more work than setting up GitHub sponsoring and I'm still
+not 100% happy with it. I would like a nicer header image and improve on the
+goals a bit as well.
+
Apart from the Patreon page, I've been working through Ralf Jung's Rust
+101 course to check up on my Rust fundamentals. What I like most
+about this course is the focus on exercises. As a result of the course I created
+about 25 new flashcards mostly around raw pointers and std::sync.
This January I want to try and find my Clippy/Rust motivation again. I think,
+after we finished completing the rustfix testing issue in
+September, I was lacking a new clearly defined goal.
+
To put down some more precise goals:
+
+
I want to try out embedded rust development to see how it feels and possibly contribute
+back some documentation
+
I want to fix a bug where Clippy never stops running.
That's all I have for now. See you here for the January review!
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
I'm incredibly thankful to the following people for sponsoring my open source
+work this past month: @repi, @oli-obk and @yaahc.
+
If you like what I'm doing and want to support my work, please consider
+sponsoring me on Patreon or via other
+means 💙
+
What I've worked on
+
February has been quite a non-productive month from the outside. Maybe it's the
+winter blues finally catching up to me, but that's for the next section of the
+post.
+
It indeed doesn't look like a lot in terms of merged PRs this month. The only
+merged PR is to the rustc-guide where I've added an introductory
+section to the Name Resolution chapter.
+
I've been learning about name resolution in rustc because I've been looking into
+making some improvements to a rustc diagnostic that is emitted exactly during
+name resolution. So that instead of this:
+
12 | let _ = HashNap::new();
+ | ^^^^^^^
+ | |
+ | use of undeclared type or module `HashNap`
+
+
You will get an additional suggestion of the most likely alternative:
+
12 | let _ = HashNap::new();
+ | ^^^^^^^
+ | |
+ | use of undeclared type or module `HashNap`
+ | help: a struct with a similar name exists: `HashMap`
+
+
This PR has taken most of my time and energy in February. I want to finish it
+this month and continue with work around name resolution.
+
Reflections
+
I did not get further into embedded development as I ran into issues with my
+tools, which I was hoping to avoid by jumping into embedded development.
+
Instead of doing more embedded development, I've started looking into
+librustc_resolve. Specifically a PR to improve some diagnostics
+as mentioned above. This PR has apparently triggered some sort of impostor
+feeling in me. While working on this PR I noticed two things:
+
+
In the beginning I had absolutely no idea what librustc_resolve is about,
+lowering my confidence in completing this PR
+
My low confidence in completing the PR also produced feelings of guilt when
+asking otherwise busy contributors for help
+
+
In the future I hope this feeling will go away as I dig further into rustc.
+Until then, I plan to 'just' push through these feelings, keeping my main goal
+in the back of my head: Making diagnostics and lints better for rust users.
Further improving the name resolution chapter of the rustc-guide
+
Potentially do more work around librustc_resolve diagnostics
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Embark Studios continued to support my work throughout January.
+
They have been supporting all kinds of open source Rust contributors this past
+year and are a huge boon to the Rust community. I'm exited to work with them to
+bring more Clippy features on the way!
+
I also want to thank the following people for continued sponsorship of my open
+source work this past month: @repi, @oli-obk and @yaahc.
+
If you like what I'm doing and want to support my work as well, please consider
+sponsoring me on Patreon or via other
+means 🧡
Finally, I started a new Rust side project: webdriver-install. As the name
+suggests it manages the installation, updating and removal of webdrivers, such
+as chromedriver.
Currently it supports the installation of chromedriver and
+geckodriver on Windows, MacOS and Linux. It comes both as a Rust library as
+well as a CLI for usage in non-Rust environments.
+
Reflections
+
Two really important things happened for the Clippy team this month:
I believe this is going to be great for long-term contributor retention and
+finding more team members. The bi-weekly meetings may also improve my personal
+motivation to get things done.
+
As mentioned in my previous post, I'm now back in the
+reviewer rotation for Clippy. To be honest, I don't have a good system for
+managing review notifications, yet. So far I only decided that I will take a
+month off from reviewing and open source once every year.
+
One thing that didn't go so well, is the implementation of the internal cargo dev bless command that I rewrote in Rust in December. I came to the conclusion
+that the way I implemented it was not the best way. The details can be found in
+this comment. Instead of keeping the current
+implementation, I am helping out with implementing it the proper way in
+compiletest-rs.
Push webdriver-install to a point where I can publicly announce a release
+
Fixing more Clippy bugs
+
Get a freelancing registration
+
+
+
+
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Another interesting thing, if you're contributing to Clippy, is some
+streamlining around Clippy's developer tooling: I replaced a shell script with a
+cargo alias to make contributing easier if you're on Windows.
+
Reflections & Goals for February
+
This January I've unsubscribed from Clippy repository because I
+couldn't deal with all of them anymore.
+
+
going to try and unsubscribe from all rust-lang/rust-clippy notifications and instead schedule fixed times for doing PR reviews
I have found it increasingly exhausting to try and react to every GitHub
+notification. While I admit that it's not required to respond to every
+notification properly, I was also feeling bad about constantly marking
+notifications as done from my side even though they really weren't done from the
+other person's perspective. When I came to that realization, I decided to
+unfollow the repository and instead assign fixed time chunks for reviewing PRs.
+
At the end of the month I unfortunately caught a cold and I'm still partly
+recovering from it. Still, I think since unsubscribing from Clippy notifications
+I've gained back some of my previous momentum.
+
For this February I have the following goals:
+
+
Actually starting with embedded development, using the discovery kit
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Apart from that, I migrated this blog from Jekyll to Zola and I have a separate
+blog post in the pipeline for that. I also started work on a private project
+that uses Rust (tide) in the backend but it's too early for details.
+
Reflections
+
Reviewing pull requests
+
Clippy has now been using rust-highfive for two months and we're down to 14
+open PRs currently. rust-highfive has removed so much pressure and guilt, I
+can't say enough how much it helped me with long-term motivation as a reviewer.
+
qwerty touch typing
+
I didn't practice enough touch typing in May so I'm still not consistently
+writing at 80WPM, rather at 70WPM. However, since I'm using it every day, my vim
+muscle memory is back to what it was before. At the end of June I started
+having some minor pain in my left hand due to an inconvenient CTRL
+key placement. I've since changed that and hope it will be better this way.
+
Goals
+
+
My primary goal for July is to get one of my private projects to a finished
+MVP that I can talk about.
+
I think that my Clippy activity will stay at the current level for now.
+
Reviews will get the highest priority and I will continue to fix bugs.
+
I want to do daily touch typing exercises again.
+
+
+
+
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
I'm incredibly thankful to the following people for sponsoring my open source
+work this past month: @repi, @oli-obk and @yaahc.
+
If you like what I'm doing and want to support my work, please consider
+sponsoring me on Patreon or via other
+means 💚
+
What I've worked on
+
You might have noticed that the review for March is missing. This was mostly a result of the still ongoing pandemic. I started working from home mid-March and it took me a
+few weeks to adjust. The following is what I've worked on in March and April
+combined:
I've also been trying to review more of the incoming pull requests which, at least for me, takes a lot of energy. Currently that's around 15 minutes per day and one 1 hour timeslot per week for bigger PRs.
+
Reflections
+
As mentioned above, I started working from home in March when the virus started
+to become an issue here. At the beginning I had a lot of trouble concentrating
+and getting a new daily routine in place. Things really only started getting better in April.
+
Towards the end of April I also decided to ditch touch typing with dvorak
+(after using it for 6 years) and learn touch typing on qwerty instead. This
+is currently slowing me down a lot:
+
+
It's also incredibly frustrating because my brain slips back into dvorak every time
+I'm not 100% focused. Once I'm faster, I want to write about this switch a
+bit more.
+
Goals
+
My primary goal for May is to reach 60+ WPM touch typing on qwerty. Another
+thing I want to work on is adding indicators to Clippy's lint
+documentation
+that highlight which lints can be automatically fixed using cargo fix --clippy (#4310).
+
+
+
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Since Clippy is now using rust-highfive, incoming pull requests are
+automatically assigned to people on the reviewer list. Something about the random
+assignment makes a big difference to me. I feel so much more motivated to review
+pull requests. @flip1995 also did a lot of PR triage and we're down to ~20 open
+PRs from around 40 at the beginning of May.
+
This makes me think that I should prioritize reviewing pull request more. It
+brings in more contributors and team additions in the long run which means more
+people are going to be in the reviewer pool.
+
qwerty touch typing
+
I almost achieved my primary goal from last month: Reaching 60+ WPM touch typing
+on qwerty. Currently I'm hovering around 50 WPM. This graph shows my progress
+on 10fastfingers.com starting with the 10th of May:
I'm still not where I want to be, especially when it comes to my vim muscle
+memory that I had to give up. While I'm typing with qwerty these days, I also
+want to be more mindful about potential finger pain and RSI because dvorak
+felt much more comfortable to me.
+
Goals
+
My primary goal for June is to reach 80+ WPM touch typing on qwerty. I feel as
+if I can't get into proper flow without being able to touch type properly.
+
Apart from that I want to try and prioritize my assigned Clippy pull request
+reviews over providing my own code contributions.
+
+
+
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Thanks to @oli-obk and @yaahc, for their continuous support!
+
There haven't been any new sponsors this month. If you want to support my work,
+please consider sponsoring 🎉
+
What I've worked on
+
This past November I've been on vacation for two weeks, both of which required
+some sort of preparation the days before. Therefore my main goal for November
+was getting just two PRs merged:
The first one is just a simple bug fix. The second one means that Clippy will
+point to the Clippy issues if there's a crash happening in Clippy. This
+hopefully prevents Clippy issue reports in the rust repo in the future.
+
Reflections & Goals for December
+
This December I want to try and put more structure into my learning. While
+it's fun and rewarding to fix Clippy bugs, I'm slowly coming to the realization
+that it's not necessarily a good way to learn more about Rust or rustc.
I want to try and review some of the open Clippy PRs
+(there's been a lot of activity 🎉).
+
I want to create more flashcards with the things I'm learning. I've been
+hovering at 50+ cards, but I want to double that this month.
+
+
See you here for the December review!
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
My main goal for October was getting all the sponsoring figured out and set up.
+The first half of the month was more or less about figuring out all this stuff and
+making sure sponsoring is fine with my employer. This included:
Unfortunately I got sick with a strong cold at the end of the month and I'm
+still recovering from it as I'm finishing up this post, so I'm going to keep
+this months review a bit shorter and focus on getting healthy again.
+
This November I hope to finish up my two existing Clippy PRs (1,
+2) but I will also be on holiday for two weeks. The remaining time I
+want to try and see how I can help out with the effort over at
+annotate-snippet-rs.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Before I moved to Berlin last year, I wanted to have a netbook which would allow me to do a few basic things:
+
+
Take notes during class on Google Docs
+
Capable of 3D graphics for basic game programming and gaming
+
Lightweight
+
Long battery life
+
+
So I got myself an ASUS Eee PC 1215n about 5 months ago. This is a kind of a personal review on the netbook and how it was useful (or not) to me.
+
Positive things to note
+
The main purpose I bought the netbook was to write down stuff during classes. That just works perfect. Except math classes. To me, it's easier to write down formulas on paper rather than using the word formula editor. Pen and pencil is just way more efficient when it comes to formulas.
+
It's a real lightweight and it's small enough to fit in my backpack. That's a huge benefit for me. Previously I would use an extra laptop bag for my father's laptop. Now I have all the stuff in my backpack which makes things a lot more comfortable.
+
Another important thing to me is the battery power. My current university schedule includes days where I'm at university all the day. While there is always access to some power supply, I wanted to be sure my netbook could run all day, taking only notes on Google Docs. That's totally possible. I just have to make sure unnecessary program aren't running in the background and the screen brightness is turned to its lowest setting. Disabling wireless LAN and Bluetooth also saves a lot of battery power.
+
What's not as good
+
Programming at small resolutions requires some getting used to. On Windows, if you use an IDE like Code::Blocks you just don't see a lot of code at all. It can be difficult to understand how a function works just because you have to scroll to see the rest of the function. I am used to at least one big widescreen display to program stuff (Having two at home). So I actually didn't get around to program stuff on my laptop AT ALL. The screen is just too small for some serious programming.
+
Another thing is the CPU. When I was running XNA stuff, which requires Visual Studio, the CPU is running at 100%. Not to mention the memory consumption, which is always at maximum with Visual Studio and Firefox running.
+
What I didn't know at the time I bought the netbook was that we would program using Ubuntu Linux. We simply use gedit and compile the files via the terminal right now. Not using an IDE. So I removed Windows 7 and installed Ubuntu on my netbook. Sadly, at the time I tried that, ION graphics support wasn't complete and all the benefits in terms of power saving were gone on Linux. So back to Windows again. I'm not sure what has changed by now but I'm happy with Windows 7 right now. I probably should dedicate a few blog posts to running Linux on a 1215n at some point..
+
Overall I'm happy that I have a device where I can save notes on Google Docs during class. Except for math stuff I can easily search for things I wrote down and categorize stuff in a nice way.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Today I took some time to work on my PowerShell configuration. Here is what it looks like now:
+
+In case you already know about customizing the PowerShell, you can get the file here. If not, read on.
+
Shortening The Prompt
+
+This is the default git shell prompt. As you can see, the path takes about 75% of the prompt's width. Let's change that.
+
Admittedly, until today I didn't know a lot about PowerShell. So, after a bit research, I found an article on prompt shortening. The following two functions need to be placed into %USERPROFILE%\Documents\WindowsPowerShell\GitHub.PowerShell_profile.ps1
+
function shorten-path([string] $path) {
+ $loc = $path.Replace($HOME, '~')
+# remove prefix for UNC paths
+ $loc = $loc -replace '^[^:]+::', ''
+# make path shorter like tabs in Vim,
+# handle paths starting with \\ and . correctly
+return ($loc -replace '\\(\.?)([^\\])[^\\]*(?=\\)','\$1$2')
+}
+
+function prompt {
+# write status string (-n : NoNewLine; -f : ForegroundColor)
+write-host 'PS' -n -f White
+write-host ' {' -n -f Yellow
+write-host (shorten-path (pwd).Path) -n -f White
+write-host '}' -n -f Yellow
+return ' '
+}```
+
+`shorten-path()` takes care of shortening the path in a GVim manner and replacing the user profile path with a `~`.
+`prompt()` is a built-in function that is used to format the prompt.
+
+## Putting It Together
+
+While this was working, it turned out that this got rid of the branch status. Luckily, someone wrote an article about [displaying git data in the prompt](http://tiredblogger.wordpress.com/2009/08/21/using-git-and-everything-else-through-powershell/).
+I spent a good hour playing around with the code and eventually I got PowerShell to display the data again.
+
+```ps1
+function prompt {
+if(Test-Path .git) {
+# retrieve branch name
+ $symbolicref = (git symbolic-ref HEAD)
+ $branch = $symbolicref.substring($symbolicref.LastIndexOf("/") +1)
+
+# retrieve branch status
+ $differences = (git diff-index HEAD --name-status)
+ $git_mod_count = [regex]::matches($differences, 'M\s').count
+ $git_add_count = [regex]::matches($differences, 'A\s').count
+ $git_del_count = [regex]::matches($differences, 'D\s').count
+ $branchData = " +$git_add_count ~$git_mod_count -$git_del_count"
+
+# write status string (-n : NoNewLine; -f : ForegroundColor)
+write-host 'GIT' -n -f White
+write-host ' {' -n -f Yellow
+write-host (shorten-path (pwd).Path) -n -f White
+
+write-host ' [' -n -f Yellow
+write-host $branch -n -f Cyan
+write-host $branchData -n -f Red
+write-host ']' -n -f Yellow
+
+write-host ">" -n -f Yellow
+ }
+else {
+# write status string
+write-host 'PS' -n -f White
+write-host ' {' -n -f Yellow
+write-host (shorten-path (pwd).Path) -n -f White
+write-host ">" -n -f Yellow
+ }
+
+return " "
+}```
+
+
+##PowerShell Properties
+If you right-click on the PowerShell menu bar, you will find a menu called `Properties`. In there, you can change a few things that will make your work with the PowerShell a little easier.
+Here are the properties I changed:
+
+ BufferSize: 500
+ QuickEditMode: true
+ Font: Lucidas Console
+ Font Size: 14
+ Screen Buffer Width: 100
+ Screen Buffer Height: 1000
+ Window Width: 100
+ Window Height: 54
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
I did something stupid when transferring my old domain to namecheap.com.
+You see, namecheap didn't offer transfers for .de domains. So I sent a close request to my old registrar.
+
Huge mistake.
+Apparently, the domain is now located in Greece.
+I no longer own phansch.de.
+
To get everything in order again, I purchased phansch.net and set up proper domain forwarding.
+There's also a new theme, as you might have noticed. It's a mix of the-pr0gram and Tom's jekyll theme.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Here's what I've been working on, the past couple of days.
+
http://tools.plyturon.net/translator/
+
Update: Unfortunately the translator is not up anymore as I retired the project. If you are interested, you can drop me a mail at: hi AT phansch.net.
+
This tool translates any text to New Krytan, the language used by the inhabitants of Kryta in Guild Wars 2.
+The language is based on a very simple substitution cipher. Additionally there is a decimal numeral system in place.
+
+
Go check it out!
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Disqus has not been working properly for me for quite a while already. The login inside the page never worked and comments randomly disappeared from time to time.
+
Now, Disqus has been acquired by another tech marketing company and it looks like they will be focusing solely on B2B, instead of focusing on their users.
+
Of course, the same argument can be made for Google Analytics, too. I will replace Google Analytics with piwik by the end of the year. Once that is done, this blog should be free of opaque tracking scripts.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
I am participating in the One Game A Month challenge. Each month, I am going to show off a finished game.
+Last month's Ludum Dare taught me how important it is to plan ahead. And to stick to your plan.
+
Here's what I've planned in order to complete the challenge.
+
+
The first weekend of the month is where I will finish the majority of the game.
+
I will then use the rest of the time to add polish.
+
Every Sunday, a new game update is published on this blog. The game should be in a playable state without any obvious bugs.
+
Use game jams whenever possible.
+
Use the GitHub Issue System for monitoring my progress. I have a milestone for 1GAM setup here.
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
It's hard for me to believe but it's already been over a year since I
+seriously committed to learning Rust and I have now reached my initial goal of
+100 open source contributions to the Rust ecosystem. You can see the full list
+here.
+
+
+
+
+
278 / 100
+
+
+
+
I want to use this blog post to review the work I've done, talk about
+the challenges I've come across and how I've tried to deal with them. I'm afraid
+I haven't blogged in a long time and this is a bit longer than usual.
+
Clippy!
+
I decided to work on Clippy for a couple of reasons:
+
+
I love helping people and Clippy is the perfect force multiplier for that
+
It's quick to iterate on bug fixes and new lints - Running the UI test suite
+takes only 1 minute on my machine
+
It had a lot of reach, with at the time ~2000 GH stars (now at 3000+)
+
Clippy had (and still has) the good first issue label that made finding
+tasks super easy
+
The other contributors were super responsive and helpful
+
As a jumping point towards more advanced rustc internals
+
+
I had done some small documentation contributions and was watching other people
+contribute new lints and such. With the beginning of 2018 I decided to focus
+on Rust in my free time as much as possible. It was also a sort of experiment on
+whether I had the grit to stay with a longer-term project.
+
January to March
+
At the beginning of January 2018, my first big Clippy contribution was a
+Lint that detects empty lines after outer attributes, such as:
The rationale for this lint is that the attribute was probably meant to be an
+inner attribute because it has empty lines that follow. In the process of
+writing that lint I learned that there are a lot of things to consider when
+linting Rust code and the lint resulted in a few false-positives that I also
+fixed.
+
I think this experience made me aware of how much potential for improvements
+there is in Clippy and I decided to spend more time on bug fixing than adding
+new lints from then on.
+
April to June
+
To prevent Clippy crashing on essential ecosystem crates, I added an
+integration test suite to Clippy that makes sure Clippy doesn't crash
+when it's executed on them.
+
In May I expanded the existing build script to include a check that ensures
+a recent nightly release is used to build Clippy. As of now, this has been
+removed again because Clippy is now distributed via Rustup.
+
July to November
+
From August to November 2018 I rewrote a 300 line python script in Rust to make
+it work cross-platform: #2985, #3320, #3325,
+#3327, #3388, #3399, #3408.
+If you've contributed a Clippy lint before,
+chances are that you've used one of these versions. The rewrite is probably
+worth its own blog post at some point.
+
December to February 2019
+
In December I added Rustfix support to the compiletest-rs
+library, which in turn allows Clippy to test its
+code suggestions. This will prevent suggestion regressions, improve future
+suggestions and help pave the path to a reliable Clippy ⟺ Rustfix integration.
+This is an ongoing effort and if you want to help out with this, there is an
+open tracking issue with some instructions.
+
In January 2019 I added a lint that detects whether a function can be const or
+not. This lint is currently in the nursery group as the const_fn feature is
+not fully stabilized yet. You can give it a try by using
+#![warn(clippy::missing_const_for_fn)] if you are on beta or nightly.
I added the ability to create GitHub review comments to hubcaps
+
I made the tests of rustc's compiletest runnable via ./x.py
+
+
Did it work?
+
I specifically started this project to improve my grit for longer-term projects
+and I would say that it worked. Together with other things, working on Clippy
+helped me to increase my focus to stick through harder tasks.
+
Working on crashes where I know next to nothing in the beginning is really
+hard motivation wise. In one case it has caused me to step away for a couple of
+weeks. This is something that I want to still work on.
+
I also want to solidify more fundamentals. When I go to the Rust Berlin learners
+meetup I sometimes feel like I can't explain some things properly. I suppose one
+problem of fixing bugs in Clippy is that there's not a lot of general Rust
+knowledge to learn. It's more about very specific rustc or Clippy internals.
+
What's next?
+
For the reasons mentioned at the beginning, I will absolutely continue working
+on Clippy and focus on improving its reliability. I am currently reworking the
+contribution guidelines to lower the bar of entry for new contributors and then
+want to get back to fixing bugs and crashes.
+
However, I also want to improve my fundamentals. To do that, I'm expanding my
+Anki card collection to be able to recall more from memory and going through
+TRPL a second time.
+
On to the next hundred contributions!
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Here's my most recent addition to my vimrc. I was looking for a way to open Markdown or HTML files in the browser, with a single keystroke from vim.
+
In vim you can execute shell commands with :!command. This will put vim in the background and execute the given command. You have to hit enter in order to go back to vim.
+
So, to open the current file in Firefox you can use :!firefox %. Where % is expanded to the current active file in vim.
+
To make this a bit more flexible, on Debian based systems you can use :!sensible-browser % to open the file in your default browser. On a Mac it should be :!open %, although you will have to try that one for yourself.
+
Now, there's one thing that is getting in the way: You still have to press enter to get back to vim. So, the next step is to prepend a :silent execute to our command:
+
:silent execute "!sensible-browser %"
+
+
This should work on most systems. However if your vim turns blank when executing your command, you will have to force a redraw afterwards with :redraw!. You could also hit CTRL+L to achieve the same thing, however we can use :redraw! in combination with the other command:
+
function! OpenCurrentFileInBrowser()
+ " Open current file in browser
+ :silent execute "!sensible-browser %"
+
+ " Fix empty vim window by forcing a redraw
+ :redraw!
+endfu
+
+
Now we can conveniently bind it to a shortcut:
+
augroup filetype_markdown
+au!
+au BufNewFile,BufRead *.md set filetype=markdown
+
+au FileType markdown nnoremap <leader>f :call OpenCurrentFileInBrowser()<cr>
+augroup END
+
+
+
Actually opening Markdown files in your browser
+
By now, the browser should open a download dialogue when executing our command. To fix this, we have to install an addon that provides a markdown parser.
For Firefox there's pretty much only Markdown Viewer available. And chances are it doesn't work out of the box on Linux. If it doesn't, you are probably missing an entry in ~/.mozilla/firefox/*default/mimeTypes.rdf.
+
Add the following to mimeTypes.rdf to make it recognize .md files as text/plain:
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
In this video, PC Gamer shows off the effects of the different graphics settings in Guild Wars 2. Watch the video after the jump!
+There are some interesting things to note:
+
+
The transition between all of the settings is seamless. No loading screens, no frozen screens.
+
High resolution character textures were not part of this beta client.
+
Depth of field was not included in this beta client.
+
+
In regards to the client performance, keep in mind that the game is still in beta and optimization is always the last thing in software development.
+
In case you were wondering about the system specifications:
+CPU: AMD Phenom II X6 1090T, 3.6GHz six-core
+MOBO: ASUS Crosshair IV Formula
+RAM: 8 GB
+GPU: Radeon HD 6970 2GB
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
I didn't get a lot of stuff done last week. And I only managed to squeeze in 24 hours of work this week. I did manage to add a new enemy, a new title screen, camera shake and a game ending. I also increased the difficulty a lot.
+
+
What's new
+
+
You can now get killed by your own projectiles
+
A new enemy: The strategic bomber (has placeholder graphics)
+
Camera shake!
+
More shooting!
+
+
Running the game
+
+
If you don't have Love2D installed, download it here and install it first.
On Linux, use love /path/to/game.love to run the game.
+
On Windows use love C:\path\to\game.love, double click the file, or drag the .love file onto love.exe
+
On Mac use open -n -a love "/home/path/to/game" or drag the .love file onto the Love.app application bundle
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Originally, this was going to be called HeartDefender, but I had to ditch the Heart because my time this month in somewhat limited. Now it's just circles. Anyway, here's PiDefender:
+
+
+
The player is using the mouse to control his ship. This, in turn, controls the cannon, which is the primary weapon against the enemies.
+The player has to guide the cannon while avoiding the enemies.
+
The game is obviously a work in progress. Both graphics wise and gameplay wise. At the end of January, there will be multiple enemy types and different ammunition types to choose from. The rest is just juice that's missing.
+
Running the game
+
+
If you don't have Love2D installed, download it here and install it first.
On Linux, use love /path/to/game.love to run the game.
+
On Windows use love C:\path\to\game.love, double click the file, or drag the .love file onto love.exe
+
On Mac use open -n -a love "/home/path/to/game" or drag the .love file onto the Love.app application bundle
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
I had more important stuff to work on, this week. It's the usual madness at the end of every semester. Projects piling up and exams are coming closer each day. So I have to commit a lot of time to that. Luckily, I'm done with almost all of the projects, so I can focus on learning and finishing PiDefender.
+
Due to that I cut down on a lot of stuff I was going to do with PiDefender. Here's a list of what initially was going to be in, but now isn't making it:
+
+
Possible boss mechanics
+
Main screen fanciness (random ship movement in the background)
+
Circle diameter is based on window size.
+
Loot drops
+
Player docks on cannon, instead of passing through the planet.
+
+
Did I mention that I switched to Linux Mint + dwm? This made me realize that the game crashes on Linux. So far, I didn't really investigate the crash, but I honestly have no clue why that happens. It's running fine on Windows and LÖVE claims to work on Windows, Mac OS X and Linux.
+
That's also the reason why there is no download this week. However, if you feel adventurous, you can still download the source, .zip it, rename it to .love and run it. (Make sure that main.lua is at the root of the .zip file)
+
What's left to do
+
Increasing difficulty. I want this game to be more challenging!
+
+
If the player is hit by his own fire, he looses a life.
+
+
I want to add one more enemy type, sort of like a strategic bomber:
+
+
Stays at distance, but moving.
+
Deals more damage/second than the suicidal enemies.
+
Can take multiple hits
+
+
I also want to add an AOE weapon for the player:
+
+
Works in the same way as the projectile.
+
Kills everything within a specific radius, including the player
+
+
See you next week!
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Ich habe wieder Zeit gefunden um an meinem Pacman Spiel weiter zu arbeiten.
+
Für den DirectX-Teil brauche ich eine Klasse um eine Map Datei zu öffnen. Diese war praktischerweise schon für den MapEditor geschrieben. Also habe ich die Klasse in ein Core-Projekt verschoben und setze diese nun für beide Programme ein.
+Das hat den Vorteil dass es anstatt zwei ähnlicher Klassen nur eine gibt und somit weniger Sourcecode vorhanden ist (Stichwort: refactoring).
+
Im Grunde lässt sich die Klasse nun auch für andere Spiele verwenden die auf einem Raster basieren.
+
So wären zum Beispiel Spiele wie Schiffe Versenken durchaus mit diesem Grid realisierbar.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
In den letzten zwei Wochen habe ich wieder Zeit für das Pacman Spiel gefunden.
+Es hat sich einiges getan. Unter anderen verfügen die Geister nun über eine automatische Wegfindung. Außerdem können sie von Pacman durch das Sammeln von großen Pillen für 5 Sekunden verlangsamt werden. Was es sonst noch neues gibt, erfahrt ihr hier
+
Geister "AI"
+
Die Geister Wegfindung ist sehr einfach gehalten.
+Befindet sich ein Geist auf einer Kreuzung, wird eine zufällige Richtung ausgewählt. Ausgenommen ist dabei die Richtung aus der der Geist gekommen ist.
+
public void GetPossibleDirections(Map map)
+{
+_possibleDirections.Clear();
+foreach (Direction dir in Enum.GetValues(typeof(Direction)))
+ {
+if (CanMove(dir, map))
+ {
+_possibleDirections.Add(dir);
+ }
+ }
+
+//Remove the opposite direction
+if (this.CurrentDirection == Direction.Right)
+ {
+_possibleDirections.Remove(Direction.Left);
+ }
+else if (this.CurrentDirection == Direction.Left)
+ {
+_possibleDirections.Remove(Direction.Right);
+ }
+else if (this.CurrentDirection == Direction.Up)
+ {
+_possibleDirections.Remove(Direction.Down);
+ }
+else if (this.CurrentDirection == Direction.Down)
+ {
+_possibleDirections.Remove(Direction.Up);
+ }
+}
+
+
Natürlich ist das noch keine große Herausforderung für den Spieler. Im Original hat jeder Geist seine eigene Persönlichkeit, so dass er zum Beispiel auf die Nähe Pacmans reagiert.
+Dazu gibt es einige wunderbare Artikel im Netz:
Ich werde wenigstens eine Alternative Wegfindung für die Gegner implementieren.
+
Collision Detection
+
+
Die erstbeste Methode zur Kollisionserkennung auf die man stößt wenn man nach "XNA collision detection" recherchiert, ist Rectangle.Intersects(Rectangle r). Wenn sich Rechteck A mit Rechteck B treffen hat man eine Kollision. Hier stoßen wir beim Spielen aber früher oder später auf Schwierigkeiten.
+
+
Anhand des Bildes kann man das leicht erklären. Der Gegner (rot) befindet sich auf dem Weg nach oben und ist Pacman schon fast ein ganzes Feld voraus. Da sich jedoch die Rechtecke beider Objekte berühren, kommt es zur Kollision.
+
public bool GetsEaten_Hardcore(List<ghost>)
+{
+foreach (Ghost g in ghosts)
+ {
+if (this.RectBoundary.Intersects(g.RectBoundary))
+ {
+return true;
+ }
+ }
+return false;
+}
+
+
Eine andere Möglichkeit: Während des Spiels wird von der Spielfigur und den Gegnern jeweils das aktuelle Feld erfasst. Befindet sich ein Geist mit Pacman auf demselben Feld, kommt es zu einer Kollision.
+
public bool GetsEaten_Liberal(List<ghost>)
+{
+foreach (Ghost g in ghosts)
+ {
+if (this.CurrentField == g.CurrentField)
+ {
+return true;
+ }
+ }
+return false;
+}
+
+
+
Nun, damit entsteht ein Problem: Was passiert wenn sich Pacman und Gegner (rot) auf demselben Feld sind, sich aber nicht berühren? Genau: Die Methode gibt true zurück und der Spieler hat ein Leben weniger.
+Einen optimalen Lösungsweg habe ich hiermit noch nicht gefunden. Ich werde mich nochmals mit der letzteren Methode beschäftigen, da die erste Methode zu frustrierend für den Spieler wäre. Immerhin kann der Spieler die Bounding Rectangles nicht sehen.
+
Verlangsamung der Gegner
+
In der jetzigen Version kann Pacman die Gegner für eine bestimmte Zeit verlangsamen indem er eine große Pille sammelt. Ist die festgelegte Zeit abgelaufen, haben die Gegner wieder ihre ursprüngliche Geschwindigkeit.
+
Alles fängt damit an, dass Pacman eine große Pille sammelt:
Die Methode Update_Ghosts() überprüft ob GameData.AteBigPill == true ist und ändert entsprechend die Geschwindigkeit der Gegner.
+
//Slow each ghost for GHOST_SLOWTIME in seconds if pacman ate a big pill
+if (GameData.AteBigPill == true)
+{
+//Start counter
+GameData.GhostSlowTimer -= gameTime.ElapsedGameTime.TotalSeconds;
+foreach (Ghost g in _ghostList)
+ {
+g.Speed = MovingCreature.MovementSpeed.Slow; //Force effect on each ghost
+ }
+
+if (GameData.GhostSlowTimer < = 0) //if time is over
+ {
+GameData.GhostSlowTimer = GameData.GHOST_SLOWTIME; //reset timer
+GameData.AteBigPill = false; //reset flag
+ }
+}
+else if(GameData.AteBigPill == false)
+{
+foreach (Ghost g in _ghostList)
+ {
+g.Speed = MovingCreature.MovementSpeed.Fast; //Remove effect
+ }
+}
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Ich arbeite zur Zeit an einem Pacman ähnlichen Spiel, welches auf C# und dem XNA Framework basiert.
+
Das Spielfeld soll als Raster aufgebaut sein. Das Raster wird mithilfe einer Textdatei mit entsprechenden Shapes gefüllt. Um das erstellen der Textdatei zu vereinfachen, habe ich kurzerhand einen MapEditor für mein Spiel erstellt.
Diese Datei wurde vorher mit dem Map Editor erstellt und gespeichert.
+
+
Als nächstes steht nun die Erstellung des Spielfeldes mithilfe des XNA Frameworks an.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
So I wrote down this list of things that I want to accomplish in 2012. Let me share it with you.
+
+
I want to get into C++ heavily. Meaning that I am able to start DirectX game programming at a small scale.
+
At the end of the year I want to have at least one finished DirectX 2D project.
+
I want to publish an addon for the game RIFT that I am going to support until the 31st December
+
I want to have at least 52 blog posts at the end of the year.
+
+
+
You don't become great by trying to be great. You become great by wanting to do something, and then doing it so hard that you become great in the process.
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
So I have been keeping track of the stuff I do for a while now.
+I'm using a simple markdown formatted file to write things down. It's part of my GTD process and feels nice to look over when feeling less productive.
+My editor of choice is Sublime Text 3.
+
After using this setup for a few months, I felt it wasn't efficient enough.
+Opening the journal file in markdown required tedious navigation through many directories.
+
So I started writing a simple ruby script.
+
Introducing jou
+
Jou is a simple command line utility that helps with maintaining a journal file in markdown syntax.
+
+
Install it with gem install jou
+
Set a path to your journal file: jou --set-journal "/home/user/Documents/Journal.md"
Routines is my way of building and keeping habits. It's the morning part of my GTD process.
+The script is launched when I power on my PC. It then continues by reminding me of my morning routine.
+It launches my calendar, email, my tasklist and anki. Here's a screenshot:
The script is part of my dotfiles repository and can be found here.
+
Have a beautiful day!
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
A year ago, I wrote about my first experiences with the Asus EeePC 1215N. It's time that I do another review of my netbook usage.
+
I've been running Windows 8 for about two weeks before I removed it. I was unable to connect to my university's eduroam network due to faulty drivers.
+Before that, my netbook was running on Windows 7. Running Windows 7 was quite effortless. The reason I gave Windows 8 a try was keyboard accessibility. The new Win + X keyboard shortcut is awesome. The new task manager and file transfer dialog are nice as well. But those just didn't cut it.
+
The thing is, that my netbook crashed down twice, from 1m height. Because of that, my touch-pad broke and now it stops working a few minutes after start-up. With Windows, I had to bring a mouse with me every time I wanted to use the netbook for longer.
+After Windows 8, I decided to give Linux another try. I heard about XMonad, a tiling window manager, a couple times before, so it was time to reevaluate my netbook usage.
+
What I wanted
+
+
A fast and lightweight system
+
Long battery life
+
Simple application launcher
+
Easy note-taking – without a distracting Internet browser
+
Simple 2D game programming
+
Everything should be accessible by the keyboard, due to a broken touch-pad
+
As much screen real estate as possible
+
+
My setup
+
Linux Mint (MATE)
+
Frankly, it doesn't really matter what distribution you are using. I opted for Linux Mint because it comes with proper media support and working wireless drivers. After trying the Cinnamon and the MATE desktop, I must say that the Cinnamon desktop felt a bit sluggish compared to the MATE desktop.
+I also tried a minimal Debian setup, but I couldn't get the wireless working. If wireless worked out of the box on Debian I probably would have sticked with it.
+
XMonad
+
I have been using XMonad for over a month now. I really like it. There are no window decorations and there is no mouse required to do anything.
+Windows are closed with Win + Shift + C and that's basically it. Depending on the current layout, the size of the active window can be increased with Win + H and decreased with Win + L. To switch between windows, I use Win + Tab.
+
My XMonad config just adds a few custom keyboard shortcuts:
+
+
Win + Shift + Enter open gnome-terminal
+
Win + Shift + P open dmenu
+
Win + Shift + V open virtualbox
+
Win + S Shutdown
+
Win + Shift + S Suspend
+
+
If you want to see how XMonad can be used, take a look at the config archive.
+
Filesystem access to Google Drive
+
Sadly there is no official Google Drive client for Linux. Therefore you have to rely on third party developers.
+To access Google Drive on Linux, you have two options:
The main difference between both is that Grive doesn't sync automatically. You have to tell it to sync. Grive also doesn't support symbolic links.
+Insync, on the other hand, is a fully functional Google Drive client. Although, the GUI is not working for me. I just keep the application running in the background and it will do the syncing.
+
Sublime Text 2 for writing and web stuff
+
I recently talked about setting up custom Build Systems for Sublime Text 2. Currently I have a build system to build a Love2D project, one for pdflatex and a build system to preview a markdown file in google chrome. I have a small set of shortcuts that I regularly use. I think they are common knowledge, but here are they anyway:
+
+
Shift + RMB to select columns
+
Shift + Alt + up or down to select columns
+
Ctrl + Shift + P to open the Command Palette
+
Ctrl + B to use the current build system on the current file.
+
F6 for spell-checking
+
+
I also put the settings for ST2 on Google Drive. On a new machine, I can then create symlinks to Google Drive and have the settings and plugins quickly available.
+
NetBeans for Java programming class
+
While Sublime Text 2 is an awesome piece of software, I am pretty lazy. At some point, I want to use ST2 to do all the Java stuff for university.
+Until then, I'll be using NetBeans. In NetBeans I got rid of a lot of unnecessary UI. I also disabled a lot of plugins to make NetBeans start up faster. It still takes 20 seconds, but that was a huge improvement already.
+
What requires fixing
+
There are a couple things left to do, that could save some time.
+
+
My git login is not saved to the gnome keyring. Have to login for every push
+
I still struggle with navigating websites by keyboard.
+
Use Sublime Text to work on Java assignments.
+
A few Google Chrome plugins don't sync their settings.
+
+
+
To wrap things up, I can say that I am really happy with my setup. It was a bumpy road to get there but I think it pays off. The battery lasts for around 4 hours with wireless. For note-taking I use Sublime Text 2 and save notes as markdown. With XMonad, pretty much everything is accomplishable by keyboard shortcuts. And I finally have enough screen space available to do some programming on my netbook.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
In this article from TalkTyria, Skyriar talks about what it might be like to play other MMO's after Guild Wars 2 has been released. Will other games feel differently? Will they still be fun?. It's a fear that I share to an extend. Musings after the jump!
+
Skyriar's article ends with a few questions left to answer:
+
+
What are your expectations for Guild Wars 2? How do you think the game may affect the way you see other (or older) games, if at all? Do you feel GW2 is going to be as revolutionary to the genre as the hype suggests?
+
+
Here are my thoughts.
+
+
What are your expectations for Guild Wars 2?
+
No preparation required
+
The last game I seriously played was EVE Online. I played it for almost 4 years, with a few breaks in between. Most of the time I was part of a small PVP alliance. An alliance in EVE consists of multiple corporations, or simply guilds. Small meant that there were around 1000 players in the alliance with 200 to 400 active in our prime time.
+
Large scale PVP in EVE can be compared to raiding, it's only more people. I've seen 500 people in a single teamspeak channel. But coordinating hundreds of people isn't easy. As a PVP leader in EVE, you not only have to master the game, you have to pay attention to a dozen chat channels, delegate tasks to a group of around 5 to 10 helping hands and at the end give exact orders that everyone in voice chat can understand. For the average player, there was absolute silence most of the time, except when a fight was actually going on.
+
Delegating important tasks, getting at least 100 people together and actually moving out of your meeting place takes **at least an hour **. An additional 30 minutes until you arrive at the objective and depending on the situation either 1 hour of mindless repetition because the enemy didn't show up OR 1-5 hours of epic fights you would talk about until the next dawn.
+
+
+
Okay, enough EVE talk! The point here is the preparation time and not knowing if the waiting time is worth it. If your are one of the many who aren't in control, you have nothing to do until everyone else is ready. You sit there and wait an hour for your fellow pilots to show up.
+
Guild Wars 2 does it all differently. For structured PVP there's hot join in place. Games are always running therefore you can have instant action. You can always jump into WvW or complete a dungeon with your friends. You don't have to for for your guilds only healer or tank. The holy trinity has been replaced by a better trinity, where everyone can almost fulfill any role.
+
Cooperation instead of competition
+
I hope that we really don't have to fight over NPC enemies with other players. This is one of the things, I hope Guild Wars 2 is doing right. For each player fighting a monster, there's a different loot-table. Everyone gets rewarded for defeating a single enemy. This will not only make it easier to make friends, this will also reduce the amount of general anger in the game.
+
Competitive PVP
+
I also have high hopes for structured PVP. I hope that it will eventually become a part of the e-sport community, just like Starcraft 2 and League of Legends. However I can't really see millions of people playing PVP, like in League of Legends. I think it will settle at around 100.000 active PVP players, which is still a lot!
+
It's easy to get stuck with just numbers. But the total amount of players is just not as important as the amount of high quality commentators. Support from global tournaments like WCG, MLG and Dreamhack will also come in handy and will spread the word about Guild Wars 2 PVP.
+
How do you think the game may affect the way you see other (or older) games, if at all?
+
It already changed the way I view other games. When I start up EVE, I think of the preparation time prior to having fun. The moment I realize that the time I spend is not meaningful to the rest of the time I spend in the game, that's the moment where I turn off the game. When it comes to the standard MMORPG's like Rift or WoW, I immediately think of the clunky UI and how playing as a healer was just looking at bars going up and down.
+
However, there are other genres besides MMORPG's. I still play Team Fortress 2 and Minecraft. I find plenty of joy in those games. Those are easy to pick up and offer almost instant fun. I also still find joy in games like Mass Effect and Portal, even if they don't offer as much replayability like MMO's
+
I think, Guild Wars 2 has kind of turned me into a more casual player but in a good way. Guild Wars 2 is finally a game where you can play hardcore without hundreds of meaningless hours spent in the game. You can still be hardcore by mastering your profession. For example, every minute you spend on working out that one build is truly meaningful and not wasted time.
+
Now I'm trying to pay attention to how I spend my time in games. And that is one of the lessons Guild Wars 2 has taught me.
+
+
Do you feel GW2 is going to be as revolutionary to the genre as the hype suggests?
+
I think quite a few players should lower their expectations for the game. People who are used to raiding will have to adapt to the fact that there are no raids. On release we will see what feature is there and what is still missing from the game. People will demand features they were used to, in other games. Just think of dungeons finders and in-game voice chatting.
+Oh and it's still a Many Men (and women) Online Roleplaying Game. There will of course be drama around guilds and there will be flaming going on in PVP - that's inevitable.
+
Concerning that revolution..
+
To a certain degree the game will be evolutionary but not revolutionary. It's the way things are put together that make this game better than others, but not revolutionary. If you take apart the game and look at it's different systems and mechanics, you will see that none of these are actually new to games.
+
We have seen alternatives to quests in other games that weren't MMO's. Think of games like Mass Effect or Portal where the story is told without quest NPC's. We have seen action oriented combat in games like Vindictus. We have seen good PVP in games like Counter Strike, Warcraft and Starcraft. We have also seen large scale, meaningful PVP in games like DaoC and EVE Online.
+
ArenaNet employees are playing these games and as game developers they get the chance to develop a new game from scratch and rethink all the stuff that has been done in previous games. They experiment with new stuff, but if it doesn't work it won't be in the final game. They might even combine mechanics from two different games so that they work hand in hand. That's essentially what evolution is about.
+
I'm ending this post with a weird metaphor. I'm famous for those!
+
+
Imagine a planet where at the start there only live MMOG's, MOBA's, RPG's, Shooters and RTS games. Given about 2.5 billion years of evolution, you would most likely get a Guild Wars 2 out of it.
+*[MLG]: Major League Gaming
+*[WCG]: World Cyber Games
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Then all what's left is adding a new build system for LOVE.
+
+
In Sublime Text 2, go to Tools -> Build System -> New Build System...
+
Change "cmd": ["make"] to "cmd": ["love", "$file_path"]
+
Save the file as RunLove.sublime-build and select RunLove from Tools -> Build System
+
+
To see if this is working, go to your main.lua and hit CTRL + B.
+You can also use the built-in console to see the output of your game.
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
This series will have a focus on DIY computer stuff, privacy issues, automation and security related topics.
+
One thing I want to achieve this year, is independence from most customer cloud services. Customer cloud services meaning services that I use for personal stuff.
+That includes stuff like Google Mail, Google Calendar, GoogleDocs/Dropbox and many more.
+
+
As a first step, one thing I recently did was moving my blog away from GitHub Pages. This blog is now hosted on my own server. This costs a little money, but I have full control over the environment. The setup is different for each provider, but essentially it's a git post-receive hook that triggers jekyll to build the page:
More information about deploying with jekyll can be found here.
+
The biggest advantage I see is being able to customize the post-receive hook. There are so many possibilities, like automatically posting a tweet once a post is published.
+
It's important to note that if you are planning to move away from GitHub Pages, you don't necessarily need a hoster that offers Ruby support. All you need is a webserver that can serve static files. You would first generate your blog with jekyll locally and then upload it it your server via FTP.
+
After moving the website away from GitHub, I also moved most of my GitHub repositories to GitLab. As a result, most of the links to my GitHub repositories have to be changed at some point. A mirror of this websites repository is available on GitLab.
+
I haven't written any other posts for this series yet, but potential next topics include: Owncloud, Laptop Setup, Backups, Email, Password Management and Android liberation.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
This is the place where I talk about the progress on my quest on self-improvement. Follow me on this quest to a better self where you might learn something as well. Here's what I did last week in terms of self improvement, focusing on important stuff and getting rid of bad habits.
+
I finished Week 3 of c25k! I'm really getting into it and I started looking for my first official 5k run as well.
+On Monday I finished a Geocaching presentation for English class. As English is not my native language I spent almost the whole day practicing my speaking.
+Thursday was the day where I held my Geocaching presentation. I was quite nervous but according to my teacher there were next to no flaws!
+On Friday, on the quest to leave my comfort zone more often, I went to uni to study Mobile Applications with a fellow student.
+Saturday evening my uni took part in Berlin Science Open Door. I paid a short visit to see what people were presenting.
+Did I mention that my tent arrived on Sunday? Yes, finally! However, all the other equipment is still missing. :(
+
As for other stuff, I ...
+
... simplified things
+
Previously, I had my documents all over the place and emails/contacts/calendar only accessible at one computer. This week I fixed that.
+I simplified stuff by using Google Mail/Calendar instead of Outlook. I'm also using Google Drive to save my documents now. This somewhat saves me from doing regular backups of my documents.
+For note taking I'm using Evernote. Evernote also lets you sync over different devices. I use Evernote to write up my long term goals, class notes and ideas in general.
+For short term tasks I'm using Wunderlist, which lets you sync over different devices as well!
+This way I have all my stuff wherever I need it.
+
... got rid of internet distractions
+
When I'm programming I don't want to be distracted. Once I do something else, I would lose at least 5 minutes by getting into the code again. So I tried to get rid of as many distractions as possible.
+First, I disabled Google Mail notifications. I only check my mail three times every day now.
+Second, I got rid of MetroTwit's Twitter notifications. This was a HUGE change and an easy one. I don't feel like I want to enable them ever again.
+Apart from that, I disabled Skype and Steam notifications as well as several software update notifications.
+The next thing was my biggest distraction. The browser bookmark sidebar. I can only encourage you to either get rid of the sidebar or remove all the distracting bookmarks. This greatly increased my productivity.
+I also learned that when I have lots of tabs open, my productivity goes down. So, for now I'm trying to take a look at my tab count every 5 minutes to cut down on tabs I no longer need. By doing this I'm making sure that I'm staying on one task only.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
It took me about two days to get everything set-up. The first day was spent with learning the basics of jekyll, liquid and markdown.
+
The second day was littered with small challenges and quite a few problems. But problems are there to be solved. So here's my summary of day #2:
+
Setup a local test environment###
+
First thing I did, was figuring out how to setup a local testing environment. The previous day I did 80 commits for testing purposes. That was a little bit too much, in my eyes. Luckily there are quite a few tutorials on how to setup such a test environment. This is the one I used (My desktop machine is running Windows 7). All you need is ruby, the ruby dev kit, jekyll, rdiscount and a clone of your repository.
+
+
So, from 80 commits without a testing environment I went down to 18 commits on day 2.
+
Importing blog posts from Wordpress
+
As I wanted to keep my old blog posts archived, I looked for ways to convert the Wordpress export xml file to markdown. I eventually found thomasf/exitwp which does exactly what I needed. All that was left to do was getting rid if [caption] tags, making the code look nicer and some general formatting.
+
I also removed tags and categories from each post as I'm not making use of them. Sadly, embedded YouTube videos were removed by exitwp, so I had to put them in again.
+
The last thing that was on my list was the code formatting. Apparently there is GitHub flavoured markdown. Except that it didn't seem to work on here. After I've spent some time messing around with that, I simply used the basic markdown syntax for code. No syntax highlighting, sadly.
+This is also where most of the commits came from. Obviously, GitHub flavored markdown is not available in a local testing environment, so I had to test it on GitHub.
+
My own theme
+
This theme is a fork of Tom's jekyllbootstrap theme. A few changes to the font, a new archive page and a different footer - That's all I changed. But it's not finished yet. I'm planning to add a "fork me" badge and I might change the footer a little bit. But so far I'm pretty much done.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
I want to participate in the next game making competition for Ludum Dare. The last time I participated, I created a screenlapse of my work over the weekend.
+This time I want to do that again, but with a twist. I'm planning to live stream my work over the weekend.
+
However, this is not your usual video livestream. It will be images from the screenlapse recording output. A new image every 30 seconds. Since my laptop is not powerful enough to do actual video livestreaming, I hope this will be an interesting alternative.
+
Here's a preview of how it might end up looking like:
+
+
+
+Additionally, older screenshots will be displayed as thumbnails at the bottom.
+
New things learned!
+
The image livestreaming server is pretty much done and there's just a few finishing touches left. It is not available online yet, but the source code is available here on GitLab. The server itself can be found in the app.rb. It is built with Sinatra and provides a text/event-stream route for a client that uses the EventSource API. The other important route is post '/screenshot/:filename', which provides an interface for someone to push new images to the server. This route is also protected with HTTP Basic Auth, so that only authorized people (i.e me) can post screenshots.
+
The client code can be found in views/index.erb. The frontend part is also quite interesting: Once a new image gets posted to the server, it will show up in all connected clients without reloading. The old image will be moved to the list of thumbnails while the top image gets replaced with the new image. I extracted the code responsible for moving the images into a small Jquery plugin, which can be found here. I also wrote tests in Jasmine, because it got very tedious to test the frontend code. The tests can be found here.
+
I am really happy about this little project coming together because I learned so many new things. I never used Sinatra before. I had JavaScript testing on my list of things to do anyway and coincidentally, Jquery plugins make testing a lot easier.
+
What's left to do
+
The most important part that is missing, is a tool that automatically posts images to the server. Additionally I'd like to automatically remove images from the server once they aren't needed anymore. And tests for the Sinatra app. Other than that, I'm really looking forward to the next Ludum Dare.
+
Have a great time!
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Being a huge fan of Amnesia: The Dark Descent and Minecraft, I wanted to talk about a very specific topic in my first sketchbook article: The feeling of fear and horror in games and how this could work in Guild Wars 2. Please turn off your lights, put on your headphones and plug-in some dark ambient music before you are starting to read this article.
+
I like scary games. What I like most about them are those moments of shock. I think Amnesia and Minecraft achieved this quite well. Let's see if we can achieve those moments in an MMO like Guild Wars 2.
+
+
Part 1: Darkness
+
The point of darkness in games is to produce disorientation. The player doesn’t see the enemies coming, the player probably just hears them.
+
Let’s have a quick look at the torch mechanic in Amnesia. This is how it basically works:
+
Have torches placed on walls where players have to light them. Distribute a resource (let’s call it tinder) throughout the dungeon that allows the player to light up the torches. Tinder should be relatively rare and far apart. As players should get rewards for exploring the dungeon, have the tinder placed in hidden places, like behind a huge rock. Essentially, in Guild Wars 2 players should be encouraged to explore the dungeon to find more tinder, to light up the dungeon, to learn about the story or to get some other form of benefit.
+
What would players get from lighting the torches? Well, as a start they gain more vision around them. While the main benefit is an increased brightness, there could be further benefits from an increased light intensity. Monsters could get some form of combat advantage in dark places. Monsters could also actively approach lightning, like in Minecraft. So setting a torch on fire could actually have bad consequences.
+
+
Part 2: Defenselessnes
+
With the combat system of Guild Wars 2 consisting of skills, weapons and dodging, it's hard to generate a feeling of defenselessness. Players will always have a way to fight back, making dark and eerie areas not necessarily scary. So, we have to get rid of that system if we don't want the players to be able to fight back. How could this work?
+
Well, all player skills and weapons could be disabled as long as the players are in dark areas. That would require players to run away from monsters in the darkness and/or hide from them until the monsters give up chasing them (assuming they aren’t stationary). Player HP (or all stats in general) would have to be reduced in darkness, as a “tank” could probably walk past the monsters and just leave them behind, breaking the feeling of defenselessness.
+
But won't players know that a scary part starts once their skills and weapons disappear? Yes. But as long as it's their first time playing that part they still won't know what's going to happen. It was the same when I first played Amnesia. My friends told me that game is scary as hell. But that didn't spoil anything. I would even go as far to saying that knowing this beforehand made more immersed while playing the game.
+
Part 3: Replayability
+
Of course replayability is a problem in a scripted environment like the dungeons in Guild Wars 2. Therefore, those scary parts shouldn't be part of the main dungeon path. This is something for the explorable modes or for a dynamic event inside a dungeon.
+
Part 4: POV and Brightness
+
Another important aspect of creating a scary atmosphere is the point of view. If there's a way to see what's going on behind your character, without turning around, then surprise attacks won't happen. As we all know, Guild Wars 2 only comes with a third person view.
+
Lastly, it all depends on how dark the dungeon would actually be. Obviously you can’t present the player with a pitch black screen just displaying the UI. You have to have at least some kind of ambient lightning and give players the tools to light up an area. Oh, and from a technical point of view players could easily turn up the screen brightness to circumvent the in-game darkness.
+
With that being said, I don't think it's possible to create a fully immersive horror part inside a dungeon in Guild Wars 2. But I do think it's possible to create some challenging encounters that include dark and eerie areas in a dungeon.
+
Note: This is an extension of a post I made on GW2Guru a while ago. You can find the topic here (note: forum does not exist anymore). Also I'm neither a psychologist nor a torturer in any way. I just enjoy thinking about the design choices behind great games like Amnesia, Minecraft and, of course, Guild Wars 2.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
The past two years I have been working on Clippy in my free time, sometimes
+before and sometimes after my full-time programming job. To date I have
+contributed over 200 pull requests to Clippy, Rust and other Rust related
+projects. If you feel like my work is worth supporting, you now have the option
+to do so!
I've set the bar for rewards high. I only have limited time every day to work on
+open source and want to spend that time on the Rust things I'm passionate about.
+This makes sure I'm motivated for the tasks I choose to work on.
+
To keep my work sustainable, I make one commitment for now: I will
+post monthly reviews publicly here on the blog. These reviews will include:
+
+
A special shout-out to new sponsors (unless you don't want to be
+mentioned)
+
Review of what I've worked on during the past month
+
Goals for the next month
+
Reflections on my work, productivity and motivation for the past month
+
As I'm freeing up more time to work on open-source based on sponsorships,
+there will be more things coming in the future, for sure
If you have any questions or feedback, I'm happy to talk on Twitter or in
+private at dev@philhansch.net.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Counter Strike und viele andere Spiele sind auf Linux schon länger kein Problem mehr. In diesem Tutorial wird beschrieben, wie man Steam unter Ubuntu Linux installiert.
+
Zunächst wird Wine benötigt, um Windows Programme auszuführen:
+
Um die aktuelle Version von Wine zu installieren, werden der Reihe nach diese Befehle in das Terminal eingegeben:
Anschließend wird winetricks installiert um Steam schnell und problemlos zu installieren zu können:
+
wget http://www.kegel.com/wine/winetricks
+
+
Nun können wir Steam bequem über winetricks installieren:
+
sh winetricks steam
+
+
Steam sollte nach der Installation problemlos funktionieren.
+Für viele Steam Spiele, wie z.B. Counter Strike 1.6, werden übrigens die proprietären 3D Treiber der entsprechenden Hersteller benötigt.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
This is the stuff that happened 2012. Stuff that I discovered, learned and practiced. In a somewhat chronological order.
+
Software
+
RIFT Macro stuff
+
So, RIFT launched early in 2011. It's an MMORPG. I was hyped for it. I played for a couple months in 2011.
+I don't remember exactly why, but I came back to RIFT in early 2012. Something that really bothered me that time, was that English macros didn't work in the German client. So, I wrote a macro translator for RIFT. (In February I wrote about the macro system in RIFT and what's wrong with it.)
+
plyturon.net
+
After I stopped playing RIFT, I was quick to find another MMORPG to fill the time: Guild Wars 2. I was hyped for it. I played it for two months in 2012. During February and July I put a lot of time into plyturon.net. A blog dedicated to Guild Wars 2. You can find all the posts scattered in the archive. To add on to that, I also wrote a New Krytan translator that translates text to New Krytan.
+
Moved blog to GitHub and learning git
+
In July, I moved my blog to GitHub. I now also use git for my university assignments. Since my university provides free private git repositories, I don't keep my assignments on GitHub.
+
New languages
+
C, Java, Python and Lua.
+
Favorite books
+
Pirate Cinema, by Cory Doctorow
+The Flinch, by Julien Smith
+
Life
+
Running
+
I was still being treated for kidney stones earlier this year. As a result of this, I decided to start running. And I must stay that I really love running! Also, running made me aware of what I eat. It made me reconsider my daily consumption of unhealthy food.
+
Minimalism
+
Minimalism is a process, so there's no point in time where I really turned into a minimalist. But after I stopped playing Guild Wars 2, I really started to de-clutter my life. I got rid of a ton of clothes, digitized old photos and documents and cut down on media consumption.
+
I also minimized my digital life. I got rid of old Email accounts and moved to Gmail. I got rid of my Wordpress blogs and now use GitHub Pages to do my blogging. For note-taking I use simple markdown files. All my stuff is synced and available everywhere.
+
Doing all this stuff makes focusing on the important things a lot easier. Cleaning my room is as easy as it never was before. There are no distracting social networks that take up my time. It saves money. It makes moving easier. There is less stuff to worry about.
+
Less is more.
+
Plans from 2011
+
+
I want to get into C++ heavily. Meaning that I am able to start DirectX game programming at a small scale.
+
+
and
+
+
At the end of the year I want to have at least one finished DirectX 2D project.
+
+
failed because I didn't learn any C++ or DirectX.
+
+
I want to publish an add on for the game RIFT that I am going to support until the 31st December
+
+
Wrote a RIFT macro translator and supported it until May. Didn't play the game anymore at that point.
+
+
I want to have at least 52 blog posts at the end of the year.
+
+
Looking at the archive, I never wrote as much blog posts in a year before, but I didn't reach 52.
+
+
See you next year.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
It's been 18 days since I handed over the keys at my last job and over 30 days since I opened my editor, in which in writing this post right now.
+
I'm tired. I'm not sure where I'm going with this, but I'm tired.
+
+
I'm tired of selling myself on social media.
+
I'm tired of algorithmic feeds.
+
I'm tired of tech that makes my life more complicated.
+
I'm tired of tech that doesn't solve actual problems.
+
I'm tired of toxic productivity.
+
I'm tired of relaxing with the goal of more productivity.
+
I'm tired of doomscrolling.
+
I'm tired of overly complex tech.
+
I'm tired of working in tech and not working to limit its destructive potential.
+
I'm tired of buzzwords.
+
I'm tired of the current web.
+
I'm tired of constant stimulation.
+
+
So I've been spending more time outside. And apart from cycling I've also picked up running a few weeks ago. All this 'being tired' may sound a bit alarming, but in the past 30 days I've more happy than I've been in a long time. I haven't written any code, haven't kept up-to-date with tech news, haven't had to solve fake-problems. I need a break for the sake of taking a break.
+
This past Sunday I joined a group ride and rode 175km, following the complete Berlin wall trail:
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
HTMLProofer allows to test your HTML output. It can check alt tags of images, if links are working and a few more things.
+
I decided to give it a try on my website. Initially I was surprised at the amount of output and decided that it was too much to fix all at once. So first, I only had it check for broken links. It found about 30 of 200 outgoing links that were not working.
+
Most of them were part of of my Hackership series where I sometimes linked to local startups that apparently didn't make it until today. Unfortunately Link Rot is a thing.
+
Before I dealt with all the broken links, I started to integrate HTMLProofer into the test suite by adding a custom Rake task:
Using rake html_proofer it builds the site and runs HTMLProofer with the given options on the Jekyll output.
+You can check the Travis CI integration in script/ci.rb and .travis.yml.
+
If you run into SSL issues with HTMLProofer, you may have to installlibcurl4-openssl-dev on Travis.
+
The last thing I did, was to fix the links, as it was the least compelling part of the task. There are many reasons why a link may be broken and almost each cause can be handled differently.
+
+
+
A missing article may be caused by a new URL structure and forgotten redirects, so I looked around on these sites and tried to find the correct link if possible.
+
+
+
Broken domains are a lost cause most of the times, although some startups had renamed themselves or were bought up, so using the new domain makes sense there.
+
+
+
Domains may be unreachable only temporarily, so I don't want to remove the link and instead whitelist it.
+
+
+
This all took some time, but it paid off and now I can be certain that there's no broken links in any of the HTML on this website.
+
As mentioned in the beginning, HTMLProofer has a couple of more nice features, but I didn't get around to trying them, yet. In the next post I will probably have a look at the other features.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Even when it is just a static website like this one, it is always good to know that the most important things work.
+
I recently had problems when I was migrating this blog from Jekyll 2.5 to Jekyll 3.3. The permalinks were broken after the upgrade and I only noticed this after the change went live. Some basic tests could have easily prevented this.
+
After I fixed the broken permalinks I decided to add some basic Capybara tests, as I write them day-to-day for Ruby on Rails apps, too.
+
The setup
+
The setup is pretty basic for now with capybara, rack, rake and most importantly rack-jekyll:
Apart from the atom feed validation this is all straight Capybara using has_content and some basic Ruby for the time check. You can find all the tests here.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
As you may or may not know, I have a gaming section over at games.phansch.de (no longer maintained) where I keep stuff for various games.
+Most importantly, I wrote a macro translator that translates Rift macros written in English, to German and the other way around. Today, I want to talk about the pitfalls of Rift's macro and command system and possible solutions.
+
Introduction
+
When I started playing Rift, I would usually use the English client because I preferred the English forums over the German forums for its up-to-date guides and tutorials. Still, I was playing on a German server because I preferred to play with people who speak my native language (being lazy here!).
+
As mentioned, I was always more in touch with the international community than the German community, except for my guild. I was quite active on telarapedia (link dead unfortunately), for example. The downside of using the English client was, that communicating with my guild was sometimes difficult. So I eventually switched to the German client. And here the trouble begins.
+
I quickly noticed that all my macros stopped working. Apparently Trion localized parts of the macro syntax into German! So I started to figure out what was going on ~
+
What’s so wrong
+
The way Rift macros are localized into the additional supported languages (German and French) is kind of weird.
+
First of all, when using a localized client, the macro system expects the localized ability/item names, not the English ones, which is fine. Furthermore, certain key modifiers have been localized. For example, [ctrl] becomes [strg] in German. And most importantly all the emotes are localized.
+
And here the real trouble begins. Some parts aren't localized. Take the _/cas_t command. It works in the German client as well and there doesn't seem to be a translation for it. As well as the suppressmacrofailures command. However, there once was a German translation available for it but stopped working a few updates ago.
+
+
Then there are certain emotes in the German client that allow you to use both the English and the German command: /dance and /tanzen will both work in the German client! These are just a few examples I stumbled across when I was writing up the Commandlist over at Telarapedia during beta.
+
Possible solutions
+
The most obvious solution would be for Trion to streamline the command and macro system. Adding a documentation of what is possible and what isn't, is needed anyway. The /help command which just prints the list of commands is just not enough. However, that will require a lot of work. And the small macro system probably isn't worth the work. It works fine, as long as people don't change the client language.
+
For me, there's also the option to move to an English speaking server. And I might end up doing that soon.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
As you might have noticed, the blog has been silent for a few days weeks. It will stay that way for a little while, but do not fret! The content drought was mainly due to me being a lazy asuran engineer and also because of a boat load of news after the first press beta event that I just couldn't (or didn't want to) keep up with. Head past the jump to see what's up.
+
+
I like lists, so here are three things that will change for plyturon.net, put into a list.
+
+
+
No more weekly wrap-ups until maybe a month after a release. There is just too much news out there right now.
+
+
+
Less posts about centaurs Guild Wars 2. Therefore more personal stuff.
+
+
+
Website theme not appropriate for new content, will change that once new content is ready to be published.
+
+
+
Thanks for your patience.
+Plyturon
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Time flies. It's been almost over two weeks now since the first round of the beta application ended. Still, a lot has happened in the previous days. Here's the usual round-up, updated once every day at around 8am GMT!
+
Friday, March 09
+
GuildCast: Trinity Killer Site offline
+• The people from GuildCast take on the subject of the missing holy trinity in Guild Wars 2 and how it actually works in the game.
GuildMag: Jormag – Frigid Shadow of the North
+• Thalador from GuildMag has another post on Guild Wars 2 lore. This time he's talking about the elder dragon that resides in the northern reaches of the Shiverpeak Mountains - Jormag.
+
Thursday, March 08
+
GWI: Sea of Sorrows Release Date Update
+• Sea of Sorrorws, the third Guild Wars Novel, which was previously announced for August 28th has been pushed back according to GWI.
+
MMORPG.com: The Thief Preview (dead link)
+• David North continues with his series on the Guild Wars 2 professions. This time he played the thief profession and gives his thoughts on playstyle and animations.
+
Postmagazine: Audio for games
+• Jennifer Walder from the post magazine has an intereting article about audio in games. The first part is about Guild Wars 2, so be sure to check it out!
+
+
+
Wednesday, March 07
+
Yogscast: Norn Levelling Part 3 - A Long Skill Point
+• Simon and Lewis in their third and last part of their leveling footage. They continue to explore the wintery norn scenery and engage in a huge battle for a skill point.
+
TalkTyria: You Said There Was No Holy Trinity!
+• Damagedself from TalkTyria tried to explain the lack of the holy trinity to his friends. Check the article if you want to know what he learned. It's a great read!
Boons & Conditions Podcast #1: Mono Intro Site offline
+• The premiere episode of the BnC podcast. Their introductory podcast is all about the recent press beta event and the new information on attributes and traits.
+
MMORPG.com: The Warrior Preview (dead link)
+• Garrett Fuller from MMORPG.com published a nice overview on the Warrior profession and gives some advice on properly using the unique Warrior mechanics.
+
[Flameseeker Chronicles: How do trinities work?(#) (Dead link, because
+joystick.com shut down)
+• Elisabeth explains how trinities work in this week's Flameseeker Chronicles
Tyria Talk: SWTOR vs. GW2
+• In his newest episode of Tyria Talk, Richie is talking about the differences between levelling in SW:TOR and GuildWars2.
+
TapRepeatedly: Necromancer PvP
+• Lewis B from TapRepeatedly shows off his Necromancer PVP skills in this 40 minute video on Youtube.
+
+
Do you like the daily updates? Would you prefer a more detailed summary for each link? Did I miss an article or video? Let me know!
+Last edited on March 10, 2012 at 9:59 am GMT
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Week 11 is here! Pre-Purchase information, official forums and more. Here’s the usual round-up, updated once every day at around 8am GMT, now with twitter citations!
+
Thursday, March 15
+
ArenaNet: Blogpost: Building Community (note: link broken)
+• The most recent blog post from ArenaNet reveals that official forums are on the way. Martin Kerstein goes on by highlighting the challenges of modern community management.
+
MMORPG.com: Live Interview with Jon Peters on Traits and Professions Site offline
+• Bill Murphy from MMORPG.com collected user questions for this interview. If you are into building your character, this interview answers some interesting questions.
Tasha Darke: International Pricing Inequalities (website went dead)
+• A post on the pricing of the collectors edition. Tasha Darke did the math and explains why the game costs more in Europe than in the US.
+
Tyria Talk: Pre-Order Editions
+• This time Richie gives a quick overview over the different Pre-Purchase editions that are available.
+
KillTenRats: Demand More
+• Why everyone should help building community. It's a great read, go check it out.
+
+
+
Wednesday, March 14
+
GuildMag: Blog Carnival 3: Character Diversity
+• GuildMag's new Blog Carnival is out. If you are interested in writing articles about Guild Wars 2, you should definitely check it out.
+
Kill Ten Rats: Momentary Deluxe
+• A word on the pricing and content of both, the Collector's edition and the Digital Deluxe edition.
+
Yogscast: Charr Questing [Extra Footage]
+• Somehow Yogscast managed to release yet another video of their press beta footage. Showcasing the 5 to 15 area again.
+
Guild Wars Insider Podcast EP11: The Return
+• After a short break, the Guild Wars Insider Podcast with Seven, Gallo and FeralEngineer is back! Discussing guilds, attributes, jumping puzzles, meta events and more.
+
GWOnline: Traits: An Analysis Site offline
+• Alaris from GWOnline gives a quick overview over traits. This certainly comes in handy for players who are new to Guild Wars 2 or those who just started to lay out their builds.
+
ArenaNet: ArenaNet won't be on PAX East this year. Only Martin Kerstein and Jon Peters will be there.
+
+
As some of you have asked: We will not be at PAX East, we are busy working on the game. But Jon Peters and me will be on panels. ^MK
MMORPG.com: Everything to Everyone
+• (Link Dead) Everything to Everyone is the topic on David North's newest article on MMORPG.com. Jump in on the discussion about whether pleasing everyone is good, bad or even possible.
+
Tales of Tyria Podcast #22: Traits vs. Talents
+• As usual Tales of Tyria gives a quick recap of last week's news and then goes on to talk about game mechanics and gameplay. This week's roundtable topic is Build Wars 2 continued.
+
GuildMag: Viva la Difference!
+• Draxynnic from GuildMag posted his thoughts on different player types. Are you a killer, socializer, explorer or achiever?
+
+
Do you like the daily updates? Would you prefer a more detailed summary for each link? Did I miss an article or video? Let me know!
+Last updated on March 14, 2012 at 12:51 pm GMT
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
This week was packed with new videos from the recent press beta as well as new information about the beta invites. Without any further ado, here's what happened the past week.
On Tuesday Yogscast released another part of their class spotlight: The Elementalist. Oh, and Jon Peters is going into detail on Traits and Attributes on the ArenaNet Blog (link dead)! Furthermore, the guys from mmorpg.com have been pretty active this day. William Murphy from takes a look at the Engineer class (dead line) and David North talks about his overall Beta impressions (dead link). Wrapping up Tuesday, Elisabeth Cardy from Massively talks about PVE in her weekly Flameseker Chronicles.
+
Wednesday German fansite Wartower.de released a new TowerTalk with Jeff Grubb talking about the Asura. The introduction is German but the interview itself is held in English. David North from mmorpg.com also gave a preview of the Guardian (dead link) class.
On Friday Yogscast released the first part of their dungeon play-through. GuildCast also published their new episode: Peer Pressure where they are talking about WvW coordination, possible changes to the particle effects and the marketplace.
+
The weekend was far from quiet. GW2Gurus own Lewis B. goes into detail on the Traits system (forum does not exist anymore) that ArenaNet talked about on their blog on Tuesday. Yogscast released the second part of their dungeon play-through and the first part of their Norn levelling series. Over at borderhouseblog, Quinnae Moongazer has published the first part of an interview (note: link broken) with Angel Leigh McCoy, one of the writers at ArenaNet working on Guild Wars 2.
+
This weekly got a little short. There are probably a dozen interviews and a couple more videos I missed during my time in hospital. But I'm fine now and next weeks weekly will be even bigger!
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
While this post might seem very concise and short, it really took some time until I was happy with the current setup.
+This setup is relatively simple in retrospect, but it was hard to find any documentation on how to set everything up correctly.
+
This post is for people who have some basic experience with Ruby on Rails, Test Driven Development and also have a rough idea what Continuous Integration or Continuous Deployment are about.
+I assume you already know how to connect a GitHub repository with Travis. You will also need a Heroku account.
+
The goal is to automatically deploy successful builds from Travis to Heroku.
+
+Credit: A good part of this post was inspired by [this](http://stackoverflow.com/a/14788282/3298908) awesome Stack Overflow post.
+
+
The problems with secrets and open source
+
When working on an open source project, how do you keep stuff like the Rails Secret Token an actual secret? Where do you put API keys that are required in production?
+You don't want to keep passwords and otherwise secret stuff in your GitHub repository. However, at the same time it should be easy for contributors to get started quickly.
+
The joy of continuous deployments
+
Not so long ago, people used to upload their changed files via FTP to their servers. Luckily we don't have to do that anymore. Continuous deployments allow you to automate updating your production environment. Let's see how to do this with Travis CI and Heroku.
+
Local setup
+
Starting with the local setup, first we need to setup the secret_token.rb and the database.yml.
It is parsed by Ruby's ERB interpreter (yes, Ruby — not Rails). This allows us to read the environment variables we will set up in the next step.
+
We are using fancy yaml here in order to avoid repetition. Note the *, & and << in there. Using & creates something like a constant. In yaml, this is called an anchor. We can access the value of this anchor by using the *.
+Finally, the << inserts the content of that node.
+
+
Enter the dotenv gem
+
In order to set the environment variables on your local machine, I am using dotenv.
+Add this gem to the top of your gemfile and run bundle install afterwards.
Dotenv creates environment variables from the contents of .env files. This is what we need in order to manage different databases and users for our test and development environment.
+
The .env files look something like this:
+
# .env.development
+SECRET_TOKEN=generate this with "rake secret"
+DB_NAME=project_development
+DB_USER=username
+DB_PASSWORD=password
+
+
There are separate files for each environment. For the test environment, specify the test database:
+
# .env.test
+SECRET_TOKEN=generate this with "rake secret"
+DB_NAME=project_test
+DB_USER=username
+DB_PASSWORD=password
+
+
Don't forget to add these files to your .gitignore.
+
Travis CI Setup
+
The travis setup is very simple. First you will have to encrypt your secret data with travis encrypt.
And you're done! Now, whenever you push your changes to GitHub, the Travis build will be started. If the build was successful, the changes will automatically be pushed to Heroku.
+
Let me know if that worked for you as well.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Recently I thought about how I could make my life even more interesting. I have to admit that I feel quite unmotivated right now. But as I was browsing the internet, I stumbled across a speech from Matt Cutts, which you can see here.
+
Matt Cutts suggests trying something that you always wanted to do for thirty days. Luckily I have a huge list of ideas and goals floating around. However most of them deal with computer stuff. After watching Matts speech, I wanted to do something entirely different.
+
Stay tuned for more stuff this February.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
The Rift macro translator has been updated for Rift 1.7.
+
Rift 1.7 comes with quite a few new abilities as well as new items. All these are included in the new update for the translator. Head past the break to read the full patchnotes.
+
Patch Notes Macro Translator for Rift 1.7
+
+
Items, skills and abilities are now on par with changes made in Rift 1.7
+
Added macro modifier: [notactive] and respective translations
+
Removed the German translation of suppressmacrofailures as the translation wasn't working properly
+
Abilities of the Elementalist and Void Knight are now properly translated
+
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
As of today, the domain plyturon.net is free to grab. I removed the old landing page and the tools as well.
+I also removed everything filed under games.phansch.de. That also includes the RIFT macro translator.
+
phansch.de is now pointing directly to this blog.
+Furthermore, I'm planning on canceling my current webhosting contract and just keeping my domain at namecheap.com.
+
As for the blog theme, I hope to have an overhaul ready until the end of the year.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
This is what I have been using for a couple weeks now and it's so amazing, I have to share it with you.
+Up until a few months ago, I was using the standard command line of my OS. Now, there's nothing wrong with it, but I always like to work on improving my tools.
+
For one, switching tabs in the terminal was inconvenient. Then the different tab setup every day made it hard to get used to a specific pattern.
+This is no longer a problem with tmux and tmuxinator.
+
Tmux is short for terminal multiplexer which is a fancy way for saying that it allows you to switch between multiple programs in one terminal. Tmux can do much more, but I am going to focus on window management for this post.
+
Tmuxinator allows you to easily script tmux sessions. I am using tmuxinator to setup different window layouts for each of my projects.
+
Tmux windows and panes
+
The idea of tmux is that you have one single terminal window with multiple tabs inside. In each tab you have the ability to split up your window into multiple panes.
+To start a simple tmux session just run tmux.
+
You can open new tabs with ctrl + b + c and close them with ctrl + b + x.
+
To switch between tabs use ctrl + b + tab-number.
+
Open new panes with ctrl + b + % / ".
+
To switch between panes use ctrl + b + o
+
Tmux configuration
+
Tmux configuration is saved in ~/.tmux.conf. I recommend adding the following lines to your configuration since the defaults aren't really nice.
+
# Renumber windows sequentially after closing any of them.
+# Otherwise if you close the second tab of three, you end
+# up with tabs numbered 1 and 3.
+set -g renumber-windows on
+
+# set window and pane index to 1 (0 by default)
+set-option -g base-index 1
+setw -g pane-base-index 1
+
+# Allows for faster key repetition
+set -s escape-time 0
+
+
Also, here is a great cheatsheet for the most important tmux shortcuts.
+
Save time with tmuxinator
+
Tmux comes with an extensive command line interface, but it can be a little bit difficult to figure out. Tmuxinator makes use of the commands that tmux comes with, but it extracts all the complexity into a single yaml file:
With this file in place, you can now run mux railsproject and everything will be started automatically.
+
This is liberating in so many ways. In the morning, you don't have to remember what tools you need for the project you're working on. Throughout the day you can rely on keyboard shortcuts always bringing you back to the same program.
+And then you quickly get used to the patterns with your project specific settings. I found that I can stay focused way better this way. The tab for logs, server, console and editor are always the same.
+
I encourage you to give tmux and tmuxinator a try. If you happen to run into problems, feel free to leave a comment and I will see what I can do.
+
You can find my whole .tmux.conf here. Additionally some of my tmuxinator configuration files are located here.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Hello, and welcome to plyturon.net! Enjoy your stay.
+
My name is Plyturon and this blog is my contribution to the Guild Wars 2 community.
+I am trying to provide community spotlights, Guild Wars 2 design/mechanics discussions and weekly wrap-ups of Guild Wars 2 news.
+
At a later date you will probably see guides and useful web applications for Guild Wars 2.
+
If you have suggestions or feedback, drop me a mail at feedback@plyturon.net or simply use the comment box below.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
I have been reading Apprenticeship Patterns by Dave Hoover and I found a lot of the patterns really helpful. The first thing I put into practice, was to read books and maintain a reading list.
+
However, this post is not about that. It's about a different pattern: Expose Your Ignorance
+
+
Tomorrow I need to look stupider and feel better about it. This staying quiet and trying to guess what's going on isn't working so well.
+Jake Scruggs in "My Apprenticeship at Object Mentor"
+
+
+
The idea about exposing your ignorance is to put away your pride. To make a list of things you don't know.
Creating my list has helped me realize where I need to dig deeper. For example, notice the lack of items on my Ruby and Rails list. You could say that I know a lot about Rails because the list is very short. But in reality, I haven't really dug deep into Rails and it shows in the lack of specific questions.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
The mission of blogging is to empower all of us to go directly to each other with our expertise. So if you know something as well as anyone else, or you learn something or know something that should be shared, then you should share it on your blog.
+
+
+
Blogging needs your help. There's cobwebs in the blogosphere. I want to dust everything off, and start linking our stuff together, and get some developer energy flowing, and let's do some new stuff.
+
+
I have a couple ideas for upcoming blog posts, but if you want me to write about something specific, feel free to add an issue here or just send me a tweet.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
Dank MSDNAA bin ich nun im Besitz von Windows 7 Professional.
+
Nun, vor kurzem habe ich mir ein NAS von Iomega zugelegt. Leider ist bisher noch kein offizieller Treiber für Windows 7 x64 erschienen.
+
Also blieb mir nur die manuelle Methode:
+
Computer -> Netzlaufwerk verbinden
+
+
Nach einem Neustart kam jedoch folgende Nachricht:
+"Netzlaufwerk konnte nicht wiederhergestellt werden"
+
Das Problem ist warscheinlich, dass die Netzwerkdienste zu spät gestartet werden. Mit Windows XP hat Microsoft versucht, den Systemstart zu beschleunigen und dabei die Netzwerkdienste zu niedrig priorisiert.
+
Es gibt aber zwei Lösungen die für mich funktioniert haben.
+
Anmeldung herauszögern
+
Der Gedanke hierbei ist, dass die Netzwerkdienste vor der Anmeldung starten können. Man wartet 15 bis 20 Sekunden bevor man das Nutzerpasswort eingibt und sich anmeldet.
+
Wem das Warten nicht gefällt, den kann ich beruhigen.
+
Batchdatei zum Einbinden der Netzlaufwerke im Autostart
+
Der Autostart ist so ziemlich der letzte Teil beim Start von Windows. Die Netzwerkdienste sind vor dem Autostart verfügbar.
+
Mit einer kleinen Batchdatei lassen sich sich die Netzwerkordner einbinden.
+
net use W: \\nas-server\public passwort /user:kontoname /Persistent:NO
+net use X: \\nas-server\backups /Persistent:NO
+net use Y: \\nas-server\itunes /Persistent:NO
+net use Z: \\nas-server\web /Persistent:NO
+
+
Bei der ersten Ressource werden die Logininformationen angegeben.
+Außerdem wird für jedes Netzlaufwerk Persistent auf "NO" gesetzt. Das heißt, das die Netzlaufwerke nur für eine Sitzung existieren. So sparen wir uns das manuelle Trennen der Netzlaufwerke.
+
Nun muss die Batchdatei noch in den Autostart-Ordner gespeichert werden.
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
+
+
+
+
+
+
+
+
+
diff --git a/posts/year-2032-the-dark-age-of-gaming-is-history/index.html b/posts/year-2032-the-dark-age-of-gaming-is-history/index.html
new file mode 100644
index 00000000..a4636a08
--- /dev/null
+++ b/posts/year-2032-the-dark-age-of-gaming-is-history/index.html
@@ -0,0 +1,105 @@
+
+
+
+
+
+ Year 2032: The dark age of gaming is history
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Just in case you didn't know: It's the year 2032.
+Can you imagine, by now there are 20 year old MMO players that have never heard of grind, the gear treadmill, dungeon timers, monthly fees or the holy trinity.
+So I was wondering how do we tell them about the dark age of gaming? Do we want to? They would probably laugh at us for having played such terrible designed games!
+Actually, how do we define the dark age of gaming?
+
I don't know. It wasn't just one single terrible MMO. Things like grinding were present in almost every MMO. And for a reason: More money to devs by increasing the time a player has to spend in order to be rewarded.
+People paid money for the service and then they wanted to get something out of their money. And so they played. Hours and hours of the same mundane tasks. Kill ten rats, gather 5 iron. Kill hundred rats, craft 50 gold ingots, kill this boss, acquire that gear, kill the next boss, ...
+
And the worst thing? They were not alone. MMOs being MMOs at that time, they had competitors! Every monster presented a competition as to who got rewarded for the quest. Every nook and cranny was designed in a way that players don't do what they actually like to do: Playing together with friends. They paid hoping to play together with their friends, to make new friends even. But how do you even make new friends in such a hostile environment? How do you make friends when you have to compete over every single entity in the game?
+
+
+
Let's make a cut here and talk about immersion quest texts. Do you remember the last time you read an actual quest text and what it was about? No? Me neither! But do you remember the last time you completed that insanely difficult encounter, holding up against that elder dragon? I don't know about you but, well, I certainly remember!
+
In case you never played an old-school MMO before, I'll quickly summarize quest texts. You go to an NPC and left-click him to start a conversation. A wall of text pops up. It probably contains a lot of interesting lore about the area you are in, but you don't care. All you really need to know is at the bottom of the window: What you need to kill or gather; where it can be found and the amount you have to kill or gather. That's all you need to know to complete the quest. The quest text? Well, except for immersive types, no one read them back in the days.
+
The next thing about NPCs and quest texts is that they didn't reflect reality. A quest text might have said: "Go kill 10 boars for me, they constantly break into my house and destroy the interior." - Here's where immersion breaks. They are not actually breaking into the house. You are presented with a plain field with grazing boars on it. There was a huge mismatch between story and reality.
+
By now you can probably imagine how boring most MMOs were at that time. You approach an NPC and proceed by killing 10 rats that were waiting for you to kill them. Enemies were not even running away from you but faced you head on! That's how stupid MMOs were back then.
+
+
+
There lies another problem in the way quests are designed. Some of those NPC are damn greedy! If you were to ask an NPC how many ores he received from players at the end of the day, his answer would be a very huge amount. Every player did the same thing as the player before them. Nothing changed for the next player. If the NPC grateful accepts medicine you crafted to help his daughter, he would just stay there instead of running away and helping his daughter.
+
The game doesn't react on my actions - It doesn't care that I'm there. It doesn't care about anyone else either. NPCs, monsters and the environment can in some way compared to theme park attractions. That's where the term theme park MMO came from. Everything was set up so that an unlimited amount of players can experience a very limited story.
+
As you can see, quite a lot has changed for MMO games. They went from being a theme park to an engaging experience. We see carrots and sticks being used less frequently. Intrinsic motivation finally wins over extrinsic motivation. More tools for the players means more intrinsic motivation. Give players a sandbox and they will play for as long as they are having fun.
+
These days you are free. So have fun and explore the (MMO) sandbox!
+
+
+
+
+
+
+
Philipp Hansch
+
Full Stack Developer
+
+ Philipp is a full stack developer currently heavily involved with Rust. Most notably he's a member of the Clippy team where he helps with bugfixing and documentation. You can follow him on Mastodon and find him on GitHub as well as Patreon.
+
+
+
+
+
+
+
+
diff --git a/slides/learning_journals/.gitignore b/slides/learning_journals/.gitignore
new file mode 100644
index 00000000..9ffdbc73
--- /dev/null
+++ b/slides/learning_journals/.gitignore
@@ -0,0 +1,6 @@
+.DS_Store
+.svn
+log/*.log
+tmp/**
+node_modules/
+.sass-cache
\ No newline at end of file
diff --git a/slides/learning_journals/Gruntfile.js b/slides/learning_journals/Gruntfile.js
new file mode 100644
index 00000000..892469a4
--- /dev/null
+++ b/slides/learning_journals/Gruntfile.js
@@ -0,0 +1,132 @@
+/* global module:false */
+module.exports = function(grunt) {
+
+ // Project configuration
+ grunt.initConfig({
+ pkg: grunt.file.readJSON('package.json'),
+ meta: {
+ banner:
+ '/*!\n' +
+ ' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' +
+ ' * http://lab.hakim.se/reveal-js\n' +
+ ' * MIT licensed\n' +
+ ' *\n' +
+ ' * Copyright (C) 2013 Hakim El Hattab, http://hakim.se\n' +
+ ' */'
+ },
+
+ // Tests will be added soon
+ qunit: {
+ files: [ 'test/**/*.html' ]
+ },
+
+ uglify: {
+ options: {
+ banner: '<%= meta.banner %>\n'
+ },
+ build: {
+ src: 'js/reveal.js',
+ dest: 'js/reveal.min.js'
+ }
+ },
+
+ cssmin: {
+ compress: {
+ files: {
+ 'css/reveal.min.css': [ 'css/reveal.css' ]
+ }
+ }
+ },
+
+ sass: {
+ main: {
+ files: {
+ 'css/theme/default.css': 'css/theme/source/default.scss',
+ 'css/theme/beige.css': 'css/theme/source/beige.scss',
+ 'css/theme/night.css': 'css/theme/source/night.scss',
+ 'css/theme/serif.css': 'css/theme/source/serif.scss',
+ 'css/theme/simple.css': 'css/theme/source/simple.scss',
+ 'css/theme/sky.css': 'css/theme/source/sky.scss',
+ 'css/theme/moon.css': 'css/theme/source/moon.scss',
+ 'css/theme/solarized.css': 'css/theme/source/solarized.scss'
+ }
+ }
+ },
+
+ jshint: {
+ options: {
+ curly: false,
+ eqeqeq: true,
+ immed: true,
+ latedef: true,
+ newcap: true,
+ noarg: true,
+ sub: true,
+ undef: true,
+ eqnull: true,
+ browser: true,
+ expr: true,
+ globals: {
+ head: false,
+ module: false,
+ console: false
+ }
+ },
+ files: [ 'Gruntfile.js', 'js/reveal.js' ]
+ },
+
+ connect: {
+ server: {
+ options: {
+ port: 8000,
+ base: '.'
+ }
+ }
+ },
+
+ zip: {
+ 'reveal-js-presentation.zip': [
+ 'index.html',
+ 'css/**',
+ 'js/**',
+ 'lib/**',
+ 'images/**',
+ 'plugin/**'
+ ]
+ },
+
+ watch: {
+ main: {
+ files: [ 'Gruntfile.js', 'js/reveal.js', 'css/reveal.css' ],
+ tasks: 'default'
+ },
+ theme: {
+ files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
+ tasks: 'themes'
+ }
+ }
+
+ });
+
+ // Dependencies
+ grunt.loadNpmTasks( 'grunt-contrib-jshint' );
+ grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
+ grunt.loadNpmTasks( 'grunt-contrib-uglify' );
+ grunt.loadNpmTasks( 'grunt-contrib-watch' );
+ grunt.loadNpmTasks( 'grunt-contrib-sass' );
+ grunt.loadNpmTasks( 'grunt-contrib-connect' );
+ grunt.loadNpmTasks( 'grunt-zip' );
+
+ // Default task
+ grunt.registerTask( 'default', [ 'jshint', 'cssmin', 'uglify' ] );
+
+ // Theme task
+ grunt.registerTask( 'themes', [ 'sass' ] );
+
+ // Package presentation to archive
+ grunt.registerTask( 'package', [ 'default', 'zip' ] );
+
+ // Serve presentation locally
+ grunt.registerTask( 'serve', [ 'connect', 'watch' ] );
+
+};
diff --git a/slides/learning_journals/LICENSE b/slides/learning_journals/LICENSE
new file mode 100644
index 00000000..e1e8bf7a
--- /dev/null
+++ b/slides/learning_journals/LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) 2013 Hakim El Hattab, http://hakim.se
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/slides/learning_journals/README.md b/slides/learning_journals/README.md
new file mode 100644
index 00000000..c452cf91
--- /dev/null
+++ b/slides/learning_journals/README.md
@@ -0,0 +1,798 @@
+# reveal.js [](https://travis-ci.org/hakimel/reveal.js)
+
+A framework for easily creating beautiful presentations using HTML. [Check out the live demo](http://lab.hakim.se/reveal-js/).
+
+reveal.js comes with a broad range of features including [nested slides](https://github.com/hakimel/reveal.js#markup), [markdown contents](https://github.com/hakimel/reveal.js#markdown), [PDF export](https://github.com/hakimel/reveal.js#pdf-export), [speaker notes](https://github.com/hakimel/reveal.js#speaker-notes) and a [JavaScript API](https://github.com/hakimel/reveal.js#api). It's best viewed in a browser with support for CSS 3D transforms but [fallbacks](https://github.com/hakimel/reveal.js/wiki/Browser-Support) are available to make sure your presentation can still be viewed elsewhere.
+
+
+#### More reading:
+- [Installation](#installation): Step-by-step instructions for getting reveal.js running on your computer.
+- [Changelog](https://github.com/hakimel/reveal.js/releases): Up-to-date version history.
+- [Examples](https://github.com/hakimel/reveal.js/wiki/Example-Presentations): Presentations created with reveal.js, add your own!
+- [Browser Support](https://github.com/hakimel/reveal.js/wiki/Browser-Support): Explanation of browser support and fallbacks.
+
+## Slides
+
+Presentations are written using HTML or markdown but there's also an online editor for those of you who prefer a graphical interface. Give it a try at [http://slid.es](http://slid.es).
+
+
+## Instructions
+
+### Markup
+
+Markup hierarchy needs to be ``
`` where the ```` represents one slide and can be repeated indefinitely. If you place multiple ````'s inside of another ```` they will be shown as vertical slides. The first of the vertical slides is the "root" of the others (at the top), and it will be included in the horizontal sequence. For example:
+
+```html
+
+```
+
+### Markdown
+
+It's possible to write your slides using Markdown. To enable Markdown, add the ```data-markdown``` attribute to your `````` elements and wrap the contents in a ```
+
+```
+
+#### External Markdown
+
+You can write your content as a separate file and have reveal.js load it at runtime. Note the separator arguments which determine how slides are delimited in the external file. The ```data-charset``` attribute is optional and specifies which charset to use when loading the external file.
+
+```html
+
+```
+
+### Configuration
+
+At the end of your page you need to initialize reveal by running the following code. Note that all config values are optional and will default as specified below.
+
+```js
+Reveal.initialize({
+
+ // Display controls in the bottom right corner
+ controls: true,
+
+ // Display a presentation progress bar
+ progress: true,
+
+ // Push each slide change to the browser history
+ history: false,
+
+ // Enable keyboard shortcuts for navigation
+ keyboard: true,
+
+ // Enable touch events for navigation
+ touch: true,
+
+ // Enable the slide overview mode
+ overview: true,
+
+ // Vertical centering of slides
+ center: true,
+
+ // Loop the presentation
+ loop: false,
+
+ // Change the presentation direction to be RTL
+ rtl: false,
+
+ // Number of milliseconds between automatically proceeding to the
+ // next slide, disabled when set to 0, this value can be overwritten
+ // by using a data-autoslide attribute on your slides
+ autoSlide: 0,
+
+ // Enable slide navigation via mouse wheel
+ mouseWheel: false,
+
+ // Transition style
+ transition: 'default', // default/cube/page/concave/zoom/linear/fade/none
+
+ // Transition speed
+ transitionSpeed: 'default', // default/fast/slow
+
+ // Transition style for full page backgrounds
+ backgroundTransition: 'default' // default/linear/none
+
+});
+```
+
+Note that the new default vertical centering option will break compatibility with slides that were using transitions with backgrounds (`cube` and `page`). To restore the previous behavior, set `center` to `false`.
+
+
+The configuration can be updated after initialization using the ```configure``` method:
+
+```js
+// Turn autoSlide off
+Reveal.configure({ autoSlide: 0 });
+
+// Start auto-sliding every 5s
+Reveal.configure({ autoSlide: 5000 });
+```
+
+
+### Dependencies
+
+Reveal.js doesn't _rely_ on any third party scripts to work but a few optional libraries are included by default. These libraries are loaded as dependencies in the order they appear, for example:
+
+```js
+Reveal.initialize({
+ dependencies: [
+ // Cross-browser shim that fully implements classList - https://github.com/eligrey/classList.js/
+ { src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
+
+ // Interpret Markdown in elements
+ { src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+ { src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+
+ // Syntax highlight for elements
+ { src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
+
+ // Zoom in and out with Alt+click
+ { src: 'plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
+
+ // Speaker notes
+ { src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } },
+
+ // Remote control your reveal.js presentation using a touch device
+ { src: 'plugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } },
+
+ // MathJax
+ { src: 'plugin/math/math.js', async: true }
+ ]
+});
+```
+
+You can add your own extensions using the same syntax. The following properties are available for each dependency object:
+- **src**: Path to the script to load
+- **async**: [optional] Flags if the script should load after reveal.js has started, defaults to false
+- **callback**: [optional] Function to execute when the script has loaded
+- **condition**: [optional] Function which must return true for the script to be loaded
+
+
+### Presentation Size
+
+All presentations have a normal size, that is the resolution at which they are authored. The framework will automatically scale presentations uniformly based on this size to ensure that everything fits on any given display or viewport.
+
+See below for a list of configuration options related to sizing, including default values:
+
+```js
+Reveal.initialize({
+
+ ...
+
+ // The "normal" size of the presentation, aspect ratio will be preserved
+ // when the presentation is scaled to fit different resolutions. Can be
+ // specified using percentage units.
+ width: 960,
+ height: 700,
+
+ // Factor of the display size that should remain empty around the content
+ margin: 0.1,
+
+ // Bounds for smallest/largest possible scale to apply to content
+ minScale: 0.2,
+ maxScale: 1.0
+
+});
+```
+
+### Keyboard Bindings
+
+If you're unhappy with any of the default keyboard bindings you can override them using the ```keyboard``` config option:
+
+```js
+Reveal.configure({
+ keyboard: {
+ 13: 'next', // go to the next slide when the ENTER key is pressed
+ 27: function() {}, // do something custom when ESC is pressed
+ 32: null // don't do anything when SPACE is pressed (i.e. disable a reveal.js default binding)
+ }
+});
+```
+
+
+### API
+
+The ``Reveal`` class provides a JavaScript API for controlling navigation and reading state:
+
+```js
+// Navigation
+Reveal.slide( indexh, indexv, indexf );
+Reveal.left();
+Reveal.right();
+Reveal.up();
+Reveal.down();
+Reveal.prev();
+Reveal.next();
+Reveal.prevFragment();
+Reveal.nextFragment();
+Reveal.toggleOverview();
+Reveal.togglePause();
+
+// Retrieves the previous and current slide elements
+Reveal.getPreviousSlide();
+Reveal.getCurrentSlide();
+
+Reveal.getIndices(); // { h: 0, v: 0 } }
+
+// State checks
+Reveal.isFirstSlide();
+Reveal.isLastSlide();
+Reveal.isOverview();
+Reveal.isPaused();
+```
+
+### Ready Event
+
+The 'ready' event is fired when reveal.js has loaded all (synchronous) dependencies and is ready to start navigating.
+
+```js
+Reveal.addEventListener( 'ready', function( event ) {
+ // event.currentSlide, event.indexh, event.indexv
+} );
+```
+
+### Slide Changed Event
+
+An 'slidechanged' event is fired each time the slide is changed (regardless of state). The event object holds the index values of the current slide as well as a reference to the previous and current slide HTML nodes.
+
+Some libraries, like MathJax (see [#226](https://github.com/hakimel/reveal.js/issues/226#issuecomment-10261609)), get confused by the transforms and display states of slides. Often times, this can be fixed by calling their update or render function from this callback.
+
+```js
+Reveal.addEventListener( 'slidechanged', function( event ) {
+ // event.previousSlide, event.currentSlide, event.indexh, event.indexv
+} );
+```
+
+
+### States
+
+If you set ``data-state="somestate"`` on a slide ````, "somestate" will be applied as a class on the document element when that slide is opened. This allows you to apply broad style changes to the page based on the active slide.
+
+Furthermore you can also listen to these changes in state via JavaScript:
+
+```js
+Reveal.addEventListener( 'somestate', function() {
+ // TODO: Sprinkle magic
+}, false );
+```
+
+### Slide Backgrounds
+
+Slides are contained within a limited portion of the screen by default to allow them to fit any display and scale uniformly. You can apply full page background colors or images by applying a ```data-background``` attribute to your `````` elements. Below are a few examples.
+
+```html
+
+
All CSS color formats are supported, like rgba() or hsl().
+
+
+
This slide will have a full-size background image.
+
+
+
This background image will be sized to 100px and repeated.
+
+```
+
+Backgrounds transition using a fade animation by default. This can be changed to a linear sliding transition by passing ```backgroundTransition: 'slide'``` to the ```Reveal.initialize()``` call. Alternatively you can set ```data-background-transition``` on any section with a background to override that specific transition.
+
+
+### Slide Transitions
+The global presentation transition is set using the ```transition``` config value. You can override the global transition for a specific slide by using the ```data-transition``` attribute:
+
+```html
+
+
This slide will override the presentation transition and zoom!
+
+
+
+
Choose from three transition speeds: default, fast or slow!