Games with balls
What is it with games with balls?
Games with balls simply marble^Wrock.
Master Control Program
What is it with games with balls?
Games with balls simply marble^Wrock.
Posted by
elmuerte
at
23:53
One of my all time favorite games is Little Big Adventure. The first game in the series was released in 1994, a sequel was released in 1997. The team behind it also planned for a 3rd release, but things didn't went as they hoped to. A lot of things happened, the team moved to various companies, split up, etc. The posibilities for an LBA3 were quite slim, even tho the whole team wanted to make the game.
But recent developements gave new light to the posibility of LBA3. This got the fans from the Magicball Network excited. They have started a campaign to put LBA in the spotlight to give LBA3 a higher chance to be picked up by a developer.
On a side node: Sebastien Vianny showed some activity on the LBAwin project again, version 0.8.1 might be close. I hope this will be a steady walk to a final release.
Posted by
elmuerte
at
09:31
A while ago I finally finished some work on the wiki for the UnrealAdmin page. It's an modified version of the MediaWiki wiki engine (the same one as is used for WikiPedia). One of the more important things I modified was to hook up the user system with our main site that was powered by vBulletin. It's isn't as easy as it looks. Because MediaWiki is quite limited in the username format, only alphanum and _ are allowed. But vBulletin allows pretty much everything. This create a very annoying problem. How to hook up those users. I could imply convert the username to MediaWiki style, but this could create name clashing. So instead I ripped out the whole User namespace support and changed the way usernames where parsed. Username will now foward to the vBulletin profile page for users that exist. Some of the changes required modifing original files (which I don't like). So right now when a user type ~~~ (for a signature) it will be replace with a new tag [[profile:uid|Username]]. The username is ignored in further processing, it's only useful when editing a page and still being able to see the actual username. All links to the user namespace, [[user:Username]], will also be rewritten to an url to the vBulletin profile page (if the username can be found). Now this creates another problem, some usernames can contain characters so that [[user:Username]] doesn't work well. I fixed this by adding some magic: [[User:?|Username]] will work for these usernames and still allow me to look up the actual info.
If you are creating a new site with MediaWiki (or any other wiki) and vBulletin simply limit the characters that people can use to alphanum and the underscore (or space). This will save you a lot of work.
Besides the vbulletin integration I also made a couple of other extentions, pretty much all are available. While working on extentions I found out that MediaWiki doesn't really make it easy to develop extentions. Sometimes you need to change stuff deep inside some routines, or at least on certain places. Then you'll find out there are not enough hooks available to get to the right place. vBulletin 3.5 did it much better. For example simple things as adding ACL for pages isn't possible without modifyin the original code. But then again, MediaWiki is one of the nicer PHP powered wikis I've found so far, and their text syntax is nice too (much like the syntax UnrealWiki uses).
Posted by
elmuerte
at
15:44
There you've got it. The second more mature release of the UnrealScript Unit Testing Framework. A few minor changes to the real framework. More important is a working WebAdmin module.
So far UsUnit contains some graceful code, some somehwta hacky code and some scary code. For the webadmin module I tried to create a better PlayInfo to HTML converter that the one that was already present. Actualy, the existing one couldn't be use in arbitrary places. My converter current supports just check and text types, but also arrays. My initial idea was to auto detect arrays, but because of a bug in PlayInfo's validation code for TEXT render types this can't be used. Instead you will have to use a CUSTOM render type which will figure out of it was suppost to be rendered by the TEXT type. For the TEXT type I also made a special case of numeric values. If the extra data contains range information it will be used to show a specialised text filed with a plus and min button and it will respond to certain key events (up, down, home, end, pgup and pgdown) to modify the value.
An other tricky issue I had to solve was to add some logic to cope with possible invalid test classes. The test class configuration uses strings. It might happen that a single entry isn't a valid name for a class. But during configuration I don't want to remove those entries, or change them at all. Therefor I added a displacement array that keeps track of the array index differences between the two arrays.
Posted by
elmuerte
at
23:44
Sometimes you want to do some special dynamic stuff on a webpage, by means of javascript. Well apperently a lot of people on this world think that only anchors (you know, thos <a href="..." />
thingies) are the thing for that. Well it's NOT. In fact it's the worst possible thing. Why? well, an anchor should contain a link to a new location. "javascript:..." is not a new location. Besides, since it's already used for dynamic stuff you should just use the "onclick" argument of pretty much every visible HTML tag. And now we ofcourse get: <a href="#" onclick="..." />
. Well that's wrong too. Why? because you you create a link to nowhere. People (like me) often open a link in a new window\tab (middle mouse button is some browsers, or ctrl+click). Using a "#" or "javascript:" as link just breaks stuff like this and makes it annoying.
What is the right thing? Well, there are two options:
<span onclick="javascriptFunctionCall()" >your text</span>
, and maye make it more visible my means of CSS<a href="linkToTheDocument" onclick="javascriptCallToOpenWindow('linkToTheDocument'); return false;">your text</a>
. This way when a user normally clicks on the link it will call that javascript function with the url. If the user clicks on that link with the middle mouse button (or ctrl+click) it will simply open that link in the default behavior of the browser. The "return false" in the onclick makes sure the default behavior doesn't happen in case of the onclick event. This method gives you the best of both worlds and doesn't annoy users that link to middle click or don't have a javascript enabled browser.
Posted by
elmuerte
at
23:11
It has been a while since my last dev journal entry (again). First a little update about my last entry. I'm no longer actively working on a VisualStudio AddIn. The features I wanted to add required me to write a VisualStudio Package instead of just an AddIn. Writing a package isn't as simple as writing an AddIn. I hit an issue while implementing the basic framework that I haven't been able to resolve (devstudio gives me an error when I want to load a few things here and there). So that project has been put on ice.
As for other projects, a while ago I continued some development of LibHTTP and got a bit annoyed on my testing class. So I decided to make a testing framework based on unit testing. That's how UsUnit came to life. Because I wanted to include the source file and line where a check failed I had to write an UnrealScript PreProcessor, and I also wanted a few other features that a precompile could accomplish. And that's why I created UCPP. Well, UCPP had some releases, and it quite mature and finished right now. So I've gone back to working on UsUnit some more. I've already made one release so far. But this was mostly to put out the first binary package for people to play with. You could consider it a beta release for now. I want to complete just a few more things for the next release, it can be summed up into: finish the webadmin module.
Also, today barnEbiss contacted me if I was interested in helping him with a weapon mod. His idea is quite interesting. He wants to create a weapon that allows you to create a line of gasoline and set that one fire (the fire ofcourse will hurt people). It's quite an interesting weapon to create, with some interesting implementation issues to solve. So I will also be working on that project.
Well I guess that's all I have to say about that for now.
Posted by
elmuerte
at
23:00
PowerDNS express is no longer free. It used to be completely free for pretty much unlimited control over 5 domain names. It's a great service and the interface to manage the DNS entries was clean and simple enough. But because of various reason they can no longer provide the service for free. Too bad, I really liked it. Since my registrar also provides DNS services (my previous registrar didn't that's why I used powerdns) without extra cost I've switched to that one. Thier interface isn't as nice as the one provided by powerdns, but it doesn't cost me at least $8 a year. So here powerdns, some free advertisment in return for those years of free service.
Posted by
elmuerte
at
19:08
I'm a big LBA fan, have been since I first got the game (june 1995). I completed the game so many times I've lost count. After a certain point it's no longer fun to play the game because you know every little thing in the game. So I stopped with that. After a while one of the team members that made the game poped up with a windows port of the game (LbaWin). Since he was doing it by himself he could use some beta testers. I decided to help him out (just like quite some others) and started to play the game again, but this time to find bugs. I did that for quite some time. But before the development of LbaWin came to a stop I already got sidetracked from playing the game. So it has been quite some time since the last beta release of LbaWin. And for some reason I wanted to play LBA once more. Installed the game and started playing, only took me a few hours to complete the game once more (in all it's glory). I still know exactly what to do. The game just looks so small when you know what to do and where to go. But the fact remains that it actually is still quite a large game if you compare it to the time needed to complete other games. I mean, the first time I played LBA it took me quite some hours to finish it. I've played other games that I completed the first time in just a couple of hours. Ofcourse you could strech the game, but that might just make it boring. LBA is still a awesome game, I just want something new to explore. (note: stil have to replay LBA2, haven't done that in some time now)
Coming back to the point of something new, LBA has quite some places that could be expanded (made larger). And there are quite some places where more world could be placed between some scenes. It would be great if these things could be expanded. And maybe even add some side quests.
Some people in the LBA community continued work I started years ago and already made some tools to view and even edit the scenes in the game. Additional tools to compile story code and stuff like that are also being worked on.
Posted by
elmuerte
at
12:47
BeyondUnreal has been offline for a couple of days now. And because the UnrealWiki is hosted on the same machine so is that site. It kinda sucks, because now nobody can get any information from that site, unless they have a copy of the offline unrealwiki. I've created a UnrealWiki mirror using the offline copy. It's not perfect but at least you can still view all documents. The offline copy isn't great to use as a mirror because the case of the characters in the page names have been lost and subpages don't exist on-disk. So a direct link back to the original wiki page isn't possible (unless when you use the link at the bottom). It would be nicer if there was some way of distributing the unrealwiki over multiple servers, but I guess the wiki engine must be designed for that or else you would get annoying edit conflicts.
Posted by
elmuerte
at
15:02
Well I laid my plans for a VS.Net Package aside for a while, kept getting annoying errors outside my source code. I'm been working on a UnrealScript Unit Testing Framework, somewhat similar to DUnit and JUnit. It's called UsUnit. It's almost done, but UnrealScript doesn't allow me to do certain cool things (like point out what check() failed). For this I started to create a PreProcessor for UnrealScript: UCPP
UCPP stands for UnrealScript (Class|Code) PreProcessor, the extention for UnrealScript classes is .uc so therefor UCPP, I'm not sure what the 'c' stands for. So far I've implemented quite some useful features:
#define NAME VALUE
#if EXPR (#else) #endif
#define
statement#if
is quite extensive, simple boolean evaluations and some basic math functions.
But my current problem is with defining function macros:
#define DUMMY(a,b) DoSomething(a, b) DUMMY("bla", 12345) -> DoSomething("bla", 12345);I'm having problems to create a nice way to implement this feature. I don't want the definition list to be depended on a parser, but how do I process the definition to replace the arguments.
a
should be replace, but aa
or "a"
shouldn't be replaced. A simple replace text routine won't work.
I could write an eventOnParseArguments(args: array of string; func: string; var OffsetList: TListOfSomeSort)
#
and ##
).But I guess that can be hacked in to the offset list in someway. Or I can add self
and give direct access to the object that is actually being parsed.
Posted by
elmuerte
at
09:37
Ok, adding a new tool window wasn't hard at all, actually it's quite simple.
Just create an ActiveX form, get it's GUID from the type library window View -> Type Library
and call the following functions:
myToolWindow = DTE(Application).Windows.CreateToolWindow(AddInInstance, 'your_library.activex_form', 'Some Title', '{THE GUID}', dummyIDsipatch);
The form is just like any other form in Delphi, you might want to set the form's AxBorderStyle
to efbNone
.
One ting, when creating an activex form Delphi automatically changes the target extention to ocx
, I didn't like that and changed it back to the normal dll
. Also, don't forget to register the "ActiveX Server" when you added a new COM object, otherwise the GUID won't be registered in the registry.
Posted by
elmuerte
at
18:55
I'm planning to create a spin-off of UnCodeX (again), this is going to be an add-in for VisualStudio.Net. Right now Epic has a simple tool that gives a class and package tree, but compared to UnCodeX is kinda inferior. Since I have a lot of base code it would be easy to create an add-in right?
Well not completely, first the add-in creation is done via an wizard in VisualStudio, well great, but how would I do the same in Delphi?. The add-ins are all COM based, so I will have to import a type-library somewhere. The VS.Net wizard does all the base work, so I have a few pointers, like what interfaces I should implement. But I have no idea what type-libraries to import. After a long search and some pointers here and there I've found out how to create a Add-in for VS.Net in Delphi.
Microsoft Add-Iin Desginer
, the actual file is called: MSADDNDR.DLL
.
Microsoft Development Environment 7.0
, the actual file is called: dte.olb
.
Uses
tab.
I
)
Implements
tab_IDTExtensibility2
AddIn
interface
uses list: , EnvDTE_TLB, AddInDesignerObjects_TLB
Run -> Register ActiveX Server
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\7.1\Addins\
. The key name should be: <library name without extention>.<automation object name>
If you want to change the descript and version information in a later stage just open the .tlb
file in Delphi. This will pop-up the type library tool.
These are just the basics for a add-in, how the rest works is still a mystery, but I hope to solve it soon and report it here. Next thing might be how to add your own tool window, I assume this can done via an ActiveForm. The tool windows are refered to via the GUID in VisualStudio.NET, so it would be some more ActiveX\COM stuff.
Posted by
elmuerte
at
18:38
Delphi 6 misses (at least) one important feature: being able to create\manage build configurations. For my UnCodeX project I want two build configurations: debug (or development) and release. For the simple reason that the debug builds will include debugger information so I can use some tools to find memory leaks and what not. The release builds ofcourse should not contain the debug info and should be optimized. But Delphi 6 was no way to manage the project options\settings. You can have various "desktop" configurations, really don't see the use of that, but not build configurations. So far I've only found one IDE expert that helps me a little bit: GExperts. However, the way I have to use this isn't great at all, the overview of te configuration is completely lost and it doesn't store the alternate configurations on the project. This way I can't include it with the CVS and use the alternate configurations on other machines. This sucks a lot.
I don't know if newer Delphi releases do support management of alternate build cofigurations, I don't have the money to upgrade to a newer Delphi release anyway. Delphi 6 still works well enough for me, except for a couple of annoyances.
If anyone knows of an IDE expert, or maybe an other method, that makes this easier please let me know. Important to note that this tool has to be free (as in beer), or at least with a small price tag, because I don't want to limit people in being able to work on my open source uncodex project.
Posted by
elmuerte
at
09:40
I think I need to make my release schedule for UnCodeX a bit shorter. It has been almost 1 year since the last stable release. And I've only had a few major stable releases since the beginning. So right now, I'm going to finish all tasks that have a priority of 7 or higher and then I'll release a stable version.
Ofcourse I also need to update quite some documentation, specially the PascalScript part requires a lot of documentation work. I'm not really looking forward to do work on that part of the documentation. But there's not much choise.
I hope to release a new version before the last one is a year old, I think two weeks, but maybe a little more.
Posted by
elmuerte
at
12:02
I'm not going to stay Open Source is the way to go, or that everybody must switch to open source (altough it would be very nice).
I'm working on a fully Open Source programms (UnCodeX), and while working on it I sometimes use other open source tools (FreePascal compiler) and components (RemObjects' PascalScript). Both the examples are open source (and free software, in a way).
PascalScript didn't compile for FreePascal out of the box, but because the source was available I could apply the changes required to make it compile. I mailed my changes to the developers and they applied them to their SubVersion repository. Now everybody can enjoy PascalScript in FreePascal.
As for FreePascal, the ini file classes provided by Borland in Delphi 6 didn't meet up to some of my requirements, and because of the private
vs protected
shit I could override some functions. FreePascal provided similar classes, and because the license of FreePascal is compatible with the license of UnCodeX (both are LGPL) I could use the FreePascal implementation and make my adjustments. While I was making some adjustments I discovered a few bugs in their implementation (the Delphi memory leak detection script by Vincent Mahon helped me to find one of them). I reported the bugs I found, and the fixes for it, and they have been applied to the standard distribution of FreePascal.
So, for at least two projects I found some issues, was able to fix them and contributed the fixes back to the creators. They helped me, I helped them in return. Sure, there are a lot of people that don't help out. But why shouldn't you? What would be the reason not to help others out that helped you at the first place. Please that report bugs are great, people that report bugs with correct patches are just awesome. And you can't create patches when you don't have source access.
Posted by
elmuerte
at
11:01
Pretty much every object oriented programming language let's you set the visibility of object members. Usually it defaults to public
. That means everybody can access that member. Ofcourse often you don't want to other objects to access certain parts of your object. This is where private
or protected
come in to play.
An object should only expose members that really need to be accessed from the outside. All other members should be "hidden". It's not just a security issue but also creates nicer foot prints to work with the code. For example IDEs only have to list the public accessable functions in their "code insight" (or whatever you want to call it) listing. The public members are the members to work with, it also makes it easier for you to find what entry points you need to use on an object (in case it's not your code).
The actual outcome of this depends on the language. But usually it comes down that only the objects within the same scope can access this member, subclasses do no have access to this member. What the scope is depends on the language used, often the scope is just the object itself. In ObjectPascal however the scope is the unit file (the source code).
One of the basics of OOP is that you can extend an object and add additional functionality. And usually you can only add additional functionlity outside of the "scope" because you can either not touch the original source or you simply shouldn't.
Using private
to protect members of an object will prevent an subclass to work with these members. This is often needed.
Protected
is similar to private
except that subclasses can always access these members no matter if they are in the same scope.
Making members protected opens a security issue for those members. Since a subclass has access to these members it's possible to work around security measures.
I'm sure somebody already though about that, however I am not aware of a document that introduces a formal method for member accessability. If such document would exist it would be very technical for most programmers to understand, or at least it would way to time consuming. That doesn't mean it's not wise to read it and use it's methods.
Here's a simple classification scheme I think should work well enough for most people.
public
public
protected
private
and create a protected
accessor method; No -> private
protected
; No -> private
private
and create a protected
method that will validate and set the private
method; No -> protected
getMyVariable()
that will simply return the current value of the variable.private
so it can't be accessed from the subclass and create protected accessor methods (get and set). In your set method you will validate the new value and pass it to the protected member. This way subclasses will have to use the parent set method in order to write the new value.
//pseudo code var private string SensitiveInfo; protected function bool SetSensitiveInfo(string newValue) { if (newValue doesn't meet constraints) return false; SensitiveInfo = newValue; return true; } protected function string GetSensitiveInfo() { return SensitiveInfo; }
Posted by
elmuerte
at
10:07
MSIE doesn't really support the <button> as defined in the HTML 4 specification. Sure it does render a button, and something happens when you push on it. But it doesn't work as specified.
<input type="submit" name="mybutton" value="add this new entry" />
displays:mybutton = "add this new entry"
action
variable. It would be much nicer in the code if that value would be addChild
or addSibling
(also better for localization). But this is not possible with the <input> element. <button name="action" value="addChild" />add as child<button></button name="action" value="addSibling" />add as sibling</button>
produces:action
would be either addChild
or addSibling
while the text on the button is descriptive.Input[type="submit"]
elements in CSS).value
property, it will send the value of the innerText
(note: this is documented on MSDN), in other words, it will just behave like a normal <input> . ?action=addChild&action=addSibling
. This makes the button element complete useless since you don't know what button was pressed. This incorrect behavior isn't even documented on the MSDN.<button type="button" onclick="onButtonClick(this, 'action', 'addChild')">Add as a child
function onButtonClick(btn, name, value) { btn.name = name; btn.value = value; btn.form.submit(); }This will simply set the name of the button pressed to the desired name and set the value. After which it will submit the form.
Posted by
elmuerte
at
16:37
UnCodeX Tribes:V ponderings:
Posted by
elmuerte
at
14:18
LibHTTP 3 is getting pretty solid. I've added a test class to perform various requests. I already found a few minor bugs using that test class, bugs that have been in there for quite some time.
The build is currently 133KiB, I'm not going to strip source from the package because of the simple reason that you can no longer use the package during compile time, only run-time. Stripping the source would reduce the package to 54KiB.
I've been thinking about creating a better source stripper. It doesn't strip the complete source, only the function and state body. The result would be that the TextBuffer (that usually contains the source code) only contains the declarations. This should be enough to use the package for compiling, and have a minimal size. I would add a comment to the top of the TextBuffer explaining that the code was removed to reduce size and stuff. However, creating such a tool isn't every easy. You can't simply replace the TextBuffer with a new one, you will have to update all the offsets in the file. Note that this tool is not for code protection, because you can still decompile the package. It's just to reduce the size.
Posted by
elmuerte
at
15:41
Well found some time to work on LibHTTP version 3. So far I've made the following changes:
Posted by
elmuerte
at
13:03