The upper tier is going to be the core once I figure out some meat to add. There have been a few ideas - in-game messaging, in-game mailing, in-game trading, etc, but I'm having issues with implementing some of them due to limitations; I can't send a data item from one person to another for instance. Current layouts include using a global data store, but that can be dangerous and inefficient; I'll continue working on it though. The entire library will be open source shortly; I've created the CodePlex page, I just haven't published it yet (need to verify that I've removed all pertinent info from the source code, pick a decent license, and get some more meat in it.)
Currently the only service working is the news service. This is a simple game-news service; the typical "A new update is available" whatnot. I've created a tool that allows you to log in and the library provides what facilities to access the news (note that it isn't designed for a large number of items, but it works off of a single data store so you could theoretically store up to 16MB of news entries.)
Here are some screenshots:
[The News Manager]
Items are managed via a context menu on the tree view on the left.
[In Game Example]
A loading message is displayed while the items are retrieved asynchronously (though all request have synchronous versions) and then they display on screen marquee-style.
[Android]
All libraries involved are dual built against Android.
Here is the necessary source code for the example:
// How to instantiate the services manager
var GameJoltServicesManager = new GameJoltServices.ServicesManager("GAMEID", "PRIVATEKEY");
// The news item control used in Young Minds Memory Game
namespace Mnemosyne
{
public sealed class NewsItemControl : Control
{
private enum FeedState
{
Active = 0,
Paused = 1,
Finished = 2,
};
#region Variables
private bool itemsAreLoading = false;
private List<NewsItem> newsItems = null;
private System.Collections.IEnumerator currentItem = null;
private float marqueeX = 0.0f;
private float minMarqueeX = 0.0f;
private FeedState state = FeedState.Active;
#endregion
#region Properties
public NewsItem[] NewsItems
{
get
{
return newsItems.ToArray();
}
set
{
newsItems.Clear();
newsItems.AddRange(value);
currentItem = newsItems.GetEnumerator();
MoveToNextItem();
}
}
#endregion
#region Constructors
public NewsItemControl()
{
newsItems = new List<NewsItem>();
currentItem = newsItems.GetEnumerator();
}
#endregion
#region Methods
private void MoveToNextItem()
{
if(!currentItem.MoveNext())
{
currentItem.Reset();
state = FeedState.Finished;
return;
}
var itemText = string.Format("{0} - {1}", ((NewsItem)currentItem.Current).Title, ((NewsItem)currentItem.Current).Content);
var textSize = Font.MeasureString(itemText);
minMarqueeX = -textSize.X;
this.Width = (int)Math.Ceiling(textSize.X);
marqueeX = this.Width;
}
protected override void OnDrawText(Lust.Renderer renderer, string overrideText = null)
{
if(state == FeedState.Finished)
overrideText = string.Empty;
else if(itemsAreLoading)
{
overrideText = "Loading news items...";
marqueeX = 0.0f;
}
else if(currentItem.Current != null)
overrideText = string.Format("{0} - {1}", ((NewsItem)currentItem.Current).Title, ((NewsItem)currentItem.Current).Content);
FlatStyle style = null;
if(Styles.TryGetValue(this.State, out style))
FlatControlRenderer.DrawText(renderer, Font, overrideText, new Microsoft.Xna.Framework.Rectangle((int)marqueeX, Y, Width, Height), style, this.TextFormatFlags, null);
}
protected override void OnClick(Microsoft.Xna.Framework.Point position)
{
if(state == FeedState.Paused)
state = FeedState.Active;
else if(state == FeedState.Active)
state = FeedState.Paused;
base.OnClick(position);
}
public override void Update(float delta)
{
if(IsEnabled && !itemsAreLoading && state == FeedState.Active)
{
marqueeX -= 128.0f * delta;
if(marqueeX < minMarqueeX)
MoveToNextItem();
}
base.Update(delta);
}
public void LoadItems(ServicesManager servicesManager)
{
newsItems.Clear();
itemsAreLoading = true;
var newsService = new NewsService(servicesManager);
newsService.GetNews((storedNewsItems) =>
{
this.NewsItems = storedNewsItems;
itemsAreLoading = false;
});
}
#endregion
}
public enum NewsItemDisplayStyle
{
Marquee,
}
}
// You would then simply call newsItemControlInstance.LoadItems(GameJoltServicesManager)
Alrighty, that's enough work for tonight; I'm off to bed.
[edit]
Some (planned) key features:
- Multi-user login tracking (up to 4 characters)
- Guest log in
- Simple UI elements (notification, user login pop up, etc)
Create a custom theme





This seems like it would be a lot of fun to play with and I bet there are a few people out there that have been hunting for something just like this.