![]() |
|
|
|
Thread Tools | Display Modes |
|
(#1)
|
|
|
Member
Posts: 36
Join Date: 2002.04
Location: Sweden
|
Perfect language features -
2002.11.30, 05:42 PM
I've been working on a game oriented programming language for a while, I don't know if I'll ever have the time to implement it - it's still in the specification stage.
The recent thread about "The Perfect Game Programming Environment" has made wonder what kind of features people would like to see or would find useful. Below is a preliminary list of design goals: Code:
* Be useful for game development (and general programming). * Speed (low level) - at C / C++ level when needed. * Extensible - Simple system level access, it should be _very_ simple to interface with OS and 3rd party libs (primarily C/C++). * Rapid development - Refactoring - it should be easy to change the code at need and support evolutionary requirement changes. - High level - small semantic gap between idea and code i.e. fast development. - Scaleable - it should be easy to write both small scripts as well as apps that use millions of lines of code and still be able to maintain the system. - Concurrency & networking - systems should scale well with a minimum of changes to run on larger systems - more than one CPU or distributed in a network environment. - Useful set of base libs, like: + math (physics, 3D, statistics) + Flexible string processing (lib or syntax ?) - useful for scripts ... + Constraint / search / AI problems - backtracking ... ? * Safe - No pointers(supply useful base types), no state management(use functional lang), no memory management (use GC) and loop constructs that don't suffer from looping one step to far or to short(use higher order funs). - Error handling. - Default behavior should always be safe rather than fast, speed is usually gained by the loss of safety and rapid development (by introducing more complex low level code). * Maintainability - Comprehendible error messages, useful in debugging. - It should also be easy to understand code written by others i.e. use simple syntax and a minimal number of key concepts i.e. a small language. - Documentation should ideally be implicit in the code (preconditions and types) or close to it like comments that can be turned into external docs like in javadoc. - Tool support e.g. profiling and debugging. - Easy to interact with / patch / upgrade running system - dynamic code load. |
|
|
|
|
(#2)
|
||
|
Moderator
Posts: 417
Join Date: 2002.04
Location: Newcastle, UK
|
Re: Perfect language features -
2002.11.30, 05:56 PM
Quote:
|
|
|
|
|
|
(#3)
|
|
|
Member
Posts: 4,923
Join Date: 2002.04
Location: Darkest California
|
2002.11.30, 06:18 PM
I agree with Hokan, I'd rather have safety than speed most of the time, and since one of his specific goals is that speed should be possible when required, I don't see what the problem here is. 90% of the code doesn't need to be fast, but if it's not safe it'll take 3 times as long to develop that 90% as it really needs to!
Anyway, it sounds a lot like Dylan. Functional, and therefore safe; efficient when necessary; compiles to C so relatively easy to integrate with existing C libraries. |
|
|
|
|
(#4)
|
||
|
Member
Posts: 36
Join Date: 2002.04
Location: Sweden
|
Re: Re: Perfect language features -
2002.11.30, 07:18 PM
Quote:
Lets assume that we want to loop over an array and write a element n+1 beyond the the end (n = size of array). * In C this might go unnoticed and result in a strange crash several thousands lines of code later when the overwritten data is used. * In my case (in safe mode) it would be similar to java - the user would get a outOfBounds error and a stack trace that indicates where the error occurred. * (unsafe mode) On the other hand when we know that the code works and it has been profiled and found to consume a lot of CPU time - then and only then is the time when it should be decided if we want to resort to compiler flags like "-no_array_bound_check" for that file or maybe even call/embed C code directly. * (safe and fast) There will also be compromise solutions like "foreach Array DoSomethingCode" or "forrange Range Array DoSomeThing" constructs that can be translated into regular loops, assuming that arrays contain their own length. "foreach" doesn't need to do any bound checks and "forrange" would only need to do two bound checks rather than one for each "Array[i]=....". The only limitation of these functions is that they are not as flexible as the regular loops (they can't do random acess). |
|
|
|
|
|
(#5)
|
|
|
Moderator
Posts: 803
Join Date: 2002.10
Location: Texas
|
I'm sick -
2002.11.30, 08:01 PM
I like pointers
I like memory handling I like math I dislike high level routines that slow down low level routines. I like writing performance code I dislike exception handling I dislike bugs, therefore, I do not program them. speed is ALWAYS better than "safety" you should never use bad programming practices and write sloppy code. and by sloppy code I don't mean you should write "structured" code or "classify your data" I like fast graphics handlers I dislike complex graphics handler I like simple to use structure, CSK was not simple to use. *shudders in horror* |
|
|
|
|
(#6)
|
||
|
Moderator
Posts: 417
Join Date: 2002.04
Location: Newcastle, UK
|
Re: Re: Re: Perfect language features -
2002.11.30, 08:14 PM
Quote:
Speed is utterly essential for games. The faster all your routines run, the more things you can put in your game and the faster you can read the controls. Also, the faster the code runs, the lower the spec of the base machine for the game and the more money you can make. basically "Less Bloat = More Groat" ![]() |
|
|
|
|
|
(#7)
|
||||||||||||||
|
Member
Posts: 4,923
Join Date: 2002.04
Location: Darkest California
|
Re: I'm sick -
2002.11.30, 09:16 PM
Quote:
Quote:
No, I don't make those kinds of errors hugely often -- but I'd prefer to know that I haven't made any. And when I do make one, tracking it down usually takes a significant amount of time I could be using to add features. Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
![]() Quote:
And you're not sacrificing speed, either. If you don't want the bounds check, take it out. I'd rather write slightly slower code with bounds checking, then remove the bounds checking once I know it works, than make the mistake in the first place. Quote:
Speed is essential, but speed over all your code base is not. Realistically, most games have 90% of their time spent in 10% of their code. That's the 10% that needs to go fast. For the rest, it probably doesn't matter if you can double the speed of some routine, it's simply not getting called enough for the player to care. |
|||||||||||||
|
|
|
|
(#8)
|
||||||||
|
Moderator
Posts: 803
Join Date: 2002.10
Location: Texas
|
2002.11.30, 10:13 PM
Quote:
Quote:
Quote:
Quote:
Quote:
![]() Quote:
Quote:
|
|||||||
|
|
|
|
(#9)
|
||||||
|
Member
Posts: 4,923
Join Date: 2002.04
Location: Darkest California
|
2002.11.30, 10:34 PM
Quote:
Quote:
a) you don't have to use it b) if you want a complex container like a map, there's already one written. Rapid development! If it's not fast enough, you can replace it easily enough later... c) why are you manipulating std::strings in performance-critical code? Call c_str() and length() outside your performance-critical areas and pass that information round. Then they're no less efficient than C strings. Quote:
Have you ever (for example) tried to write something that uses QuickTime's graphic importers? Virtually every line of code can potentially generate an error. That means that every line of code is followed by an if statement passing you off to an error handler of some sort. If you don't want those errors to be fatal, you'll either find yourself using exceptions or goto -- and I know which I'm voting for! Quote:
Quote:
|
|||||
|
|
|
|
(#10)
|
|
|
Member
Posts: 146
Join Date: 2002.06
Location: CA, USA
|
2002.12.01, 05:10 AM
I'm pretty happy with C++ as it is now, but there's a couple things I'd love to see added to the language:
- object states. Classes can define "states". Each state replaces some or all of the default constants and virtual methods with different versions for that state. This is really useful for game programming. The only language I've seen do this is UnrealScript. - interfaces. Multiple inheritance adds non-trivial overhead. I'd like to see interfaces like other languages have. - bitwise rotate and overlay operators built into the language. - implicit "inherited" class in methods (obviously not for classes with multiple inheritance) so you could have Code:
class newclass : oldclass{
virtual void thinger() { // inherited virtual too
dostuff();
inherited::thinger();
}
}
- more control over when v-table setup takes place during object construction. I'd like to be able to tell the compiler that for descendants of some class, the v-table should be set up before the parent constructor is called. Likewise I'd like to be able to have v-table teardown after parent destruction (effectively never). - hinted branches and loops. I'd like syntax to indicate to the compiler what the probability of various flow options is so that it can take advantage of those estimates in optimization. For example if(foo):0.2{...} to indicate an if that will be taken 20% of the time or for(foo;bar;baz):50{...} to indicate the loop will repeat on average 50 times. - hinted dynamic casts. I'd like to be able to tell the compiler that I'm going to be dynamic casting one specific class to another very frequently, so it should store information to make that dynamic cast as fast as possible. - explicitly non-volatile pointers. I'd like to be able to specify struct/class members and local pointers as explicitly non-volatile so that they'd be held in registers as much as possible and only written back to or read from memory when absolutely necessary. - output-only pass-by-reference. (effectively multiple return values). compiler features: - pass-by-reference of primitives in registers. - more efficient and complete register usage. Optimize register saving/restoring around and in leaf procedures. Would require two-pass compiling to figure out how many/which registers a leaf procedure needs/used. - pass-by-reference of structs in registers. If a procedure only uses a small set of the elements of a struct/class, make the the responsiblity of the caller to load/store those. This would also require two-pass compiling to figure out which elements of a struct each procedure needes. - transparent "safe pointers" for debugging. Basically, I'm happy with the language, I'd just like more control over, and be able to give hints to, the optimizer. - Gandalf the Gray-Hat[/size] Bring Alistair Cooke's America to DVD! |
|
|
|
|
(#11)
|
|
|
Member
Posts: 36
Join Date: 2002.04
Location: Sweden
|
2002.12.01, 06:55 AM
OneSadCookie has essentially summed up my point of view so I only want to point out some minor points:
- We would still write assembler if speed would be the only thing that matters. - Each level of abstraction (and simplification of coding) consumes some performance but reduces dev time e.g. assembler is faster than C, C is faster than C++ and so forth. - What I'm trying to do is to allow the programmer to access the lower levels in a simple manner when needed, just like some C++ code may be pure C or some app might include some assembler code. - There are plenty of cases where programming convenience or flexibility is more important than performance e.g. - scripting languages are often interpreted, this makes it easy to load custom scripts without affecting the main application, libraries like OpenGL or TCP/IP give portability in exchange of performance loss (speed, memory use, bandwidth). - Also consider that coding and debugging time saved can be used to implement new features or better algorithms for performance critical sections. This can be especially important if you have a limited amount of manpower. So hopefully we can conclude this argument and agree on that there is trade off between speed of development and application performance. I'm essentially aiming for a simple way to control this balance and get as much performance as possible for as little work as possible. |
|
|
|
|
(#12)
|
||
|
Member
Posts: 36
Join Date: 2002.04
Location: Sweden
|
2002.12.01, 07:00 AM
Quote:
|
|
|
|
|
|
(#13)
|
|
|
Moderator
Posts: 417
Join Date: 2002.04
Location: Newcastle, UK
|
2002.12.01, 07:31 AM
The quickest (?) and easiest solution to an easy development language would be to write a C interpreter that can error check while running.
You'd run your game through the interpreter first and iron out any obvious bugs, then compile for full results. I've used interpreted C languages before, such as Poco Script in AniPro ( An old PC Animation/Drawing package) and they're rather good for quick early development. A note to the 'speed isn't absolutely required everywhere' people. It is, even if the bit of code that's only being called 10% of the time is running 50% slower than it should, that's a 5% CPU overhead, that could be the difference between the right number of enemies at a critical point in the game and (the right number - 1) enemies. Don't optimise too early, but don't cripple your game with bloat from your developer environment. |
|
|
|
|
(#14)
|
||
|
Posts: n/a
|
2002.12.01, 04:32 PM
Quote:
Plus your maths is flawed. For a function that executes 10% percent of the time to use 5% of the cpu (on average) it will have to use 50% of the cpu when in does. Now, lets be slightly more realistic and say that our target function uses 1% of the runtime (which is still a lot). So you optimise it and say it takes you 4 hours to double it's speed which is a pretty good return on your time. Now to get your 'money' back your program will have to run for 4 * 200 hours or 33 days before your optimisation is paying for itself. I'm sure there are better things you could have done with your time. |
|
|
|
|
|
(#15)
|
|
|
Moderator
Posts: 417
Join Date: 2002.04
Location: Newcastle, UK
|
2002.12.01, 05:39 PM
If that 1% of bloat stops your game running at the required frame rate (even more critical in console games), then you have to sacrifice functionality (ie numbers of enemies on screen at once or detail of models) to get the game to the desired frame rate. Again, this could also be the difference between running acceptably on a slower machine or not as that 1% could just throw it into unusability.
If I needed to spend 4 hours optimising a routine just because the compiler output slow code, I'd be pretty annoyed. I'd rather have the compiler let me make mistakes (and abuse the language to get better results) and have faster code to start with. I'm not saying you shouldn't have 'protective' code, just that it shouldn't be in the compiler only in the interpreter. |
|
|
|
| Thread Tools | |
| Display Modes | |
|
|