Jump to content
  • Advertisement

Otay

Member
  • Content Count

    11
  • Joined

  • Last visited

Community Reputation

9 Neutral

About Otay

  • Rank
    Member

Personal Information

  • Role
    3D Artist
    Game Designer
    Programmer
  • Interests
    Art
    Audio
    Design
    Education
    Programming

Social

  • Twitter
    Otaykins
  • Twitch
    Otaykins

Recent Profile Visitors

417 profile views
  1. Otay

    Realm of the Tempest RPG

    Demo is out! https://otay.itch.io/realm-of-the-tempest
  2. Otay

    Realm of the Tempest RPG

    I'll share some technical notes about the transition effects since they were so fun. Background Info Three years ago I actually had a playable game. Then I transferred to a university, and dropped my game dev hobby when my obsession with math and computer science sparked up instead. When I returned to game dev earlier this year, I was disgusted by my code, especially its lack of encapsulation. After considering my options for how to clean up my code, I painfully decided that rewriting everything from scratch was the lesser headache. This game was started in 2011 with the UDK engine, and I have refused to switch due to how much I enjoy the aesthetic I worked so hard to achieve with all the lighting and materials. UDK is not at all friendly with UI, so I write a lot of UI code from scratch. After months of my eyes bleeding through UI code, programming these transition effects has been a much needed change of pace. Transition Effects UDK (kind of?) allows fancy shader code, I think? Seems like most shader stuff is done in the editor interface rather than in code, which makes me sad. I chose to implement my transition effects with a big array of black sprite tiles instead. The premise of the algorithm for transition effects that I outlined before coding is this: Add all tiles to a dynamic array, initialize visibility on (or off) Sort the array based on each tiles distance to an equation of your choice With each tick from a timer, randomly select "k" of the first "m" elements out the total array of "n" tiles Change the visibility of the selected tiles, and remove them from the list Repeat until list is empty All I needed to accomplish this was a static array of tiles, dynamic array of tile indices and distance calculations, a custom comparitor for sorting tiles by distance, and a dynamic array of function pointers to delegate sorting equations for the various effects. I use the fancy delegate array so that I can customize what set of effects will be randomly picked from (notice fading into battle is always the vertical down one.) I'm more of a C/C++ kind of guy, but I dont mind working in UDK's unrealscript language. Here's the code. Data // Tile count for transition effect // 60x60 tiles, 1440x900 resolution, 1440/60 * 900/60 const TILE_COUNT = 360; const TILES_PER_ROW = 24; const COLUMN_PER_ROW = 15; // Tile sorting information struct TileInfo { var int index; var int distance; }; var private array<TileInfo> tileIndices; // Sprite tiles var private GUISprite blackSquares[TILE_COUNT]; // Effect functions var private array<delegate<tileSorter> > sorterEffects; delegate int tileSorter(int index); Algorithm /*============================================================================= * tileSort() * * Sorts tiles for transition effect *===========================================================================*/ private function tileSort(delegate<tileSorter> sorter) { local TileInfo newTile; local int i; // Reset array tileIndices.length = 0; // Populate list for (i = 0; i < TILE_COUNT; i++) { newTile.index = i; newTile.distance = sorter(i); tileIndices.addItem(newTile); } tileIndices.sort(tileComparison); } /*============================================================================= * tileComparison() * * Compares distance between tiles. Negative result signifies out of order. *===========================================================================*/ private function int tileComparison(TileInfo a, TileInfo b) { if (a.distance < b.distance) { return -1; } else if (a.distance > b.distance) { return 1; } else { return 0; } } /*============================================================================= * renderTiles() * * Timer allocated function for drawing tiles effects to the screen *===========================================================================*/ private function renderTiles() { local bool displayState; local int index, k; // Transition direction displayState = (transitionStyle == TRANSITION_OUT); for (k = 0; k < tilesPerTick; k++) { // Check for remaining indices if (tileIndices.length == 0) { endTransition(); return; } // Render a random batch from the sorted list index = rand(20); if (index >= tileIndices.length) index = rand(tileIndices.length); blackSquares[tileIndices[index].index].setEnabled(displayState); tileIndices.remove(index, 1); } } Effect Equations /*============================================================================= * sortMethod1() * * Circle effect *===========================================================================*/ private function int sortMethod1(int index) { // Distance to x=1/2, y=1/2 return distanceFormula( blackSquares[index].posX, blackSquares[index].posy, NATIVE_WIDTH / 2, NATIVE_HEIGHT / 2 ); } /*============================================================================= * sortMethod2() * * Four corners effect *===========================================================================*/ private function int sortMethod2(int index) { local float d1, d2, d3, d4; // Distance to MIN(four corners) d1 = distanceFormula( blackSquares[index].posX, blackSquares[index].posy, 0, 0 ); d2 = distanceFormula( blackSquares[index].posX, blackSquares[index].posy, NATIVE_WIDTH, 0 ); d3 = distanceFormula( blackSquares[index].posX, blackSquares[index].posy, 0, NATIVE_HEIGHT ); d4 = distanceFormula( blackSquares[index].posX, blackSquares[index].posy, NATIVE_WIDTH, NATIVE_HEIGHT ); d1 = fMin(d1, d2); d2 = fMin(d3, d4); return fMin(d1, d2); } /*============================================================================= * sortMethod3() * * Vertical lines effect *===========================================================================*/ private function int sortMethod3(int index) { local float d1, d2; // Distance to MIN(x=1/3, x=2/3) d1 = abs(blackSquares[index].posX - (NATIVE_WIDTH / 4)); d2 = abs(blackSquares[index].posX - (3 * NATIVE_WIDTH / 4)); return fMin(d1, d2); } /*============================================================================= * sortMethod4() * * Horizontal line effect *===========================================================================*/ private function int sortMethod4(int index) { // Distance to Y = 1/2 return abs(blackSquares[index].posY - (NATIVE_HEIGHT / 2)); } /*============================================================================= * sortMethod5() * * Randomized effect *===========================================================================*/ private function int sortMethod5(int index) { // Random method return rand(10); } /*============================================================================= * sortMethod6() * * Vertical curtain effect, used only for opening combat *===========================================================================*/ private function int sortMethod6(int index) { // Distance to Y = 1 return abs(blackSquares[index].posY - NATIVE_HEIGHT); } Final thoughts Even though the mixing of 2D / 3D is the most frequently criticized design choice in my work, I'm personally happy with how this is turning out aesthetically.
  3. Otay

    Realm of the Tempest RPG

    Implemented some screen transition effects for swapping between 3d and 2d world today (placeholder test zombies are spawning right now, working on enemy spawning next) also made some music
  4. Otay

    Realm of the Tempest RPG

    Thanks I dont do 3D characters because I dont enjoy it. It is always the first recommendation anyone ever makes.
  5. Otay

    Realm of the Tempest RPG

    Yeah, the music is made in Reason 5.0, textures made in Photoshop, 3D models made in 3ds Max I compose each song note by note, but Reason comes with a lot of "patches" for synths, and sample sets of every note from common instruments like pianos and violins. So some of the sounds come from tweaked versions of existing synth patches, or pre recorded instruments that I never physically touched. Sometimes I do synth from scratch though. My sound engineering knowledge is limited, I just took one class in college and really enjoyed it. As a kid I took piano lessons, so I have some music theory under my belt.
  6. Otay

    Realm of the Tempest RPG

    working on these silly little rainbow beacons today, which add a hero to your team
  7. Overview Realm of the Tempest is a personal and desultory exploration of creativity. When viewed as game development, my work is unprofessional, awkward, neglects the target audience, and disregards marketing value. After investing thousands of hours into this project, I don't think of it as a game at all. To me it is an intimate conversation between me and my compiler, that has been going on for 5 years. The only reason I pour my heart into my work is because it starts to reflect myself, which is the only sense of security I have ever had. Combat It has turn based 2D random encounter combat, because that's what I enjoy designing. Worlds It has 3D worlds because I like making 3D art. Music It has an original soundtrack, because I like making MIDI music
  8. Otay

    Commonly Used Forms of Calculus

    Ah yeah, a quick google search confirms its been obsolete since 1999, and there's a big article on it here: http://assemblyrequired.crashworks.org/timing-square-root/ In response to the original question about calculus in programming, I think calculus comes in handy most for analyzing data structures and algorithms (like Alvaro mentioned) more than it does directly in the code. Don Knuth, the "father of algorithm analysis" wrote several volumes on the art of computer programming, and flipping to a random page usually turns up an integral or two. There's a lot of interesting math stuff that comes up unexpectedly in computer science, like how collapsing sets of imaginary numbers are what make fast fourier transforms "fast"
  9. Otay

    Commonly Used Forms of Calculus

    I dono ive never seen this one, the one i posted was 4x faster than the regular computation. How fast is this method?
  10. Otay

    Commonly Used Forms of Calculus

    fast inverse square root is a common engine function used for calculating surface normals for lighting, and it combines the magic of bit level hacking with some root finding calculus tricks. this involves calculating the first few terms of a Taylor series. Taylor series are pretty cool in general. https://en.wikipedia.org/wiki/Fast_inverse_square_root float Q_rsqrt( float number ) { long i; float x2, y; const float threehalfs = 1.5F; x2 = number * 0.5F; y = number; i = * ( long * ) &y; // evil floating point bit level hacking i = 0x5f3759df - ( i >> 1 ); // what the #*@!? y = * ( float * ) &i; y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration // y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed return y; } If you count polymorphic lambda calculus as calculus, the entire foundation of object oriented programming that saved the world of computer science from the software crisis in the 1970s is in a sense a "calculus" https://en.wikipedia.org/wiki/System_F "... simply typed lambda calculus has variables ranging over functions, and binders for them, System F additionally has variables ranging over types, and binders for them. "
  11. Overview Realm of the Tempest is a personal and desultory exploration of creativity. When viewed as game development, my work is unprofessional, awkward, neglects the target audience, and disregards marketing value. After investing thousands of hours into this project, I don't think of it as a game at all. To me it is an intimate conversation between me and my compiler, that has been going on for 5 years. The only reason I pour my heart into my work is because it starts to reflect myself, which is the only sense of security I have ever had. Combat It has turn based 2D random encounter combat, because that's what I enjoy designing. Worlds It has 3D worlds because I like making 3D art. Music It has an original soundtrack, because I like making MIDI music. Videos & Demo There's no demo yet and no videos. I develop live on twitch if you ever want to see more. Thanks for viewing my work.
  12. Otay

    Realm of the Tempest

    Album for Realm of the Tempest
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!