• Log InLog In
  • Register
Liquid`
Team Liquid Liquipedia
EDT 23:48
CEST 05:48
KST 12:48
  • Home
  • Forum
  • Calendar
  • Streams
  • Liquipedia
  • Features
  • Store
  • EPT
  • TL+
  • StarCraft 2
  • Brood War
  • Smash
  • Heroes
  • Counter-Strike
  • Overwatch
  • Liquibet
  • Fantasy StarCraft
  • TLPD
  • StarCraft 2
  • Brood War
  • Blogs
Forum Sidebar
Events/Features
News
Featured News
Maestros of the Game: Week 1/Play-in Preview9[ASL20] Ro24 Preview Pt2: Take-Off7[ASL20] Ro24 Preview Pt1: Runway132v2 & SC: Evo Complete: Weekend Double Feature4Team Liquid Map Contest #21 - Presented by Monster Energy9
Community News
Weekly Cups (August 25-31): Clem's Last Straw?7Weekly Cups (Aug 18-24): herO dethrones MaxPax6Maestros of The Game—$20k event w/ live finals in Paris45Weekly Cups (Aug 11-17): MaxPax triples again!15Weekly Cups (Aug 4-10): MaxPax wins a triple6
StarCraft 2
General
Weekly Cups (August 25-31): Clem's Last Straw? #1: Maru - Greatest Players of All Time Maestros of the Game: Week 1/Play-in Preview Weekly Cups (Aug 11-17): MaxPax triples again! 2024/25 Off-Season Roster Moves
Tourneys
Maestros of The Game—$20k event w/ live finals in Paris Monday Nights Weeklies LiuLi Cup - September 2025 Tournaments 🏆 GTL Season 2 – StarCraft II Team League $5,100+ SEL Season 2 Championship (SC: Evo)
Strategy
Custom Maps
External Content
Mutation # 489 Bannable Offense Mutation # 488 What Goes Around Mutation # 487 Think Fast Mutation # 486 Watch the Skies
Brood War
General
ASL20 General Discussion No Rain in ASL20? Victoria gamers Starcraft at lower levels TvP BGH Auto Balance -> http://bghmmr.eu/
Tourneys
Is there English video for group selection for ASL [ASL20] Ro24 Group F [IPSL] CSLAN Review and CSLPRO Reimagined! Small VOD Thread 2.0
Strategy
Simple Questions, Simple Answers Muta micro map competition Fighting Spirit mining rates [G] Mineral Boosting
Other Games
General Games
Stormgate/Frost Giant Megathread General RTS Discussion Thread Nintendo Switch Thread Path of Exile Warcraft III: The Frozen Throne
Dota 2
Official 'what is Dota anymore' discussion
League of Legends
Heroes of the Storm
Simple Questions, Simple Answers Heroes of the Storm 2.0
Hearthstone
Heroes of StarCraft mini-set
TL Mafia
TL Mafia Community Thread Vanilla Mini Mafia
Community
General
US Politics Mega-thread Things Aren’t Peaceful in Palestine Canadian Politics Mega-thread Russo-Ukrainian War Thread YouTube Thread
Fan Clubs
The Happy Fan Club!
Media & Entertainment
Anime Discussion Thread Movie Discussion! [Manga] One Piece [\m/] Heavy Metal Thread
Sports
2024 - 2026 Football Thread Formula 1 Discussion TeamLiquid Health and Fitness Initiative For 2023
World Cup 2022
Tech Support
Computer Build, Upgrade & Buying Resource Thread High temperatures on bridge(s) Gtx660 graphics card replacement
TL Community
The Automated Ban List TeamLiquid Team Shirt On Sale
Blogs
hello world
radishsoup
Lemme tell you a thing o…
JoinTheRain
How Culture and Conflict Imp…
TrAiDoS
RTS Design in Hypercoven
a11
Evil Gacha Games and the…
ffswowsucks
INDEPENDIENTE LA CTM
XenOsky
Customize Sidebar...

Website Feedback

Closed Threads



Active: 536 users

[Game Programming]Some of my code designs

Blogs > Bill307
Post a Reply
Normal
Bill307
Profile Blog Joined October 2002
Canada9103 Posts
July 16 2009 02:29 GMT
#1
Since ~January, I've been hard at work programming a mid-sized (from my perspective) game. Through this experience, I've learned and come up with a number of code design ideas, both good and bad. To save others from making the same mistakes that I did, and to give others ideas for their own games or programs, I've decided to share some of my experience here.

Please comment if you found this information useful / easy to understand / hard to understand, or if you have suggestions or improvements for it.

By the way, the game is being programmed in C# using XNA Game Studio. It's also a long way from being finished, so many aspects of the game have not matured yet and won't be covered here.


--------------------------------------------------

Class Organization

Below is an overview of many of the game's classes, showing how they are organized from the top down, i.e. from general knowlege to specific knowledge.

  • Game class -- the over-arching class that encompasses the entire game. Essentially all of the game logic is off-loaded to other classes. It also provides static methods for accessing "global" objects anywhere. (Using XNA's "game services" functionality.)

  • Stage Updater and Stage Drawer classes -- these classes manage the game logic and rendering of the game, respectively. These also off-load most of the work to other classes. All they really know is the order in which parts of the game are updated/drawn.

  • Various manager classes -- e.g. Enemy Manager, Bullet Manager, etc. These classes know some of the detailed game logic for their own little subsets of game objects.

  • Various game object classes -- e.g. Enemies, Bullets, Explosions, Players, etc. These classes are self-explanatory, and contain the rest of the detailed game logic.

  • Lower-level classes and data structures -- e.g. Sprites, Particles, Hitboxes, Custom Lists, Custom "Vertex Buffers", inactive object Pools, etc. These don't contain any game logic, and handle small, common tasks like displaying sprites, moving particles, checking for hitbox collisions, storing vertices, etc.

  • Physics class -- handles all game physics (just basic linear kinematics with linear forces, acceleration, velocity, and position, and all objects being treated as circles/spheres). The only "physics" code outside of this class is simple stuff like adding an acceleration to a velocity, or multiplying a force by the inverse of a mass to get an acceleration.

  • ... and more!

--------------------------------------------------

Pooling Objects

When a game is running, you want to create and destroy as few objects as possible (outside of loading screens and the like). This is especially true when using a managed language such as C# or Java that uses garbage collection.

A common solution to this problem in general is to use "pools" of inactive objects.

Basically, your objects have two pairs of methods:
- a constructor and a destructor / Dispose()
- Activate() and Deactivate()

When objects are created, they are initially inactive and don't do anything. You start your game / level by creating a bunch of these inactive objects and sticking them in a pool (e.g. a stack). Then whenever your game needs one of these objects, instead of creating a new one, it gets an inactive one from the pool. Similarly, when an object is no longer needed, it is not destroyed / disposed of: it is deactivated and stuck back into the pool.

Sounds simple, but there's a caveat: when an object is deactivated, you have to remove all references to it (aside from the pool) immediately. E.g. if an enemy explodes and disappears, the Enemy Manager needs to stop calling its Update() and Draw() methods, homing missiles need to stop following it, etc. You have to remove all these references immediately. E.g. you could use the Observer design pattern (event sending and receiving) to accomplish this.

You might think of adding an IsActive() method as an alternative, and each time something wants to use the object, it checks whether the object is still active before using it, and removes the reference to the object if it is inactive. Unless you do some ugly workarounds, this isn't going to work, because the object could be reactivated as a totally different object. It's much simpler to just remove all references to the object right away.


--------------------------------------------------

Drawing Sprites yourself

This tip is for do-it-yourself sprite-drawing, in contrast to using a sprite-drawing library such as XNA's SpriteBatch. (I don't use SpriteBatch mainly because it uses a different coordinate system from all the 3D graphics.)

Sprites can be rendered in 3D in one of two ways: Orthographic Projection, or Billboards. Which method you use doesn't matter. In both cases, you're drawing the sprite on a rectangle made from two triangles.

When you learn how to draw a sprite on a quad (a rectangle), you get some tutorial code that will draw a single sprite for you. Chances are, when you want to draw a collection of sprites, you'll simply run that tutorial code for every sprite.

THIS IS BAD!! Your game will slow below 60 fps with just a few hundred sprites. Even something as simple as a 30x30 grid of tiles will bring your graphics card to its knees if you draw it like this!

The problem is that your graphics card is designed to process a large number of vertices / polygons all at once, but instead, you're sending it 4 vertices / 2 polygons at a time.

The solution is to put all your sprites' vertices into one big array, then tell your graphics card to draw that. Yes, it really makes a BIG difference! E.g. previously, only 3 particle explosions (~50 sprites each) were enough to slow down my game, but after I made this change, I could fill the screen with explosions without any drop in framerate.

More precisely, you need to group all your sprites' vertices by texture, then for each texture, draw all the sprites that use it (as a big array of vertices). So you'll want to put multiple sprite images into a single texture, instead of giving each sprite its own texture. (If you've ever seen a "sprite rip" of a game, then you'll know what I mean. )


--------------------------------------------------

A way to organize your collision detection (hitbox) code

It's a good idea to take your code for comparing hitboxes against each other and put that into its own class(es), as opposed to putting that logic into every single class with a hitbox.

For example, you can make a Hitbox class that stores four coordinates -- x1, y1, x2, and y2 -- and provides a method to test if it is overlapping another Hitbox.

But what if some of your game objects have multiple hitboxes, like an irregularly-shaped enemy? Or maybe you want to give some objects Hitcircles instead of Hitboxes? Or maybe you want to check against a bounding box before doing finer collision detection? In any case, it'd be nice to have all of this mass wrapped away in some separate class heirarchy, so that all your player or enemy needs to do is "myHitArea.IsOverlapping(otherHitArea)" no matter how complicated the collision areas actually are.

My first attempt at designing this code was a huge failure. It's so obviously bad in retrospect that I won't even bother sharing it here.

Instead, I'll share my second attempt, which I'm implementing right now. (By the way, a good way to check if your design is good or bad is to try writing it out like this. It'll help you to see problems with your design that you wouldn't have found if you kept it in your head, especially when you try to explain why your design is so good.)

I'm going to make a class called HittableArea, that has a method "Overlaps(HittableArea other)" to check if this area overlaps the given one. I'm going to make an interface called Hittable that has a method "GetHittableArea()" that returns the object's collision area. Every player, enemy, bullet, crate, etc. in my game is going to implement Hittable, and have a HittableArea object to keep track of its hitbox / bounding box / finer hitboxes / whatever.

So whenever I need to do a collision test, I can just write:

bullet.GetHittableArea().Overlaps(player.GetHittableArea());


And that's it: that's my whole design.

Why is this a good design? Because it works even though we don't know anything about how HittableArea works. (Hell, not even I know how it'll work just yet.) It decouples the long and volatile collision detection code from the rest of my program, simplifying the rest of the code and making the collision detection code much easier to modify.

This will definitely be slower than a simple hitbox-hitbox check, however. But this is something I should look into at the END, when the game is 99% finished. If this code is causing a bottleneck, then I can optimize it knowing I probably won't need to change it again. (As opposed to right now, where I may decide the player won't have just a simple hitbox, or that some bullets will have two hitboxes, etc.)


--------------------------------------------------

Passing some of your game objects' initialization parameters in structs

Suppose you're activating a new game object. (Activating, not constructing, since you got an inactive one from a pool. )

Your activation method might look like this:

public void Activate(Vector2 position, Vector2 velocity, float mass, float size, int hitpoints, float aggression, bool isAsleep, ...)


I suggest replacing it with something like this:

public void Activate(Vector2 position, Vector2 velocity, Params ps)


Where Params is a data structure like this:

public struct Params
{
public float mass;
public float size;
public int hitpoints;
public float aggression;
public bool isAsleep;
...
}


(in Java, you can use a class instead of a struct, but keep in mind you might end up frequently creating and destroying instances of the class, whereas a struct in C/C++/C# is passed by-value)

Right away, you can see that the Activate() method looks a lot cleaner, but that's not the main reason to do this.

The main motivation is that if/when you start storing your game data in XML or binary files, you're going to want a data structure like that, anyway, to contain the same data as your XML/binary file. If you're really lucky, you might not have to change your old code at all when you want to load your game data from a file instead. Speaking of which...


--------------------------------------------------

Loading Game Content, part 1: Game Data class

This is a new idea I came up recently, so it might actually be terrible.

Originally, all our game content -- enemy properties, level design, etc. -- was being loaded all over the place. Eventually the time came to actually organize all this code. So I decided to store all of our game content in a single class called Game Data.

Whenever the game needs some content, it always loads it through the Game Data class. The reason for this is that it allows me easily to change whether this content is loaded from hard-code, or an XML file, or a binary file, or wherever. See, right now almost all of our content is hard-coded, but eventually we'd like to store it in XML or binary files. My hope is that, when the time comes to switch from hard-coded to file-loaded content, I'll have to modify only a single method.

E.g. suppose we've written a map editor and now our maps are stored in XML files. In theory, all I'd have to change is the folllowing:

public static MapParameters GetMap(String name)
{
// OLD:
//return mapHashtable.Get(name); // all the hardcoded map data is stored in this hashtable

// NEW:
return XMLLoaderThingy.Load(MAP_PATH + name);
}


Hopefully this will actually work well in practice.


--------------------------------------------------

Loading Game Content, part 2: Data Loading classes

This is a simple improvement to how I load all my static game content at the start of the game. Note that I haven't really thought about how to load content in short bursts between levels instead of loading it all at the start of the game, so this idea might flop hard if/when we need to do that. Anyway, at least it's better than what I was doing before.

Game has a method called LoadContent() that's called by XNA at the start of the game, and it's the place where you're supposed to load all of your game content. Originally, this method looked like:

Game.LoadContent()
{
Enemy1.LoadContent();
Enemy2.LoadContent();
Map1.LoadContent();
Map2.LoadContent();
HitBox.LoadContent();
Sprite.LoadContent();
ExplosionParticle.LoadContent();
// etc.
}


Basically, every class that had to load some static data had its method called here. This mess was compounded by the fact that the Game class is already bloated with other code.

The solution: every code folder (that needs one) has a class like "LoadEnemyData" that calls LoadContent() for each class in that subfolder. So the code flows like this:

LoadGameData.LoadContent() // load root folder
--> Hitbox.LoadContent()
--> Sprite.LoadContent()
--> ...
--> LoadEnemyData.LoadContent() // load enemies folder
----> Enemy1.LoadContent()
----> Enemy2.LoadContent()
----> ...
--> LoadMapData.LoadContent() // load maps folder
----> Map1.LoadContent()
----> Map2.LoadContent()
----> ...
--> ...


And so on. Much cleaner than putting everything in the Game class.


--------------------------------------------------

Well, that's it for now. I probably won't write one of these again unless a significant # of people actually learn from this one or start some good discussion around it. Enjoy!

b3h47pte
Profile Blog Joined May 2007
United States1317 Posts
July 16 2009 02:51 GMT
#2
Wow thanks, I'll definitely use this for reference as i'm writing my game (my first!) although it is somewhat late to implement some of these things and I guess some things may be different as your'e writing in C# with XNA game studio while i'm making it from scratch in C++ . But very nice anyways.

Game class -- the over-arching class that encompasses the entire game. Essentially all of the game logic is off-loaded to other classes. It also provides static methods for accessing "global" objects anywhere. (Using XNA's "game services" functionality.)

Stage Updater and Stage Drawer classes -- these classes manage the game logic and rendering of the game, respectively. These also off-load most of the work to other classes. All they really know is the order in which parts of the game are updated/drawn.

Various manager classes -- e.g. Enemy Manager, Bullet Manager, etc. These classes know some of the detailed game logic for their own little subsets of game objects.

Various game object classes -- e.g. Enemies, Bullets, Explosions, Players, etc. These classes are self-explanatory, and contain the rest of the detailed game logic.

Lower-level classes and data structures -- e.g. Sprites, Particles, Hitboxes, Custom Lists, Custom "Vertex Buffers", inactive object Pools, etc. These don't contain any game logic, and handle small, common tasks like displaying sprites, moving particles, checking for hitbox collisions, storing vertices, etc.

Physics class -- handles all game physics (just basic linear kinematics with linear forces, acceleration, velocity, and position, and all objects being treated as circles/spheres). The only "physics" code outside of this class is simple stuff like adding an acceleration to a velocity, or multiplying a force by the inverse of a mass to get an acceleration.

... and more!


Yea i agree. The game i'm programming is an RTS/TFS sort of game and as I've begun to code the moving part of the ships I've realized how helpful a movement manager/controller would've been. Would you care to expand under the 'and more' section as I think that would give us (me) a better idea on the structure of a game.

Drawing Sprites yourself


Wow! I never suspected that it was the drawing of the sprites themselves to be the cause of my game's FPS to be lower. I'm not exactly sure how to implement it your way. I'm using DirectX 9 (DirectDraw 9), i have a game class, a GUI class, and a graphics class (not all but all that's relevant). The graphics class LPDIRECT3DTEXTURE9 class that DirectX uses to display the image ( *.tga) and from what i read, DirectX uses the LPDIRECT3DTEXTURE9 class to display sprites. I have multiple vectors of all the things that need to be drawn and I retrieve the retrieve the Graphics object either from the vector or from the object in the vector and i retrieve the LPDIRECT3DTEXTURE9 object as well as any other parameters I need to display. I hope that made sense? :3 If i have it set up this way, how would i be able to implement your way of doing things?

I'll comment on the others as I come to actually design those myself but I'll make sure to reference this ! Please keep it updated with your progress!

On a side note: that pool idea is really good, I think i'm doing something like it. Kinda, sorta.
On another side note: What's considered a mid-sized game?
GoSu
Profile Blog Joined June 2009
Korea (South)1773 Posts
July 16 2009 04:14 GMT
#3
great article for people who love that!
#1 olleh KT 팬 http://sports.kt.com/ | #1 김택용 선수 팬 | 좋은 선수: 송병구, 이제동, 도제욱, 정명훈, 이성은 | KeSPA 한국 e-Sports 협회
Alphonsse
Profile Blog Joined March 2009
United States518 Posts
July 16 2009 05:47 GMT
#4
Thanks for this, I'm going to be writing a game in XNA / C# as a school project, so this is very relevant to me. I hope you post more!
nvnplatypus
Profile Blog Joined April 2004
Netherlands1300 Posts
July 16 2009 06:22 GMT
#5
Hey Bill - how have you been?

Is this a hobbyist/student project or did you wind up in the industry?

Let's catch up sometime - araxas at symbol gmail point com

freelander
Profile Blog Joined December 2004
Hungary4707 Posts
July 16 2009 11:13 GMT
#6
Maybe I can use some of this for my current project..

I am making a 2D shmup, and my question is how I should do hitbox collision searching, because I can have a lot of hittable objects and projectiles on the screen.
Maybe this won't make the performance any better because there are not that many stuff ... but...

So I search something more elegant instead of the O(n^2) method where I take the objects one by one and check one by one in the set of if there is anything that could hit them.

Now it's like:
for (i=0 , i<size of objects_vector, i++)
for (j=0 , j<size of objects_vector, j++)
check if objects_vector[i] hittable box is underlapped by the hitbox of objects_vector[j]
And all is illuminated.
konadora *
Profile Blog Joined February 2009
Singapore66201 Posts
July 16 2009 13:50 GMT
#7
Wow I can barely understand 1% of all the jargon mentioned here

Seems like a totally new language to me T___T

Impressive!
POGGERS
gokai
Profile Blog Joined August 2004
United States812 Posts
July 16 2009 14:08 GMT
#8
Wow, I have trouble enough making a game with game maker. I think my mind would explode if I program a game by hand.
Bill307
Profile Blog Joined October 2002
Canada9103 Posts
July 16 2009 18:11 GMT
#9
Hmm lots of stuff to reply to. I'll start with b3h47pte's reply, for now.

On July 16 2009 11:51 b3h47pte wrote:
Wow thanks, I'll definitely use this for reference as i'm writing my game (my first!) although it is somewhat late to implement some of these things and I guess some things may be different as your'e writing in C# with XNA game studio while i'm making it from scratch in C++ . But very nice anyways.

Show nested quote +
Game class -- the over-arching class that encompasses the entire game. Essentially all of the game logic is off-loaded to other classes. It also provides static methods for accessing "global" objects anywhere. (Using XNA's "game services" functionality.)

Stage Updater and Stage Drawer classes -- these classes manage the game logic and rendering of the game, respectively. These also off-load most of the work to other classes. All they really know is the order in which parts of the game are updated/drawn.

Various manager classes -- e.g. Enemy Manager, Bullet Manager, etc. These classes know some of the detailed game logic for their own little subsets of game objects.

Various game object classes -- e.g. Enemies, Bullets, Explosions, Players, etc. These classes are self-explanatory, and contain the rest of the detailed game logic.

Lower-level classes and data structures -- e.g. Sprites, Particles, Hitboxes, Custom Lists, Custom "Vertex Buffers", inactive object Pools, etc. These don't contain any game logic, and handle small, common tasks like displaying sprites, moving particles, checking for hitbox collisions, storing vertices, etc.

Physics class -- handles all game physics (just basic linear kinematics with linear forces, acceleration, velocity, and position, and all objects being treated as circles/spheres). The only "physics" code outside of this class is simple stuff like adding an acceleration to a velocity, or multiplying a force by the inverse of a mass to get an acceleration.

... and more!


Yea i agree. The game i'm programming is an RTS/TFS sort of game and as I've begun to code the moving part of the ships I've realized how helpful a movement manager/controller would've been. Would you care to expand under the 'and more' section as I think that would give us (me) a better idea on the structure of a game.

Well, I think the overview up there already shows the gist of how my game is organized:
1. lots of high-level classes that "manage" lower-level classes
2. a set of game objects at the ends of the "management" tree
3. a set of bottom-level classes like Sprites
4. content-loading and -storing classes like LoadGameData
5. utility classes like Physics and general Utils

But I'll give you some more examples...


InputSource interface and replays

The InputSource interface is used by the game to get the player's input. For a shoot-em-up, it might have methods like IsUpPressed(), IsFirePressed(), IsBombPressed(), etc. So the game doesn't know what keys, mouse buttons, or joystick buttons correspond to these inputs: it's all hidden behind the interface.

Specifically, my InputSource interface has a method called GetInputBits(), which returns an integer where each bit corresponds to an input, like move up, or fire bullets, or fire a bomb. Not only is this slightly faster, it makes the replay-saving code a little easier: I just have to write this integer to a file at each frame, and voila: all the game input is saved!

The InputSource interface is great because it allows you to change the source of the input -- from a keyboard, from the mouse, from a gamepad, etc. -- without having to change any of the game code. In particular, I can simply make the input source a replay file, and that's it: replay functionality done.

This allows you to easily add replay functionality to most genres of games... but not RTSes. If you did this in an RTS, you'd get a first-person-replay, which is nice, but generally people like to have the ability to control the screen and the mouse themselves when they're watching an RTS replay.

For RTS replays, I'd suggest following StarCraft's example and saving the actions performed at each frame, not the player's exact mouse and keyboard inputs. In that case, you might want to write an "ActionSource" interface instead. Then you could add first-person support by storing the mouse position and screen location at each frame, as well.


PhysicsObject interface

Each game object that obeys the laws of physics implements this class, allowing it to be used by the Physics class. It has methods like GetPosition(), GetMass(), GetCollisionRadius() (every object is treated as a circle/sphere), ApplyCollisionForce(), and so on. Pretty self-explanatory.


EnemyMovement class

(Actually, I should make this a general movement class, not something specific to enemies. Thanks for indirectly bringing this to my attention. Anyway...)

This class fills two roles:
1. it implements the PhysicsObject interface, and
2. it controls the movement of an enemy.

Previously, all of this code was lumped into my Enemy class, which was a bad idea. So as part of our enemy code overhaul, I'm moving it into its own class.

It has methods for:
- implementing PhysicsObject: GetPosition(), GetVelocity(), ApplyCollisionForce(), etc.
- controlling movement indirectly: SetPropulsionDirection(), Accelerate(), Turn(), Decelerate(), etc.
- controlling movement directly: SetPosition(), SetVelocity(), etc.


Show nested quote +
Drawing Sprites yourself


Wow! I never suspected that it was the drawing of the sprites themselves to be the cause of my game's FPS to be lower. I'm not exactly sure how to implement it your way. I'm using DirectX 9 (DirectDraw 9), i have a game class, a GUI class, and a graphics class (not all but all that's relevant). The graphics class LPDIRECT3DTEXTURE9 class that DirectX uses to display the image ( *.tga) and from what i read, DirectX uses the LPDIRECT3DTEXTURE9 class to display sprites. I have multiple vectors of all the things that need to be drawn and I retrieve the retrieve the Graphics object either from the vector or from the object in the vector and i retrieve the LPDIRECT3DTEXTURE9 object as well as any other parameters I need to display. I hope that made sense? :3 If i have it set up this way, how would i be able to implement your way of doing things?

While I know how to program graphics in OpenGL, I'm afraid I don't know how to use DirectX.

But basically, my code is like this:

1. For each sprite (with some texture T), add its vertices into a big array called spriteVertices.
2. Also maintain an array of indecies for these vertices.
3. Once that's done, tell the graphics card to draw a triangle list, and send it the vertices and indecies.

Actually, I use a single class, "SpriteVertexSet", to manage those two arrays: it gets passed around to all the different game objects that use sprites (of the same texture) and when it finally reaches a Sprite, the Sprite simply adds its vertices to the SpriteVertexSet. The drawing code is also inside the class: SpriteVertexSet.Draw().

As for the exact DirectX functions to call, I'm afraid you'll have to find that out on your own.

By the way, once you get this working, I suggest looking into Vertex Buffers. These are very useful when you have a set of vertices that never changes, e.g. your terrain. They allow you to copy the vertices to the graphics card only once, and store them in the GPU's memory. This is another big performance gain. Unfortunately, it isn't useful for sprites in general, which will usually move around and animate.

There are also Dynamic Vertex Buffers, which would probably be useful for sprites that move and change, but I haven't learned how to use them, yet.


I'll comment on the others as I come to actually design those myself but I'll make sure to reference this ! Please keep it updated with your progress!

On a side note: that pool idea is really good, I think i'm doing something like it. Kinda, sorta.
On another side note: What's considered a mid-sized game?

Thanks, guess I will.

I call it a "mid-sized" game because I can think of games that are probably a lot more complex, and games that are a lot simpler. I'd guesstimate that your RTS will also be a "mid-sized" game, if not bigger.

It's actually very risky what you are doing, imo: undertaking such a large and complex game for your first game. To be honest, I expect you won't be able to finish it: not because it's big, but because you'll write code that isn't very clean or easy to modify, and as your game grows you'll waste exponential amounts of time rewriting old code or hacking around your code's limitations. :S

In any case, good luck.
yh8c4
Profile Blog Joined July 2009
108 Posts
Last Edited: 2009-07-16 19:02:55
July 16 2009 18:59 GMT
#10
On July 16 2009 20:13 freelander wrote:
Maybe I can use some of this for my current project..

I am making a 2D shmup, and my question is how I should do hitbox collision searching, because I can have a lot of hittable objects and projectiles on the screen.
Maybe this won't make the performance any better because there are not that many stuff ... but...

So I search something more elegant instead of the O(n^2) method where I take the objects one by one and check one by one in the set of if there is anything that could hit them.

Now it's like:
for (i=0 , i<size of objects_vector, i++)
for (j=0 , j<size of objects_vector, j++)
check if objects_vector[i] hittable box is underlapped by the hitbox of objects_vector[j]


you can cut down from n^2 checks to (n - 1) + (n - 2) + ... + 1 = ((n^2 - n) / 2) checks with some minor changes to the loops, to make sure that i != j (wouldnt make sense to check for collision with itself) and j > i (if object[i] hits object[j], object[j] hits object[i], no need to check both ways)

num = number of objects
for (i = 0; i < (num - 1); ++i)
for (j = (i + 1); j < num; ++j)
// check for collision of object[i] and object[j]
King K. Rool
Profile Blog Joined May 2009
Canada4408 Posts
July 16 2009 19:29 GMT
#11
Nice read. Never really worked/wrote a large-scale game before, largest was only a small 1-level Kirby game (reflecting upon it now, had lots of bad programming practices - but that's high school for ya).

How is C# for game programming? I've only used it for web/desktop apps. Also, did you go off a book or is this just all "as it goes"?
b3h47pte
Profile Blog Joined May 2007
United States1317 Posts
July 16 2009 22:55 GMT
#12
Thanks, I guess I'll have to dive into that DirectX stuff myself

It's actually very risky what you are doing, imo: undertaking such a large and complex game for your first game. To be honest, I expect you won't be able to finish it: not because it's big, but because you'll write code that isn't very clean or easy to modify, and as your game grows you'll waste exponential amounts of time rewriting old code or hacking around your code's limitations. :S


Let's hope for the best shall we.
Myrmidon
Profile Blog Joined December 2004
United States9452 Posts
July 17 2009 03:50 GMT
#13
As an EE who's never had to learn any object-oriented programming, this is pretty easy for me to understand. You did a good job breaking down the information.

For loading static game content, would it make more sense to load only information pertinent to the entire game at the beginning and then load level-specific content at the beginning of each level? That way you can discard the first level's content at the end of the first level, load the second level's content, and move on. Level content would include what enemies/objects are used in that level and particularly that level's map, locations of things, etc. If an enemy and its data is used in multiple levels, there's some waste reloading that information I guess...or you could just put any repetitive level data into data loaded at the start of the game.
Zona
Profile Blog Joined May 2007
40426 Posts
July 17 2009 03:54 GMT
#14
I'd like you to know I'm also following this. I'm also working on a game - but with PyGame. Once I get a few projects under my belt I'll probably delve deeper with OpenGL, though.
"If you try responding to those absurd posts every day, you become more damaged. So I pay no attention to them at all." Jung Myung Hoon (aka Fantasy), as translated by Kimoleon
freelander
Profile Blog Joined December 2004
Hungary4707 Posts
July 17 2009 09:04 GMT
#15
Wow Bill, using input flags frame by frame with integers is a fuckin good idea.

If you make a fighting game, and do this method, and the players have 8 inputs each (4 direction 4 buttons), the max replay size will be:

3 * 90 sec rounds * 60 frame/sec * 2 byte = 32 400 bytes = 32.4 kbytes

If the players use more than 8 inputs, for instance Street Fighter series, you'll need a Uint32 to store everything .. so tha max size will be doubled, 64 kbytes.

Interesting, I just checked, the Guilty Gear XX # R replays are between 3 and 10 kbytes in size. How did they do it ? ~~
And all is illuminated.
MasterOfChaos
Profile Blog Joined April 2007
Germany2896 Posts
July 17 2009 11:53 GMT
#16
Did you do any measurements to determine that object allocation limits performance?
And why do you have so many different managers?
@freelander
Simply compress it afterwards?
LiquipediaOne eye to kill. Two eyes to live.
keNn)
Profile Blog Joined February 2003
Philippines297 Posts
Last Edited: 2009-07-17 14:15:06
July 17 2009 14:10 GMT
#17
a month earlier this blog might earn you a sc2 beta key.
^_^
freelander
Profile Blog Joined December 2004
Hungary4707 Posts
July 17 2009 15:28 GMT
#18
@freelander
Simply compress it afterwards?

that's probably true
And all is illuminated.
Bill307
Profile Blog Joined October 2002
Canada9103 Posts
July 19 2009 21:54 GMT
#19
On July 16 2009 15:22 nvnplatypus wrote:
Hey Bill - how have you been?

Is this a hobbyist/student project or did you wind up in the industry?

Let's catch up sometime - araxas at symbol gmail point com


A couple of friends and I are hoping to break into the industry with this.


On July 16 2009 20:13 freelander wrote:
Maybe I can use some of this for my current project..

I am making a 2D shmup, and my question is how I should do hitbox collision searching, because I can have a lot of hittable objects and projectiles on the screen.
Maybe this won't make the performance any better because there are not that many stuff ... but...

So I search something more elegant instead of the O(n^2) method where I take the objects one by one and check one by one in the set of if there is anything that could hit them.

Now it's like:
for (i=0 , i<size of objects_vector, i++)
for (j=0 , j<size of objects_vector, j++)
check if objects_vector[i] hittable box is underlapped by the hitbox of objects_vector[j]

I don't know if you're doing this already, but: you can simply store each kind of object in a different vector, then only check two vectors' objects against each other if those objects can hit each other.

E.g. you wouldn't check the vector of player bullets for collisions with the player.

That alone is probably enough. Unless your game is going to have a LOT of objects that can collide with each other, you'll only be wasting your time by trying to optimize it further.

If you do need a more efficient algorithm, then you can start your search here:
http://en.wikipedia.org/wiki/Collision_detection#Spatial_partitioning


On July 17 2009 04:29 King K. Rool wrote:
Nice read. Never really worked/wrote a large-scale game before, largest was only a small 1-level Kirby game (reflecting upon it now, had lots of bad programming practices - but that's high school for ya).

How is C# for game programming? I've only used it for web/desktop apps. Also, did you go off a book or is this just all "as it goes"?

I've never read a single programming book in my life, actually. The vast majority of my experience came from programming stuff in my own time, through high school and university. Some stuff I learned from classes, and some of it I read online, but most of it is stuff I came up with myself.

On one hand, looking to see if someone else has already solved your problem can be immensely helpful. In particular, if you're working with people who are more experienced than you, then you should never hesitate to ask them for help or advice.

On the other hand, you learn 100x better from your own programming experience than from reading or listening to another's experience.
Bill307
Profile Blog Joined October 2002
Canada9103 Posts
July 19 2009 23:07 GMT
#20
On July 17 2009 18:04 freelander wrote:
Interesting, I just checked, the Guilty Gear XX # R replays are between 3 and 10 kbytes in size. How did they do it ? ~~

Like MoC said, they compress them.

If you think about it, between most frames, the players' inputs will not change, and compression algorithms can take great advantage of this.

In theory, one could write replay saving and loading code that exploits this pattern to save smaller replay files.

In practice, one should leave this to a general compression algorithm and focus on useful tasks.


On July 17 2009 20:53 MasterOfChaos wrote:
Did you do any measurements to determine that object allocation limits performance?

I've read repeatedly this as fact, both in general and regarding XNA on the XBox 360 specifically. Since C# is a managed language, it's not just object creation and destruction, but also requiring the garbage collector to do its job.

I should be using a single generic Pool class to handle all of my object pools, and in the interest of measuring this difference, I've set it up to not use a pool at all and create new objects as they're needed if NO_POOLS is defined. It's not a true comparison, but hopefully it'll be better than nothing.


On July 17 2009 20:53 MasterOfChaos wrote:
And why do you have so many different managers?

To divide the code into sane portions.
Bill307
Profile Blog Joined October 2002
Canada9103 Posts
July 20 2009 00:37 GMT
#21
On July 17 2009 04:29 King K. Rool wrote:
How is C# for game programming?

As for C# and XNA, I think the fact that nearly-identical code can run on both a Windows PC and an XBox 360 is great. I also think Visual C# is a terrific IDE.

However, I have a number of gripes with the language and with XNA.


1. XNA's Matrix multiplication is backwards. Seriously. If you have two matrices A and B, and you want to transform A by B, then in linear algebra, you'd write "B * A", but in XNA, you'd write "A * B".

I have a strong math background, so for me, this is the biggest WTF by far.


2. The documentation is ass. A while ago, I was trying to figure out exactly when data was copied from your system's memory to your GPU's memory. Repeatedly, I ran into such detailed documentation as:

http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.vertexbuffer.aspx

VertexBuffer Class
Represents a list of 3D vertices to be streamed to the graphics device.

Useless.

Another example: I was trying to see how to load a custom Effect file on the XBox 360 without going through the ContentManager, or if this was even possible. I still don't know if this is possible or not, actually: after searching for hours I gave up and changed the way my code worked instead.

After learning much of my Java knowledge by reading its incredibly-detailed API documentation, XNA's documentation was hugely disappointing.


3. C# Properties. Properties in C# are used like variables, but they are accessed through "get" and "set" methods.

For example, suppose you want to change an enemy's hitpoints. In Java, you'd do something like this:

oldHP = enemy.GetHitpoints();
enemy.SetHitpoints(newHP);

Using a C# Property, you would instead write:

oldHP = enemy.Hitpoints;
enemy.Hitpoints = newHP;

When you access enemy.Hitpoints, you are actually calling the Property's "get" method, and when you assign it a new value, you are calling the Property's "set" method.

Maybe you can already start to see why Properties can cause problems...


3a. The naming convention for Properties.

Suppose my game class has a Camera variable. Naturally it'll be called "camera". Now suppose I want other classes to be able to access it. The C# way is to use a public Property, called "Camera". Great, a variable with the same name as a class!

In general, Properties look like classes or inner classes when you use them. The only visual cue is Visual C#'s syntax highlighting, where classes are written in teal while Properties are written in black.


3b. Properties are operator overloading.

The danger of using public variables is that somewhere down the road, you might want to run some additional code whenever a variable is changed, e.g. to send an event when an enemy loses hitpoints, but if the public variable is being changed directly, then you can't do that.

On the other hand, it's a lot easier to get and set public variables versus having to type GetValue() and SetValue() every time, not to mention having to write these methods. Indeed, it can get tiring to write these methods over and over when 99% of the time, all they do is set and get a variable.

At a glance, Properties seem like a solution to this problem. Syntactically, they're used just like a public variable, but they also allow you to run some additional code whenever a variable is set or retrieved, which is the benefit of writing GetValue() and SetValue() methods.

But they're really just operator overloading, complete with all the problems of it.

Operator overloading abuse aside, 99% of the time, when you see a Property it's going to be simple get/set one, that acts just like getting and setting a variable. So when that 1% case comes up, where the get/set does something else, it can be confusing for everyone, even the original author if he's away from his code for too long. In contrast, when you have to call GetValue() or SetValue(), it's a visual reminder that you might be doing more than just getting or setting the variable.



Needless to say, while I'm forced to use the Properties built into C# and XNA, I completely avoid using Properties myself.
FreeZEternal
Profile Joined January 2003
Korea (South)3396 Posts
Last Edited: 2009-07-20 02:00:06
July 20 2009 01:55 GMT
#22
Maybe this is just a gaming thing where every milliseconds count but from experience, object allocation is VERY cheap these days (at least in the JVM. I would assume the same in the CLR), in some cases even cheaper than in C++. Object pooling do have their uses but they can be error prone (memory leak, etc) because the scope the object gets bigger. I would say in the majority of cases, it's always better to narrow the scope of your objects. Anyways this is for general programming, but for gaming I may be completely wrong since every milliseconds count.
FreeZEternal
Profile Joined January 2003
Korea (South)3396 Posts
Last Edited: 2009-07-20 02:04:05
July 20 2009 02:03 GMT
#23
On July 17 2009 20:53 MasterOfChaos wrote:
Did you do any measurements to determine that object allocation limits performance?
And why do you have so many different managers?
@freelander
Simply compress it afterwards?


I think what Bill meant with "Object Allocation limit" is that when you start creating thousands of objects over and over, GC will take a toll. Usually the GC overhead is negligible in business apps as long as you avoid nasty Full GC, but for gaming I would assume everything counts.
MasterOfChaos
Profile Blog Joined April 2007
Germany2896 Posts
July 20 2009 07:34 GMT
#24
I think I have read almost every article about the .net GC in existance because I simply can't get myself to really trust such a beast. The problem is that my current game design uses lots(perhaps 100k) of small objects.
But I guess I'll simply hope that .net 4.0's background GC is good enough.

The one thing I fear the most is not deterministic behaviour. My networkcode(and replays) require that the game runs completly deterministic given the same input on different machines. For example this means I can't use any floats inside the gamelogic(I have implemented a fixedpoint struct). Other things which might get problematic are GetHashCode, iteration over the entries of a dictionary, weakreferences, and probably a lot of features I don't even know about yet -_-

Personally I like properties and the naming conventions of C# a lot, because it's basically the same as in Delphi.
The one thing where they are counter intuitive is if you have a property of a mutable struct type and call a method which modifies it. As the method is called on a copy of the struct(it is returned by value) the property will not be changed. But mutable structs are usually bad style anyways.
LiquipediaOne eye to kill. Two eyes to live.
evanthebouncy!
Profile Blog Joined June 2006
United States12796 Posts
July 20 2009 07:49 GMT
#25
haha learning java now.
Object oriented is fun

Before:
Is_A_equal_to_B(a,b);
After:
a.Do_I_look_Like_That_Other_Dude(b);
Life is run, it is dance, it is fast, passionate and BAM!, you dance and sing and booze while you can for now is the time and time is mine. Smile and laugh when still can for now is the time and soon you die!
MasterOfChaos
Profile Blog Joined April 2007
Germany2896 Posts
July 20 2009 08:52 GMT
#26
On July 20 2009 16:49 evanthebouncy! wrote:
haha learning java now.
Object oriented is fun

Before:
Is_A_equal_to_B(a,b);
After:
a.Do_I_look_Like_That_Other_Dude(b);

IMO the "Before" part is nicer. It reflects the symmetry of a comparison a lot better than the second one. And the second one has the additional disadvantage that it throws if a==null.
LiquipediaOne eye to kill. Two eyes to live.
FreeZEternal
Profile Joined January 2003
Korea (South)3396 Posts
July 20 2009 13:23 GMT
#27
Yeap but equals is a method that comes from the Object class. Usually your classes will override the equals method from the Object class so most projects you see will actually use the "Before" part.
Bill307
Profile Blog Joined October 2002
Canada9103 Posts
July 21 2009 04:40 GMT
#28
On July 20 2009 16:34 MasterOfChaos wrote:
The one thing I fear the most is not deterministic behaviour. My networkcode(and replays) require that the game runs completly deterministic given the same input on different machines. For example this means I can't use any floats inside the gamelogic(I have implemented a fixedpoint struct). Other things which might get problematic are GetHashCode, iteration over the entries of a dictionary, weakreferences, and probably a lot of features I don't even know about yet -_-

Wait... what are the odds that floats will be computed differently on different machines? o_Oa I guess it's not much of a problem for me, since our main target platform is the 360. And if a replay fails on someone else's computer, then at least you can always make a recording of the replay on your own computer.

I don't trust C#'s GetHashCode(), either. Java's hashCode() method will "typically" convert the object's reference address to an int, but the documentation for C#'s method was very vague (as usual -_-).

You could probably implement your own Dictionary without too much trouble, imo. At least then you could guarantee it'll always iterate over its entries in the same order.
Bill307
Profile Blog Joined October 2002
Canada9103 Posts
July 21 2009 04:43 GMT
#29
On July 20 2009 22:23 FreeZEternal wrote:
Yeap but equals is a method that comes from the Object class. Usually your classes will override the equals method from the Object class so most projects you see will actually use the "Before" part.

This reminds me of yet another case of bad C# documentation. -_-

Java's equals() method will return true iff the objects' references are equal. This is written explicitly in the documentation.

C#'s Equals() method, however, doesn't say anything about what it will return by default. (*sigh*)

C# does have a static ReferenceEquals() method for that purpose, though.
MasterOfChaos
Profile Blog Joined April 2007
Germany2896 Posts
July 21 2009 07:28 GMT
#30
If I recall correctly GetHashCode returns some strange SyncObjectID which is determined at allocation time for reference types and the hashcode of the first field for structs. And the predefined valuetypes use sensible overrides.

And the floatingpoint desyncs shouldn't be that uncommon since .net generates CPU dependent code, and the x87 and SSE commands return different results for many calculations. My research showed that it is possible to tweak c++ to get reproducible floatingpoint code, but not .net. So I wrote a 32bit fixedpoint struct.

I think Equals() checks the identity for all fields for valuetypes and reference equality by default for reference types. But I never used it myself except for overriding it in my valuetypes to get rid of some warnings.
I only used == operator, ReferenceEquals and equality comparers.

And if you haven't used it so far, check out redgate reflector. My favourite .net "documentation".
LiquipediaOne eye to kill. Two eyes to live.
evanthebouncy!
Profile Blog Joined June 2006
United States12796 Posts
July 21 2009 08:15 GMT
#31
On July 20 2009 17:52 MasterOfChaos wrote:
Show nested quote +
On July 20 2009 16:49 evanthebouncy! wrote:
haha learning java now.
Object oriented is fun

Before:
Is_A_equal_to_B(a,b);
After:
a.Do_I_look_Like_That_Other_Dude(b);

IMO the "Before" part is nicer. It reflects the symmetry of a comparison a lot better than the second one. And the second one has the additional disadvantage that it throws if a==null.


Hehe yeah but iono, recursion with objects are mad fun
Life is run, it is dance, it is fast, passionate and BAM!, you dance and sing and booze while you can for now is the time and time is mine. Smile and laugh when still can for now is the time and soon you die!
FreeZEternal
Profile Joined January 2003
Korea (South)3396 Posts
July 21 2009 14:59 GMT
#32
On July 21 2009 13:43 Bill307 wrote:
Show nested quote +
On July 20 2009 22:23 FreeZEternal wrote:
Yeap but equals is a method that comes from the Object class. Usually your classes will override the equals method from the Object class so most projects you see will actually use the "Before" part.

This reminds me of yet another case of bad C# documentation. -_-

Java's equals() method will return true iff the objects' references are equal. This is written explicitly in the documentation.

C#'s Equals() method, however, doesn't say anything about what it will return by default. (*sigh*)

C# does have a static ReferenceEquals() method for that purpose, though.


True, Sun did an amazing job documenting Java.
b3h47pte
Profile Blog Joined May 2007
United States1317 Posts
July 21 2009 15:36 GMT
#33
http://msdn.microsoft.com/en-us/library/w4hkze5k.aspx

Return Value
Type: System..::.Boolean
true if the instances are equal; otherwise false.



http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx
Return Value
Type: System..::.Boolean
true if the specified Object is equal to the current Object; otherwise, false.


Not sure how it isn't clear
MasterOfChaos
Profile Blog Joined April 2007
Germany2896 Posts
July 21 2009 15:38 GMT
#34
On July 21 2009 13:43 Bill307 wrote:
C#'s Equals() method, however, doesn't say anything about what it will return by default. (*sigh*)

The Object.Equals documentation is not that bad:
The default implementation of Equals supports reference equality for reference types, and bitwise equality for value types. Reference equality means the object references that are compared refer to the same object. Bitwise equality means the objects that are compared have the same binary representation.
LiquipediaOne eye to kill. Two eyes to live.
Bill307
Profile Blog Joined October 2002
Canada9103 Posts
July 23 2009 12:59 GMT
#35
On July 22 2009 00:36 b3h47pte wrote:
http://msdn.microsoft.com/en-us/library/w4hkze5k.aspx
Show nested quote +

Return Value
Type: System..::.Boolean
true if the instances are equal; otherwise false.



http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx
Show nested quote +
Return Value
Type: System..::.Boolean
true if the specified Object is equal to the current Object; otherwise, false.


Not sure how it isn't clear

Are you joking?!?!

I think I could have figured out from the name "Equals()" that it compares if two objects are equal. Those remarks are completely useless.

Anyone checking the documentation for a method like "Equals()" is wondering, how exactly does it determine whether two objects are equal? E.g. does it compare the references, or does it check every member variable?

On July 22 2009 00:38 MasterOfChaos wrote:
Show nested quote +
On July 21 2009 13:43 Bill307 wrote:
C#'s Equals() method, however, doesn't say anything about what it will return by default. (*sigh*)

The Object.Equals documentation is not that bad:
Show nested quote +
The default implementation of Equals supports reference equality for reference types, and bitwise equality for value types. Reference equality means the object references that are compared refer to the same object. Bitwise equality means the objects that are compared have the same binary representation.

I assume by "supports" they mean "implements". But to me, "supports" is just what it can or may do, whereas "implements" is what it actually does. As a result, I probably disregarded that info the first time I read it.
Normal
Please log in or register to reply.
Live Events Refresh
Replay Cast
00:00
SEL S2 Championship: Playoffs
Liquipedia
BSL Team Wars
21:30
Round 5
Team Dewalt vs Team Sziky
Liquipedia
[ Submit Event ]
Live Streams
Refresh
StarCraft 2
WinterStarcraft496
RuFF_SC2 150
Nina 146
NeuroSwarm 101
ProTech39
Ketroc 32
StarCraft: Brood War
Shuttle 873
sSak 747
Hyuk 184
Aegong 81
Noble 80
HiyA 51
ajuk12(nOOB) 37
NaDa 14
Snow 11
Icarus 5
Dota 2
monkeys_forever736
Counter-Strike
Stewie2K470
Super Smash Bros
hungrybox511
C9.Mang0490
Other Games
shahzam893
JimRising 540
Maynarde140
Mew2King60
Livibee49
Organizations
StarCraft 2
Blizzard YouTube
StarCraft: Brood War
BSLTrovo
sctven
[ Show 15 non-featured ]
StarCraft 2
• practicex 14
• intothetv
• AfreecaTV YouTube
• Kozan
• IndyKCrew
• LaughNgamezSOOP
• Migwel
• sooper7s
StarCraft: Brood War
• BSLYoutube
• STPLYoutube
• ZZZeroYoutube
League of Legends
• Rush820
• Lourlo713
• Stunt575
Other Games
• Scarra1017
Upcoming Events
Sparkling Tuna Cup
6h 12m
PiGosaur Monday
20h 12m
LiuLi Cup
1d 7h
Replay Cast
1d 20h
The PondCast
2 days
RSL Revival
2 days
Maru vs SHIN
MaNa vs MaxPax
OSC
2 days
MaNa vs SHIN
SKillous vs ShoWTimE
Bunny vs TBD
Cham vs TBD
RSL Revival
3 days
Reynor vs Astrea
Classic vs sOs
BSL Team Wars
3 days
Team Bonyth vs Team Dewalt
CranKy Ducklings
4 days
[ Show More ]
RSL Revival
4 days
GuMiho vs Cham
ByuN vs TriGGeR
Cosmonarchy
4 days
TriGGeR vs YoungYakov
YoungYakov vs HonMonO
HonMonO vs TriGGeR
[BSL 2025] Weekly
4 days
RSL Revival
5 days
Cure vs Bunny
Creator vs Zoun
BSL Team Wars
5 days
Team Hawk vs Team Sziky
Sparkling Tuna Cup
6 days
Liquipedia Results

Completed

CSL Season 18: Qualifier 2
SEL Season 2 Championship
HCC Europe

Ongoing

Copa Latinoamericana 4
BSL 20 Team Wars
KCM Race Survival 2025 Season 3
BSL 21 Qualifiers
ASL Season 20
CSL 2025 AUTUMN (S18)
Maestros of the Game
Sisters' Call Cup
BLAST Open Fall Qual
Esports World Cup 2025
BLAST Bounty Fall 2025
BLAST Bounty Fall Qual
IEM Cologne 2025
FISSURE Playground #1
BLAST.tv Austin Major 2025

Upcoming

LASL Season 20
2025 Chongqing Offline CUP
BSL Season 21
BSL 21 Team A
Chzzk MurlocKing SC1 vs SC2 Cup #2
RSL Revival: Season 2
EC S1
BLAST Rivals Fall 2025
Skyesports Masters 2025
IEM Chengdu 2025
PGL Masters Bucharest 2025
Thunderpick World Champ.
MESA Nomadic Masters Fall
CS Asia Championships 2025
ESL Pro League S22
StarSeries Fall 2025
FISSURE Playground #2
BLAST Open Fall 2025
TLPD

1. ByuN
2. TY
3. Dark
4. Solar
5. Stats
6. Nerchio
7. sOs
8. soO
9. INnoVation
10. Elazer
1. Rain
2. Flash
3. EffOrt
4. Last
5. Bisu
6. Soulkey
7. Mini
8. Sharp
Sidebar Settings...

Advertising | Privacy Policy | Terms Of Use | Contact Us

Original banner artwork: Jim Warren
The contents of this webpage are copyright © 2025 TLnet. All Rights Reserved.