Jump to content

SoulofDeity

Member
  • Posts

    437
  • Joined

  • Last visited

  • Days Won

    43

Everything posted by SoulofDeity

  1. Found this earlier today. Wish I could figure out where the first song came from. Sounds like a mix of "Nine Thou" by Styles of Beyond and "Down With The Sickness" by Disturbed. Also, I've been listening to this one guy on youtube called 331Etrock shred guitar on a lot of different songs. He's fricken amazing, you guys should sub him
  2. The n64 uses gauraud shading with the vertex colors being premultiplied with the normal vector to decrease bandwidth and make lighting calculations faster
  3. Back On Topic Now... I went back to the drawing board for my interchange format. What I needed was a way of representing both metadata and data. So I chose the easiest thing: '[ ]' = metadata, '{ }' = data. If the text inside of these brackets has unescaped brackets, then it's a subproperty. If not, then it's a value. For example: File [ Name { My File.txt } Type { Text } ] { Text { This is a text file! ~Awesomeness!\n \tLeading and trailing whitespace is ignored, so you have to manually add newlines and indentation.\n Also, properties begin with \[ \] and \{ \} so those must be escaped in text. } } Here, 'File' is an object that has the values 'Name' and 'Type' for metadata and the value 'Text' for it's data.
  4. The 3D castle town market looks great While I can't say I'm a fan of 1995 Link, your model does seem to be pretty accurate Could use some shading though.
  5. As seen above, I've been advocating duck-typing and a sort of parametric/ad hoc hybrid polymorphism. I think I'm going to do away with the ad hoc part and add a 'use' keyword paired with a set of types. The idea being that you can do something like: use add integer, integer add := x, y => x + y Before I had this idea, unless you added a set of type-constraints, code would only be generated if you used it on those types. Here, I'm doing away with type-constraints and allowing the programmer to explicitly declare the use of types to generate code for. Note that you'd only need to do this to generate code for unused types, eg. If you call 'add(5, 5)' somewhere in your code, it'll see that you're using a type signature of 'integer, integer' and behave as though you've added 'use add integer, integer' to your code. For this reason, the 'use' keyword is only necessary when creating libraries; and in any other situation, simple parametric polymorphism is fine. Old Notes... EDIT: An idea I just had, 'x()' could be interpreted as, "value of x". In this sense, the '(' and ')' could be used for both arrays and functions. Then, perhaps '{ }' could be used for references. eg. x = (1, 2, 3) x(0) // value is '1' (*x) x(1) // value is '2' (*(x+1)) x{0} // pointer to 'x' (&x) x{1} // pointer to 'x + 1' ((&x)+1) print(x(1)) It's like inside-out C pointers.
  6. Working on the shorthand syntax a bit. and && be := do => let \ minus - on \ or || plus + times * to .. :: # used for delimiting namespaces Here's a short preview of what function declaration looks like: System::Console::Print := argc, argv => x := 5 Print := System::Console::Print This is equivalent to on System::Console::Print := argc, argv do let x be 5 let Print be System::Console::Print For the sake of clarity, I decided not to kill off the 'on' keyword in favor of 'let'. Since I'm using the ':=' operator to assign by reference, I thought that the C++ style of 'System::Console::Print' looked more suitable than 'System.Console.Print'. For the 'do' keyword, I chose '=>' because it's used for lambda in C#. I had thought about incorporating ternary if statements like: if \ then ? else : So you could do: \(x < 5)? => something :(x > 5)? => something : => something In place of if x < 5 then do something else if x > 5 then do something else do something Note that the '\' is optional; I only used it because I'm an obsessive compulsive douchbag turned on by symmetry. Anyhow, if I go this route, then I can't use the ':' symbol for 'as'. Although, if I excluded the 'as', then ':' could also be used for the 'in' keyword like: for e : c => something This may actually be for the best considering that the traditional syntax for 'let' as 'let x be y in z' would simply be 'x := y : z'.
  7. Game Maker is pretty awesome. Before I started using the internet, it was my tool of choice. Was spitting out games left and right. That said, player control for platform games is tedious. You have to be aware of how the physics work. So I'm with Keanine about keeping it a mod for now
  8. Some more things to mention. As said in the previous post, the 'let' keyword is equivalent to '\', technically making it optional. Well, in Ergo, sets are delimited by commas and may optionally be encapsulated by parentheses. So let print format, text do something is equivalent to print (format, text) do something () This is actually a lot like the B programming language. print (format, text) { something () } The only differences are that Ergo doesn't use brackets and that everything is generic by default, where everything in B is a 'word' (the optimal 'int' for the device being programmed for). One idea I was thinking about was to have Ergo bring back ANSI-C style type constraints. To the less informed, this is how C used to look... print (format, text) char *format; char *text; { } What I like about this the most is the separation between the definition of the function and the 'contract'. While it may seem wordy, it's also extensible. Instead of types, you could have 'concepts'; which are a set of assertions about which attributes, operators, and functions that an object has. In this case, we are saying that 'format' must match the concept of a 'char *'. This was actually a highly anticipated template metaprogramming feature which had been planned to be introduced into the C++ standard a while back but was pulled out at the last moment because the standardization committee didn't feel it was mature enough. Before I implement it in Ergo though, I want to tinker with the syntax a bit to make it more understandable.
  9. I'm going to be selling some games soon: 3DS Games: Zelda - Ocarina of Time 3D Zelda - Majora's Mask 3D Zelda - A Link Between Worlds Harvest Moon - A Tale Of Two Towns Animal Crossing GC Games Zelda - Twilight Princess Metroid Prime II - Echoes Wii Games Zelda - Skyward Sword Soul Calibur Legends PS Vita Games Gravity Rush Jack and Daxter - The Complex Collection Also, I'm might have sold them already, but if not, I'll be getting rid of Zelda - Phantom Hourglass and Zelda - Spirit Tracks for the 2DS. All of the games are physical copy.
  10. Some changes have been made. Firstly, the 'let' keyword is no longer used to create local variables. Instead, it's used to define locally-scoped macros. For constants, the format of a let-statement is 'let var be something'. For example: let x be 5 For functions, the format of a let-statement is 'let fn arg1, arg2... do something'. For example: let print format, text do something () This new syntax makes it unneccessary for there to be an 'on' keyword. Another change I've been working on is an alternative wordless syntax. and && as : be := else ..1b from = if 0b.. let \ or || then \ to .. An example usage of this, the following code: let print format, text do let x be 5 if format != null and text != null then do something () else do something () for i as Integer from 0 to 100 do something () could be alternatively be written as: \ print format, text do \ x := 5 0b.. format != null && text != null \ do something () ..1b do something () for i : Integer = 0 .. 100 do something () or print format, text do x := 5 0b.. format != null && text != null do something () ..1b do something () for i : Integer = 0 .. 100 do something () I'm hoping to make it possible for all keywords to have symbolic alternatives. Another thing I've been working on is the type system. The suffixes 'b' and 'i' appended to numbers stand for 'boolean' and 'integer'. Instead of the traditional 'float' or 'double' types, I've been pondering the use of a type called 'scalar'. The meaning of the word is unambiguous between computing and mathematics as a representation of a real number which may be a field of a vector or matrix. If I did this, it'd also make sense for Ergo to natively support vector operations. A feature like that could allow Ergo to outperform C or C++ in many situations. EDIT: Thinking about the new syntax a little bit. With consideration for the symbolized form, a better format may be: let print for format, text as String, String do something The 'as String, String' part is an optional type constraint. One benefit of this syntax is continuity. Functions are pretty much the same thing as loops. 'for <input> do <something>'
  11. I had originally began tinkering with this idea in a separate thread about a new interchange format, but finally decided it was deserving of it's own thread. The vision for Ergo is a statically typed compiled language for systems programming focused on abstraction, expressiveness, and simplicity. It's goals include high polymorphism, high code reusability, high readability, and a low learning curve. Let The 'let' keyword is used to declare new local variables. let x = 5 x = 6 The Ergo programming language also supports tuple assigment like in Python. let x, y = 5, 5 x, y = 6, 6 The types of the variables are deduced from the values assigned to them upon declaration. And The 'and' keyword is used to combine statements. something () and something () Do The 'do' keyword is used to execute instructions. When immediately followed by an instruction, it executes that instruction. do something () this can also be used in conjunction with the 'and' keyword. do something () and something () If a newline immediately follows a 'do' keyword, then it executes a block of instructions with the same indentation level. do something () something () For (+ 'from', 'to', 'by', 'in') The 'for' keyword is the most powerful keyword in the Ergo language. It doesn't create loops, it declares the subject for a specific context. The most recognizable form is the iteration context. for i from 0 to 5 by 1 do something () for j, k to 10, 10 do something () Here, the subjects are 'i', 'j', and 'k'. The above code is equivalent to the following C++ code: for (int i = 0; i < 5; i++) something (); for (int i = 0, j = 0; i < 10 && j < 10; i++, j++) something (); Iterations have the format 'from <start> to <stop> by <step>'. The start and step are optional though. By default, the start will be 0 and the step will be 1. The next most recognizable form is the enumeration. for e in c do something () Enumerations have the format 'in <collection>'. This is equivalent to the following C# code: foreach (int e in c) something (); The best way to visualize the 'for' statements in Ergo is to break them into 3 parts: for i to 5 do something () for i # part 1 - the subject is 'i' to 5 # part 2 - the context is the range from 0 to 5 by 1 do something () # part 3 - the predicate As you can see here, the loop is created by the context. In the future, if anything aside from an iteration or enumeration is used as a context, the predicate will only be executed once. Next The 'next' keyword is used to advance the iterator or enumerator in a context. It's equivalent to the 'continue' keyword in C. for i to 5 do next Exit The 'exit' keyword is used to escape from a context. It's equivalent to the 'break' keyword in C. for i to 5 do exit On (+ or) The 'on' keyword is used to create an event handler. on print do something () Events may optionally have parameters. on print format, text do something () In the above code, both 'format' and 'text' are parameters. Despite their appearance, they are statically typed. The way this works is simple: they're generic. It's equivalent to saying the following in C++: template <typename T, typename U> void print (T format, U text) { something (); } When some code tries to trigger the event: print ("%s", "Hello") The compiler says, "oh, I see you're passing strings for the format and text, so the print event handler must accept those types". If you're an experienced programmer, just take a minute to let that one sink in. Unlike most other languages, Ergo actually assumes that you know what you're doing and generates code for whatever object types you trigger the event with. If you wanted to pass numbers instead, Ergo is perfectly okay with that and you don't have to change a single line of code. This extreme level of polymorphism and simplicity makes Ergo easy to use for prototyping. However, it has to know ahead of time which types to generate code for. For this, the 'for' keyword is used to specify a set of type constraints. on add x, y for int, int or float, float do something () These constraints ensure that only code for ints and floats will be generated. So, if you were to call 'add' with doubles, it'll implicitly cast to float instead of generating an add event handler for doubles. If The 'if' keyword is used to conditionally execute instructions. if true do something () any statement checked with 'if' will be implicitly casted to a boolean. In other words, null or 0 is false and if it's not false it's true. To As shown in the prior example of an iteration context, the 'to' keyword creates a branch from one value to another. This is not limited to integers though. Ergo allows you to exploit this fact to chain multiple conditions together. if x < 5 do something () to x > 5 do something () This construct is a 'to-do list'. If 'x' is less than 5, then the result will evaluate to true. This means that the next statement is implicitly 'true to x > 5'. Note that the range specifies an iteration context, so regardless of if 'x' is greater than 5 or not, the predicate will not be executed. In laymens terms: if 'x' is less than 5, then all the proceding 'to' statements are ignored. However, if 'x' is not less than 5, then the result will evaluate to false. This means that the next statement is implicitly 'false to x > 5'. In this case, if 'x' is equal to 5 then this becomes 'false to false', and thus the result remains false; passing on to the next 'to' statement. If 'x' is greater than 5, then this becomes 'false to true', causing the predicate to be executed once and the result to be changed to true; meaning all proceding 'to' statements will be ignored. In laymens terms, the 'to' keyword + boolean values = else if. Note that this isn't limited to if statements. The following is a syntactically correct fake if-statement in Ergo false to x < 5 do something () One way of looking at this is that there is no such thing as an if statement, only 'to' statements; and 'if' is just an alias for 'false to'. You can also use it to execute a piece of code a specific number of times. 0 to 5 do something () Else The 'else' keyword is used to conditionally execute instructions if the prior statement wasn't executed. The most common use of this is with 'if' statements. if true do something () else do something () For this usage, a 'do' statement must come immediately after the 'else' keyword. if x < y do something () to x > y do something () else do something () -------------------- Up For Consideration I'm considering the use of 'select' queries like in C#. The type system is also in need of work, C-types just look out of place in Ergo imo.
  12. That happened to me on my first attempt. You need to make sure you triangulate the faces and export the normals.
  13. Nemu64 doesn't like the extended rom for some reason. Project64 was okay with it (at least for me). I would suggest testing on actual hardware.
  14. Actually, if you're using Windows, you might have better luck than me at doing this. Download ToolN64 and SM64 Level Importer. If your rom has the .n64 extension, it's most likely middle-endian, so you'll need to open the directory it's in in ToolN64, right-click on it, and click "big-endian" to byteswap it. Next, run the SM64 Level Importer. Set the rom to your *.z64 big-endian rom. It'll say something about needing to extend the rom; go ahead and do that. It'll spit out a *.ext.z64 file. If it repeats the same message after that, just click cancel. Set the rom to the new *.ext.z64 rom. Next, set the model to your wavefront obj. If you use Blender, make sure it has normals, otherwise you'll end up with nothing. Then, click the "custom import..." button at the bottom. It'll open a new window with a list of models. Select "Mario - Head" and then click the button at the bottom to replace it.
  15. I don't have any experience with SM64 modding, but I would be happy to look up some specs and see what I can do. This sounds like it'd be a really neat birthday gift. EDIT: *Almost figured it out: EDIT #2: Model import works now, but the texturing is screwed up because the texture converter crashes due to a missing function in vcomp.dll. (I'm on linux, the conversion tool I'm using won't run in wine, so I'm 'pretending' to install it in PlayOnLinux). I might be able to hunt down the 'real' DLL, toss it into the app dir and get it working.
  16. I had mentioned this on skype before, but I never was really interested in modding. I was more interested in the N64's architecture. Plus it's very time consuming.
  17. Flotonic hates Zeth for unknown reasons. Saying that he ran off with the money is bs though. Donations are for the website, not the project. Aside from that, they weren't paying for a product. I think it's low myself. Most fan games don't get finished. It's difficult to keep a group of unpaid people happy and working for free.
  18. The problem I'm talking about is when you try to replace a module. With OOP, you can't just swap out a class. Tight coupling dictates you either rewrite a majority of it for use in your code base or merge it's entire dependency web into your project. Especially in large projects, tiny changes cause huge code ripples. Generally, you should always strive for low coupling and high cohesion; so OOP by design teaches bad programming habits. On a side note, I decided on how type constraints will work: on add a, b for int, int or float, float do reply a + b Note that these are optional unless you want to forcefully generate code for specific type signatures.
  19. The high level of abstraction in the public interface while keeping other things private is what I refer to as data-hiding. Strong coupling is a very bad thing because it makes it difficult to change and reuse code as well as vastly decreasing both modularity and polymorphism.
  20. Oh, this isn't for school. I'm meeting with someone this monday to share ideas. I scribbled a little example on a receipt, and the guy was genuinely interested in it. (I mean, he literally just sat there quitely for about 5 minutes, deep in thought at first, and while we were talking about it, he kept asking to make sure he heard me right when I said this was a statically-typed compiled language). He also happens to be a fan of object-oriented programming, so I wanted to show him exactly why I avoided it.
  21. I'm not particularly good at citing things. I basically just read a lot of articles and books about these subjects from various authors, comparing theory and practice, and came to my own conclusions. The ones that I know most people would be pissed off by are my slides on garbage collection and object-oriented programming. But they're true. Heavy use of references and pointers scattered all about leads to a lot of cache misses, mark-and sweep algorthms have considerable overhead, and in almost every OO-programming language, the use of finalizers is discouraged because some GC's may never even collect at all. GC makes use of linked lists, which by Bjarne Stroustrup goes on record for having made an entire presentation showing that they're worse than vectors in every single way (indexing, insertion, allocation, etc.) because they cannot make use of the cache. Additionally, with reference counting, there are cases in which you can accidentally create a reference without knowing it. The reference count will then be greater than 0 despite nothing actually referencing it. As a result, the object is never freed. This is the cause of many C++ memory leaks. With object-oriented programming, you have to understand that by encapsulating methods in specific classes, you're placing a type-constraint. Which is counter-intuitive because it's pretty much the exact opposite of polymorphism. The only useful thing encapsulation brings to the table is data-hiding, but that's not an exclusive thing. To work around these type constraints, OOP uses inheritance. This is well known to be a horrible and flawed way of improving polymorphism. This is why many newer languages are making use of traits and mixins. OOP has no benefits at all, adds unnecessary complexity, and requires tons of boilerplate. I believe it was Linus Torvalds who had said that the only thing OOP does is allow you to write structured spagetti-code. The example I gave in my presentation shows a way in which you can actually write far less code that's much simpler while being far more polymorphic. I also made note of Alan Kay's quote that modern OOP is not what he invisioned. Which, after reading his original work where he introduced the concept, I can affirm that this is true. What he was talking about is most closely related to actor-oriented programming, though not entirely the same. My assertions on what makes a good programming feature are based on my studies of linguistics. Short and simple words that express abstract ideas effectively increase how well people can communicate. What is most important in a programming language is readability.
  22. Here's an unfinished presentation I've been working on that briefly summarizes my conclusions about popular concepts in programming, what I define to be a good language, and the design decisions for my language. http://www.mediafire.com/download/r68oy7qc07g4awv/Language.pptx There's still a bit more to go. My deadline for this is 07/05/15 (this Monday).
  23. We can probably just borrow the range syntax from for loops.eg. "from 2 to 22 by 1". Note that the "from <start>" and "by <step>" parts can be omitted. The language does pay attention to whitespace, since it uses indentation instead of using brackets. eg. on main argc, argv do if argc > 1 then do for i from 1 to argc do printf ("%s\n", argv [i]) next # not needed, just for example else do printf ("Error: Not enough arguments.\n") if-statements are a little verbose and feel out of place... EDIT #1: EDIT #2: Another idea instead of static typing is default generic typing, where: on main argc, argv do something() Is equivalent to: template <typename T, typename U, typename V> T main (U argc, V argv) { something(); } Only the code for types that are used are generated. So, if some code calls: main (0.5, "Hello") Then the code for: int main (float argc, string argv); Will be generated. Of course, we'll also want some way of generating code regardless of whether or not it's used for external linking; like how C# uses the "where" keyword. Forcing specific code to be generated will have a lengthier syntax than C or C++, but generally, code written in my language will be far more polymorphic and reusable. EDIT #3: Another idea I just had, using an 'at' keyword to create labels for loops. eg. for i to 5 at loop1 do for j to 5 at loop2 do next loop1 This way, you can skip and break out of multiple levels of loops. EDIT #4: Another idea that just popped into my head, instead of a "break" keyword, you have "enter" and "leave" keywords. The "leave" keyword is pretty much self explanatory, but the "enter" keyword is pretty neat. Consider the following code: i = 5 while i < 5 do something() Typically, "something()" would never get executed because 'i' is >= 5. However, the enter keyword allows you to ignore the condition and jump into the block regardless. eg. i = 5 enter while i < 5 do something() Which is equivalent to the traditional: int i = 5; do { something(); } while (i < 5); Even cooler is that because the "at" keyword allows you to label blocks of code, you can do this: if someCondition do enter loop else if someOtherCondition do enter loop for i to 5 at loop do something () Here, if 'i' is < 5 or someCondition or someOtherCondition is true, then the loop will be executed. Algebraically speaking, `if (someCondition || someOtherCondition || i < 5) enter loop` EDIT #5: Another idea, being able to label 'do' blocks. eg. at place do something() enter place It's a sort of fake goto statement. Actually, it technically could be used as one like: at place do leave enter place The above would be an infinite loop. For syntactic purposes, this could perhaps be rewritten as leave at place enter place or void at place enter place
  24. I'm trying to avoid parentheses and brackets as much as possible. They require use of a shift key and are difficult to type with an osk on a phone. EDIT: Also, my language does have tuples since I'm borrowing Python syntax for variable declaration; so comparison by "is" wouldn't work. Perhaps a comparison like that could reuse the "in" keyword.
  25. Something I was thinking about at work today was a format like: if x == 5 then do something() else do something() if x is 1 do something() is 2 do something() else do something() where "then" captures all non-zero/null values, "is" captures specific values, and "else" captures all remaining values. This way the general syntax of if statements is pretty much the same. The main issue though is "else if". Technically, there's no such thing... The if-statement is just a block-instruction being executed by "else". However, this illusion reduces the need to have an extra level of indentation into code. That said, I'm still not 100% comfortable with my "if _ is _ do _ else do _" format. though I think it's a bit of an improvement. You have any other ideas?
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.