Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


Norman Barrows

Member Since 04 Apr 2012
Offline Last Active Jul 31 2015 04:15 PM

#5233868 How long should a mobile PvP game last?

Posted by Norman Barrows on 09 June 2015 - 01:04 PM

platform is irrelevant. game type is what matters here.

 


I am working on a concept for now of a PvP game which would be limited to phones and possibly tablets.

 

this really is largely irrelevant. whether you play skyrim on a PC or a tablet, its should last a long time.  whether you play galaga on a PC or phone, each "round" is typically a few minutes at most.

 


i'm modeling it after two styles - tower defense and card games.

 

this is whats important - game type. a phone is just another platform - albeit somewhat less powerful than an alienware rig.

 

how long it should take is really up to you. who says tower defense should only take five minutes?  that's not much of a game if you ask me.

 

how " casual" vs "hardcore" your game is will probably be the deciding factor.  for casual, you want something they can pick up quickly, play quickly, and put down at any time. but as long as they're playing, you want them to be able to continue playing. so a design like galaga with 100 levels is better than something with just 5 levels.  insufficient content / gameplay hours leaves a bad taste in the payers mouth, "i got ripped off! its too short!"  for something more hardcore, you'll want longer term gameplay most likely, with the ability to save and resume. but since its two player only, playing a longer game - possibly over multiple sessions - doesn't really fit well. i mean, when's the next time you and your buddy will both be able to continue the game?




#5233860 Renderer Architecture question

Posted by Norman Barrows on 09 June 2015 - 12:43 PM


The way I have found it to work is to take a list of "renderables" sort them by a certain criteria and then loop through them to render, is this correct / the right way to be doing it?

 

basically, yeah.

 

you'll want to sort as little as possible, that's why they cull first.

 

your sort criteria should generate an optimal draw order with respect to pipeline state changes, for whatever drawing methods you're using.

 

that's more or less it.

 

biggest variation seems to be in the sorting method used. encoding sort criteria in ints and then sorting the ints is popular. apparently its faster than sorting on the criteria themselves.

 

when i was faced with the question of how to speed up sorting in my render queue, i had never heard of the technique of encoding sort criteria into ints.  so i had to come up with my own solution.  in my typical overkill fashion, i  went straight for the fastest possible sort: bucketsort.  i use a multi-dimensional indexing system (as in: an index into database) that basically does an in-order bucket sort insertion of renderables into the render queue's index. so i have no extra sort step required. as soon as all renderables have been added, the index is already sorted and ready to use for optimal draw order rendering. i've never tested this vs encoded ints to see which is faster. for now, the indexed system is plenty fast enough - at least for my needs.




#5233852 should i release my code?

Posted by Norman Barrows on 09 June 2015 - 12:07 PM


Well, realistically if you just drop it in a Github repository and forget about it you won't really get any visitors to it

 

not really trying to win a popularity contest here, maybe just help some folks out where i can. no sense reinventing the wheel when i've got one right here you can have for free.

 

 

 


You'll need to at least tell people that it exists, via e.g. social media or a GDNet journal entry or whatever.

 

yes, i  was thinking GDnet journal entry,GDnet  announcements forum, and a web page on Rockland's site.

 

 

 


Beyond that, you don't have to maintain it if you don't want to, but if you are not interested in maintaining it, it's unlikely someone will just step up from the shadows to contribute and provide feedback, especially if it hasn't been "cleaned up"

 

this is not a code dump of deprecated code, like so many devs do - the "post the DOOM code, 'cause now we're on QUAKE" kinda idea.  this is rockland's own in-house gamedev library used on a daily basis. IE: it passes the "dog food test" as Hodgmann (sp?) says. its constantly being expanded, with skinned meshes being the latest capability added to the code base. there's even a dx11 prototype version. so its a living and maintained code base. this would be roughly the equivalent of square enix giving away the luminous source, while continuing to maintain, improve, and use it for their own titles - although my library is not nearly as powerful as the luminous engine. 

 

as for the cleanup - that depends on what you want to do. if you want to just use the libraries as is, its pretty turnkey. or you could use the code as the guts for a version using classes instead of pods and stand alone functions. the APIs are already pretty much split up into class-like ADTs. if you want dynamically resize-able memory pools, just use vectors instead of arrays.

 

being a set of libraries as opposed to an engine, the code can be made to play nicely with existing code bases, libraries, and engines. if you can call a c++ routine from your code (and most languages can), you can use this stuff.

 

 

i'm looking at a lot of artwork time and not a lot of coding on the current and next two projects.  while i can do both, i think i prefer coding.  if there's sufficient interest, i might get motivated to do the classes and vectors myself - just so i can do some semi-real coding. <g>.

 

the big question is: is there anyone out there interested? no sense in posting, if nobody is interested in it.




#5233579 should i release my code?

Posted by Norman Barrows on 08 June 2015 - 12:24 PM

now that i'm finishing up my skinned mesh code, i'm seriously considering releasing it.

 

i know that if i has something like it when i started on this skinned mesh adventure it could have probably saved a week or two of R&D. and i find it hard to believe that given the large number of people that have played with skinned meshes in dx9, nobody has ever put the stuff together into a neat little package. 

 

and really, the proper was to release it seems to be release all my gamedev code, IE:

 

the Z3D game library

the Zaudio labrary

the various other Z libraries (GUI components, fonts, rigid body modeling/animation editor, etc).

skinned mesh and other code of interest from Caveman 3.0 (some library APIs have yet to be moved from the game to the Z3D libraries).

sample code and sample programs that use the libraries.

the CScript macro processor and cscript source code for all of the above.

 

the code is largely directx code, which is why i'm asking in this forum.

 

pros:

* it could help others

* feedback might lead to better code

 

cons:

* dx9 based - but many folks still use dx9 or dx9 based libraries. i do have the beginnings of a dx11 version going.

* procedural code and PODs, but can easily be changed to classes.

* limited documentation currently available, but the code is pretty high on readability, pretty well commented, and there's lots of sample code available.

* use of arrays to implement memory pools. can be easily converted to use vectors.

 

 

any other cons or gotchas to consider?

 

what might be a good "as is" type license to use?

 

all things considered, should i do it, or would it be a waste of time?

 

if i do, what's a good way? dropbox, and links on my website and in my dev journal here?

 




#5232670 Moving beyond Arcade Style Games

Posted by Norman Barrows on 03 June 2015 - 04:20 PM


What if then if you increase the fixed number of animals? You'd need to write the first n animals with m properties, then later on n animals with the 1 new property, then later on more animals with (m + 1) properties.

 

simply designing the format from the get go for a variable number of objects as in my example above precludes this issue.

 

if you kick up the max number of avatars in the game,  a savegame will have at most the old max, and you'll be saving up to the the new max. 

 

going the other direction, reducing max_avatars, you might have to throw away data from old file formats, if you have no place to put it / no use for it.

 

as for writing a fixed vs variable number of objects, i tend to use memory pools implemented using arrays for most everything for which there can be more than once instance in the game. IE just about everything. since i'm dealing with arrays, i personally find it easier to simply dump the entire player and npc memory pools to disk, rather than only writing active ones (IE a variable number of objects). to squeeze a few more millisecs out of my load and save times, i could switch to only loading and saving active ones. but many are relational databases, and memory dumps means no pointer index fixup on load to get everything related correctly again. about the only fixup i need on load is creating animation controllers for active characters.




#5232667 Moving beyond Arcade Style Games

Posted by Norman Barrows on 03 June 2015 - 04:05 PM


What if you add a property to animal? You have to write the new properties for all animals at the end of your save function?

 

any new variable you want to add to the format goes at the end. does that answer your question? not sure what you mean by a property.




#5232666 Moving beyond Arcade Style Games

Posted by Norman Barrows on 03 June 2015 - 04:02 PM


Or do you have fixed numbers of each type of game object?

 

bingo.

 

but no reason it couldn't be variable.

 

an example:

 

lets start with a character struct with just a name, x, and y. and we load and save a variable number of these. no problem, write the number of character structs, followed by the name, x, and y for each struct. very standard stuff, right? when you read, you read how many there are, then do a loop of that number of iterations reading in the values for each struct.

 

ok, now - add something else - how about z?   it should work for this example.

 

so you leave the existing code alone, and add new code at the end:

 

// you've already written num_structs, so no need to do it twice. just write the (new) struct data.

for each struct, write z

 

so you're saving all the version 1 format data first (name, x and y), followed by all the version 2 data (z).

 

and load just reverses the process:

 

read num_structs

for i=0 i<num_structs i++

    {

    read name

    read x

    read y

    }

// you could be clever and realize you probably don't need to write num_structs twice, so for new format 2 data just do:

for i=0 i<num_structs

    {

    read z

    }




#5232659 Need some tips and tricks to hunt down a bug

Posted by Norman Barrows on 03 June 2015 - 03:40 PM


Nah... I love arrays

 

sounds that like me, you like to use memory pools implemented using arrays.

 

i've found that with a bit of careful api design for array access, you can preclude the need for almost all range checks.

 

i honestly can't even remember the last time i had a range check error. its been that many years. and i've been doing this full time (for the forth time in my life) for the last 3 years now.




#5232614 Moving beyond Arcade Style Games

Posted by Norman Barrows on 03 June 2015 - 01:09 PM

It doesnt realy matters for small stuff, big stuff you Always write blocks if you can anyways.

I think you dont notice the difference with 1 write to disk, or more writes to disk.

 i used to think that way too. write out each member of each struct individually? instead of blockwriting the whole array of structs? naw! it would never work! too slow!

but once you get down to the bare bones fwrite_nolock routines, its actually doable. i'm saving 72 meg in about 5 seconds flat.

 

the whole problem with writing blocks is that if the definition of a block changes in the code, you can't read existing savegames without converting them first.

 

by writing out blocks one variable at a time, you can change the definition of a block, and still read existing savegames. by only adding new variables at the end of the file format, and initializing new variables to default values before loading, you can convert old format savegames to new format just by loading and saving them.




#5232564 I find it hard to find new games

Posted by Norman Barrows on 03 June 2015 - 09:05 AM

as a hard core gamer (as well as a game developer), i struggle with the same problem. day after day, year after year, i find myself playing the same titles over and over, because i cant find anything better.  

 

for me, those games are a RPG, a sub sim, and a wargame: elder scrolls, silent hunter, and total war.  there are things about each i dont like, but cant find anything better.

 

i also used to play city simulators, but simcity3 was a letdown, and the Caesar series is no more.

 

flight sims are another one i cant find anything good (and current).

 

carribean (a pirate rpg) has caught my eye, but looks like it ended up being shovelware (they didnt finish it, just shoveled it out the door). i was hoping i wouldn't have to make a pirate rpg, and could just buy and play one. i was hoping carribean would let me do that. but thats ok, last night i got my 100 animated skinned meshes onscreen at once test going, and got skinned mesh LOD going too. so that pirate rpg idea of mine with 100+ combatants in real time boarding action combat is no longer a dream. i could build it today.

 

mech sims is another one. i was a big fan of the metaltech battledrome series by dynamix (not mechwarrior, the other guys.  mechwarrior was the action game, battledrome was the hard core sim).

 

or anything to replace red barrron II. or x wing, or tie fighter, or falcon 4.0 gold edition.  the list goes on and on.  

 

some games i have taken a hard look at:  mount and blade: warband - i'll probably give this a try.  GTA4 - something different, never actually played GTA myself, though all my friends do. but DRM for PC version from steam is an issue, so i passed on that.

 

sometimes i'll spend a whole evening looking for a new game , instead of playing skyrim yet again. 

 

and the saddest part of all...   look at what you find when you go look for a game. 90% of it is all the same crap.

 


So, if you are a gamer then how do you find out about cool indie games? Any favorite sites you use, or just word of mouth? What cool games have you discovered’?

 

search the web, and the usual online outlets. perhaps a little word or mouth, i've hard good things about witcher3, and the battlefield and uncharted series on consoles. i didn't have the heart to tell my console buddies that battlefield started out as a hard core mission based WW2 FPS. they just think its yet another cool cops and robbers title like GTA or Juarez.

 

as for what i've discovered, not much. first: cool is subjective - opinion, not fact. so one person's "cool" game might be next person's "stupid", "boring", "childish", "too easy" or "too hard" game.

 

right now, we're in a very "me too" time in the game market. low cost development tools and a plethora of devices to develop for leads to a lot of new entries into the field. unfortunately, most are just building yet-another-tower-defense game. someone made money on angry birds? me too! i want to do that too! let's make yet-another-angry-birds clone!

 

eventually, the uninspired copycats will realize they can't reproduce the fad success of angry birds (or tetris back in the day), and will stop flooding the market with clones.  at the same time, original works with true merit will start to slowly rise to the top - stuff like minecraft, kerbal space program, etc. so its not all bad news. but like anything, you have to sift through 99.9% junk to get the 0.1% good stuff. and yes, i'd say its close a 1000 to 1 ratio of crap to quality titles out there right now.

 


If you are a developer then how and where do you promote your game?

 

in the past: free playable demos on bbs's and AOL. posting demo links to every game site you can. i've also gotten free tv coverage on the evening news and a top 10 DL on AOL, both of which are the type of PR you simply cannot buy.

 

this time around, i'll probably use the same basic marketing strategy. but the number of game sites (such as gamespot, ign, etc) has gone down, and the number of online game stores has gone up.  not quite sure why, but i get a bad vibe from GOG and Steam and such.  they will require serious thought before i decide to use them as marketing tool / channel.

 


and if it Is easy to increase your fanbase before launching or after release?

 

the idea is to create demand for the product that pulls it through the channel, not spend cubic dollars trying to push it though the channel. fanbase is at most perhaps an indirect indicator of how successful you are at this. probably its greatest value is as a source of info as to how well your design works in the field, and what changes need to be made in the next design-implement-deploy-fieldtest cycle.




#5232421 skinned mesh triangle count

Posted by Norman Barrows on 02 June 2015 - 12:12 PM


I would suggest you first get a working process running. Then, if needed, profile the process to determine where improvements could be made.

 

i've got all the code up and running.

 

its just a test routine off the tools menu in Caveman 3.0, but it does the following:

 

loads and draws skinned meshes with multiple animations, and can change between animations. no animation blending yet.

supports all 5 or 6 skinning methods from tiny.cpp.

can set the texture for each mesh in a skinned mesh on the fly before drawing. textures can be pooled. materials can be pooled if desired.

can draw an object in relation to a bone (IE attach wpn to hand bone type stuff).

drawing multiple instances of a skinned mesh, each with its own animation controller, using a single shared skinned mesh and skeleton.

there's different versions of the code so you can load non-pooled textures and materials with the mesh and use them for drawing subsets, like a regular dx mesh,

or you can draw using the current texture and material for all meshes and subsets in the skinned mesh, or you can set textures for each mesh in the skinned mesh individually, then draw it using the current material.

 

the last thing i tested was using the in-game realtime 10 channel matrix editor to scale, rotate, and translate eyeballs to their correct position with respect to the head bone, while playing an animation where they don't move. this allows me to read off the srt values for use in a pre-defined "offset" matrix used to draw each eye. since the eyes are drawn as an attachment to a bone, i can change their texture, or make them look in any direction desired. to support visual tracking, the xr and yr angles from the lookat (or camera's forward) vector to the target's direction vector from the camera should be the rotations that need to be applied before the offset matrix, follwed then by the combinedtransform matrix - i think. haven't tested it yet, but i think its right, might need to negate the angles or something.

 

about the only code left is a skinned mesh pool class, and a controller pool class. i've pseudo coded them, but was too lazy at 1am last night to lookup syntax and var names, so it still needs about and hour's worth of work perhaps, at most.

 

so i'm more or less ready to go for it with a fully rigged and ready to rock model. the question is how many tris? i started with a beautiful mesh - excellent topology, easy to mod, looked great right out of the box. when i went to export with two animations, i thought blender had crashed. i tried exporting just the mesh. it took 10 minutes. turned out the mesh was over 100K tris. i decimated it to about 10K for testing, but the topology was ruined. about half way through testing, i switched to a nice topology mesh of about 30K tris. but this is probably still a bit big for 100 onscreen at once type of thing. a female will require 3 drawsubset calls - a male, two calls (no bra). i decided to implement bra and loincloth as separate meshes along with a head and body mesh, as the two or three meshes in a single skinned mesh. eyeballs and hair will add three more DIP calls per character, using static VBs and IBs. in my rigid body system, i'm using 14 (male) or 15 (female) static meshes to draw a character (if they're bald, subtract one hair mesh). some of them i know are perhaps unreasonably highpoly, 50K for a body, 20K for a head, that kind of thing. but they're all static.  i was somewhat surprised to find little difference in FPS between various skinning methods in tiny.cpp sample running on my pc. something like 169 vs 175.




#5231980 Help - getting input form windows

Posted by Norman Barrows on 31 May 2015 - 09:20 AM

ok, i'm checking into that wm_quit and wm_close question, here's what seems to be going on...

 

my code is only for fullscreen d3d apps, not windowed. so the only way to get a wm_close message is to alt-tab or ctrl-alt-del out of the app, then close it from the desktop toolbar or program manager. both of which seem to send wm_destroy messages. that's why i don't need to process wm_close.

 

but if the user does break out and kill the app, i do need to process wm_destroy, which should postquitmessage, and shutdown the app.

 

postquitmessage sends a wm_quit to windows, which unhooks the windows message proc. wm_quit is a message sent from an app to windows to unhook its message proc, its not a message sent from windows to an app.

 

wm_close:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms632617(v=vs.85).aspx

 

wm_quit:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms632641(v=vs.85).aspx

 

wm_destroy:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms632620(v=vs.85).aspx

 

postquitmessage

https://msdn.microsoft.com/en-us/library/windows/desktop/ms644945(v=vs.85).aspx

 

 

a more typical implementation would probably be to set a "I_got_a_destroy_message" flag in the window proc, then process it when you process input. input can basically be processed two ways:

immediate processing - as soon as you get a wm_destroy or whatever, you process it.   my code above is an example of this.

deferred processing - you set a flag or post some sort of message to an internal message queue or something, indicating some sort of input has occurred, then process it later, perhaps when its more convenient or whatever.  but this requires extra flags, message (input) queues, variables , etc, and spreads the code over multiple areas of the program (received in one place, but processed elsewhere). 

 

for my input system, i've opted for immediate processing whenever possible. its just simpler and i don't need timestamps. so i just postquitmessage, shutdown the game library and exit. seesm to work fine. its similar to back in the day with a simple text based app - you get input to quit. well, you can exit out of all those subroutines back out to main, or just halt. there's no real difference. good idea to cleanup first (release stuff), but windows does a pretty good job cleaning up after you even if you don't - but you should not rely on that.

 

as for keyboard input, i'm only concerned with key states at the time of polling, and poll at a fixed rate. so i don't require input time stamps, and consuming input in ET sized chunks, a la L Spiro.

 

for a full-tilt implementation, use L Spiro's time stamped and "consume input in ET sized chunks" method. unfortunately i can't find the link at the moment. can't recall if it was an article or posting here or on lsprioengine.com.




#5231880 Moving beyond Arcade Style Games

Posted by Norman Barrows on 30 May 2015 - 03:22 PM


Are you saving one struct per file? Otherwise, I don't know how your system could work.

 

i'm saving every variable in the game pretty much - more or less the entire state - missiles in flight and all. in a single binary file.

 

think of it this way:

 

time to save the game, so you're going to write some data to disk. a bunch of variables. some might be members of objects, some might be members of structs, some might be stand alone variables. 

 

all i do is write them all out to a binary file, one at a time, in a fixed order, then read them in, in the same order.

 

the fixed read /write order means you know what variable to read next, and thus its type - and its size. no key:value parsing required.

 

now, time to add a new variable to a class declaration.  and we want to load and save this new variable as part of a savegame.

 

so first you do all the usual things, declare, init, change, and use it. then comes time to load and save.  this means your savegame file format is going to change. the old format won't have the new variable, the new format will.

 

now, how to change the format? well, you could just insert it into the existing load and save code right after the previous variable in that class, but that would change the existing load and save order, and any games saved with the old order could no longer be read. and you want to be able to read the old AND new formats, as well as save in the new format.

 

so what you do is this:

1. when loading a savegame, init all loaded vars to default values first, then read in saved values over them. if the savegame file ends before you read all the variables, any unread variables will retain their default values.

2. to add new variables to the savegame format, you always add the load and save code at the end of the routine, IE at the end of the list of variables to load/save. this preserves the loading order of existing variables. so now you can add code to the end of your load and save routines for the new vars, load in an old format file, and the new vars will take default values, and when you save, it'll save in the new format - automatic conversion with no special routine or utility.  and backward compatibility all the way back to the original format.

3. to remove existing variables, you just read and write junk values to maintain the read order (and size). if you add a new variable of that type later, you can use that "empty slot" for the new variable, instead of using a junk value. this can safely be done if both your junk and new default values are zero. this saves space, but then very old formats with the deprecated value in them will no longer be compatible with the new format.  i find it handy since i only really have the one in-house long term playtest savegame file to convert at the moment, and variables continue to be  added to and removed from the format as the game evolves. no sense reading and writing a bunch of junk values in the Caveman 3.0 release version. it doesn't have to be backward compatible with anything. but if i remove variables in the version 3.1 release, i'd need to use junk values, and not reuse them, for backward compatibility with v3.0.

 

rather surprising - or perhaps not - you don't get much of a performance hit writing individual variables one at a time using fwrite nolock (or whatever its called) - ie the good old fashioned bare bones down to the metal no error checks c-type runtime library code. i'm saving something like 73 meg in 4-5 seconds flat.

 

 

 

i find this method gives me a number of advantages:

1. no key-value pair parsing required

2. easy to mod: wi(intname) wf(floatname) ws(stringname) - write int, write float, write string.  ri(intname), rf(floatname), rs(stringname) - read int, read float, read string.

just add a line of code to the end of load and save for each new var - all cut and paste boilerplate stuff. you can also save chunks of vars/data with blockread and write, since its binary format. but that means the chunks can't change without automatically breaking the load and save code. the thing about writing out individual members vs a whole struct is you can change a struct definition without automatically breaking the existing load and save code.

3. automatic backward compatibility

4. automatic format conversion.

5. only have to save the members you want out of a struct.

 

i was looking for a savegame system and file format that was

1. easy to use

2. fast

3. backwardly compatible

 

my savegame format for Caveman has probably changed six times since i implemented the system. no more re-creating or converting long term playtest games from old to new formats. and i have a long term playtest game i started almost two years ago now.

 

over the long term, you end up with a save routine something like this:

init vars to default

open file

load original format vars

load file format 2 additional vars

load file format 3 additional vars
(...)
load file format N additional vars
close file
 
save is identical, with write instead of read calls.



#5231720 Equipment/modules for ships

Posted by Norman Barrows on 29 May 2015 - 01:21 PM

hull upgrades can go both ways. USAF operates airframes that are over 50 years old (transports and tankers).   but the f-111 vs the f-117 is a definite hull upgrade due to new materials. note that both are deep penetration ground strike aircraft. one pre-stealth, and the other post-stealth. this is somewhat similar to the tiger I vs tiger II, where the hull itself was one of the the major new technologies in the design. the t-34 is another example of a "new kind of hull" type design.

 

the US navy commonly will rip out the entire guts of a ship to refit it over course of many months. about the only thing they can't do is put intercontinental ballistic missiles on a ship not originally deigned for it, and they can probably do that too, given enough time. 

 

there's no reason to think that such behavior patterns would not occur in the future, any future, unless you have game universe rules that make it otherwise.

 

so you probably only need hull upgrades when you have changes in hull technology - which would most likely be the result of completing a node on the research tree.

 

by limiting or eliminating changes in hull technology you can limit or eliminate hull upgrades.




#5231711 Equipment/modules for ships

Posted by Norman Barrows on 29 May 2015 - 12:51 PM


There's more to consider than simple friction even in real non fictional science and it can be made very believable if you have a good writer and like all good lies base it partly in truth...

 

all of the people some of the time, some of the people all of the time, you know the rest.

 

remember its a 4x, not angry birds, your target demographic will tend to be a little smarter than the average bear.

 

its doesn't have to be "realistic", but it does have to be believable within the rules of the game universe.






PARTNERS