Combien ça rapporte de développer un jeu pour mobiles ?

Et bien pas grand chose !

Attention, on parle d’un jeu de base sans prétention développé par un clampin sur ses heures de sommeil.

Prenons Colorseeds pour Windows Phone : il est gratuit, et rapporte quelques millièmes de centime d’euro à chaque fois qu’une publicité s’affiche (bannière en haut de l’écran de jeu).

Prenons le mois d’avril :

– Colorseeds est présent dans plus de 180 pays, et il a été mis en avant (= plus de visibilité sur le Store) environ 60 fois (dont des pays à fort potentiel comme les Etats-Unis et le Canada),

– Il a été téléchargé 8290 fois, dont 1000 en France (c’est très peu !),

– Plus d’un million de publicités ont été affichées (c’est beaucoup ! Les gens qui ont téléchargé ont beaucoup joué),

– Le CPM (« coût par mille »), c’est à dire le nombre d’euros que me rapporte 1000 publicités affichées est de : 0.05€ (pas terrible),

– Ce qui donne : 1 543 138 pub * 0.05 CPM / 1000 = 51€ environ…

Bref, il me faudrait plus d’une vingtaine de jeux pour gagner un SMIC… Ou alors investir dans de la promo massive !

pubcenter_colorseeds_avril2014

 

Pour les heureux possesseurs d’un Windows Phone, Colorseeds se télécharge ici :

Download Colorseeds for Windows Phone !

DevOps, ou comment nommer l’innommable.

Le métier de DevOps est de réconcilier les développeurs et les exploitants.

Les exploitants de production gèrent leurs serveurs avec toute l’affection qu’une mère porte à sa couvée. On surveille, on s’inquiète. Pas trop de température ? Pourquoi les fichiers de logs grossissent ? Y aurait pas comme une pointe de consommation de CPU là ?

Quant aux développeurs, voilà une bande d’hystériques* toujours à l’affût du dernier framework à la mode, prêts à déployer n’importe quelle fonctionnalité à peine testée sur les beaux serveurs clusterisés qui n’avaient rien demandé.

Bref, on oppose stabilité et changement. Deux politiques contradictoires qui doivent pourtant collaborer étroitement !

Quoi de plus frustrant qu’une gestion de projet agile s’il elle se casse les dents au moment de la mise en prod ?

pass

Mais voici le DevOps ! Celui qui va faciliter les mises en prod, fluidifier les processus, apaiser les craintes.

Il intervient dans la mise en place des processus suivants – que chaque adorateur de l’agilité reconnaîtra :

  • L’intégration continue : Déploiements réguliers sur les serveurs d’intégration.
  • La livraison continue : Déploiements réguliers de builds vers la recette, puis pré-prod et prod.

Et le DevOps intervient aussi dans la mise à disposition d’outils « passerelles » entre ces différentes plateformes.

Pourquoi je parle de tout cela ? Parce qu’il s’agit de ma mission actuelle. Difficile à nommer au départ (admin ? dev ? AMOE ?), elle peut peut enfin être qualifiée en « DevOps ».

Plus qu’un terme à la mode, les équipes DevOps sont une brique essentielle des grandes entreprises IT telle que Google, qui peuvent rapidement mettre en place de nouvelles fonctionnalités dans leur services.

Sources : Article sur 01.netDevOpsDays

*Humour

Pourquoi avoir choisi Windows Phone pour mes applications mobiles ?

Au départ, j’avais commencé à développer pour Android. Hélas, le SDK pour la version 1.5 de cet OS n’était pas mûr, et l’utilisation d’Eclipse était une calamité. Au même moment, Microsoft annonçait le successeur de Windows Mobile : Windows Phone, avec un Framework dédié au jeu : XNA. Idéal !

Hormis le choix technique, il y avait le choix stratégique : il était plus simple de percer dans un marché jeune, où le nombre de part serait plus simple à grignoter. Sous Android, il y a beaucoup d’utilisateurs, mais aussi énormément d’applications ! Il est donc plus dur d’être visible.

Quand j’ai exposé ce point de vue à un collègue, il a fait un rapprochement avec la « matrice BCG » (Boston Consortium Group) :

matrice-bcg

Facilement, mes  premières applications (ColorSeeds et Snake7) sont devenues « Vache à lait » : Part de marché élevée, croissance ‘e (peu de maintenance et de mises à jour) = revenus intéressants (enfin, c’est relatif, on parle de quelques centaines d’euros).

L’équation était simple. Mais les choses ont changé avec l’arrivée de la concurrence : ma dernière application Hexx marche très mal. Malgré quelques investissements pour une meilleurs visibilité (pubs, promo) et des mises à jour courantes afin de répondre aux remontées des utilisateurs, les téléchargements sont faibles (mais avec de bonnes notes !). Je me retrouve avec un bon produit devenu un poids mort

Je dois donc réfléchir à un nouveau modèle économique. Pourquoi ne pas passer à l’application payante ? Qui ainsi se noiera moins dans pléthore d’applications gratuites ?

J’espère mettre en place tout cela cette année. En tout cas, certains portages sur Android sont en cours !

 

Check my « European e-Competence Framework »

Quand on demande « quelles sont vos compétences », il est important d’avoir le même langage, les mêmes termes. C’est le but du « Référentiel européen des compétences informatiques » (e-CF), qui permet au personnel technique, aux clients de services informatiques et aux RH de communiquer 🙂 Alors je me suis amuser à auditionner mes propres compétences – en toute transparence !

Compétences

 

Source : http://www.ecompetences.eu/site/objects/download/6063_EUeCF2.0userguideCWAPartIIFR.pdf

http://www.ecompetences.eu/site/objects/download/6068_EUeCF2.0CWAPartIFR.pdf

Utilisation du type de variables « Decimal »

« Decimal » a été créé pour avoir une précision plus grande, mais dans une plage de valeurs plus restreinte.

Il est préconisé dans les applications monétaires, tandis que les autres types à virgules flottantes (double, single) sont destinés aux calcules scientifiques (et ils ont une vitesse de traitement plus rapide).

Fait amusant :

Decimal numerateur = 1m;
Decimal denominateur = 3m;
Console.WriteLine(numerateur / denominateur * denominateur);

Le résultat sera 0.999999… Ceci parce que Decimal est justement trop précis !

L’utilisation de Round permettra de profiter de la précision de Decimal, tout en faisant les arrondis nécessaires. Comme cité dans cette ressource : « Le type Decimal n’élimine pas la nécessité d’arrondir. Il réduit plutôt des erreurs en raison de l’arrondi ».

Console.WriteLine(Math.Round(numerateur / denominateur * denominateur, 2));

Ceci retournera 1.00.

L’utilisation des autres flottants n’est pas conseillé. Car les erreurs d’arrondis vont plus faciement s’accumuler à fur et à mesure des calculs.

Cet exemple ci-dessous ne doit pas fausser l’opinion des développeurs :

Double numerateur = 1f;
Double denominateur = 3f;
Console.WriteLine(numerateur / denominateur * denominateur);

Le résultat sera de 1 ! Mais cela reflète simplement un manque de précision de la division avec ce type de flottants : numerateur / denominateur = 0.3333343

 

Log4Net / Powershell : Modifier à la volée la configuration d’un appender

Pour les besoins d’un projet, je devais modifier dynamiquement le nom du fichier de traces généré par la bibliothèque Log4Net. La majorité de la configuration est située dans un fichier .config, tandis que le nom du fichier de sortie est géré à l’exécution du script.

Voici l’adaptation de mon script Powershell que j’ai dû effectuer :

# Chargement de la bibliothèque et de sa configuration.
 [void][Reflection.Assembly]::LoadFrom( "log4net.dll")
 $FileInfo=new-object System.IO.FileInfo "log4net.Config"
 [log4net.Config.XmlConfigurator]::Configure($FileInfo)
# Configuration du nom du fichier de trace
 # - Récupération de l'appendre défini dans le fichier .config
 $hierarchy = [log4net.LogManager]::GetRepository()
 $appender = $hierarchy.GetAppenders() | Where-Object { $_.Name -eq "MonAppender" }
# - Modification du nom du fichier log
 $appender.File = "E:	racesout.log"
 $appender.ActivateOptions()
# Récupération de l'objet pour gérer les traces dans le script
 $LogFile = [log4net.LogManager]::GetLogger($logger)
$LogFile.Error("bla bla bla")

Pour info, voici à quoi ressemble le fichier de configuration :

<?xml version="1.0" encoding="utf-8" ?>
 <log4net>
 <appender name="MonAppender" type="log4net.Appender.RollingFileAppender">
 <file value="E:	races" />
 <appendToFile value="true" />
 <staticLogFileName value="false" />
 <rollingStyle value="Date" />
 <layout type="log4net.Layout.PatternLayout">
 <param name="ConversionPattern" value="%d{yyyy-MM-dd hh:mm:ss} %-5p - %m%n" />
 </layout>
 <filter type="log4net.Filter.LevelRangeFilter">
 <levelMin value="DEBUG" />
 <levelMax value="FATAL" />
 </filter>
 </appender>
<root>
 <level value="DEBUG" />
 <appender-ref ref="MonAppender" />
 </root>
 </log4net>

Hexx 3.0 dispo sur Windows Phone

Logo_128x128

Enfin la grande mise à jour de Hexx ! Il y a eu du boulot :
– 23 nouveaux tableaux de jeu,
– Des nouvelles cases (bombe, titanium) pour ajouter un peu de fun,
– Un mode daltonien (ce n’était pas très futé de faire verts vs. rouge)
– 3 niveaux d’intelligence artificielle
– Nouveau logo

J’en suis fier ! Merci à Jérôme pour le dev de l’IA !

Batch DOS : Supprimer un ensemble de fichiers en conservant les plus récents

Pour supprimer tous les fichiers d’un répertoire, mais en conservant les plus récents, une seule ligne de commande suffit.

Pratique lorsque qu’on souhaite conserver les fichiers de traces *.log des 7 derniers jours par exemple :

forfiles /P "C:dossier races" /M "*.log" /C "cmd /c del @file" /d -7

Et oui, je découvre la commande « forfiles » à 33 ans, c’en est presque émouvant. Plus d’info ici : Technet.

SharePoint 2010 : Workflow d’envoi de mails déclenché par un utilisateur anonyme.

Les utilisateurs anonymes ne sont pas autorisés à déclencher certains flux de travail (workflow), notamment ceux qui envoient des mails.

Prenons l’exemple d’une liste qui déclenche un workflow d’envoi de mail sur l’ajout d’un élément :

Workflow_1

Ici l’envoi de mail sera un échec, car la tâche d’envoi de mail nécessite plus de droit que ne peut avoir un utilisateur anonyme.

Pour remédier à cela, une solution serait de faire déclencher le workflow par un événement tiers :

Workflow_2

Il suffit d’insérer un event-handler qui va prendre en charge l’événement « ajout d’un élément » à la place du workflow, et qui va forcer le démarrage du workflow « à la main ».

Le code de l’event-handler pourrait ressembler à cela :

public class List_EventReceiver : SPItemEventReceiver
{
 /// <summary>
 /// Un élément a été ajouté, on lance le workflow avec privilèges.
 /// </summary>
 public override void ItemAdded(SPItemEventProperties properties)
 {
    base.ItemAdded(properties);
    
        // Exécution en élévation de privilège
    SPSecurity.RunWithElevatedPrivileges(delegate()
   {
      using (SPSite site = new SPSite("http://mon_site"))
      {
        using (SPWeb siteWeb = site.OpenWeb())
        {
          SPList list = siteWeb.Lists["Ma_Liste"];

          SPWorkflowAssociation wf = list.WorkflowAssociations.GetAssociationByName("Nom_du_Workflow", System.Globalization.CultureInfo.CurrentCulture);

          // Lancement du workflow
          site.WorkflowManager.StartWorkflow(list.GetItemById(properties.ListItemId), wf, wf.AssociationData);
        }
      }
   });
 }
}