Posted by & filed under Uncategorized.

2013-11-18_22-37-15

Today, there was a minor discussion on #quassel on UI ideas for multi split chat. I origionally set out with the idea of adding small icons next to the selected buffers in the buffer list widget to show which buffers are selected. This idea spiralled into learning a little bit of AngularJS to make a semi-functioning UI.

You can try it out here: http://jsfiddle.net/YwDPf/4/

Posted by & filed under Code, Project.

2013-06-15_00-29-04

During the Beta for Hawken, the developers turned off the server browser to maximize the usage of their matchmaking (in order to perfect it). This made those who wanted to setup an organized scrim very painful. I checked out how Hawken retrived the list and put together a simple interactive table using jQuery and Datatables. To actually fetch the data, I had to create a simple library in python 2.x for Hawken’s services as Javascript by itself would fail (due to some overhead required in XHRs). I then used it in combination with Flask as a proxy in order to filter and combine multiple requests together. The result would show the users on the server, the map, and the ip address + port the server is running on.

This project is the first one I hosted on Heroku. It’s a very good service if you don’t need to a database.

I then rewrote the entire thing from scratch and used Bootstrap as a base for the client side to make things look nicer.

Posted by & filed under Project Summaries.

Hawken – Player Count Graph

After Ashfire made his graphs private. I decided to go ahead with a project I’d been holding off because he had already made a solution. I installed MongoDB + PyMongo and wrote a script to poll the server list periodically, then store the resulting JSON in the database. Once that was done, I modified my flask web server for the server list to serve a simple graph using HighStocks. It uses ajax to fetch the data from the database as I did not store the derived data (the player count). Instead each request will parse X data points of server list jsons which makes it useful as a local application only.

Hawken – Server List

During the Beta for hawken, the developers turned off the server browser to maximize the usage of their matchmaking (in order to perfect it). This made those who wanted to setup an organized scrim very painful. I checked out how Hawken retrived the list and put together a simple interactive table using jQuery and Datatables. To actually fetch the data, I had to create a simple library in python 2.x for Hawken’s services as Javascript by itself would fail (due to some overhead required in XHRs). I then used it in combination with Flask as a proxy in order to filter and combine multiple requests together. The result would show the users on the server, the map, and the ip address + port the server is running on.

I then rewrote the entire thing from scratch and used Bootstrap as a base for the client side to make things look nicer.

Quassel – Web Search

Finalized my first pull request to a larger Open Source project. I copied Chrome’s Search for __ when right clicking selected text in chat.

Posted by & filed under Project Summaries.

Bukkit Plugin – PrideArena

I took over a writing a friend’s plugin for the Pride PvP Games server. Essentially, I put into practice the game mechanics of a Deathmatch arena in the style of the Hunger Games. Actually, it’s not that much like it as there’s no cornicopia danger. You choose a kit (class) and there a grace period when there’s no PvP. My personal highlight of this project is the that I shosed the status of the arena with signs around the portal you enter. Giving a very good user feedback about the sate of the arena. While I don’t have credit for the idea, I also added a gate that closes down to prevent people from walking though the portal (as opposed to just not teleporting them).

Quassel

Looking for an IRC client that that fully customizable skins eventually brought me to Quassel. While I love the fact everything is styleable in QSS (CSS for QT), the client itself has a few minor annoyances. Thus began my first serious foray into C++.

Bukkit Plugin – Vault Promoter

This project was spurred by the fact that bPermissions’s promotion system limitations. While it focus’s on tracks, the actual permission node for each track uses one node per group. My desired setup was that normal users could promote Guests. Giving users the promote.User permission node would then allow users the ability to both promote to guests to User and to demote them from it. Not ideal. While I first debated forking and submitting a patch (which I half did), I also wanted the promotion commands to be more configurable. Currently they were /promote [trackname]. Which would force a mod use the command more than once to go all the way from Guest -> Mod.

Posted by & filed under Code.

Quassel - WebSearch Selection

Finally got a working feature working. I’ve been hacking away in Quassel‘s C++ for the past few months as it seemed a good incentive to learn the language through practice. My feature was to allow selected text to be google searchable. It’s not been submitted yet to the main repo. I’ve still got to give it a unique icon, and possibly give it a shortcut. The image to the left is the first working screencap with just a placeholder that doesn’t work. The problem there is it requires a bit more capability at understand pointers than I’m comfortable with. The major thing though would probably be the option to use a non hardcoded url to Google Search. It also looks like my domain is going to expire soon. A full year since this particular site has been up. I’ve been working less and less on Towny of late. Venturing into a number of side projects, and ones with a little profit.

Posted by & filed under Code.

Over the past months, I’ve submitted a few changes to Towny.

  • (Old News) If you didn’t know, I’ve added a new war mode. It’s different than the previous one where the admin would trigger an event and the entire world is at war. This version will take your alliance (enemy / allied) into effect, and allow you to capture your enemy’s plots. * A more recent change to it is that I’ve added economic costs for attacks in the new war mode.
  • A smoke effect around the border of a plot do help distinguish the boundaries of a plot better. This should lead into a few optional modules to build a fence around plots, etc later. I’ve done more tinkering outside of Bukkit though.
  • Created a custom theme for the Quassel IRC client. It’s simple CSS based on the Monkai theme you see in a lot of places. You can check it out here.
  • Learned a few python tricks and tried out the Google App Engine through Udacity‘s CS235 free online class.

Posted by & filed under Project.

I realized my entire design for Quest Editor was flawed. While NPC data is mostly consumed of checkmarked options and a ComboBox, Quest data has an insanely complicated hierarchy. My experience with extending Java’s native GUI components is slightly better after my first attack, but I know that making 20 slightly similar classes along with a fair amount of custom panels and comboboxes (item/npc/quest selection). The worst would be the text editing. The entire point of the GUI was to make things simplier than formatting YAML markup. Which I realized wouldn’t be the case. The best method would actually be to create a script alongside a parser that would build the YAML markup. After 5 hours of hacking and slashing, I’ve gotten it working. A fair amount of time was spent updating Citizen’s own save functions for quests.yml. Here’s an example of the script, and it’s output.

===
New Players
Rift

NPC guardian
===

The Rift is a seperate entity outside of time and space. Here generations before you have made it simple to go to any slot in time you wish. The portal behind me will take you to Eldaria in the year 1600 AD.

To open a portal, throw the lever beside it, but be sure to quick and step through before the portal closes!

Some portal can take you to multiple places, to chose one, click the panel beside the lever till the desired target is selected.

Now step forth and try it. Then witness with your very eyes, the fall of Eldaria.

* The guardian hands you a book for you to pen your adventure. Then lightly shoves you towards the portal.
ITEM book

===
Go Kill Zombie
Eldaria
1600 AD

NPC alex
===

Ah, another one. Well I'm sure you can make yourself useful. Here. Go kill a zombie or two.

Try not to die.
ITEM stone_sword

KILL zombie 5

ITEM cookie
Well at least you're not useless. Here's a bandaid. And since you've been such a good boy, a cookie as well.

===
Supplies
Eldaria
1600 AD

NPC alex
===

You'll probably want to get up to speed with everything.
I'm not the best one for that, so go meet the guy who runs the inn on the way to Miran Des. Just follow the road.

ITEM paper
While your at it, give him this supply sheet. We're low on supplies. When you've gotten them, hand them to me.

NPC innkeeper

GIVE paper

ITEM potion 1 8257
Ah. Welcome, welcome. Come sit down and rest up.

What is this place? Hmmm. *puff* Where to start?

This land used to be filled with dragons you know. It was their home before we came. We lived with them for a time, but things grew complicated as friendships always do. We drove them off. Well, killed em all really. That was years ago now.

The last ones fell just near here at the heart of Miran Des. You ought ta go check out them bones. Huuuuge. Each one was near a quarter of the Tower in height.

Well now. If you're off in that direction, ask Steve over there. He's a mage. He'll know more of the specifics on the dragons and the Tower.

ITEM apple 64
Oh and before you jaunt off to Miran Des with him. Take these supplies over to the guys back at the portal.

NPC alex

GIVE apple 64

Thanks for bringing the supplies foreigner. Now get on your way to Miran already.

Turns into this:

'Rift: New Players':
  texts:
    description: 'Rift: New Players'
    completion: 'Rift: New Players completed'
    acceptance: 'Rift: New Players started'
  repeats: 0
  objectives:
    '0':
      '0':
        type: talk
        npcdestination: 0
        message: The Rift is a seperate entity outside of time and space. Here generations before you have made it simple to go to any slot in time you wish. The portal behind me will take you to Eldaria in the year 1600 AD.
    '1':
      '0':
        type: talk
        npcdestination: 0
        message: To open a portal, throw the lever beside it, but be sure to quick and step through before the portal closes!
    '2':
      '0':
        type: talk
        npcdestination: 0
        message: Some portal can take you to multiple places, to chose one, click the panel beside the lever till the desired target is selected.
    '3':
      '0':
        type: talk
        npcdestination: 0
        message: Now step forth and try it. Then witness with your very eyes, the fall of Eldaria.
    '4':
      '0':
        type: talk
        npcdestination: 0
        message: '* The guardian hands you a book for you to pen your adventure. Then
          lightly shoves you towards the portal.'
        rewards:
          '0':
            type: item
            id: 340
            amount: 1
            data: 0
            take: false
'(1600 AD) Eldaria: Go Kill Zombie':
  texts:
    description: '(1600 AD) Eldaria: Go Kill Zombie'
    completion: '(1600 AD) Eldaria: Go Kill Zombie completed'
    acceptance: '(1600 AD) Eldaria: Go Kill Zombie started'
  repeats: 0
  requirements:
    '0':
      type: quest
      quest: 'Rift: New Players'
      take: false
  objectives:
    '0':
      '0':
        type: talk
        npcdestination: 5
        message: Ah, another one. Well I'm sure you can make yourself useful. Here. Go kill a zombie or two.
    '1':
      '0':
        type: talk
        npcdestination: 5
        message: Try not to die.
        rewards:
          '0':
            type: item
            id: 272
            amount: 1
            data: 0
            take: false
    '2':
      '0':
        type: hunt
        amount: 5
    '3':
      '0':
        type: talk
        npcdestination: 5
        message: Well at least you're not useless. Here's a bandaid. And since you've been such a good boy, a cookie as well.
      rewards:
        '0':
          type: item
          id: 357
          amount: 1
          data: 0
          take: false
'(1600 AD) Eldaria: Supplies':
  texts:
    description: '(1600 AD) Eldaria: Supplies'
    completion: '(1600 AD) Eldaria: Supplies completed'
    acceptance: '(1600 AD) Eldaria: Supplies started'
  repeats: 0
  requirements:
    '0':
      type: quest
      quest: '(1600 AD) Eldaria: Go Kill Zombie'
      take: false
  objectives:
    '0':
      '0':
        type: talk
        npcdestination: 5
        message: You'll probably want to get up to speed with everything.
      '1':
        type: talk
        npcdestination: 5
        message: I'm not the best one for that, so go meet the guy who runs the inn on the way to Miran Des. Just follow the road.
    '1':
      '0':
        type: talk
        npcdestination: 5
        message: While your at it, give him this supply sheet. We're low on supplies. When you've gotten them, hand them to me.
      rewards:
        '0':
          type: item
          id: 339
          amount: 1
          data: 0
          take: false
    '3':
      '0':
        type: delivery
        npcdestination: 6
        item:
          id: 339
          amount: 1
          data: 0
    '4':
      '0':
        type: talk
        npcdestination: 6
        message: Ah. Welcome, welcome. Come sit down and rest up.
      rewards:
        '0':
          type: item
          id: 373
          amount: 1
          data: 8257
          take: false
    '5':
      '0':
        type: talk
        npcdestination: 6
        message: What is this place? Hmmm. *puff* Where to start?
    '6':
      '0':
        type: talk
        npcdestination: 6
        message: This land used to be filled with dragons you know. It was their home before we came. We lived with them for a time, but things grew complicated as friendships always do. We drove them off. Well, killed em all really. That was years ago now.
    '7':
      '0':
        type: talk
        npcdestination: 6
        message: The last ones fell just near here at the heart of Miran Des. You ought ta go check out them bones. Huuuuge. Each one was near a quarter of the Tower in height.
    '8':
      '0':
        type: talk
        npcdestination: 6
        message: Well now. If you're off in that direction, ask Steve over there. He's a mage. He'll know more of the specifics on the dragons and the Tower.
    '9':
      '0':
        type: talk
        npcdestination: 6
        message: Oh and before you jaunt off to Miran Des with him. Take these supplies over to the guys back at the portal.
      rewards:
        '0':
          type: item
          id: 260
          amount: 64
          data: 0
          take: false
    '11':
      '0':
        type: delivery
        npcdestination: 5
        item:
          id: 260
          amount: 64
          data: 0
    '12':
      '0':
        type: talk
        npcdestination: 5
        message: Thanks for bringing the supplies foreigner. Now get on your way to Miran already.

As you can see, it’s still needs to be improved upon. Mainly the saving of objectives, and filtering default settings to keep filesize down. The schema of the scripts are built like so:

root
    header
        name
        world
        time
        npc
    body
        objective (new step)
        objective

        objective (new step)

        objective (new step)

        switch target npc for all following objectives (for diliveries and talking)

        objective (new step)
        objective

As you can see, it allows long conversations to be written very easily. The builder itself deals with all the counting.

To Do

  • Add the rest of the objective types (and rewards).
  • Add a config file to skin text messages with:
  • (Click to continue) as a suffix and greyed out.
  • Option for a prefix.
  • Prefixes include putting the targetted NPC’s name in front like so: Name: blah
  • Manage the npc-profiles. Making specified NPCs a quester.
  • Option for sidequests and non-linear plot. My thoughts are to keep the automatic linking to the last quest unless specified as a sidequest or a required quest has been mentioned.
  • Parametered titles in the config.
  • 1 param: %1$s
  • 2 param: %2$s: %1$s
  • 3 param: (%3$s) %2$s: %1$s

  • Allow quests.txt to be broken up into several files by moving it into a subfolder. The parser would then read files alphabetically.

  • 0-start.txt
  • 1-training.txt
  • 2-sword1.txt
  • 3-mage1.txt
  • sidequests.txt  

Posted by & filed under Project.

I managed to easily get the design and mocked up elements done well within the time limit.   From there I jumped right into learning how to make the tables and lists actually load data from Citizens. This involved deciphering the loading process of the plugin. I soon found that I would be unable to use the default plugin and would need to rewrite a few parts. They mostly revolved around the relative folder the plugin was launched from. The things I did were:

  • I copied and refactored a few functions to remove all mention of Entity and Server.
  • I needed to create an abstracted implementation of World for Location.
  • Since the npc data isn’t stored in some list in the plugin (it was a list/map of HumanNPC which extended Entity), I need to manage it in the editor.

One of the easiest things to get was the NPC types, as the loading of them (.jars) was completely separate from everything else.

My current state is learning about JTable’s and Focus Listeners so that I can have the NPCDetailsPanel show the details of the NPC. I’ve managed to load the NPC data and populate the index table.

So far I’ve spent 6 hours (2 for planning) on this project. Exploring new areas such as tables and it’s listeners is really eating away at the time spent as I don’t believe I’m doing the standard approach.

  • 2012-02-18_193457
  • 2012-02-18_193359

 

 

Posted by & filed under Project.

Designing a quest based server makes dealing with Citizen’s configurations terribly annoying. So I decided to plan this project out first (crosses fingers and hopes it doesn’t turn out like my last planned project).

Since this will revolve around a technology I’ve not profected (GUIs), I’ll be needing to associate time to learn new skills and build familiarity with it. I will be speeding this process up by using the Netbeans IDE.

Time Limits

Instead of planning the whole project out, I’ll instead do it in parts. After each part, I will re-evaluate and plan the next time slots.

  • Design: 1 Hour
  • Build the GUI: 1 Hour

Wish me luck.

Posted by & filed under Uncategorized.

2012-02-16_065646

Gimp is an awesome open-source alternative to Photoshop. However, it’s rather lacking in a few places. This review is using the 2.7.4 development build for windows found here.
* Floating point settings (eg: 0.00) increment by the hundredth (0.01) when using the arrow buttons. Same with hovering over and scrolling as well as click-draging left and right. For most use cases, this is fairly useless when your range of values can be from 0.01 to 1000.00 (in the case of brush size). That’s a lot of scrolling. The click drag usually also forces the user to delete numbers to round it manually, making the functionality useless when quick precision is desired.
* Change incremental values to jump by integer. This is done with spacing (lower right in 2.7) which is a 0.0 floating point.
* Possibly change incremental values to scale exponentially when scrolling. Then click-drag for more precision change linearly.
* The Palette Editor is nice once you find it. Clicking tiny 10px squares is not fun though. Sure a palette can be hundreds of colours in size, but that doesn’t mean we need to make choosing colours intolerable. Especially with palettes with only 10 – 20 colours. The dialog box is full of whitespace. There are buttons to zoom and change the number of rows at the bottom, however the defaults are awful.
* Increase default size of boxes.
* Edit: I found the Colors toolbox, which has a much better viewer of the current selected palette. Makes sense when the other is called “Editor”. It fills whitespace very well when there are only a few colours. My only ilk about it is that it does it’s best to not use a scrollbar, causing huge palettes to have the boxes with a tiny side.
* Add/Change the minimum size, and use a scrollbar once reached a certain limit.
* Also, the palette editor could do with a tooltip that shows a larger box with the colour, along with it’s hex / rgb value to help with choosing colours in a gradient filled palette. The tooltip could be used for other purposes as well. Examples that come to mind are a larger preview of brushes and textures. A delayed tooltip (so as to not slow old computers) for fonts.
* Modify default toolboxes. Channels (RGBA) is probably not used by the average joe. Colors would be useful as a default (redundant due to the color picker yes, but would make choosing colour faster).
* Making palettes seems to be fairly textbox heavy. A solution would be to have a dynamic palette similarly to the one in the colour picker popup. This would be the default palette, and would reset on every startup. The list of colours in the palette colour picker would need to be more than 12 however. This way, a user could create palettes as they go. Since the Colors toolbox does not add to this dynamic palette automatically, a button beside the eyedrop would suffice.