GDR Forum Index
Podcast Podcast
Dev Dev Logs
Search Search
RSS RSS
Register Register
Log in Log in
Reply to topic GDR Forum Index -> Game Developer's Refuge -> Development Log - GEL and Foundation (Engine Tools) Page Previous  1, 2, 3, 4
View previous topic :: View next topic  
Author Message
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Sun Apr 03, 2011 8:39 am    Post subject: Reply with quote

I ended up experimenting more with my scripting language (Squirrel). I want the ability to create game objects by defining them as key=value pairs, and I want a little more flexibility than that.

So I've been considering the idea of using a scripting language as a sort of high-end XML or Modeling Language dialect. Create all "things" of a game in a scripting language.

One such script.

Code:
// - ------------------------------------------------------------------------------------------ - //
class BasicShaft {
    Digging = 0;    // Can dig, but no skill of any merit //
    Piercing = 1;
    Blunting = 2;
    Blunt = true;
};

class BasicDebris {
    Scatter = true;
};
// - ------------------------------------------------------------------------------------------ - //
    
// - ------------------------------------------------------------------------------------------ - //
class Stick extends BasicShaft {
    Name = "Stick";
    Shaft = 2;
    MadeOf = ["Woodchip", "Woodchip"];
};

class Bone extends BasicShaft {
    Name = "Bone";
    Shaft = 4;
    MadeOf = ["Bonechip", "Bonechip"];
};
// - ------------------------------------------------------------------------------------------ - //

// - ------------------------------------------------------------------------------------------ - //
class Woodchip extends BasicDebris {
    Name = "Woodchip";
};
class Bonechip extends BasicDebris {
    Name = "Bonechip";
};
// - ------------------------------------------------------------------------------------------ - //
class RoughStone {
    Name = "Rough Stone";
    Sharpening = true;
};
// - ------------------------------------------------------------------------------------------ - //

// - ------------------------------------------------------------------------------------------ - //
class SharpenedStick extends Stick {
    Name = "Sharpened Stick";
    Blunt = false;

    constructor() {
        // Sharpened form has improved piercing and all other attributes //
        Piercing = base.Piercing + 2;
    }
};
// - ------------------------------------------------------------------------------------------ - //
class SharpenedBone extends Bone {
    Name = "Sharpened Bone";
    Blunt = false;
    
    constructor() {
        // Sharpened form has improved piercing and all other attributes //
        Piercing = base.Piercing + 2;
    }
};
// - ------------------------------------------------------------------------------------------ - //

// - ------------------------------------------------------------------------------------------ - //
function Recipe_SharpenedShaft( InputSharpener, InputShaft ) {
    if ( "Sharpening" in InputSharpener ) {
        if ( "Shaft" in InputShaft ) {
            if ( InputShaft.Blunt ) {
                // Can produce this recipe //
                return true;
            }
        }
    }
    
    // Can not produce this recpipe //
    return false;
}
// - ------------------------------------------------------------------------------------------ - //

// - ------------------------------------------------------------------------------------------ - //
class IgnoreList {
    constructor() { };
    MadeOf = null;
};
// - ------------------------------------------------------------------------------------------ - //

//local Object = Bone();
//local Object = Stick();
//local Object = Woodchip();
//local Object = SharpenedStick();

// Dynamically generate the object by name //
local ObRoot = "Bone";
local ObName = "return Sharpened" + ObRoot + "();"
local ObFunc = compilestring( ObName );

// Instance the object //
local Object = ObFunc();

print( "Object is a \"" + Object.tostring() + "\"\n" );

if ( "Shaft" in Object ) {
    print( "Object has shaft " + Object.Shaft + "\n" );
}
else {
    print( "Object is no shaft!\n" );
}

if ( Object instanceof BasicShaft ) {
    print( "Object is a BasicShaft\n" );
}
else if ( Object instanceof Debris ) {
    print( "Object is Debris\n" );
}
else {
    print( "Object is of unknown base\n" );
}

if ( Recipe_SharpenedShaft( Woodchip(), Bone() ) ) {
    print("Yes\n");
}
else {
    print("No\n");
}

if ( Recipe_SharpenedShaft( RoughStone(), Stick() ) ) {
    print("Yes\n");
}
else {
    print("No\n");
}

if ( Recipe_SharpenedShaft( RoughStone(), SharpenedStick() ) ) {
    print("Yes\n");
}
else {
    print("No\n");
}

print( Object.Name + " is made of:\n" );
foreach( idx,var in Object.MadeOf ) {
    print( idx + ": " + var + "\n" );
}
print( "\n" );

print( Object.Name + " has properties:\n" );
foreach( idx,var in Object.getclass() ) {
    if ( idx in IgnoreList )
        continue;
    
    print( idx + ": " + var + "\n" );
}
print( "\n" );


Object is a "(instance : 0x026B90A8)"
Object has shaft 4
Object is a BasicShaft
No
Yes
No

Sharpened Bone is made of:
0: Bonechip
1: Bonechip

Sharpened Bone has properties:
Blunting: 2
Blunt: false
Name: Sharpened Bone
Shaft: 4
Piercing: 1
Digging: 0
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Sat Jul 30, 2011 7:12 pm    Post subject: Reply with quote

Hey! I'm working on new stuff again!

Today I finished the HUGE source tree restructuring I briefly talked about earlier. So big, I created a completely separate repository for it. The build system is now broken up in to "Target's" and "SKU's", where game/game build specifics go in SKU's, and Platform specifics go in Targets. Works really nicely, very happy with the setup. My "New Game" code is builds and runs on Windows and Linux, which was MORE than half the battle. All that's left to do here is migrate more platforms over, and eventually Smiles' code.


Also, I got a cool new toy from Razer in the mail (Hydra). Of course, I just *HAD* to make it work with my code:



Motion Controllers FTW!!
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Sun Jul 31, 2011 9:40 pm    Post subject: Reply with quote

Alrighty! Yesterday I got my new build system up and running on Windows (MinGW32) and Linux (64bit Ubuntu). Today I made some improvements (SKU folder was called "Custom" originally). The big thing I added though was Visual Studio project generation (as sadly, one cannot rely on MinGW alone if you want to sell apps in stores, same with GCC vs Xcode).

I am using something called Premake, which is like Cmake and Scons, in that it generates makefiles and project files (MSVC, Xcode). The difference between the 3 tends to be the scripting language (CMake is custom, Scons is Python, Premake is Lua). I find it far nicer to use that building a MSVC project in the IDE.

I talk more about my adventures here:

http://www.toonormal.com/2011/07/31/premake-my-new-best-friend-re-msvc-xcode/

So far I've only built a MSVC generator. The Xcode one I'll do later, once I get around to updating the Mac.
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Sun Aug 07, 2011 10:49 pm    Post subject: Reply with quote

Oh boy! I better take some notes about "What I did", before I forget.

* * * *

August 1st (Monday) - Sent Kindle Smiles off. Didn't do much else. Reading maybe?

August 2nd (Tuesday) - Saw Cowboys & Aliens. Experimenting with Squirrel scripting (trying to figure out why it doesn't do what I'm expecting it to do). Patched cJSON and added some other/alternative JSON and XML parsers to the codebase. Haven't done anything with 'em yet though.

August 3rd (Wednesday) - Got Squirrel scripting working as expected. Very happy with this.

Write brand-new font code: A reader for BMFont files. I still don't have a way to render them, though the data is ready for it. I need to make some tweaks to the Texture Pool stuff... Maybe. We'll see.

August 4th (Thursday) - Had an out-of-town friend over for BBQ. Blagged about the game alot. Didn't finish much though. Fixed a bug in my BMFont Kerning while I was out, away from the home due to real-estate checking the place out.

August 5th (Friday) - Lunch with friends. Watching Assembly 20XX archive videos for inspiration. Found some great ones on demo-making from 2010. I think I'll be taking some of the ideas presented here. Gotta make my process fast and cool looking, like a demo. Forget creating the perfect system. Get it doing cooler stuff now! Go me!

Also I should add SSAO, which means a deferred renderer. Hell, why not. All the awesome effects I want suit a deferred renderer anyway.

The ASD dude suggested that his demos tend to use just a few textures (3-4 he said, Madness!). Now that's economical. I should learn from that, make less but do more with.

And MAAAN! I need refresh keys ASAP! Or better yet, simply reload all (changed?) scripts upon the app gaining/losing focus. Alt tab to text editor, CTRL+S, Alt tab back: instant update. I want this.

August 6th (Saturday) - Watched Assembly 2011, and probably stayed up too late on Google Hangout. Researched stuff like SSAO. No real progress to show for the day though.

Actually, that's not true. I spent the day learning Wings 3D, and re-learning some Blender. I think Wings3D is a better tool, at least, some of the simple modeling features like extruding via normals doesn't create pointless gaps (like it does in Blender). I set out to make a treasure chest, but didn't have much luck (not happy with the results). Spent some later time reading more about Wings3D. I want to try again in the morning.

August 7th (Sunday) - Major refactoring. In addition to internal format textures, I can now load PNGs, PSDs, TGAs, and a few others (STB_Image). The final game doesn't need this feature, but for rapid development (and possibly mod support) I wanted to be able to read intermediate files.



Also, the groundwork is now there to change my TexturePool in to an AssetPool. I may still separate them per type (Texture, Model, Audio, Other), but undecided.

Made a working "Treasure Chest" model in Wings3D, and imported in to Blender. Learned that Collada (DAE) files between the 2 have different UP axis. 3DS files and OBJ files work fine, but it seems OBJ files lack "non-smooth" support, and 3DS files have many DOS era issue (8.3 filenames and such). Hmm.



TODO: I need to get shaders working again. I set-out this morning to do this, but ended up on the Texture Pool stuff (since I found some horrible design problems). But anyway, I want to start having/using a spec file or script file that defines the render stages.

Also, I want a dummy shader that uses face normals as a shadowing value: like SSAO, but without any actual attention or understanding for local objects. Merely, a way to have shading in the interim until the SSAO and other deferred effects work. If affected by the same values, it may work as a "super-low spec" alternative.

Will probably use an Ubershader (i.e. one big shader of shader-feature #ifdef's).

I want to track the current framerate, and dynamically use smaller regions of the render targets to compensate for frame-loss. I was watching Carmack's keynote from Quakecon, and his shpeil reminded me of this. I have already done this before in Smiles for a horrid Samsung phone, but it wasn't dynamic. I simply picked a fixed scale that worked better.

Render yay fun!
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar


Edited by PoV on Mon Aug 08, 2011 4:21 pm; edited 1 time
View user's profile Send private message
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Mon Aug 08, 2011 2:04 pm    Post subject: Reply with quote

Okay, so I have a cool short-term goal I'm aiming for; Something Madgarden and I like to refer to as Live Coding.

Our conceptual Live Code system means built in text editor inside the application, but what I'm thinking probably works better and is simpler to do than that. In essence, upon resume of the application: scripts, shaders, and assets will be checked for updates. My thought is you must alt+tab to get to the text editor to change code anyways, so I simply start a check whenever the application regains focus.

In theory, at least early on it shouldn't block too much, but I suppose the file check process could be moved to a thread. That may mean adding a job system: start a job, check if the job is done somewhere in the main loop (as responding right as it finishes may be unwise, as it could conflict with currently accessed resources).

I'd like to eventually add in-app log display, maybe a full fledged console. I'm using the Squirrel scripting language, and I guess theoretically this is possible. Hmm.

At the moment I'm dealing with asset loading. Yesterday I added a general Image/Texture loader (for general file formats), and now I just added general 3D model loading via something called Assimp. Its easy to use and works very well. At the moment I convert a loaded model via Assimp to my native format, and really I'll probably stick with this.

A bit scatterbrained and all-over the place regarding what's next (animation playback?), but the end goal is Live Code.

I'm hoping to have this up and running by the weekend (gotta start Ludum Dare prep then... not prep for me to enter, but the compo is next week, so I gotta ready the event!).

Fun fun.
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
Sirocco
Moderator

Joined: 19 Aug 2005
Posts: 9412
Location: Not Finland
PostPosted: Mon Aug 08, 2011 2:05 pm    Post subject: Reply with quote

Quote:

The ASD dude suggested that his demos tend to use just a few textures (3-4 he said, Madness!). Now that's economical. I should learn from that, make less but do more with.


Procedural generation is immensely powerful -- I also remember reading that much of the data used in ASD demos is precalculated and stored until needed. But if you wander through the demos you won't see much in the way of identifiable textures; lotsa primitives, lotsa shaders. Shaders out the wazoo ^_^
View user's profile Send private message Visit poster's website
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Mon Aug 08, 2011 4:15 pm    Post subject: Reply with quote

August 8th - Now that the general model loader works, I may as well take a shot.



As you can see (X-ray), I modeled insides. The model may be too geometrically detailed for actual use (dunno yet), where I'll have to replace the dents with Normal and Parallax maps.

Added AnimKit to the source tree (a skeletal animation library, a derivative of OgreKit and Bullet), but it seems a bit complicated to actually use at this stage. I'm going to leave it for now.

Walk time.
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
n29
Developer

Joined: 13 Sep 2005
Posts: 879

PostPosted: Mon Aug 08, 2011 7:22 pm    Post subject: Reply with quote

1) I counsel caution in going down the live scripting route. I've done this type of thing in Java apps where your scirpt has access to EVERYTHING in the jvm, and every class on the classpath. It takes a lot of care to determine what run time objects to make available how to expose them.

2) Wow, animkit and assimp are really cool. I had no idea that stuff was out there. Looks like you'll have to evaluate dealing with other peoples comlexity and libraries vs rolling you're own.
_________________
My Blog
View user's profile Send private message
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Mon Aug 08, 2011 7:35 pm    Post subject: Reply with quote

1. Yes, I agree. I'm not giving access to all, but letting the scripting determine the rules and function of things. Object interactions, Asset loading/optimizing, and most technical things will handled on the C++ side, but it will be completely dumb. Health and damage may possibly be implemented on the C++, but the script says if an interaction hurts. We'll see. I'm playing it by ear. Bottom line I'm not going 100% scripting. I'm too comfortable with 100% compiled, that I can only go a little bit at a time.

2. AssImp works really great. I've only used it for a whole couple hours, but it does everything you pretty much want in such a library (even post-load processing such as triangulation of quads, calculating normals, whatever you want).

AnimKit I stumbled upon after a friend told me there was Blender model loading code inside OgreKit (a project run by the dude that made Bullet the physics library). This is just one isolated little piece, almost entirely standalone (uses Sony's vectormath library, included with both this and bullet). Very cool. I definitely plan to use it, since it does some of that fancy animation blending stuff that stops arms from collapsing in on the socket. Score!

But yeah, I'm usually very against using 3rd party libraries, but this time I'm making an effort to broaden my horizons. This project is going to take me a-lot of time, and while I refuse to use complete middleware (Unity), I should still get SOME advantage.

A different kind of "growing up" with this new project of mine. All that matters is finishing, not my "from scratch" coders pride (what a stupid thing).

I'll be doing the rendering though. ;)
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Tue Aug 09, 2011 7:56 am    Post subject: Reply with quote

August 9th - Wrote a very basic libCurl test app that pulls a file down from a URL, and set up a place on my webserver for something like this. I was going to write an auto-updater/installer, but I'm pretty tired today, and I don't need it right away.

Seems the IGF Deadline is October 17th. Too soon... but you know, I am still wondering what I can get done by then. If it's something of merit, I may enter, and an updater would be useful to cheat the deadline (I think updates are legal anyway).

Anyways, I need to focus on the most important parts. I can revisit this idea of an updater in October.
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Thu Aug 11, 2011 8:15 pm    Post subject: Reply with quote

August 9th (Tuesday): See above. +new Planet of the Apes (enjoyed it).

August 10th (Wednesday): Did the core integration of Squirrel (not just a test). It doesn't do much, but it's there. It just needs to be fed an actual game script.

Began converting my TexturePool in to an AssetPool, a generic thing for reading and caching content. At the end of the night it was broken, but nearly working. Was segfaulting for a couple hours at the end, but managed to trace the problem back to a null-pointer instance of a class, and that I never would check the "this" pointer if it was zero. With checks in place, we simply did not work instead of crashing.

August 11th (Thursday): AssetPool works. I can now load textures and scripts with it. Other assets just need to be added.

Finally moved my logging code in to a function (was all #defines, as var args are easier that way). In anticipation of an integrated something (probably not in the near term though).

Though I feel accomplished, I guess I really didn't do much today. Huh.

I dunno if I'm on schedule to have live-coding working by the weekend, but I am close to having scripts and content bits refreshing upon resume. I guess if I hook up a script that does something, and add some smarter checking than "reload all", and call it in my focus gain/loss, I'll have met the goal. Surely I imagined more, but having that in place will be a good first step. I think the setup just needs more thinking, thinking I can do later once I really start using it.

Rest of the weekend I may be caught up with some Ludum Dare site stuff.

EDIT: Okay, now with a TODO list (above) I knew what to do. Dummy script loaded and executed. Setup could be cleaner, but is acceptable. Next TODO item is to figure out how to safely reload/overwrite a script (execute again it seems), then hook it up to the focus gain/lose.
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Thu Aug 11, 2011 9:28 pm    Post subject: Reply with quote

Okay, that's better.

Script reloading now works. I have a function linked to the spacebar, prints a message to the console. When the window loses and eventually regains focus, it (currently) reloads all scripts.

That's what's next, making it smarter than reloading all scripts.

Not today though.


The current script I'm using is a really long test script of much printing and experimenting. For game uses, I'll have to use something far less noisy. Also not today, as I really don't have a purpose yet.
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Thu Aug 11, 2011 10:30 pm    Post subject: Reply with quote

Some scheduling thoughts, by week.

Aug 14-20: Slower, due to preparing for Ludum Dare (and kicking off Friday)
Aug 21-27: Slower, Post LD early in the week.
Aug 28-Sept 3rd: "Dead Stop". Packing, and moving.
Sept 4-10: "Super Slow". Unpacking and setting up new apartment+studio.
Sept 11-17: Slower, LD results.
Sept 18-24: Slower, Kicking off "October Challenge" end of week.
Sept 25-Oct 1st: Slower, Probably watching some challenge site fun. :)
Oct 2-8: Good!
Oct 9-15: Good!
Oct 17th: IGF Submission Deadline.

9 weeks, 1 with very little chance of work. So 8 weeks to go from nothing (some unfinished libraries, unconnected middlewares, no content) to something presentable... Eeee!

To be honest, I really didn't think I'd be able to have something for the IGF deadline, and after seeing this layed out I still don't. But a part of me still wants to try. I set the goal of having all my "shit" in a state where I am creating content that will appear in the final game, and I think that's still a fair goal. One-upping that, I'd like to have core gameplay functional, playable, and able to hand over to someone in controlled conditions. Rational me says that won't be by the middle of the month, as there are still many unknowns, but I may be in better shape by the end of October (for the Oct Challenge end).

Too many unknowns to be sure of anything.

I have 5 big TODO items I need to deal with (aside from those I forgotten) that need to be done before anything resembling game code can be started (at least, given my proposed technical requirements).

1. Smart livecode refreshing - I'm doing now (hopefully no more than a couple days).
2. Merge OpenGL 1 and 2 branches. This just needs to be done (couple days).
3. BMFont Renderer. I just need to finish/do the render part, and tie in to the AssetPool. 1 day (I hope).
4. Ubershader. Get that structure ready, and doing livecode style refreshing. Capture to buffers, render targets. Hopefully 1 day.
5. Renderlist. Something like a scenegraph, but configurable render stages. What passes to do and such.

So okay. Maybe I can get those in before Ludum Dare (next Friday). I would be so happy if I do.

Onward!
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Fri Aug 12, 2011 8:52 pm    Post subject: Reply with quote

August 12th: I have a function "Log( ... )" that outputs text to the console. For Smiles, it worked exactly like "printf", meaning that you had to end each line with a \n newline. I today changed it so it now auto-adds the newline for you.

Funny enough, my prior project (PuffBOMB HD) I auto added the newlines (<< endl). In retrospect, it makes the code cleaner NOT having littered it with \n newlines. One of the biggest failings of PuffBOMB HD was over-engineering to be one thing, heavy C++'ism use and inheritances, totally hell to maintain. So I threw away all the fat when I did Smiles, and I guess this is one thing I never went back to correct.

Actually, up until now, I was using macros to handle the variable arguments stuff (since it's easy and I didn't have to understand va_list's). Now I'm using actual variable argument functions for my printf wrapper. It's ready for the next step of capturing and displaying data to an in-game console, to a file, etc.

My logging functions are now:

Log( ... );
VLog( ... );
VVLog( ... );
VVVLog( ... );

The V's are for verbosity. I tried doing Log Levels in the Log function itself way back on PuffBOMB, but I hated it. I always ended up hardcoding worthless values, and not knowing what to use. This time, each logging function has an internal "Log Level": Log is 1, VLog is 2, VVLog is 3, VVVLog is 4. Simple. Also, instead of a macro, LogLevel is a variable that these check, and can be changed to get more detailed system logging. Right now changing is done inside the C++ code, but eventually I'll have a means to set the level (via scripting console).

In addition, I have _Log( ... ), _VLog( ... ), and so on versions that DO NOT automatically add a newline. That way, I can make and compound multi-line things.

Log( ... ) is for important details that should not be missed. VLog( ... ) is for details that are useful for debugging, but not particularly useful to end users (stepping through the body of a function). VVLog( ... )'s specific use is undecided (as VLog covers much). It'll probably be Verbose things that "just don't matter". Finally, VVVLog( ... ) are super verbose logging cues. I sometimes place Log("**") like statements in code, several of them at different spots, so I can visually trace how deep something gets before seg-faulting.

I should probably add a MAX_LOG_LEVEL macro to nix stuff like my super verbose messages.

Lots to say on a somewhat minor effort, but important tool. Hell, I use logging almost every day... every hour (that I'm coding).

* * * * *

What I did that was useful and new though was I got asset change detection working. I can ask an Asset in the AssetPool "Have you been change?", which is a mere look at the modified time, but enough.

I also keep a list of scripts now and reload them all if they change. This is useful. This works nicely.

I need to make this apply to other assets.
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Sat Aug 13, 2011 12:01 am    Post subject: Reply with quote

Restructured where I place and pull files from. The main script is now a file "Main.nut", under the SOON TO BE VERY POPULATED Scripts/src/ folder.

Also, I did something I wouldn't normally do, but makes total sense: I made the source folders (source art, source models, source scripts) the FIRST place that is searched for content (at least, in the NON-RELEASE build). That means some heavy duty and max-res RGBA8888 textures get loaded first, which is meaner than I usually have (RGBA4444, often half of max res), but I run decent-enough PC's that it should be okay. If I want more performance, I can use the optimized/compiled assets...

I also added a RELEASE_MODE define that moves the Art and Model source folder searching to later in the search tree, natives get found first, with the sole exception of scripts. Compiled scripts will always be found last (i.e. in the absence of a source script, it uses a compiled one).

I am going to eventually have LOTS AND LOTS of tiny little files. By the time I ship, I may need to add a packed-file file system; Smash all the compiled assets in to a big massive file... Maybe just an ordinary TAR file?


LiveCode stuff isn't done (I still don't refresh art/models, nor even load models with the AssetPool), but it's probably done enough for now. I have scripts, and that is a big big change for me. They can't do much more than print, but they are in and they refresh. Well, the one file I have refreshes.

My point: On to the other items on the 5 item TODO list above.


Oh, and yes, on Logging.

Log -> [i.e. Level 1] -> Stuff that's always shown (unless LogLevel gets set to zero)
VLog -> [i.e. Level 2] -> Extended log information. Useful information talking about the stages of a task.
VVLog -> [i.e. Level 3] -> Further extended logging information. Essentially, VLog calls that annoy me. My way of shutting up w/o removing.
VVVLog -> [i.e. Level 4] -> Max extended logging. Stuff that is really not useful, but I don't want to delete. *NOTE: MAY DISAPPEAR IN RELEASE BUILD (undecided)*

Special Level 0 -> No Logging.
Special Level 5 -> All Logging.

My personal default setting is 2, but the game will ship with it set to 1. There should be a way on the command-line to change the Log Level. On Windows, a specialty shortcut with Max Logging enabled should be in the start menu. <-- Remember to do this me!

I have some further log functions actually.

LogAlways -> Disregards Log Level. Shouldn't technically be used.
DLog -> Disregards log level, but only shows in the debug build (not NDEBUG). Shouldn't technically be used.
ELog -> Print a bunch of extended debug information, Line number called from, File called from, Function name called from. Disregards Log Level.

All with their _Underscore variants that omit the trailing \n newline.


I'm expecting to add the Log, VLog family of functions to my scripting, but just those 4 (with _Underscore variants).


Yeah, really, this logging stuff is SUPER IMPORTANT, since it'll dictate how prepared I am to track down weird bugs. I think I'm satisfied with the above, short of adding Assert's. I am thinking about possibly having 2 types of asserts, Debug Asserts and Release Asserts, the later being ones that ship in the final game. In a way, ELog is like an Assert, but it lacks the built-in check. I think I'd also like a version that returns common error codes (0, -1, false, true), like actual { return value; } code bodies, since that's what most of my ELog instances are. return_0_Assert(...), return_1_Assert( ... ), return_negative_1_Assert(...), return_true_Assert(...), return_Assert(...), return_false_ELog(...), etc. ALog maybe for the release one? Still thinking.

Should have a "Debug.h". I have a "Debug/Log.h", and a legacy "Debug/Assert.h" (and a Debug/Bitch.h, which a class you derive from that is very noisy about its creation and scoping). All my code references the Log.h file though, which it shouldn't. Oh boy! New refactoring task!
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
Sirocco
Moderator

Joined: 19 Aug 2005
Posts: 9412
Location: Not Finland
PostPosted: Sat Aug 13, 2011 6:22 am    Post subject: Reply with quote

I have a similar logging setup, which I finally resorted to after I ran into a pile of nasty bugs in Inimicus. I've got a #defined threat level, which is checked against the level of the logging call, so only stuff as banal as I want slips through.

I totally agree with you: this stuff's ultra-important. You won't care when things are going well, but when shit breaks you'll love it.

If only I could go back in time, and clue my derpy ass into this stuff while I was working on my more epic projects :|
View user's profile Send private message Visit poster's website
sonrisu
Moderator

Joined: 31 Aug 2005
Posts: 4977
Location: Silicon Valley!
PostPosted: Sat Aug 13, 2011 12:15 pm    Post subject: Reply with quote

Why have multiple levels of logging defined as separate methods? It then turns into a mind game of "which level of logging should this log be? Hmmm....". I think it makes more sense to do something like the following, where you give your logs a "category" as to what the log message actually pertains to:
Code:

LogMethod(logCategory, logString, ...);

Then, you can configure whether logCategory actually logs anything or not by reading a script or external file to your game, and keeping track of the "enabled" logs in some sort of hash for quick lookup. No recompiling necessary to turn on or off any level of log verbosity.

By default, LogMethod does nothing, since none of the categories will be defined. For example, if you enable the logName "assets" (externally to your game), all logs that looks like this will actually write to your logfile:
Code:

logMethod("Assets", "Couldn't load asset foo: %s", assetName);


Some example log output could then look like this, making use of the category so you don't have to be overly verbose in your actual log message (since the category narrows it down for you):
Quote:

[date here] [PNG]: Corrupted header data for png: baz.png
[date here] [AssetLoading] : Couldn't load asset foo: C:\dev\foo\bar\baz.png
[date here] [Initialization] : Deinitializing due to asset loading error


This way, you can create arbitrary categories of logs without having to change a thing to your logging method. You just pass whatever string you want in as the logCategory. You can leave all your logging method calls compiled in release, too (okay, so you'll take a method call hit that turns out to be a no-op, but it should be no big deal)!

Someone in the field has an issue? Go ahead and tell them to modify logCategories.txt and put in the categories you care about (since you probably have an idea of what area of code is breaking). Have them rerun, reproduce, and send you the log.

If you want to get super crazy you can have the logging system log everything concatenated into a big logfile, while simultaneously writing logs out to their individual categories if it turns out you don't need multiple categories threaded together in a single file. Furthermore, you could turn on all logs without having to list out every single category by having a special category "everything"--it can supersede any other category checks and just logs every single log.
_________________
loomsoft :]
View user's profile Send private message Visit poster's website
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Sat Aug 13, 2011 1:20 pm    Post subject: Reply with quote

What I've been doing is:



At the moment it's ignored, but eventually I'd like to make the + and - blocks trigger an indentation. Also I want this inside an in-game console, so I can color code text inside enclosures ("", [], (), {}).

I did do the Category/Level thing on PuffBOMB, but I really didn't like the hassle of maintaining it. Not to mention, if you make a typo ("Asshets"), your data may go to the wrong stream. I did my version with #defined codes, making it a real pain to maintain. 99% of the time I do want all the logging channels, and I think I prefer to classify them by significance.


I do like the idea of better identifying the type of logging content. "+ Scanning 1 script for changes" will read better as "+ [Script] Scanning 1 file for changes...", but detail bullet point lines like "* GL_UNSIGNED_BYTE (RGBA_8888)" wont need it once I have the hierarchy thing working.
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Sun Aug 14, 2011 1:37 am    Post subject: Reply with quote

August 13th: I guess I really didnt do much today (just a blog post mainly). I experimented a bit with outputting color codes (logging), but that seems to only work on Linux. There doesn't seem to be an easy+portable solution.

Of course, shell color codes are only so useful. A good idea I saw somewhere (a book, I think) was to use a mini embedded web server, for even better logging. Simply connect to your game with a web browser, and enjoy the fun of HTML formatted logging.

Finding an easy to embed web server can be very difficult, but I did stumble across one just now that has much potential. Also, just 1 c file, so it's dead simple to add to a project.

http://code.google.com/p/mongoose/

I may give this a try tomorrow. Not as something permanent, but a test like cURL was. Oh, also, that would technically allow a remote clienT PC to view your logs, and for you to run fullscreen.

Zzzzz
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Sun Aug 14, 2011 11:41 am    Post subject: Reply with quote

August 14th: Mongoose works really well, and is really simple. My test looks like this:

Code:
#include "mongoose.h"
#define MG_NEWLINE "<br />"

static void *goose_callback( enum mg_event event, struct mg_connection *conn, const struct mg_request_info *request_info ) {
    if (event == MG_NEW_REQUEST) {
        // Return the header //
//        mg_printf(conn, "HTTP/1.1 200 OK\r\n" "Content-Type: text/plain\r\n\r\n" );
        mg_printf(conn, "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n\r\n" );

        // Return the content //
        mg_printf(conn, "%s" MG_NEWLINE, request_info->uri);
        mg_printf(conn, "Request Method: %s" MG_NEWLINE, request_info->request_method );
        mg_printf(conn, "Remote IP: <b>%i.%i.%i.%i</b>" MG_NEWLINE, ((unsigned char*)(&request_info->remote_ip))[3], ((unsigned char*)(&request_info->remote_ip))[2], ((unsigned char*)(&request_info->remote_ip))[1], ((unsigned char*)(&request_info->remote_ip))[0] );

        // Mark as processed //
        return (void*)"";
    }
    else {
        return NULL;
    }
}

struct mg_context *ctx = 0;

I added the newline thing above, but \n worked fine in text/plain mode (but what's the fun in that). The Init code:

Code:
    const char *options[] = {"listening_ports", "8080", NULL};    
    ctx = mg_start( &goose_callback, NULL, options );

And the exit code:

Code:
    mg_stop( ctx );

Accessing the data remotely returns a proper IP (http://myip:8080/sugarbear):

Quote:
/sugarbear
Request Method: GET
Remote IP: 192.168.0.101

And locally via http://localhost:8080/

Quote:
/
Request Method: GET
Remote IP: 127.0.0.1

But it's just a webserver that fills any request as it happens at this point. I don't know enough about webs to make it auto-refresh (or proper refresh, however twitter.com works as one example). It can trace HTTP GET and POST events very easily, so if I was interested in controlling the app via a web browser, I could.

Overall a great library, if I just knew what to do with it. :D
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Sun Aug 14, 2011 7:41 pm    Post subject: Reply with quote

August 14th: Part 2!

I knew I wasn't going to get much done today, so I let myself diddle around with more logging and debug stuff.

One thing I did that was pretty huge was implement a Hot Constants/Watched Constants/Tweak Values reloader. Honestly, I don't know what to call them, but in essence I can now wrap constants in my C++ code as follows:

Code:
float SomeVar = _TV( 1.0f );


And without recompiling, I can ALT+TAB to my text editor, change the value inside those brackets, ALT+TAB back to the game and the constant is changed. Snazzy!

I didn't write my implementation, but opted to use one written by one of the Ludum Dare participants:

http://code.google.com/p/ld48jovoc/source/browse/#svn%2Futil%2Ftweakval

It had a few compile bugs I had to fix, but was well set-up to support both MSVC and GCC. Making it reload was easy, as I already set up the refresh function for my scripts; Just had to call the TweakValues refresher at the same spot (on Window regaining focus). Goody!


With that done, working, and pretty cool, I finally made a Debug/Debug.h header file to contain all my debug calls. ACTUALLY! There was a conflict calling a file Debug/Debug.h. I don't know what, but some STL libraries started breaking, so I went with Debug/GelDebug.h instead.

So inside GelDebug.h, it includes my logging, asserting, bitching (inherited class for logging upon class creation and destruction... haven't used in ages), Tweak Values (above), and a deprecation macro (wrap a function in this and the compiler will warn the user... ahem, me... that they should not be using this function).

So on that note, I finally looked in to my Assert.h file to see what was there. A pair of functions Assert and Warning, both with rather nice formatting to them. I liked the formatting so much, I moved my ELog (Error Log) function there, and modified it to work just like Assert and Warning. The setup now is that Assert and Warning get removed in release builds, but ELog sticks around. Assert kills the program dead, and Warning just makes noise.

I also added the return versions of Log and ELog. I opted for return_Log( ... ) and return_value_Log( VALUE, ... ) as the syntaxes, over adding -1, false, true, etc versions.


So I think I'm done with the logging stuff for now. Satisfied for the most part, though I guess I could still categorize things (as mentioned in my response to Sonrisu). Indentation I'm going to wait on, In Game Console can also wait (font code isn't finished), and the HTML remote logger can wait.

My core logging is there and better than before, so it's time to get back to real work.
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Mon Aug 15, 2011 11:43 pm    Post subject: Reply with quote

August 15th: Nothing to show today. Up super-early to be out-of-the-haus for the real estate agents. Didn't sleep well, so napped after. Then we had our "notch attack" on the LD site (i.e. he linked a post on his twitter), and had to deal with that.

And OH! I got a support call for the Android version of Smiles... at Midnight. Amazingly, someone went through the trouble of digging up my phone number, which isn't easy (unless you know of "whois"). 3 years of selling mobile games, this was my first time ever getting a support call. :)

Tomorrow I'll probably have some obligations to take care of. I hope I can finish those soon.
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
PoV
Moderator

Joined: 21 Aug 2005
Posts: 10787
Location: Canadia
PostPosted: Mon Sep 12, 2011 8:39 pm    Post subject: Reply with quote

Hello. Progress grinded to a stop during my move (as expected). Ludum Dare week, before and after was spent dealing with server problems (local and remote). Also some minor obligations. Ludum Dare results went live this evening, and obligations are done, so back to the good stuff.

Familiarizing myself with my audio software today... It's been too long. Planning some new mockups, sonic and visual.

6 weeks until IGF deadline? No chance, but I'd still like to reach a milestone then.

Expecting a couple days of downtime this week gaming... It's also been so long. Disgaea 4 and (hopefully) Amnesia finally.
_________________
Mike Kasprzak
'eh whatever. I used to make AAA and Indie games | Ludum Dare | Blog | Tweetar
View user's profile Send private message
Reply to topic GDR Forum Index -> Game Developer's Refuge -> Development Log - GEL and Foundation (Engine Tools) Page Previous  1, 2, 3, 4

Use this link to get a Sign-On Bonus when you get started!

All trademarks and copyrights on this page are owned by their respective owners. All comments owned by their respective posters.
phpBB code © 2001, 2005 phpBB Group. Other message board code © Kevin Reems.