Game Dev Party Jam #10: Llamazord

Two weekends ago was the 10th Game Jam of the Game Dev Party association, where I was once again both participating and helping with the organization. And once again I proposed a game idea and I was lucky enough that people liked it and voted for it! So I gathered a team of 6 awesome people, 3 developers and 3 designers, plus myself as a part-time coder part-time manager, and we made a game.

Introducing Llamazord

This time around each participant received, prior to the event, a list of 3 game titles generated with the Video Game Name generator, and the game you would pitch had to bear one of those titles. Mine were: "Create Your Own Llama", "my little acid reloaded" and "Barbie's Military Force". I went with the first one, which is not a great title (we changed it to "Llamazord") but it inspired me. Here's what I pitched.

Year 2053. Underground llama fights are the big thing, people are into it to the point of creating mech enhancements for their llamas. You are a llama trainer and your goal is to have your llama win fights against other llamas. To that goal, you will enhance it with mechanical tools: canons, helmets, lasers... Make your Llama a Llamazord and crush your enemies!

llamazord-mini.png

The game is essential a Connect Three: just like a Connect Four but you only need 3 discs to create a line. The twist is that each player has access to the same 3 different types of discs, and connecting a line gives you access to upgrades of the type of the discs. For example, connect 3 "sun" discs and you will gain a "sun" upgrade (a solar canon for attack or a sun helmet for defense). The game has rounds, each round allowing each player to play 3 times. Once a round finishes, llamas will automatically attack each other using their upgrades, and then a new round begins. The player who's llama stays alive wins the game!

There are two pieces of strategy in that game: the grid where you play of course, because each play could be used by your opponent, so you have to be careful not to give them too much of an advantage. But the upgrades you choose matter as well. At the moment, if you have an attack upgrade of a given family, the defense upgrade of that same family will diminish the damage you will deal. So if your opponent gains a "sun" upgrade, you're be better making a "sun" defense for yourself. Ideally I'd like that to be changed to a rock-paper-scissor system, to encourage variety.

On the technical side, this is a Web game, meaning it is made of open Web technologies (primarily JavaScript, with a bit of HTML and CSS). We use the Phaser.io engine, a tool that Rémi and myself have already used a few times in the past, so we can build on that experience to make better games faster. Luckily we didn't have to use any physics this time, that was my main source of concern and bugs with Phaser the last times I used it. The game can be played on any platform that has a Web browser, though as usual I recommend Firefox (disclaimer: I work for Mozilla), but I know that some of us used Chrome during development. Also, the game is available on github (adngdb/llamazord) if you're interested in seeing the source.

Of course, this a Jam game, made in less than 48 hours (plus some debugging and improvements in the last 2 weeks), so it's far from being super awesome and fun and deep. But I'm quite pleased with what we did, it's one of my best Jam games so far, and definitely the best that I pitched. You might notice that the game is not ideal for a computer screen, which is because I think it is more of a mobile game. It should work great on your smartphone! :) I also think it has some potential to become an actual fun game, if we were to add more randomness (some discs falling at various intervals for example) and more strategic complexity (the rock-paper-scissor system, more upgrade types... ). The game also lacks a bunch of feedback for interactions and automatic things. There's no sound for combat. I could see a big flashy text saying that a combat is ongoing. I could do with some more indications that the current player changed. Basically it's missing all the small details that make a game really great.

Anyway, you probably want to play the game by now, so here it is:

Play Llamazord

llamazord-logo.png

Big thanks to Bemba (coder), Caro (design), Cyrielle (design), Elsa (design), Rémi (coder) and Yendhi (coder) who worked on this game with me. Great job everyone!

Feedback on the Jam

We called this Jam the "Random Title Jam", because of the random titles theme. I'm super happy that we finally did it, it's an idea that I had been proposing for some years now. And I think it went super well! We had a lot of people presenting ideas (about 20 out of 55 participants), they were very different, and the quality of the games at the end of the Jam was high.

I haven't been involved as much as I used to in organizing this round, and it's great to see that the association is live and kicking. I'm glad to see new faces joining the Game Dev Party, I'm super excited that we are doing conferences again, and I am always amazed to see the crazy ideas that some people propose in our internal mailing list (Game Dev Festival anyone? ).

If you participated in that Jam and have any feedback, positive or negative, please please let us know, by any means you like. We make events for people, we are all volunteers, and we do it because we love it. What you think about what we do is extremely valuable!

logo-game-dev-party-small.png

...

Expériences Politiques 2016

J'en ai parlé ici en décembre dernier, et les choses ont bien avancé en deux mois. Heureusement, puisque les Expériences Politiques auront lieu du 7 au 12 mars 2016, dans une semaine ! J'espère que vous êtes prêts pour cette semaine qui s'annonce riche. Jugez vous-mêmes : le programme est accessible en ligne.

Transitions démocratiques

Nous entamerons la semaine avec Hervé Chaygneaud-Dupuy, qui nous parlera de la transition démocratique en cours dans nos sociétés, et qui ouvrera les voies des possibles. Mardi nous accueillerons David Guez qui nous parlera de LaPrimaire.org, une primaire citoyenne qui veut présenter un candidat non-issu des partis aux prochaines élections présidentielles. Mercredi, Baptiste Mylondo nous parlera du revenu d'existence et de l'impact qu'il pourrait avoir sur la relation des citoyens à la chose politique. La démocratie participative sera en débat jeudi soir, avec Loïc Blondiaux, enseignant-chercheur en sciences politiques, Serge Patural, membre du conseil de quartier Mutualité-Préfecture-Moncey à Lyon et Tristan Rechid (sous-réserve), membre du conseil des sages de Saillans. Etienne Chouard et Jacques Testart viendront clore cette semaine de conférences en débattant autour du tirage au sort et des assemblées citoyennes (attention, cette soirée est exceptionnellement sous réservation).

Expériences

Après avoir débattu de tout cela, il faudra faire du concret, de l'action. L'après-midi du samedi 12 mars y sera consacrée ! Avec Philippe Cazeneuve, venez jouer la démocratie dans un atelier théâtral. Les Gentils Virus animeront un atelier constituant, durant lequel vous serez invités à réfléchir à l'organisation du pouvoir communal. Enfin le Mouvement Français pour un Revenu de Base vous proposera de créer votre propose revenu de base.

Tous les détails sur cette semaine se trouvent sur le site des Expériences Politiques : experiences-politiques.fr

J'espère vous retrouver nombreuses et nombreux à la Maison Pour Tous !

Expériences Politiques
du 7 au 12 mars 2016
à la Maison Pour Tous - Salle des Rancy
249, rue Vendôme, Lyon 3e
experiences-politiques.fr

...

How to include HTML in your React app with webpack

One of the few things that I find unpleasant with React and JSX is that it's not great for writing long static HTML content. Up to now I never encountered that problem, but I heard some colleagues complain about it and knew that it was indeed a negative point.

Until today, when I wrote some documentation in a small side project, and I took the opportunity to try and solve that problem. It was actually quite simple when working with webpack, since it allows you to bundle some HTML content and require it as a string from your JavaScript components. Once you have your HTML loaded in a string, there is a very simple way to turn it into React DOM elements: dangerouslySetInnerHTML. That function should never be used when you cannot trust the content you include, but that is obviously not the case here.

To bundle some HTML content with webpack, install the html-loader module: npm install --save-dev html-loader. To use that loader automatically for HTML files, here's the configuration you can add to your webpack.config.js:

{
  modules: {
    loaders: [
      { test: /\.html$/, loader: 'html' }
    ]
  }
}

Then simply require your HTML file from any JS file, with var htmlContent = require('path/to/html/file.html'); or import htmlContent from 'path/to/html/file.html'); if you are using ES6. Let's say we are using babel, this is what our file could look like:

import htmlContent from 'path/to/file.html';

import React from 'react';


const MyComponent = React.createClass({
    render() {
        return (
            <div dangerouslySetInnerHTML={ {__html: htmlContent} } />
        );
    }
});

export default MyComponent;

So, the good thing about this is that you can write your long HTML content in separate files, without some of the hassles of JSX (like having to use className instead of class). It will keep your components small and with a clean separation of concerns. The downside is that you cannot use anything other than HTML in that separate file, so no React components for example.

...

Expérimentons avec la politique

Je suis en ce moment en train de coorganiser, avec la Maison Pour Tous, une semaine citoyenne sur le thème de la politique (au sens noble). Notre but est de parler de notre système politique, d'en montrer certaines limites et de proposer des solutions. Pour cela, nous organiserons pendant une semaine des conférences, des débats, des ateliers, des projections autour de la démocratie et des nombreuses formes qu'on lui attribue aujourd'hui.

Cleisthenes.jpg

J'ai la conviction que la reprise de notre pouvoir politique sera un levier incroyable pour résoudre nombre de problèmes auxquels nous faisons face — pauvreté, climat, logement, économie, écologie… Nous avons aujourd'hui la possibilité de sortir des systèmes élitistes qui ont constitué la quasi-intégralité de l'histoire de la civilisation humaine. On nous parle de « crise de la représentativité », je crois en fait que nous arrivons au bout d'un système qui ne convient plus à notre société.

Il nous faut donc inventer ! Quel pourrait être le système politique de demain ? Quels outils, anciens ou nouveaux, pourrions-nous utiliser pour nous réapproprier le processus de décision ? Tirage au sort, consensus, assemblées citoyennes, participation, représentation-écart, les idées sont nombreuses, les expérimentations le sont encore trop peu.

Réinventer la démocratie

Voilà le cadre de cette semaine politique. Nous voulons apporter de la lumière sur ce qui est proposé aujourd'hui, sur ce qui est possible, sur l'importance à nos yeux de ces questions. Et puis nous voulons essayer, expérimenter, tester, voir ce qui marche ou ne marche pas, montrer qu'il est possible de sortir du schéma pyramidal que nous connaissons depuis si longtemps.

Concrètement, l'événement se déroulera du 7 au 12 mars 2016 à la Maison Pour Tous - Salle des Rancy. Chaque soir du lundi au vendredi, nous proposerons des conférences, débats et projections. Le samedi sera une journée « hands on », qui fera la part belle aux ateliers et autres expériences participatives. Voilà les grandes lignes, nous travaillons encore au programme définitif. Si vous avez des suggestions, des gens qui vous paraissent pertinents sur le sujet, des films à voir, ou des idées d'ateliers, n'hésitez pas à m'en faire part !

De même, nous ne sommes que trois à organiser cet événement, avec chacun un emploi à côté, et il y a fort à faire. Notamment, je pense que nous apprécierions un peu d'aide pour communiquer sur l'événement (il y a un site Web à construire, des affiches et flyers à créer, etc. ), ainsi que pour contacter la presse locale et les réseaux pertinents. Si ce projet vous passionne et que vous voulez absolument vous impliquer dans l'organisation avec nous, venez m'en parler !

...

Sécuriser son utilisation d'Internet

J'ai donné aujourd'hui à la Maison Pour Tous, dans le cadre des Expériences Numériques, une conférence intitulée « Sécuriser son utilisation d'Internet ». J'y ai parlé de ressources, notamment d'add-ons pour Firefox, avec une flopée de liens. Voici donc un résumé de cette conférence, et surtout l'intégralité des liens que j'y ai partagé. Et avant cela, voici le lien vers les slides de la présentation.

Tout d'abord, j'ai évidemment recommandé l'utilisation du navigateur Firefox. Pour le télécharger, direction le site de Mozilla. Voici même un lien direct pour le télécharger. Une fois téléchargé, il faut l'installer, procédure qui varie en fonction de votre système, je laisse donc à chacun la responsabilité de le faire.

Vous avez donc maintenant votre Firefox, et vous vous apprêtez à naviguer sur le World Wide Web. Voici une liste d'extensions que je vous conseille d'installer afin d'être plus en sécurité.

HTTPS Everywhere

Cette extension permet de forcer l'utilisation du protocole sécurisé HTTPS sur tous les sites qui le supportent. Cela vous assure qu'une majorité de vos connections seront sécurisées, chiffrées, et avec un interlocuteur certifié.

Pour l'installer : https://addons.mozilla.org/en-US/firefox/addon/https-everywhere/

Web Of Trust

Le « Web de Confiance » est basé sur une évaluation communautaire des sites que vous visitez, et va vous avertir lorsque vous visitez un site qui a mauvaise réputation, en vous en expliquant les raisons. Un excellent moyen de ne pas se faire piéger par des sites crapuleux.

Pour l'installer : https://addons.mozilla.org/en-US/firefox/addon/wot-safe-browsing-tool/

Lightbeam

Pour se rendre compte de l'étendue du tracking dont nous sommes la cible, rien de mieux qu'un beau schéma. Lightbeam affiche un graphe représentant les sites sur lesquels vous êtes allés, volontairement, ainsi que tous les autres services avec lesquels votre machine a communiqué, sans que vous n'ayez rien demandé. Ça vous permettra de constater que certains acteurs savent énormément de choses sur votre vie en ligne.

Pour l'installer : https://addons.mozilla.org/en-US/firefox/addon/lightbeam/

uBlock Origin

Une fois que vous avez constaté qu'on vous tracke en ligne, vous voudrez vous en protéger. Voici donc uBlock, extension qui, non content de bloquer les publicités (le Web sans pub, c'est bien mieux ! ), va également bloquer toutes ces requêtes inopportunes. C'est une extension très légère, et très puissante : vous pouvez le configurer pour bloquer tout type de contenu.

Pour l'installer : https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/

Autres ressources

J'ajoute également ici quelques articles et autres liens qui m'ont aidés dans la création de la conférence, et qui présentent de bonnes options pour approfondir le sujet.

...

15e Expériences Numériques, le 10 octobre 2015 à Lyon

Ce samedi 10 octobre 2015, l'Espace Public Numérique de la Maison Pour Tous - Salle des Rancy organise la 15e édition de ses Expériences Numériques. Au programme : une journée entière dédiée à la découverte du numérique, avec des conférences, des ateliers et des démonstrations. L'ensemble est à destination à la fois du grand public, avec des conférences de vulgarisation, et des initiés, avec quelques sujets un peu plus avancés. Si vous avez des questions ou des préoccupations autour des outils du numériques, c'est l'endroit idéal pour en parler avec des gens qui s'y connaissent !

Une fois de plus, je donnerai une conférence à destination du grand public pendant ces Expériences Numériques. Cette fois, je m'attaquerai à expliquer comment naviguer en sécurité sur le Web, via des exemples concrets et en proposant des solutions simples. Voici le résumé de cette conférence :

Sécuriser son utilisation d'Internet

Quand on n’y connait rien, c’est difficile de naviguer en sécurité sur le Web. Quels sont les dangers les plus courants ? Comment savoir si l’on est en sécurité ou pas ? Protéger ses comptes, créer de bons mots de passe, détecter les arnaques, identifier une connexion sécurisée... Au travers d’exemples et de conseils, nous vous aiderons à sécuriser vos données et à protéger votre vie sur le net.

Ma conférence aura lieu de 11h à 12h. Vous pouvez retrouver le reste du planning sur le site de l'EPN des Rancy, ou sur la plaquette de l'événement.

J'espère vous y voir nombreuses et nombreux !

...

ensy — Entity System Reloaded

tma-splash.png

During the last Game Dev Party Jam in Lyon, I pitched a game idea with the intention of building that game with Web technologies and my Entity System library. I had been waiting for an occasion to use that lib in a "real" game, and knew that would be the perfect moment: the 8th Jam happened over 3 days (when it usually is only 2) and was thus ideal for trying out risky things.

It ended up being a mildly good idea, because we spent a bit too much time writing some physics logic instead of working on the game itself. However, the Entity System engine worked like a charm: only one issue was found, and it was not even a blocker! I suppose that proves, once again, the value of unit tests.

So, in the lights of this successful use of the Entity System library, I released its first official version: 1.0.0! It is now accessible from npm and bower, with the following commands:

npm install ensy

bower install ensy

ensy stands for entity system, as you might have guessed. I realized while looking for a free name in the npm and bower repos that there where a lot of Entity System implementations out there, but most of them are either using a very different approach (something like Crafty.js does) or not maintained. I'd like to get some traction on ensy, but I know that it will hardly be used by anyone other than me. If you would like to use it but think it lacks something or does something incorrectly in your opinion, please contact me and we can see what could be done. I am happy to maintain ensy and I plan on using it for most of my jam games going forward. (I'll probably end up writing some kind of basic 2d game engine, with generic rendering and physics, to get started more quickly in jams. )

What is this Entity thing anyway?

I wrote about my Entity System library a while ago, but it has changed a lot in the meantime. This version has been entirely rewritten and is nothing like the previous one. The key concepts are still the same, but their implementations changed wildly. Let me give you a quick tour of the new concepts, and of what you can do with it.

Entity

An entity is a mere identifier, like a string or a number. It has to be unique in the system, of course. Entities represent the various objects of your game, but they do not hold any data nor logic. Their sole purpose is to serve as an evolving collection of components. That's why they are simple identifiers: the system is able to associate an entity to a list of components.

Component

Components contain the data of your game. They only exist in the context of an entity, and do no kind of logic: they are simple containers for simple data. Here's a rule that helps understanding what you can or cannot put in a component: components have to be serializable. They shouldn't contain objects either, because if you want to put an object in a component, that almost always means you actually want to create another component.

Processor

Processors are responsible for the logic of your game. They access lists of components and apply operations on them. For example, a simple Display processor would go over all the Sprite components and show them on the screen. A Physics processor would take all Falling components and apply some gravity to them. Processors should always be independent of each others, communicating data through components only.

There is documentation available on readthedocs, and if you want to understand the concepts and implementation better, I recommend you read this excellent post by Adam Martin: Entity Systems are the future of MMOs.

What does it look like?

Here is a very basic example of how to use this library:

// Create a manager for your game.
var EntityManager = require('ensy');
manager = new EntityManager();

// Create some components.
var Falling = {
    name: 'Falling',
    state: {
        x: 0,
        y: 0
    }
};
manager.addComponent(Falling.name, Falling);

// Create some processors.
var PhysicsProcessor = function (manager) {
    this.manager = manager;
};

PhysicsProcessor.prototype.update = function (dt) {
    var fallings = this.manager.getComponentsData('Falling');

    // Make them fall.
    for (var f in fallings) {
        var falling = fallings[f];
        falling.y -= 5;
    }
};

manager.addProcessor(new PhysicsProcessor(manager));

// And get your main loop starting.
function mainLoop() {
    var dt = 10; // Compute elapsed time since last frame here.
    manager.update(dt);

    requestAnimationFrame(mainLoop);
}
requestAnimationFrame(mainLoop);

There are more complex examples available: a Concentration game, quite simple, and the game I worked on during the last GDP Jam, Total Madness Arena. This last one is more substantial, though I learned a lot while working on it and would very probably code it a bit differently if I were to do it again. (Notably, I would try to keep only one manager through all scenes, instead of having one per scene. That means the Entity System manager needs a way to remove a bunch of entities at once, which is not a feature yet. )

I hope you like ensy! Let me know if you have questions, or if you are using it.

...

Rethinking Socorro's Web App

rewrite-cycle.jpg
Credits @lxt

I have been thinking a lot about what we could do better with Socorro's webapp in the last months (and even more, the first discussions I had about this with phrawzty date from Spring last year). Recently, in a meeting with Lonnen (my manager), I said "this is what I would do if I were to rebuild Socorro's webapp from scratch today". In this post I want to write down what I said and elaborate it, in the hope that it will serve as a starting point for upcoming discussions with my colleagues.

State of the Art

First, let's take a look at the current state of the webapp. According to our analytics, there are 5 parts of the app that are heavily consulted, and a bunch of other less used pages. The core features of Socorro's front-end are:

Those we know people are looking at a lot. Then there are other pages, like Crashes per User, Top Changers, Explosive Crashes, GC Crashes and so on that are used from "a lot less" to "almost never". And finally there's the public API, on which we don't have much analytics, but which we know is being used for many different things (for example: Spectateur, crash-stats-api-magic, Are we shutting down yet?, Such Comments).

The next important thing to take into account is that our users oftentimes ask us for some specific dataset or report. Those are useful at a point in time for a few people, but will soon become useless to anyone. We used to try and build such reports into the webapp (and I suppose the ones from above that are not used anymore fall into that category), but that costs us time to build and time to maintain. And that also means that the report will have to be built by someone from the Socorro team who has time for it, it will go through review and testing, and by the time it hits our production site it might not be so useful anymore. We have all been working on trying to reduce that "time to production", which resulted in the public API and Super Search. And I'm quite sure we can do even better.

Building Reports

bob-the-builder.jpg

Every report is, at its core, a query of one or several API endpoints, some logic applied to the data from the API, and a view generated from that data. Some reports require very specific data, asking for dedicated API endpoints, but most of them could be done using either Super Search alone or some combination of it with other API endpoints. So maybe we could facilitate the creation of such reports?

Let us put aside the authentication and ACL features, the API, the admin panel, and a few very specific features of the web app, to focus on the user-facing features. Those can be simply considered as a collection of reports: they all call one or several models, have a controller that does some logic, and then are displayed via a Django template. I think what we want to give our users is a way to easily build their own reports. I would like them to be able to answer their needs as fast as possible, without depending on the Socorro team.

The basic brick of a fresh web app would thus be a report builder. It would be split in 3 parts:

  • the model controls the data that should be fetched from the API;
  • the controller gets that data and performs logic on it, transforming it to fit the needs of the user;
  • and the view will take the transformed data and turn it into something pretty, like a table or a graph.

Each report could be saved, bookmarked, shared with others, forked, modified, and so on. Spectateur is a prototype of such a report builder.

We developers of Socorro would use that report system to build the core features of the app (top crashers, home page graphs, etc. ), maybe with some privileges. And then users will be able to build reports for their own use or to share with teammates. We know that users have different needs depending on what they are working on (someone working on FirefoxOS will not look at the same reports than someone working on Thunderbird), so this would be one step towards allowing them to customize their Socorro.

One Dashboard to Rule Them All

So users can build their own reports. Now what if we pushed customization even further? Each report has a view part, and that's what would be of interest to people most of the time. Maybe we could make it easy for a user to quickly see the main reports that are of interest to them? My second proposal would be to build a dashboard system, which would show the views of various reports on a single page.

A dashboard is a collection of reports. It is possible to remove or add new reports to a dashboard, and to move them around. A user can also create several dashboards: for example, one for Firefox Nightly, one for Thunderbird, one for an ongoing investigation... Dashboards only show the view part of a report, with links to inspect it further or modify it.

dashboard-example.png

An example of what a dashboard could look like.

Socorro As A Platform

The overall idea of this new Socorro is to make it a platform where people can find what they want very quickly, personalize their tool, and build whatever feature they need that does not exist yet. I would like it to be a better tool for our users, to help them be even more efficient crash killers.

I can see several advantages to such a platform:

  • time to create new reports is shorter;
  • people can collaborate on reports;
  • users can tweak existing reports to better fit their needs;
  • people can customize the entire app to be focused on what they want;
  • when you give data to people, they build things that you did not even dream about. I expect that will happen on Socorro, and people will come up with incredibly useful reports.

I Need Feedback

feedback-everywhere.jpg

Concretely, the plan would be to build a brand new app along the existing one. The goal won't be to replace it right away, but instead to build the tools that would then be used to replace what we currently have. We would keep both web apps side by side for a time, continuing to fix bugs in the Django app, but investing all development time in the new app. And we would slowly push users towards the new one, probably by removing features from the Django app once the equivalent is ready.

I would love to discuss this with anyone interested. The upcoming all-hands meeting in Whistler is probably going to be the perfect occasion to have a beer and share opinions, but other options would be fine (email, IRC... ). Let me know what you think!

...

[Snippet] Django Shell: making a user a superuser

I can never remember this snippet and I found myself duckduckgoing for it a few times, so I wanted to write it down somewhere where I can easily find it (and maybe it will help people looking for it, since I can never reliably find it in search engines).

To start Django's shell:

./manage.py shell

And to make a user a superuser:

from django.contrib.auth.models import User
user = User.objects.get(email='me@example.org')
user.is_superuser = True
user.save()
...

28 mai 2015 - Les jeux de la GDP Jam #8 à la MPT

Chers lecteurs,

nth-team.jpg L'association Game Dev Party organise, ce jeudi 28 mai, une soirée démo des jeux qui ont été produits pendant notre dernière Jam, la 8e. Durant le week-end du 8 mai, et pour la première fois sur trois jours, les développeurs, graphistes, sound designers, game designers et autres créateurs ont créé de toutes pièces une dizaine de jeux. Le thème que nous leur avons imposé était « Nouvelle Humanité », et au vu des pitchs et des résultats à la fin du week-end, la créativité a une fois de plus été au rendez-vous. Nous publierons bientôt sur notre blog les vidéos des présentations qui ont eu lieu en clôture de la Jam, ainsi que des versions jouables des productions.

Mais en attendant, nous souhaitons vous donner une occasion de venir mettre les mains sur ces jeux, en présence des créateurs qui pourront vous expliquer leur œuvre, leurs intentions initiales, et vous parler de tous les déboires qu'ils ont rencontré pendant la Jam (oui parce qu'une Jam ne se passe jamais sans déboire ! :) ). J'y serai bien entendu, en tant qu'organisateur mais également participant, et mes collègues de Jam et moi vous présenterons notre jeu « Total Madness Arena » (je ferai un billet détaillé sur le jeu dans un futur proche). Rejoignez-nous donc jeudi 28 à partir de 19h pour jouer, discuter, échanger, et boire un verre avec nous au bar de la Maison Pour Tous !

Soirée démo Jam #8
jeudi 28 mai 2015 à partir de 19h
à la Maison Pour Tous - Salle des Rancy
249, rue Vendôme, Lyon 3e

...

Spectateur, custom reports for crash-stats

The users of Socorro at Mozilla, the Stability team, have very specific needs that vary over time. They need specific reports for the data we have, new aggregations or views with some special set of parameters. What we developers of Socorro used to do was to build those reports for them. It's a long process that usually requires adding something to our database's schema, adding a middleware endpoint and creating a new page in our webapp. All those steps take a long time, and sometimes we understand the needs incorrectly, so it takes even longer. Not the best way to invest our time.

Nowadays, we have Super Search, a flexible interface to our data, that allows users to do a lot of those specific things they need. As it is highly configurable, it's easy to keep the pace of new additions to the crash reports and to evolve the capabilities of this tool. Couple that with our public API and we can say that our users have pretty good tools to solve most of their problems. If Super Search's UI is not good enough, they can write a script that they run locally, hitting our API, and they can do pretty much anything we can do.

But that still has problems. Local scripts are not ideal: it's inconvenient to share them or to expose their results, it's hard to work on them collaboratively, it requires working on some rendering and querying the API where one could just focus on processing the data, and it doesn't integrate with our Web site. I think we can do better. And to demonstrate that, I built a prototype. Introducing...

Spectateur

spectateur.jpg Spectateur is a service that takes care of querying the API and rendering the data for you. All you need to do is work on the data, make it what you want it to be, and share your custom report with the rest of the world. It uses a language commonly known, JavaScript, so that most people (at least at Mozilla) can understand and hack what you have done. It lets you easily save your report and gives you a URL to bookmark and to share. And that's about it, because it's just a prototype, but it's still pretty cool, isn't it?

To explain it a little more: Spectateur contains three parts. The Model lets you choose what data you want. It uses Super Search and gives you about the same capabilities that Socorro's UI has. Once you have set your filters and chosen the aggregations you need, we move to the Controller. That's a simple JavaScript editor (using Ace) and you can type almost anything in there. Just keep the function transform, the callback and the last lines that set the interface, otherwise it won't work at all. There are also some limitations for security: the code is executed in a Web Worker in an iframe, so you have no access to the main page's scope. Network requests are blocked, among other things. I'm using a wonderful library called jailed, if you want to know more, please read its documentation.

Once you are done writing your controller, and you have exposed your data, you can click the Run button to create the View. It will fetch the data, run your processor on that data and then render the results following the rules you have exposed. The data can currently be displayed as a table (using jsGrid) or as a chart (using Chart.js). For details, please read the documentation of Spectateur (there's a link at the top). When you are satisfied with your custom report, click the button Save. That will save the Model and the Controller and give you a URL (by updating the URL bar). Come back to that URL to reload your report. Note that if you make a change to your report and click Save again, a new URL will be generated, the previous report won't be overwritten.

As an example, here is a report that shows, for our B2G product, a graph of the top versions, a chart of the top signatures and a list of crash reports, all of that based on data from the last 7 days: https://spectateur.mozilla.io/#58a036ec-c5bf-469a-9b23-d0431b67f436

I hope this tool will be useful to our users. As usual, if you have comments, feedback, criticisms, if you feel this is a waste of time and we should not invest any more time in it, or on the contrary you think this is what you needed this whole time, please please please let us know!

...

Le cadeau payant de Mediapart

Pierre-Alain est abonné à Mediapart. Je ne le suis pas. Ce matin, voulant que je lise un article publié sur leur site et réservé aux abonnés, il m'a fait « cadeau » de cet article. J'ai donc reçu, dans ma boite email, un lien me permettant d'accéder à l'intégralité de l'article. C'est plutôt bien de la part de Mediapart d'avoir mis en place une telle fonctionnalité, et c'est très gentil à Pierre-Alain de me partager cet article. Sauf que, évidemment, il y a un « mais ». Dans l'email que j'ai reçu, juste au dessus du lien, se trouve le texte suivant :

Veuillez cliquer sur son titre ci-dessous pour accéder à l'article qui vous est offert. Ce faisant, vous autorisez Mediapart a vous tenir informé de ses publications. Votre adresse e-mail ne sera pas divulguée.

Ai-je bien compris ? Je suis donc sommé de payer, avec une donnée personnelle (mon adresse email, et l'autorisation de m'y contacter), pour accéder à ce qui est présenté comme un cadeau. Il est bien précisé qu'il m'est « offert ». En échange de mon consentement à me faire spammer. Donc il n'est pas si offert que ça. Certes je n'ai pas eu à donner d'argent pour consulter l'article en question, mais j'ai du donner de mes données personnelles.

Je suis un peu choqué par cette pratique, et d'autant plus de la part de Mediapart pour qui j'ai la plus grande estime. Nous sommes de plus en plus conscients de la valeur des données personnelles. On voit ce que peuvent en faire les gouvernements, leurs agences ou les mastodontes. Les actions récentes de Framasoft avec sa campagne « Dégooglisons l'Internet », Tristan Nitot qui écrit un livre sur le sujet, ma prochaine conférence à Expériences Numériques et les très nombreuses initiatives que j'oublie sont autant de pas vers une société numérique plus respectueuse de ses citoyens. Je trouve dommage que Mediapart fasse ce faux-pas. Et je trouve dommage d'avoir eu l'impression que mon ami a vendu mon adresse email pour m'offrir un cadeau, alors qu'il paye en monnaie sonnante et trébuchante le droit d'utiliser cette fonctionnalité.

...

Expériences Numériques le 31 janvier 2015 à Lyon

Bonjour bonjour !

L'Espace Public Numérique de la Maison Pour Tous organise ce samedi 31 janvier 2015 les 14e Expériences Numériques. Il s'agit d'une journée entière autour du numérique, avec des conférences, des ateliers, et des associations présentes toute la journée pour répondre à vos questions et vous présenter divers outils ou solutions. Cette édition portera tout particulièrement autour des logiciels libres, avec 9 ateliers dont des « Install Party » toute la journée : amenez votre ordinateur, et on vous aidera à installer dessus tous les logiciels libres que vous voulez. Vous pourrez également y découvrir les jeux créés pendant la dernière édition de la Game Dev Party en novembre dernier.

Par ailleurs, j'y donnerai à nouveau une conférence que j'ai donnée aux JDLL 2014, intitulée « Internet, le Web et les dangers qui nous guettent ». Rejoignez-moi de 15h à 16h pour découvrir ce que sont l'Internet et le Web, comment ils fonctionnent, ce qu'en font aujourd'hui les gros acteurs tels que Google et Facebook et en quoi cela vous concerne et vous expose au danger. Le but n'étant pas d'être défaitiste, je terminerai ma conférence en présentant des solutions à ces problèmes, dont certaines sont accessibles à tous de manière très simple. Cette conférence est destinée au grand public, aucune connaissance technique n'est nécessaire. Comme j'ai conscience que le public de ce blog est plutôt « geek », je vous invite à partager cette information autour de vous, par exemple à ceux qui sont inquiets des révélations de Snowden mais n'en comprennent pas bien les enjeux et les solutions.

Plan général de la conférence :

  • Internet et le Web, c'est quoi ?
  • Fonctionnement simplifié d'un réseau
  • Centralisation et décentralisation
  • Les stratégies des gros acteurs et leurs dangers
    • espionnage, abus des données privées, monopole...
  • Quelques solutions pour s'en sortir
    • auto-hébergement, associatif, Framasoft, Cozy...
...

Socorro: the Super Search Fields guide

Socorro has a master list of fields, called the Super Search Fields, that controls several parts of the application: Super Search and its derivatives (Signature report, Your crash reports... ), available columns in report/list/, and exposed fields in the public API. Fields contained in that list are known to the application, and have a set of attributes that define the behavior of the app regarding each of those fields. An explanation of those attributes can be found in our documentation.

In this guide, I will show you how to use the administration tool we built to manage that list.

You need to be a superuser to be able to use this administration tool.

Understanding the effects of this list

It is important to fully understand the effects of adding, removing or editing a field in this Super Search Fields tool.

A field needs to have a unique Name, and a unique combination of Namespace and Name in database. Those are the only mandatory values for a field. Thus, if a field does not define any other attribute and keeps their default values, it won't have any impact in the application -- it will merely be "known", that's all.

Now, here are the important attributes and their effects:

  • Is exposed - if this value is checked, the field will be accessible in Super Search as a filter.
  • Is returned - if this value is checked, the field will be accessible in Super Search as a facet / aggregation. It will also be available as a column in Super Search and report/list/, and it will be returned in the public API.
  • Permissions needed - permissions listed in this attribute will be required for a user to be able to use or see this field.
  • Storage mapping - this value will be used when creating the mapping to use in Elasticsearch. It changes the way the field is stored. You can use this value to define some special rules for a field, for example if it needs a specific analyzer. This is a sensitive attribute, if you don't know what to do with it, leave it empty and Elasticsearch will guess what the best mapping is for that field.

It is, as always, a rule of thumb to apply changes to the dev/staging environments before doing so in production. And to my Mozilla colleagues: this is mandatory! Please always apply any change to stage first, verify it works as you want (using Super Search for example), then apply it to production and verify there.

Getting there

To get to the Super Search Fields admin tool, you first need to be logged in as a superuser. Once that's done, you will see a link to the administration in the bottom-right corner of the page.

Fig 1 - Admin link

Clicking that link will get you to the admin home page, where you will find a link to the Super Search Fields page.

Fig 2 - Admin home page

The Super Search Fields page lists all the currently known fields with their attributes.

Fig 3 - Super Search Fields page

Adding a new field

On the Super Search Fields page, click the Create a new field link in the top-right corner. That leads you to a form.

Fig 4 - New field button

Fill all the inputs with the values you need. Note that Name is a unique identifier to this field, but also the name that will be displayed in Super Search. It doesn't have to be the same as Name in database. The current convention is to use the database name but in lower case and with underscores. So for example if your field is named DOMIPCEnabled in the database, we would make the Name something like dom_ipc_enabled.

Use the documentation about our attributes to understand how to fill that form.

Fig 5 - Example data for the new field form

Clicking the Create button might take some time, especially if you filled the Storage mapping attribute. If you did, in the back-end the application will perform a few things to very that this change does not break Elasticsearch indexing. If you get redirected to the Super Search Fields page, that means the operation was successful. Otherwise, an error will be displayed and you will need to press the Back button of your browser and fix the form data.

Note that cache is refreshed whenever you make a change to the list, so you can verify your changes right away by looking at the list.

Editing a field

Find the field you want to edit in the Super Search Fields list, and click the edit icon to the right of that field's row. That will lead you to a form much like the New field one, but prefilled with the current attributes' values of that field. Make the appropriate changes you need, and press the Update button. What applies to the New field form does apply here as well (mapping checks, cache refreshing, etc. ).

Fig 6 - The edit icon

Deleting a field

Find the field you want to edit in the Super Search Fields list, and click the delete icon to the right of that field's row. You will be prompted to confirm your intention. If you are sure about what you're doing, then confirm and you will be done.

Fig 7 - The delete icon

The missing fields tool

We have a tool that looks at all the fields known by Elasticsearch (meaning that Elasticsearch has received at least one document containing that field) and all the fields known in the Super Search Fields, and shows a diff of those. It is a good way to see if you did not forget some key fields that you could use in the app.

To access that list, click the See the list of missing fields link just above the Super Search Fields list.

Fig 8 - The missing fields link

The list of missing fields provides a direct link to create the field for each row. It will take you to the New field form with some prefilled values.

Fig 9 - Missing fields page

Conclusion

I think I have covered it all. If not, let me know and I'll adjust this guide. Same goes if you think some things are unclear or poorly explained.

If you find bugs in this Super Search Fields tool, please use Bugzilla to report them. And remember, Socorro is free / "libre" software, so you can also go ahead and fix the bugs yourself! :-)

...

Play Kawaii Killer, a horrible cuteness genocide game

Kawaii Killer, the first game of Tabemasu Games, is now out and playable on Android and iOS! Why am I writing about this game? Because it is the first commercial game of my friend Aurélien! He started as an independent game developer last year, and worked hard on making this Jam game a top-quality mobile game.

So what is this game about? You are a trapper going through his forest, and you want to kill as many animals as you can, as fast as possible. Each animal requires a different gesture to be killed, and it obviously gets more and more complex. If you are a sensitive person, or a friend of the animals, maybe you won't enjoy that game much, because those poor little things die in horrible manners… A lot of blood will be shed under your fingers! Be ready for a gory journey!

Maybe you have seen Kawaii Killer before: it was one of the best games created during the Game Dev Party Jam #3, back in 2012. Aurélien worked with a team of 5 people to build this very fun and enjoyable game. You can still find it here. Apart from the fact that the game has been rebuilt from scratch, much has been added since the Game Jam: new stages, new enemies, difficulty levels, a story, achievements and badges… If you have a smartphone and like killing cute animals, you should definitely try this game out. You can buy it from Google Play, the Apple App Store, or you can get it DRM-free from the Humble Store.

Not convinced yet? Well, take a look at the release trailer:

As a side note, I must say I am very happy that Aurélien, Fred and Vincent, the 3 guys who made this game, met during Jams organized by the Game Dev Party association. It's a proof that those events are useful to our community and help the video game industry in Lyon. Heck, Aurélien was an amateur game creator and now he has released a commercial game, isn't that awesome? So, let's keep rocking with the GDP, and let's keep building awesome video games in Lyon!

...

About Socorro

I have been working on Socorro for about 3 years now. It was about time that I started talking about it on this blog! With this first post, I am inaugurating 2 new tags, socorro and mozilla. I'm also going to add a language tag to my posts, so each new post will either be en or fr. This way, you can choose more accurately what kind of content you want to read from this blog. The previous links on the tags lead to the filtered Atom feeds, and I will add the mozilla feed to the Planet.

So, what is Socorro?

  1. a planet in the Star Wars universe
  2. a city in Brazil
  3. an island in Mexico
  4. a server to process breakpad crash reports

All of those are true, but as you guessed (I hope! ) we will only consider the last option. So basically, Socorro is a software that collects, processes and stores crash reports generated by breakpad. We use breakpad in our desktop software such as Firefox, Firefox for Android, Thunderbird and FirefoxOS. We then have a Web interface that shows information about the stability our those software, and we call it crash-stats. As usual with Mozilla, most of the information on this site is public, the only exceptions being sensitive data like email addresses, URLs, etc.

Most of Socorro's code base in written in Python. The back-end is raw Python based on a tool called configman, developed by my colleagues Lars and Peter, that handles the configuration and is used as a dependency injection system. It allows Socorro to be very modular, and to add or remove components easily without changing any code. We use 3 different databases:

  1. HBase is the primary storage and is there for data consistency (it contains all the data we receive and process and must never lose data)
  2. PostgreSQL is used as the main source of data for the UI (it contains all the processed data and has a lot of materialized views with various computed information)
  3. elasticsearch is used as the secondary source of data for the UI, mainly for everything related to search. This is what I have been mainly working on.

The Web app is based on Playdoh, Mozilla's customized django framework. We have more and more javascript, mostly using jQuery, but it's a bit chaotic at the moment.

Interested in contributing?

If Socorro sounds like a good project to you and you would like to participate, we would be very happy to hear about you! There are a few places where you can start:

You can also join us in Mozilla's IRC server, channel #breakpad. There are a good variety of bugs to fix on Socorro, from pure front-end work to complex back-end Python problems. And if Socorro is not your thing but you still want to help Mozilla fulfill its mission, you can take a look at whatcanidoformozilla.org!

...

Play Michel in Hell, our Ludum Dare 29 game!

Last year, my friend Aurélien invited me to participate with him and a few other friends in the Ludum Dare, for the 26th edition. We made a Flash game, which is probably why I didn't write about it (how could I face my Mozilla colleagues after making a Flash game? ). It's called Sniff and it's about a drug dealer that needs to deliver its magical powder to his customers. As those customers are in a night club, you will need to use the music to find your way through the town. Beware of the cops that want to catch you, and beware of not using the different powers the drug gives you...

Play Sniff

This blog post is not about Sniff, though. After having only organized, and not participated, in our last Game Dev Party Jam, I felt a bit frustrated and really wanted to work on a game. So I called a few friends and invited them to join me for the Ludum Dare 29 weekend. 4 of them answered, and we had a team! Caroline joined us as our graphics person, Pierre-Etienne would take care of all music things, while Maxime and Rémi would join me on the programming of the game.

michell.jpg

The tale of Michell

The theme of this edition of the Ludum Dare was "Beneath the surface". I was not much inspired by it, but I dislike multi-words themes in general. After about 3 hours of brain-storming, we decided to go for a tower defense game, with a bit of Hack 'n Slash in it. The idea was for the player to defend against troops sent from hell: Michell, the hero, peed on Lucifer's flowers, and that didn't make him happy at all. So Lucifer decided to send all his troops to kill him! But Michell is no mere hero, he is a magician that can grow strong plants to help him.

So, there you are on a small platform. Demons will be appearing around that platform in waves, and they will attack you. You can either fight them directly by clicking on them if you can reach them, but that is dangerous. Your other solution is to use your magic to grow powerful plants to help you. Click on a button at the bottom or use the shortcuts, then place your tower. The only limit is that you need to go close to where you want to build the tower, and wait until it is fully grown before you can do something else. The first tower is a bit weak and attacks enemies. The second one is more resilient, but it only slows them down.

Play Michell in Hell

This is the current version of the game. We continued developing the game after the end of the Ludum Dare, and have fixed some pretty big bugs. We also added more content (the second tower, the boss, sounds... ). If you want to see what the game looked like at the end of the weekend, you can play the Ludum Dare version.

The Ludum Dare 29 is now over, and we have the results of the voting. People liked our game, it seems, as we got only above-average marks. Unsurprisingly, the graphics and audio were what people liked the most! Overall we had slightly worst marks than for Sniff, but that doesn't surprise me: the game was less polished at the end of the weekend, with some annoying bugs. I hope people had played the updated version instead, but I realized only too late that I could edit the entry. Anyway, here are our ratings for the Jam competition!

ld29-ratings.png

Notes about Phaser

We used the Phaser game engine for this jam. I had played a little with it before, and I thought it was pretty cool and complete / stable enough. As usual, this assumption was stressed a lot during the weekend! Overall I am satisfied with it, the performance of the game is pretty good, the engine was quite easy to use, and the code of the engine itself is pretty clean. However, here are a few things that I didn't like or feel could be improved.

Documentation. That's the key for every developer facing code. If it isn't correctly documented, it's going to be very hard to use, people will get frustrated and the software will slowly die, or never get used at all. In the case of Phaser, discovery of features was the most difficult thing. I realized several times during the weekend that some things I had coded were already built inside the engine. That is frustrating, especially when coding in limited time like in a Jam. The API documentation was very complete and pretty good in my opinion, but it could do with some work on the search features.

Some things are still buggy, or at least did not behave like we expected them to. For example, we struggled a lot with the physics, and especially with the collision system. Sometimes collisions just stop working if you make objects unmovable. Objects push each others by default when colliding. And there are few incoherences in the collision functions that I would like to fix whenever I can find the time to open a pull request to Phaser...

The groups feature was the most misleading thing we used during the weekend. What we didn't know at first was that groups define the order in which objects are displayed. That's cool, but. If your Game object contains groups, those groups will be displayed in the order they are in Game. That's probably expected and a good behavior, but as we used groups for logical grouping (enemies together, towers together... ) and not for display grouping, we ended up with a messed up displaying. Basically, towers could never be behind enemies, even when that enemy was clearly in front of that tower. Same for the player. So I had to re-work our logic to not use Groups but lists, and use Groups as display layers. A bit confusing.

Overall, I was satisfied with Phaser and I want to use it again on my next Jams. Hopefully I will take some time to fix the few bugs we found during the development of Michell in Hell!

I want to finish this article with a big thank you to Caroline, Maxime, Pierre-Etienne and Rémi who made this game with me. I really enjoyed this weekend with you, and hopefully you did too!

...

En avril, JDLL et Game Jam #6 à Lyon

Hello !

Voici les événements lyonnais auxquels je participe en avril.

Game Dev Party - Game Jam #6

GDP Jam #6 Tout d'abord, l'association Game Dev Party organise sa 6e Game Jam le week-end des 4, 5 et 6 avril (du vendredi soir au dimanche soir). Le thème sera New York, thème inspiré du festival Hallucinations Collectives dont nous sommes partenaires pour cette édition. On vous attend nombreux pour cette nouvelle Jam, on a hâte de voir ce que vous allez créer et on a envie d'être, comme à chaque fois, émerveillés par votre imagination et votre talent. La Jam se déroulera à l'école e-artsup, au 20 rue Jules Brunard dans le 7e, elle est ouverte à tous sur inscriptions, et le public est invité à venir dimanche soir à partir de 18h à la démonstration des jeux qui clôturera le week-end.

Comme la dernière fois, nous organisons une soirée démo après la Jam. L'objectif est de réunir les créateurs de jeux et un public aussi varié que possible, afin de les mettre en contact, de tester les jeux et de passer une bonne soirée. La Maison Pour Tous - Salle des Rancy nous accueillera à nouveau, au 249 rue Vendôme, Lyon 3e, à partir de 19h et jusqu'à environ 21h. N'hésitez pas à venir voir ce que les jammeurs peuvent faire en un week-end !

Tous les détails sur la Game Jam #6.

Journées Du Logiciel Libre 2014

Également à la Maison Pour Tous, les JDLL 2014 auront lieu le week-end des 12 et 13 avril. J'y donnerai deux conférences le dimanche :

Les dangers de la centralisation sur le Web

Une conférence grand public sur la tendance à la centralisation sur le Web. J'y expliquerai grossièrement ce que sont l'Internet et le Web, ce qu'est la centralisation et quels sont ces dangers. Nous verrons également qui sont les principaux acteurs de cette tendance, quelles sont leurs stratégies, et surtout, quels sont les moyens de sortir des enclos dans lesquels ils veulent nous enfermer.

Il faut enseigner l'Internet aux adultes

L'Internet a débarqué dans nos vies à une vitesse folle, et beaucoup d'entre nous ont appris à s'en servir sur le tas. Or l'Internet, comme tout outil, peut se révéler dangereux s'il est mal utilisé. Cette conversation (plutôt que conférence), destinée à un public ayant une connaissance technique de l'Internet, vise à faire prendre conscience que nous devons expliquer ce qu'est cet outil, comment il fonctionne, et quelles en sont les limites, aux gens qui nous entourent.

Le planning des JDLL n'est pas en ligne à l'heure où j'écris ces lignes, mais il devrait être publié dans le courant de la semaine. Ce week-end sera l'occasion de rencontrer beaucoup d'acteurs du libre, de Lyon ou d'ailleurs, et de découvrir un univers qui s'il vient d'un monde technique, peut apporter beaucoup à tous les niveaux de nos vies. Mozilla aura bien évidemment un stand, et j'ai ouïe dire qu'une conférence sur FirefoxOS sera organisée.

...

Expériences numériques, ce samedi à Lyon

Samedi 11 janvier 2014, l'Espace Public Numérique de la Maison Pour Tous - Salle des Rancy accueillera la 12e édition de ses Expériences Numériques. Au programme de cette journée :

  • des conférences d'Illyse, le FAI associatif lyonnais ;
  • une "Install Party" de l'ALDIL ;
  • de la musique assistée par ordinateur ;
  • du cinéma et des effets spéciaux ;
  • du mobile, de la tablette...

Et bien entendu, une bonne ambiance et des rencontres précieuses avec des passionnés ! Pour plus de détails, lisez le le programme complet (pdf), ou rendez-vous sur le site de l'Espace Public Numérique de la MPT.

Expériences Numériques #12
samedi 11 janvier, de 10h à 19h
entrée libre et gratuite
249, rue Vendôme, Lyon 3e

...

Où est mon shaarli ?

Il est là !

Shaarli, un petit logiciel Web créé par sebsauvage, est un outil de "bookmarking", à l'origine censé être un concurrent libre et auto-hébergé de delicious. Sauf qu'avec la puissance du RSS et du libre arbitre, les gens (dont sebsauvage lui-même) se sont mis à l'utiliser plus comme un outil de partage de liens, un peu comme on utilisait twitter à l'origine (avant que ça ne soit pollué par des conversations futiles). Le tout est installable sur n'importe quel serveur Web (c'est codé en PHP), ça se configure très facilement et ça s'utilise tout aussi facilement. Pour plus d'informations, visitez la page Shaarli sur le wiki de sebsauvage.

Et pour le plaisir, les shaarlis des copains :

waldo-y-u-no.jpg

Et si vous en connaissez des qu'ils sont biens, qu'ils sont bons, qu'ils sont plein de bonnes choses, n'hésitez pas à les partager dans les commentaires.

...

- page 1 of 14