plugging up free cheating.

Development directions, tasks, and features being actively implemented or pursued by the development team.
Locked
JsnMtth
Bounty Hunter
Bounty Hunter
Posts: 174
Joined: Wed May 27, 2009 6:38 am
Location: Fresno, California - United States of America
Contact:

Re: plugging up free cheating.

Post by JsnMtth »

chuck_starchaser wrote:Well put, denyasis. You've summarized the situation EXACTLY.

As for me, I don't consider myself a developer. There's only two pieces of C++ code I wrote,
in the engine. One was a template messaging system, like an observer pattern; the other
is the code that computes tangents. In both cases, though, I just wrote the code and gave
it to Klauss to integrate into the engine, because I'd have no idea where to put it.
And shaders are something else altogether; not really a part of the engine.
But like you said so clearly, I'd love to become a developer, but I find the code inscrutable;
can't make heads or tails of it ever; even when Hellcat has tried to help me, the amount
of un-figurable stuff is staggering. Among the things you forgot to mention, using special
values in floats, like 0 or -1 to mean special things. This is a NO-NO-NO-NO-NO-NO-NO
in programming. In my coding I rigorously observe command/query separation: A function
is either a query (returns a value but changes no state, and is declared ...() const;) or it is
a command, and MUST return void. To me this is a sacred rule; but VS code doesn't even
seem to be aware of the existence of command/query separation discipline. There's hardly
ever a function returning void, in fact. So one looks at a function and can't even tell if it's a
function to get information or to effect a change, except by looking at the code. Because
even the names tell you nothing about it.
I'd name a query function

Code: Select all

    bool light_is_on() const;
and a command function

Code: Select all

   void turn_light_on();
Makes the meanings and intents clear.
But in the VS engine you might likely find a function

Code: Select all

    float light_off( double );
Same thing with naming of variables... A variable named "fuel_is_empty" HAS to be a
boolean; can't be anything else; can it? That's how one names variables. Boolean
variables should read like statements that are either true or false. But in the VS engine they
NEVER are so named. Same as "amount_of_fuel_left" is obviously a float, without looking
up the definition. But trying to read VS code you have no way to tell anything from the way
variables or functions are named. You ALWAYS have to look things up, look things up,
look things up... Study functions in detail to even get a glimpse of what they are for.
It just drives me bananas.
We need to get 600 programmers on promises of free sex, and put them to work on a
mother of all rename-athons.
Interesting -- I usually at least return a bool so I can evaluate the success or failure on a function. The only time I would consider a void would be where a failure is impossible or irrelevant.

I have also used 0 and -1 in a float to effect a change in behavior. It was to utilize a complicated data stream to effect an unplanned change that would have otherwise required two additional fields in an already complicated data-set.
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Re: plugging up free cheating.

Post by chuck_starchaser »

JsnMtth wrote:Interesting -- I usually at least return a bool so I can evaluate the success or failure on a function. The only time I would consider a void would be where a failure is impossible or irrelevant.
Returning a status from functions is OLD style; recognized to be BAD almost universally; exceptions were invented in good part to be able to stamp out the practice. Failure should be impossible, always. Preconditions for a function's success should be checked via query functions beforehand. And if that's not possible, then an exception should be thrown in the case of failure. Otherwise you get into a situation where a function returns failure; but its calling function doesn't know what to do about it, so it returns failure. And as functions sometimes call many other functions, they have to either know how to handle the failures of any of the functions they call, or pass on the failures to its calling function. And a function can be called from many places in code; so then you have to complicate ALL those callers to make them aware of possible callee failures... You know that about 90% of the code in commercial software, by lines of code count, are exception handling? So, doing it even 1% less efficiently than the most efficient way is a heavy price. Throwing and catching exceptions is like 50 times more efficient than returning success or failure up a call chain. It's inconceivable that in this day and age anyone would still not be using exception handling for exceptions.
Returns are a mess, and totally unnecessary. Exception handling (throw... catch...) allows you deal with failures at a level of your choice, and in an organized, rational way.
I have also used 0 and -1 in a float to effect a change in behavior. It was to utilize a complicated data stream to effect an unplanned change that would have otherwise required two additional fields in an already complicated data-set.
Well, Jason; what can I say? That is bad ... bad... BAD programming. I sympathize that sometimes it is tempting to do things in a quick way; but nothing is as complicated as trying to maintain code written in unmaintainable ways...

Don't EVER do that. If you need to return a special case, use a bool; then package it together with the float in a struct.

Code: Select all

struct fuel_capacity
{
    float litres;
    bool this_is_a_frigging_station__dogbreath___it_dont_use_fuel;
};
--or better yet, an enum, so that it is easier to add other special cases later, should it prove necessary.

Passing special states via numbers is inherently un-self-documenting. The Holly Grail of program documentation is when you don't need comments in code... at all.
That's right; you heard right: NO comments.
Comments are a nightmare. Why? Because they don't update themselves automatically when code changes.
Depending on comments is deprecated because the updating of comments depends upon programmer
discipline, which itself is not dependable, no matter how encourageable and encouraged it may be.

So the Holly Grail is to write code that is so clear that it doesn't need comments; and it's quite doable.
In fact, the only comments that are really justified are those which clarify the programmer's ulterior intent, or
explaining when things are accessed, ... IOW, comments are for "big picture" info:

Code: Select all

//this function is called once per physics frame, from module such and so.

Code: Select all

//an object of this aiming class is created when an ai begins shooting; then destroyed as it turns away
These would be good, useful comments; but you never find them you know where...
Or use policy. Or protocol.
Things that code itself cannot express.

Otherwise code should read as clear as narrative, or even poetry.

Code: Select all

int days_of_the_month( month m, year y )
{
    switch( m )
    {
    case september: case april: case june: case november:
        return 30;
    case: februeary
        return is_leap( y ) ? 29 : 28;
    default:
        return 31;
    }
}
Look ma, no comments!

But when you encode special cases as numbers in a float, how would you, or
someone else, reading a piece of code; --or worse, about to use that variable--,
--or worse, about to modify code that uses that variable-- know, or even suspect,
that it can have values with special meaning?
You'd have to clarify that via comments not only at the declaration point but
anywhere the variable is used!!! Because you cannot expect a programmer about
to change a piece of code to systematically look up ALL variable declarations to
scan for comments... Can you? That wouldn't be fair. So not just at the declaration,
but in fact everywhere that variable is USED, you have to put comments about
its special values and their meanings. Also, comments about not forgetting to
update the comments, should a special meaning be added or removed...
And any coding policy that *necessitates* comments is a BAD coding policy;
because use of comments should be a "last resort".

Use of special values in floats is not even "bad policy"; it's more like
"coding horror"; --akin to mass murder, or genocide.
JsnMtth
Bounty Hunter
Bounty Hunter
Posts: 174
Joined: Wed May 27, 2009 6:38 am
Location: Fresno, California - United States of America
Contact:

Re: plugging up free cheating.

Post by JsnMtth »

chuck_starchaser wrote:Returning a status from functions is OLD style; recognized to be BAD almost universally; exceptions were invented in good part to be able to stamp out the practice. Failure should be impossible, always. Preconditions for a function's success should be checked via query functions beforehand. And if that's not possible, then an exception should be thrown in the case of failure. Otherwise you get into a situation where a function returns failure; but its calling function doesn't know what to do about it, so it returns failure. And as functions sometimes call many other functions, they have to either know how to handle the failures of any of the functions they call, or pass on the failures to its calling function. And a function can be called from many places in code; so then you have to complicate ALL those callers to make them aware of possible callee failures... You know that about 90% of the code in commercial software, by lines of code count, are exception handling? So, doing it even 1% less efficiently than the most efficient way is a heavy price. Throwing and catching exceptions is like 50 times more efficient than returning success or failure up a call chain. It's inconceivable that in this day and age anyone would still not be using exception handling for exceptions.
Returns are a mess, and totally unnecessary. Exception handling (throw... catch...) allows you deal with failures at a level of your choice, and in an organized, rational way.
I'll explore exceptions very seriously. It's been a confusing subject for me, but once upon-a-time functions where too. :oops:
When I finally did look into them it turned out I used them, but didn't know the terminology.
chuck_starchaser wrote: Well, Jason; what can I say? That is bad ... bad... BAD programming. I sympathize that sometimes it is tempting to do things in a quick way; but nothing is as complicated as trying to maintain code written in unmaintainable ways...

Don't EVER do that. If you need to return a special case, use a bool; then package it together with the float in a struct.

Code: Select all

struct fuel_capacity
{
    float litres;
    bool this_is_a_frigging_station__dogbreath___it_dont_use_fuel;
};
--or better yet, an enum, so that it is easier to add other special cases later, should it prove necessary.

Passing special states via numbers is inherently un-self-documenting. The Holly Grail of program documentation is when you don't need comments in code... at all.
That's right; you heard right: NO comments.
Comments are a nightmare. Why? Because they don't update themselves automatically when code changes.
Depending on comments is deprecated because the updating of comments depends upon programmer
discipline, which itself is not dependable, no matter how encourageable and encouraged it may be.
So the Holly Grail is to write code that is so clear that it doesn't need comments; and it's quite doable.
In fact, the only comments that are really justified are those which clarify the programmer's ulterior intent, or
explaining when things are accessed, ... IOW, comments are for "big picture" info:

Code: Select all

//this function is called once per physics frame, from module such and so.

Code: Select all

//an object of this aiming class is created when an ai begins shooting; then destroyed as it turns away
These would be good, useful comments; but you never find them you know where...
Or use policy. Or protocol.
Things that code itself cannot express.

Otherwise code should read as clear as narrative, or even poetry.

Code: Select all

int days_of_the_month( month m, year y )
{
    switch( m )
    {
    case september: case april: case june: case november:
        return 30;
    case: februeary
        return is_leap( y ) ? 29 : 28;
    default:
        return 31;
    }
}
Look ma, no comments!

But when you encode special cases as numbers in a float, how would you, or
someone else, reading a piece of code; --or worse, about to use that variable--,
--or worse, about to modify code that uses that variable-- know, or even suspect,
that it can have values with special meaning?
You'd have to clarify that via comments not only at the declaration point but
anywhere the variable is used!!! Because you cannot expect a programmer about
to change a piece of code to systematically look up ALL variable declarations to
scan for comments... Can you? That wouldn't be fair. So not just at the declaration,
but in fact everywhere that variable is USED, you have to put comments about
its special values and their meanings. Also, comments about not forgetting to
update the comments, should a special meaning be added or removed...
And any coding policy that *necessitates* comments is a BAD coding policy;
because use of comments should be a "last resort".

Use of special values in floats is not even "bad policy"; it's more like
"coding horror"; --akin to mass murder, or genocide.
Well... I've been noodling this an playing with a response including explaining the circumstances that I did it. I passed the special parameters as input from a database though not as output returned from a function. Quite simply though ... your right. I'm not big on commenting code either and have worked on writing code that doesn't need it (rather than doesn't have it) lately.

The poor guys I work with are programming on an application that I wrote by myself over the course of 8 years. 10,000+ lines of PHP/XML/XSLT/HTML/SQL/Javascript, procedural code ported to OOP. They can tell the old code from the new. Much of it has been re-written using better methods.
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Re: plugging up free cheating.

Post by chuck_starchaser »

JsnMtth wrote:I'll explore exceptions very seriously. It's been a confusing subject for me, but once upon-a-time functions where too. :oops:
When I finally did look into them it turned out I used them, but didn't know the terminology.
To Hell with the terminology. Exceptions are quite simple.
Say an application expects certain files to exist. Many of them, if they don't exist, the app must terminate with an error message to the user. Some of them, if they don't exist, can be created.
Now, it would be madness for every low level function to return an error code if a file doesn't exist; then its calling function has to take that error code and pass it back to its calling function, and so on, 20 levels up.
Just have the low level function

Code: Select all

throw( new file_dont_exist( filename ) );
Then, however many levels up you want, you can put some high level function in a try .. catch block, and you catch objects thrown of type file_dont_exist, and do whatever you want: create the file, or terminate with an error message.
Exceptions are like an express train for unexpected crap. Instead of passing as returns from function to function, the stack unwinds rapidly up to the level where the try...catch is. That's all there is to it.
It helps keep most of your code clean and unconcerned with exceptional situations.
Without exceptions, your code looks like boilerplate stuff full of conditional blocks cluttering everywhere.
With exceptions, all you have to do is throw something; and somewhere, wherever it's more convenient
or appropriate, you deal with a whole family of exception types in a well organized manner, all at once.

The only catch about exceptions is the question of where you declare the types to throw.
For a small software project, you can maybe declare them at a high level. For a large project, you can't
forsee every possible exception that low level code may have to deal with; and this may be a good
example for using the header inversion idiom, to avoid circular inclusion. But that's a bit of a long story.

You see, exception handling brought back a power that had been lost since the days of structured
programming, and its abolition of goto. One of the few things that goto's were actually sort of good for
was exception handling. Back in the days of goto's, you could actually goto some good place when
an exception occurred. With structured programming, there was no longer a way to jump between
branches in an execution tree.
Exception handling brought that back with a bang. When you throw(), you're actually executing a kind
of goto. In assembly speak, a "long jump". The difference is that a goto would leave the stack in a bad
state; whereas long jump takes good care of the stack pointer. So, throw( X ) means "goto the nearest
point in the code up the stack where there's a catch for exception of type X.
pheonixstorm
Elite
Elite
Posts: 1567
Joined: Tue Jan 26, 2010 2:03 am

Re: plugging up free cheating.

Post by pheonixstorm »

Hunting down threads on the agasicles (Vark?) I came across this thread.

To end casual cheating and make the save game files smaller (and hopefully less buggy) is fairly simple. Instead of using and open ended text format for the save file it should (and eventually will be) moved over to a binary format. Text strings will remain the same size, but all numers (credits, location, etc) will only take up 4 or 8 bytes instead of 20 or 30 in some cases. See the size saving already??

On the other hand, to save mod developers time and to keep casual games happy a nice save game editor should also be developed to help with the change over as well as guide players on how to correctly change certain aspects of the game w/o introducing bugs by mangling the save file (such as modders adding money or players who have odd faction glitches).

There will be absolutely ZERO cheating in an online version of VS. While cheating in single player can be fun, cheating in multi just kills the fun for everyone else and has no place within the realm of online gaming.

And to the arguement that cheating makes a game (any game) less fun is pure bs. Some will cheat to extent the life of a game, others will cheat to beat it faster. In either case, they have fun doing so. The only way to keep any player happy with the game is to make sure there is no end of the fun aspects of the game. Waiting 10 freaking minutes to spec from a planet to a mining base is NOT fun. I like realism, but becoming too realistic makes the fun go away and that is a faster death to a game than cheating for the sake of beating a game.

Enjoy the game, and hopefully we few (klauss, myself, strook?...) can get some more developers and artists (im not forgetting about you Deus or Dave) to join up and fix the mess we were left with.
Because of YOU Arbiter, MY kids? can't get enough gas. OR NIPPLE! How does that mkae you feeeel? ~ Halo
Locked