Tag Archives: c2

Prototyping – A Killing House

After six months (almost seven!) I can say that I’ve reached what is effectively the ‘end of the road’ insofar as the Citizen prototype is concerned.

I’d like to recap what I am trying to accomplish in this prototype.

I am very aware of my inexperience; I’ve never done a game before, and so I don’t know what works and what doesn’t. I only have my own taste and sensibility for what it’s worth. Though I believe (or hope) I can pull it off, I don’t know what it really is, so this prototype has been an effort to put all the ideas that I’ve come up with into one package. I thought to myself that creating systems for a game is relatively straightforward. But can I integrate any number of those systems with each other, and have them work? If I can manage that in a prototype, then I would have the blueprint for an actual game.

I created this prototype with that mind. And having experienced the troubles of illogical inconsistencies in system, bugs of a generic sort, it feels like I’m about to ‘ship’ a game without the danger of flagellation from Steam reviews.

This is my version of the Killing House, where I rehearse and train for the game I’m going to make. I’m using live rounds and making it as realistic as possible because I want to, as much as possible, be prepared for the task up ahead. I put as much effort into it because if I can get this to a level that I’m happy with, then it’s quite possible that I can pull it off when I make the final game in Unity.

Making the prototype itself was grueling enough. I don’t remember burning so much midnight oil since I was a fledgling 3D artist back more than a decade ago. Not every idea or implementation would make it to the end. But none of those aborted/abandoned things were wasted on the experience of trying to make it.

For example, the game narrative script that I wrote at the beginning is now completely different. However, it served as a springboard for identifying and designing the systems I need to have in place, so it was still a profitable and necessary first step.

There were other ideas, like the ‘Multi-Vision System’, ‘Stacker’, and ‘Map Layers’ that I dreamed up up that had to be thrown away due to either being too oblique, complicated, or just plainly stupid.

Also, I had created and rendered NPC assets which were not used in the final version of the prototype due to a change in narrative.

While there are clear advantages working in Unity — certain bugs and limitations that I’ve encountered in C2 will no longer be relevant — I’m aware that I’m facing a world of hurt in Unity-land, too. Naturally, I will take advantage of what Unity has to offer, as well, such as a full 3D environment (something which I’m comfortable with), dynamic lighting, and a robust pathfinding system, among others. All the while, I must remember to keep it simple. It’s possible that I may have to even dumb down the game more so in Unity, to keep it within my capabilities.


Towards the end of the development, I started working on a introductory cinematic, which was a fun thing to do. It wasn’t intended to accurate represent the all the details of the story but only to give a good idea what it’s all about. Here are some screen shots:

Here are some additional screen shots demonstrating how it looks like.

Sample environment. On-screen interfaces (bottom, upper-left, upper-right)
Sample inventory screen. Item descriptions, icons.
Sample dialogue panel (Convo). Portrait.

I posted a gameplay sampler which demonstrates some of the systems in action.

… and sounds!

I’ve also cut up some audio (re-learning Cubase again!) to use with the prototype. I may post a complete playthrough in the future, perhaps after some of my friends play it first themselves and hopefully give some feedback.



Why not C2?

(This is a follow-up post to my other one which explained the reasons for choosing to remain working in C2).

When I review this whole venture, it stems from the desire to create a game on my own.  I want to create the graphics, the logic, the story, the words, the music — everything — like how those guy did it back in the day when I was a wee child playing their games.

I came to use C2 because of its simplicity, and the quickness in which I can throw something together and get results. There’s nothing like instant gratification that hooks you in.

But as project size increases, so do doubts about working in C2. Lots of niggles, lots of creaks and groans give me doubts as to appropriateness of the engine/framework for Citizen. A framework is a convenience. But everything out there is a convenience except C++. I could have approached Corona or Phaser, I could have used Godot or Unity, and some of them might have been more suited to the task.

When you turn to an established game engine like Unity, you don’t tend to have that many doubts that your main goal is achievable if you were clever enough to code/design your game well. That’s because you see the sort of games that have already been developed and you can’t really argue with the fact that Unity is established for a reason.

Then you take a gander to notice the sort of games that C2 is generally used for, which is not the sort of thing Citizen is. There are plenty of developmental previews and tutorials of isometric games, — none of them are serious enough to take umbrage — but no finished product as far as the Search Engine can see.

Then one day, you come upon some kind of undesirable behaviour that you have no control over (because Construct is a very blackbox environment). You start weighing in the facts: that C2 isn’t being developed any more; that critical bugs appear in the latest builds; that downgrading is the only recourse because the developers will likely not fix it because they are committed to C3, an app whose design philosophy doesn’t nearly tick enough of your own boxes for you to use with dignity.

These leave you imagining the sort of adventures you’ll have with this little boat, which will receive no more refits, as it takes you across the pond. What awaits you, who knows? But there are tales of show-stopping, insanity-inducing odds, and some are journalistic facts as the asset obfuscation that you won’t get.



At the end of the day, it’s a ‘use the right tool for the job’ situation. And as the days go by, C2 (and C3) are becoming less of the ‘right’ tool to actually publish a game. But as many C2 users know, C2 is great at prototyping. And so at prototyping it will be relegated to.

Even if from some miracle I complete the prototype and I am able to scale it to encompass the scope of the game I want to make, it will still be a hard-sell for me to publish the game in C2 because of the absence of even a rudimentary obfuscation method: another design philosophy that didn’t get ticked.

We shall see…

Importing into the C2 /Files folder


The C2 manual references the project file folder which contains other files other than its default.

Even though files and subfolders can be created in this folder, it doesn’t automatically become part of the caproj unless it is actually specified/registered inside the caproj. Inside C2, it is possible to ‘auto-import’ files, but this only works at the root level of /Files; directories aren’t traversed, making this mechanism suitable for single files, like configuration files.

However, when using the Files folder in other ways, such as replacing animation using Rex’s Animation Loader, it would be a monumental task to get all these files in. So I’ve written a Python function that traverses any given folder and writes out a block that can be copied and pasted into the caproj, which is near the end of the caproj. Perhaps in future, I will make the procedure more seamless; right now, the manual copy-paste is for security reasons.

The code below is very unpolished, but gets the idea across.

def make_xml_c2_file_folder():
    ''' Create a folder structure in caproj/xml format with a given directory
        The intention is to create a sprite animation folder in the /Files
        project folder, and have that referenced as imported files in the caproj.
        The output of this function is to be copied and pasted into the caproj.
    gb = glob_buffer()
    ext = '.png'
    filesdir = 'X:/GAME_PROJECTS/c2/Files/'
    unitdir = 'hero_w'
    rootdir_name = '%s%s' % (filesdir, unitdir)

    rootfolder = CaprojFileFolder(rootdir_name, ext, filesdir)
    gb.buffer += '\n%s' %rootfolder.xml

    fn = 'c:/outputcaproj.txt'
    f = open(fn,'w')
    for b in gb.buffer:

def process_folder(folder,gb):
    for c in folder.content:        
        # print(c)
        if isinstance(c,CaprojFileFolder) == True:
            # print('hi')
            gb.buffer += '\n%s' %c.xml
            gb.buffer += '\n\t%s' %c
    gb.buffer += '\n</file-folder>'
class CaprojFileFolder:
    ''' The folder class contains info about the folder, eg content, name '''
    def __init__(self, path, ext, rootdir):
        # code below considers trailing / separator like c:/test/folder/
        # where the last -1 index will contain ''. code below doesn't allow that ''
        self.rootdir = rootdir # root for relative path
        self.ext = ext # allowed file extension
        self.name = [x for x in path.split('/') if x != ''][-1]
        self.xml = '<file-folder name="%s">' % self.name
        self.path = path
        self.content = []
    def get_folder_content(self):
        mf = matchfiles_full(self.path,'*')
        for m in mf:
            if os.path.isfile(m) == False: # folder
                newfolder = self.__class__(m,self.ext, self.rootdir)

                fl = [x for x in m.split('/') if x != ''][-1]
                # check if extension is allowed
                relpath = self.path[len(self.rootdir):]

                if fl.endswith(self.ext) == True:
                    fls = '<file name="%s/%s" />' % (relpath,fl)

The class CaprojFolder represents a folder and the contents of the folder (stored in the content list). An element in content may either be another CaprojFolder object, or may be a path to a file. The caproj code snippet is written in a text file in the C: drive (!).

Once this snippet is pasted over to the caproj new folders and subfolders would be created in the /Files folder the matches the one found in the file system. The only major difference is the name of the actual files, which I explain below.

Referencing the files

Though the script mimicks the file system folder structure, C2 does not use these folders as a path to the file. In other words, C2’s folders structure is purely for visual organisation within the C2 editor. The files themselves are treated as though they were in the root directory. Therefore, I opted to name the files to represent their full relative path.

For example, say the script references a file: hero_w/run/000.png

This file is put under /Files/hero_w/run. But it is also named, literally: hero_w/run/000.png, and not just 000.png as you would normally expect. If I had named the file 000.png, there would be no way to distinguish this 000.png with other files in other C2 File subfolders. So a unique name was necessary.

Slidewalk TMX and C2 system

The Slidewalk system, taken from 2400AD is implemented by using several components in Tiled, and hooking them up in C2.

Tiled/TMX Component

The Slidewalk is comprised of several objects which are the children of an ObjectGroup; the ObjectGroup, in effect, is a single Slidewalk entity.

Components of a Slidewalk

What identifies an existence of Slidewalk is not the ObjectGroup, but the individual Objects which must be named starting with the prefix sw. Each Object component of the Slidewalk contains the name of the Slidewalk it belongs to. The name of the Slidewalk is the name of the ObjectGroup.

A Slidewalk must always have a path. A path is a Tiled polyline. It must be named swpath. The path will later define the waypoints of the Slidewalk. The swpath Object must also contain an attribute called speed. This is the speed value of this Slidewalk.

A Slidewalk must have at least one entry-only point. This point is defined by using an Object (parented under the Slidewalk in question). It must be named swin.

A Slidewalk must have at least one end-only point. This point must be named swend.

A Slidewalk may optionally have an exit point. This exit point may also be a potential entry point. Every point, whether it is an entry, exit, or end point, must begin with sw. Then use the keyword in to indicate this is an entry point, and the keyword out to indicate it is an exit point; these keywords may be used in the same point, such as swinout.

The exit and the end points must also contain a custom property called exitdir. This is a GridMove direction that specifies which direction the player will move towards when deciding the exit, in order to get off the movement effect of the Slidewalk.

C2 Implementation

In C2 the first step is to get the swpathObject to mark the waypoints of the MTiles. In the same procedure, they are marked with the name of the Slidewalk they belong to. The waypoint sequence index is internally based on how Tiled writes it, which is sequential anyway, so the C2 loop iterator does this conveniently.

As the MTiles are being tagged as waypoints, they are being added into the InstGroup with a group named after the Slidewalk’s name, which uniquely identifies these series of MTiles for SLG and GridMove. They are added in the order they are looped, so the sequence is still preserved at this point.

MTiles are then further marked with their entry/exit/end values, as well as the custom properties as inputted in Tiled.

When the player moves on top of the Slidewalk, the On GridMove reach target trigger will check whether the player is on an entry point. If it is, a function called CreatePathFromIG is called whereby it takes the Slidewalk InstGroup waypoints and transfers those waypoints to the player’s own InstGroup moving path. CreatePathFromIG does something more, though: it considers the possibility of multiple entry points; it finds the MTile that the player has entered from, and starts retrieving MTile waypoints from that point until the end.



Why C2?

For the past many weeks, I’ve been focusing a lot on the development of the animation sheets. But because of this, I hadn’t touched the former aspects of the game for some time, and when I got back to it, there were some issues that were brought to the fore, such as the Beltway being broken. To be honest, I was utterly surprised at this, since I had no recollection, or notes, that say that it had been broken when I left it to develop the other parts. There were also other things that I noticed that needed changing as I tested the implementation of the animation sheets along with overall player movement.

I found myself a bit overwhelmed and a bit tired, as I sometimes do, from having to debug C2 events. For all the user-friendliness it has, it can still be be quite opaque especially if you’re trying anything abstractly complex. It’s not totally the fault of C2, but because of its lack of modularisation, or object-oriented framework within the event system, picking apart why something doesn’t work requires a bit of jumping around, trying to sort out which are workarounds to some weird behaviour, and which ones are meant to do something actually functional.

Anyway, for several minutes I stared at the monitor, and I was seriously debating why I’m developing this game in C2, and not in Unity, where I have some experience in, and the fact that I’m actually good at coding (at least good enough not to doubt my ability to see the project through). Not only do I code, but I’ve been in the CG industry as a 3D artist and TD for 15 years now; on that alone, Unity is more of a familiar programme than C2. But I had a discussion with my wife who takes these technical diatribes with calmness and puts out good arguments, and the result is my rethinking of my situation.

So the question is: why C2?

It began with the fact that C2 made things simple. But what I’m doing with CITIZEN is not so simple. And that reason seemed to be not good enough.

C2 is fun because of the event sheets. But though the event sheets are effective, they are effective as procedures. They are less fun, and less effective when you want some object-orientation or inheritance, which is so useful when when I started delving into certain gameplay concepts that I wanted to implement for the game.

But I think one of the strongest reasons is one of a balance between a simplistic framework, and the relatively blackbox type of plugin filtered into the C2 editor which results in less bugs during development. This is both a pro and con. Taking Rex’s GridMove/Board/SLG/InstGroup system. These are separate systems working together as one. But it has some learning curve to understand how it all of them work. In fact, some components actually need the other, so they’re really necessary modules in order to come up with something like an isometric grid framework. But once this framework is up, the input and output (eg On reach target, On move accept) is unambiguous, and can interact naturally with any other event/behaviour in C2. Why unambiguous? Well, first, the C2 editor registers the event, so it’s part of the choices. Unity, on the other hand, can be quite confusing in this respect; what event handler is being called?; a search through the documentation is necessary.

In Unity, it is possible to get a well-written framework, but you’re going to have to try it out first before you know what you’re going to get. Sure, that’s the same with C2 plugins, but the C2 plugin framework shields you from some the randomness of 3rd-party scripting. C2 plugins follow C2’s rules in order to play nicely with C2. You’ll spot a lemon faster.

But I think the most important aspect to plugin frameworks is simply that they can be added in without messing things up. I don’t have syntax errors in C2 compared to Unity, so if something doesn’t work, syntax doesn’t necessarily some into the picture. Even data types are managed.

I think the best example I can think of is trying to implement Unity’s 3rd-person controller setup to your own game. There’s so much going on in that package that if you try to fix it to behave how you want it, you’re going to mess it up so much that you might as well write your own to begin with. Unity is so flexible, but unless something is so well written, with open-ended framework development in mind (like, for example, PlayMaker), the Unity environment is pretty much like a sandbox.

C2, on the other hand, is more like a playground. You can’t move the playground that’s there, but you can add other stuff into it, transforming it into something new.

At the end of the day, this is just a hobby so it’s important to have fun. Fun is a major motivator. It’s obviously not fun when I have to deal with the awkwardness of C2, or when I have to refactor my events. It’s not fun when I accidentally change the image-point on one of my images and having no undo option for that. But nevertheless, it’s fun to figure out how implement features on an engine that offers a good starting framework.

Without a doubt (in my opinion, at any rate), it is primitive tool when you consider other production engines out there, open-source or otherwise. I think it is easy to outgrow the tools due to the ever-expanding ideas for a game. That’s partly why I had to limit the ideas that I was coming up with. Is that a bad thing? No, but I think I should like a separate post about that. 🙂

I think, however, in the future, after I complete CITIZEN in C2, I will more seriously consider using Unity for other projects that may require a more expansive toolset, especially one that may yield a better game by going 3D.

Workflow: Tiled’s tile IDs not to be referenced in C2

Tiled’s tile IDs are quite volatile. Ordinarily, each tileset’s first tile should be 0-index, but unfortunately, this doesn’t seem to be guaranteed and I’m not sure if it should.

In this forum post Bjorn himself suggested not to use tile IDs as a reference, and instead use tile properties to make a harder connection, which is what I’ve done: created an ‘id’ parameter and and just retrieved it from there.

The only issue here is that each tile ID must be manually entered, but this better than figuring out how to make tile IDs behave.

To make it solid, write a tool that reads the C2 caproj, reads the Sprite object, stores the image source for each frame of a Sprite: a text lookup to associate a filename with an ID.

For example, the lookup can read:

proto_walls walls_block.0000.png 0
proto_walls walls_block_cross.0000.png 1
proto_walls walls_block_ne.0000.png 2

Where the first token is the tileset name, followed by the image filename, followed by the animation frame, which is the ID.

Then the tool is run again on the Tiled-side. Going through each line of the lookup, searches for the tileset name, locates the filename (maybe ignores the relative path), then sets the ‘id’ property to the stored value.

C2 Sprite Manager



The C2 Sprite Manager (C2SpriteMan) was written by me, Lernie, and is a Python (exe wrapped) that views and modifies image files and their corresponding data as it relates in a .caproj (C2 project) file.

This project was originally done for LW (called LWC2), and for speed and flexibility, I migrated the code to Python and turned it to a Windows-based utility.

This tool revolves around a specific pipeline which involves mass creation of sprite assets from LW (or any 3D prog) and then conforms those renders to something that can be plugged into C2.

The tools works upon existing Sprites as they are defined in the .caproj file. This is due to the fact that ‘sid’ attributes in C2 might be better of be maintained by the host prog, so new objects are created only within C2, not externally.

The tool organises sprite graphics into ‘units’ (left panel) From ‘units,’ the individual sprites are displayed (right panel) where the name, its version number, frame duration, image-point file and crop-file and crop-image-point file validation, speed, looping and such parameters as found in C2 itself.

First, the frame number is determined by the actual number of frames found in the unit’s folder, and is used to debug if more or less frames were rendered than expected. There is an option to preview the unit animation using djv (hard-coded, so it djv must be installed). The frame rate is fed as an argument in djv so it mimicks what you would expect to see in C2.

The image-point, crop, crop-image-point files are another thing. First, the image-point is a special file generated in LW which contain normalised X and Y coordinates of the hotspot, and/or an image-point for a particular frame of the animation. It is formatted thus:

_IP_hotspot 0.1 0.2
_IP_gunpoint 0.5 0.12

Again, each frame of animation has a corresponding image-point file, and are named in a specific convention that makes their relationship apparent.

NULL.0001.png # rendered frame
NULL.0001.png.imagepoint # ascii imagepoint file

Note the use of the ‘NULL’ name. This is a constant name. Remember that these files are contained under the unit animation folder, so they are unique; there is no need to make them unique from other units as C2SpriteMan identifies the image based on the folder they are in, very much the same way C2 does it.

The next step is to crop the sprite, and ImageMagick (IM) is used as the tool for it. In this process, IM outputs a file that defines the cropping operation that it has done on the image. Since any number of sprites will most likely have a different cropping result from each other, this information is important because I can use it to modify the image-point file, which changes based on how much was cropped from its partner NULL file.

These cropped files are named as such:


These CROP files are used by C2SpriteMan as the actual usable sprites that is meant to be used in C2,

After cropping, the sprites are copied over to the C2 folder, which is defined as the /c2 subdirectory under the overall project folder. (Since I use many applications, I keep a main project trunk with major areas of delineation, depending on how much relative dependencies are needed for a particular use. For instance, LW, Maya, and C2 all reference relatively. But LW and Maya reference the same things, such as texture maps, cache, other shareable data. C2 references its own assets and files. So I kept the 3D side separate from C2)

The copy procedure transfer all renders to the C2 folder in strict accordance with how C2 expects them to be: file names are stripped down, and become the ###.png format, and are put in their own sprite folder. They were managed in 3D in the same way as C2 to make this process easier.

Once copied, all data can be ‘committed’ to the .caproj file. What ‘committing’ means is that any parameter change made to the sprites (eg changing Speed) will be updated in the .caproj file. This is a write operation on the .caproj, and a backup is made every time it is done. There is a drop-down menu on the lower-right that allows for rolling back to a previous version.

From the top procedure

I’ve just explained the process, but not in the sequence that it would otherwise be done. So this could be confusing reading for my future self. So this is how it’s done from the top-down.

Note that .caproj (folder-based projects) is necessary to use, for obvious reasons.

C2: Create placeholder Sprites

In C2, Sprite objects must be create beforehand. It is important to name the Sprites accordingly because this is essentially the unit name that need to correspond with the renders in 3D.

For purposes of illustration, let’s call our unit ‘hunter’.

Save the .caproj so that these modifications are reflected in the file.

3D: Rendering to expected locations

In 3D, it’s important to render to the following location


First note the /units subfolder under the /renders folder. This is mandatory token.

Then <unit> represents the name of the sprite unit (‘hunter’).

<animation> represents that particular animation name (‘walk’)

Though there is a <version> token, this doesn’t have to be used, though it is much better to use it because you can juggle around variations quickly.

When placed properly, you should get something like this:


In the Sprite list, note ‘Fr’ is 0. This means there are no frames there. In order for any frame to register as proper frames, they need to be named thus:


Note ‘IP’ is also 0. This means that there either have been no image-points generated. The number of IP should be the same as the number of Fr.

Note ‘Crop’ is 0, which means no cropped images have been detected.. ‘CropIP’ is the same deal.

Lastly, note that the C2-related parameters like ‘Spd’, ‘Loop’, etc, are -1. -1 means that no change should be done when you hit ‘Commit caproj’. If this value is larger than -1, then that value will be set in the .caproj as your desired value.

Let’s say now that some frames were rendered from the 3D application, and move on.

C2SpriteMan: Previewing, settings attributes

This step can be done at any point even after cropping.

You can preview the animation using djv. It takes the ‘Spd’ parameter and uses that as the framerate. If ‘Spd’ is -1, then djv will play it back with whatever default it selects.

On the far-right side, an Attributes panel shows the fields which you can adjust parameters of selected sprites. Hitting the blue button ‘Apply’ will apply your changes onto the sprites. These changes are stored in their respective unit folder, so that these settings are portable and will carry over as long as you keep those files in the folders they are meant to be in.

3D: Generate imagepoint files

Generating imagepoint files in LW means getting the projected camera-view space coordinates of a particular 3D location. I’ve done this in LW using LScript but this is a 3D-specific solution. I’ve not it in Maya, and I reckon it would be a different solution.

Either way, the generation of imagepoint files must follow the rules outlined in the first section. Once the imagepoint files are done, C2SpriteMan should reflect a corresponding value in the ‘IP’ column.

C2SpriteMan: Croppping

After generating imagepoint files, the next step is to crop the sprites. This not only crops the sprites but it also ‘crops’ the imagepoint files accordingly, taking the values there and trimming them so that the cropped imagepoint files will have values that register with their corresponding cropped spirtes.

C2SpriteMan: Copying

The next step is to immediately copy the sprites over to the C2 folder.

C2SpriteMan: Commit

After copying, you can then commit.

First, select the unit animations you want to effect. Then hit ‘Commit caproj’. This function looks at all the settings of the selected animations and goes through the .caproj, parses it, and applies the XML settings.

Hotspots and image-point attributes are derived from the .imagepoint files, while the frame-related settings are derived from the other individual settings inside the 3D unit folder.

Frame duration is applied based on the number of CROP sprites detected in the 3D unit folder.

C2: Check sprites

Open up C2, and confirm the settings.