Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 23 Feb 2001
Offline Last Active Yesterday, 09:21 PM

#4953292 Realistic strategy game?

Posted by slayemin on 27 June 2012 - 05:23 AM

I used to be in an artillery unit. We had a battery if six howitzers in our company and about 150 marines. Our unit was composed of the following:
-Supply: Takes care of guns, beans and bullets.
-Gun Line: The crew running each howitzer
-Fire Direction Control (FDC): The section which calculates the needed powder, rounds, fuzes, tube elevation angles, and tube lateral angles to put a round on target.
-Forward Observers (FO): These guys are the target spotters who communicate to the FDC about what they see on the battlefield
-Comm: These guys run wires between all of the sections and maintain radios and antennas so that everyone can talk
-Local Security: People patrolling the perimeter to make sure nobody is trying to sneak in
-Command: The officers who decide when the unit moves and where the unit moves

Not in our unit, but available assets:
-Counter-battery radar: Spots the trajectory of a round in flight and calculates its point of impact and point of origin to a precise grid coordinate
-Signals Intelligence: Listens to the airwaves and triangulates the position of a broadcasting station

So, you could make a more realistic "artillery" game by adding all of these elements. If you shoot the FO's, then the artillery unit no longer has eyes. If you shoot the FDC, the artillery loses its brain. If you shoot the comm, the artillery loses its mouth and ears. If you shoot the gun line, the artillery can't shoot anymore. A functioning artillery unit works like an oiled engine, and if you take out any of its gears, it seizes up. So, imagine you've got a forward observer attached to a company of infantry in a vast battlefield. An enemy sniper spots the dude with a radio strapped to his back and shoots him first (they have one of the shortest life expectancies in a fight). The FO is dead. Artillery support is out of the picture. If you wanted to play a game of artillery vs. artillery, it's now broken because the system is so fragile.

Suppose that you and your opponent have counter-battery radar. You don't know where the enemy artillery is positioned and they don't know where you are. The first person to shoot their guns reveals their position, so you want to make sure that you're shooting to disable the enemy artillery before they can shoot you. A round can have a flight time of up to two or three minutes, depending on angle and distance. This is more than enough time for a good artillery unit to shoot back. So, two emplaced artillery batteries facing off against each other will be a contest of training, response times, and who can move out of position the fastest.

This realism doesn't make for much "fun" in a game. Most artillery games are much more simple where you've got artillery cannons facing off against each other and you have to make a guess at the needed power and elevation. The game has abstracted away the complexity, added some simplicity, broke some reality (vision), and made the skill element of the game the "FDC" (which in reality is a precision science with little guessing involved). So: "Reality/realism" is not necessarily "fun" and "fun" is not necessarily "reality/realism".

#4951780 Dedicating my whole life to creating my dream game. Going to college

Posted by slayemin on 22 June 2012 - 11:08 AM

Are you really a jack of all trades, passionate for each facet of game development?

As someone who is beginning to identify with this, does that work for or against me? (consider I want to start my own company eventually, even if it's in handing out flyers)

I'd say that it always works in your favor to know how everyone else does their jobs. This helps you work better with your counter-parts and prepares you to become a good project manager. It's also good to have a good mastery of a particular skill since that helps you have a specialty and deep understanding of how it works.

#4951688 Dedicating my whole life to creating my dream game. Going to college

Posted by slayemin on 22 June 2012 - 04:31 AM

Also, make sure you have general Computer Science knowledge as well, because what happens if you don't get hired as a game developer straight out of college? You can work QA for god knows how long until someone notices you OR you can become a Software Developer at first and make good money plus earn development experience, and then go home and work on your game until you go to sleep at a reasonable hour (while eating 3 square meals a day plus some snacks).

I think this is worth emphasizing. I would recommend avoiding the "game development" curriculumn. Colleges and universities realize that it is a very popular track, so they advertise it strongly to gain new recruits. Instead, go for the more generalized CS track and use game development as a side project/hobby to keep yourself excited by what you're learning. Work on your games, use the things you learn from class in your game (data structures, algorithms, etc), use the challenges you face in your game dev to ask questions in class, and if you work hard and do things right, you'll graduate with a degree and a polished game in your portfolio.

The hard truth is that just about every university is pursuing the "game design" track because it's popular with students and brings in new recruits. Assuming that they graduate hundreds of students with a degree in game dev, and there are a hundred universities doing this, then you can safely assume that the market for game developers is either over-saturated or the degrees aren't worth much. It's statistically unlikely that most students will become game developers. Game dev is a niche skill, so if it ends up that you're not going to be doing game dev, then the degree isn't going to work very well for you in opening up other career paths. What's your backup plan if all you have is a game dev degree? Take the pragmatic approach: With a more generalized CS degree, you could land a well paying job in a much wider field and it will still be highly relevant to game dev if you choose to go that route.

There's another thing to consider: Game development (in the broad sense) is about more than just writing code. Every game needs art assets, sound, designers, marketing, business infrastructure, project management, etc. You can do any of these things and be a part of the game industry. If you're focused on the programming aspect, make sure that you both like programming and like mathematics. If you don't like programming or math, then when the initial appeal of game dev wears off, its going to be "just another programming job" where you happen to make games instead of desktop applications/widgets/services/drivers etc. At the end of the day, regardless of whether you're making games or other applications, your job is staring at code on a screen and making it do things.

#4948927 Game Crap

Posted by slayemin on 13 June 2012 - 02:30 PM

I think the best way to get replay value out of a game is to design it so that you can accomplish the objective by using multiple strategies.
"A game is a series of interesting choices" -Sid Meier
The more "weird" the strategy, the more interesting it is to me.

The problem with some RPG's and some FPS's is that the story line is linear and character progression is also linear. The linear nature of those games puts arbitrary restrictions on what strategies you can use and usually one particular strategy is whichever is strongest. Strongest strategy is not necessarily the most interesting strategy.

I like to think of "Magic: The Gathering" as a very well designed game. It's got tremendous replay value because of its versatility. There are TONS of interesting ways to defeat an opponent. My favorite strategy is to make my opponent draw dozens of cards at a time causing them run out of cards. If you run out of cards, you lose regardless of your health. It's just so weird and unexpected.
When I played Starcraft 2, my favorite strategy was to play zerg and mass queens, spine crawlers, and overseers. It's another weird and unexpected strategy.

So, I'd say that to really get the best replay value out of a game, you have to introduce lots of mechanics which can be combined in very interesting ways. Some games just don't lend themselves very well to that. An FPS can only introduce a few different types of guns, which mostly do the same thing: Shoot stuff in different ways. The "replay" value from an FPS comes from the twitchy skills it takes to shoot quickly and accurately and competing with those developed skills against other players. It's moderately interesting, but doesn't require a clever mind to thrive at it.

#4948126 Octree adjacency information

Posted by slayemin on 11 June 2012 - 05:54 AM

One other advantage of QuadTrees and OctTrees is that the search time is logarithmic rather than exponential.

Here are some ideas you could try:
-Array grid could contain the smallest allowable blocks, and larger irregular blocks are composed of lots of smallest blocks.
ie, smallest block would be 1x1. A 1x2 block would be two 1x1 blocks linked together. You'll have to create four "connectors" for each block object (left, right, top, bottom) which point to attached neighbors.

-OctTree Method: Find the adjacent blocks when you're construction the octtree and put that data into the node. Figure it out conceptually before writing the code.

#4937590 Distance to collision in AABB world

Posted by slayemin on 05 May 2012 - 06:36 AM

It'd probably be easier to help you correctly if you gave some context on why you need to find the nearest collision along a direction.

I'm going to assume that you're using this to create a coarse and granualar collision detection check. The coarse check would be to perform a distance calculation (somewhat cheap, even with a square root in there). The granular check would be more expensive because you may have many AABB's to check.

My idea is to use a bounding sphere. The center of the sphere is at the center of your cube volume and the sphere radius is the distance to a corner (so that you cover your farthest point). Now you have two or more bounding spheres and the orientation of your AABB doesn't matter. The calculating distance between the bounding spheres is pretty easy: Just measure the distance between the centers and add both their radiuses to the distance. Loop through every collidable object in your game and store the one with the shortest distance.

It'll be an ugly O(n*n) loop though, so if you start to get a lot of objects and slowdown, watch out.

foreach(CollidableObject obj1 in CollidableObjects)
	 float shortestDistance = infinity;
	 foreach(CollidableObject obj2 in CollidableObjects)
		  if(obj1 == obj2)	 //self reference check

		  float Dist = MeasureDistance(obj1, obj2);	 //<--your function to measure distance

		  if(Dist < shortestDistance)
			   shortestDistance = Dist;
			   obj1.NearestObject = obj2;

If you do start having a lot of collidable objects in your game and its causing performance problems, look into quad trees(2D) or oct trees(3D).

#4920148 GPGPU in a local network

Posted by slayemin on 07 March 2012 - 12:51 PM

When you're writing you algorithm, make sure that you're measuring the performance of your distributed work. I once wrote an algorithm which distributed work out to multiple CPU's and broke the work down into very small increments. It turned out that while the work was done quickly, the overhead of the network latency caused the overall time to complete the job to increase (~1 minute). If I made the jobs bigger, the computers could spend more time doing work on the CPU rather than sending and recieving network packets, thus decreasing working time to about 15 seconds. There's a probably a sweet spot for every algorithm where you maximize the work and minimize the time taken.

For what it's worth, the university I was at purchased and used an NVidia card which had a ton of processing power. I think it was the tesla? I don't know what the price tag looks like or how to use it, so I can't make any recommendations from experience.

#4918667 Game Save Data

Posted by slayemin on 02 March 2012 - 12:51 PM

I like the idea of encryption :)

You could use the Ceasar Cypher: When you're encrypting a bit, add a fixed value to it before writing it to file. If your addition value is +2, then A => C. It's super simple to implement and its also pretty simple to thwart. You could make it slightly more complicated by using a pseudo random number generator to generate your fixed values. The key is that the sequence of random numbers needs to be the same every time. So, if you generate a random value between 1->26, and then add that value to your byte, you'd get something like:
Unencrpted string: {AAAA}
Random Numbers: {13, 21, 4, 16}
Encrypted String: {A+13 => N, A+21 => U, A+4=>D, A+16=>Q}

So, if someone knows that their health is 16 and they open up your file to look for that value, they won't find it :) But, if they are really determined and reverse engineer your code to figure out what encryption algorithm you're using and the random number seed you're using as a key, then they can easily decrypt and encrypt your saved data file. I'd probably not concern myself with the 0.01% of the population who might do that.
If you want to use a nuke to hammer a fly, you could look into using AES 256 bit encryption. Nobody will crack that without extreme effort and hardware. It's military grade :)

#4918378 How would a filling clock drawing algorythm work?

Posted by slayemin on 01 March 2012 - 04:03 PM

You can do this pretty easily with primitives. If you're still using .NET 3.5, you can use a Triangle Fan. If you're using .NET 4.0, the triangle fan is gone so you can only use triangle lists or triangle strips (more verts, yuck!). The coloring can be accomplished by using vertext colors. I created a very similar project to show days, hours, minutes, and seconds with four pies. If you include enough triangles, you can create a circle ;)

The basic idea is to find a center position for your pie fan. Every triangle will have one of its verticies at this center position. Then, you want to be able to create a function which accepts a percentage value (0->100%) and figures out from there how many triangles to draw and where they should be placed. You may want to use an angle or radian value as an alternative (or overloaded member function). You'll also want to feed in the radius to indicate how large your pie should be. After you have all of this information, it's just a matter of using simple trigonometery to figure out where to place the other two verticies for your triangles.
It should look something like this:

Vert0 = new Vector2(center);

Vert1.x = center.x + Math.Cos(theta) * Radius;
Vert1.y = center.y + Math.Sin(theta) * Radius;

Vert2.x = center.x + Math.Cos(theta + stepsize) * Radius;
Vert2.y = center.y + Math.Sin(theta + stepsize) * Radius;

#4918372 [C#] Is my game structure any good?

Posted by slayemin on 01 March 2012 - 03:39 PM

The only reason a customized serializer would be better is because you know the details of the object your serializing and you can control the order of how you serialize the object. This allows you to serialize the object into a very small byte array. Example:

class Knight
	static uint NextID;
	uint UniqueID;

	int Health;
	int Attack;
	int Speed;
	Vector2 Position;

	public Knight()
		  UniqueID = ++NextID;
		  Health = 10;
		  Attack = 5;
		  Speed = 4;
		  Position = new Vector2(5,5);

	 public byte[] Serialize()
		  byte[] ret = new byte[24];			   //you know this size because you know the number of variables and their byte sizes
		  ret += UniqueID.ToByteArray();	 //not syntactically correct, just for illustration purposes
		  ret += Health.ToByteArray();
		  ret += Attack.ToByteArray();
		  ret += Speed.ToByteArray();
		  ret += Position.X.ToByteArray();
		  ret += Position.Y.ToByteArray();
		  return ret;

	 public Knight Deserialize(byte[] data)
		  Knight k = new Knight();						 //probably should have made an empty constructor now that I think about it...

		  k.UniqueID = uint.parse(data[0], 4);		  //not syntactically correct, but reads the first four bytes as an unsigned int
		  k.Health = int.parse(data[4],4);					//next 4 bytes are the health
		  k.Attack = int.parse(data[8],4);
		  k.Speed = int.parse(data[12],4);
		  k.Position = new Vector2(int.parse(data[16],4), int.parse(data[20],4));

		  return k;

The size of my example Knight class is 24 bytes. If I use the [Serializeable] attribute for the class and use the built in method, the serialized data size is ~150bytes.

class Knight
	static uint NextID;
	uint UniqueID;

	int Health;
	int Attack;
	int Speed;
	Vector2 Position;


void main void()
	 Knight k = new Knight();		  //just use the default values assigned by constructor

	 BinaryFormatter serializer = new BinaryFormatter();
	 FileStream fs = File.Create("test.txt");
	 serializer.Serialize(fs, k);		  //writes the serialized data of the knight to the file stream

	 //now, the knight is stored as binary data in a file, ready to be deserialized...
	 fs = File.Open("text.txt", FileMode.Open);
	 while(fs.Position < fs.Length)
		  object o = serializer.Deserialize(fs);
		  Type t = o.GetType();
			   case "Knight":
					Knight asdf = (Knight)o;		  //just casting the object into a knight object
			   //add more case statements for each object you've got serialized

Now, the built in serializer works pretty damn well. If you have object inheritance, it will serialize the inherited data automagically. If you decide to add more member variables to your class, it will automatically include that in the new serial stream (but, watch out for attempting to deserialize an outdated binary). At the cost of a few extra bytes, you as a programmer don't have to worry about maintaining the serialization and deserialization of your objects.

However, if you do want that extra amount of granular control over your serialized data size, you can do the serialization/deserialization manually. 24 bytes vs 150 bytes can make a big difference when you're sending 1000 objects through a network, sixty times a second. If your object gets more member variables, you need to update your serialization and deserialization methods and then test it to make sure it works as planned. The first few times, it may not annoy you but after doing it a lot, it'll annoy and wear you down.

I won't say which method is better because each has their pros and cons. I leave it up to you to decide which method you'd like to use based on the situation your in Posted Image

Edit: The reason the built in serializer creates bigger binary data is because it has to include meta-data about your class. It uses this meta data to deserialize your class. When you manually serialize/deserialize your classes, the meta data is already baked into your deserializer so you can get away with smaller binary data sizes.

#4918076 [C#] Is my game structure any good?

Posted by slayemin on 29 February 2012 - 09:46 PM

...so, if you can't take the project from work due to the nature of security, are you ever planning on deploying your game or is it just a learning exercise? What's the point of building a reusable code library if you can't really reuse it on other non-work related projects?

As far as code structure for your project goes, its similar to what I'm doing in my projects so it sounds like you're on the right track.

Static keywords are important for classes which are accessed by multiple threads (ie, your network connection threads). Just be careful about how crazy you get with them. Treat them like global variables. Also, if multiple threads are accessing the same shared object at the same time, you'll have to worry about serializing their access via "locks" (lock keyword, spin locks, mutexes, semaphores, etc).

You can manually serialize your game objects into string and byte arrays, as you're currently doing. It works and its light weight, but it also puts a significant amount of overhead in your development time and effort for every object you want to send over the network. Since you're using .NET, you should look into the [Serializable] parameter. You can use a built-in serializer to convert your object into a serial stream and then either write it to disk or a network stream. Then, when you read in the serialized data, you deserialize it into an object, get its type, and then cast that object into your game object and everything is done for you. This helps you avoid having to write customized parser code. However, this comes at a bit of cost: The serialized data is often quite bloated compared to what you could get with customized data serialization. If you aren't too concerned with bandwidth/diskspace, this isn't an issue.

#4915953 Organizing and managing code?

Posted by slayemin on 23 February 2012 - 01:17 PM

:((( I write some code and then immediately step through it line by line with the debugger to make sure that it's working as I expected. Occasionally, I find errors or mistakes I wasn't expecting.

I'm pretty good with the debugger, but not good enough to read x86 assembly. Here are some tips for you:
-Keep your code clean, simple and readable. Whitespace is good for preventing eye strain and information overload.

-Every time you use a 'new' keyword to allocate memory, automatically create a 'delete' keyword to deallocate it and make sure that the delete is reached.

-Be consistent with your naming conventions.

-Comment your code. It's for you. When your eyes are bleary, your brain is mush, or six months from now when you have to relearn your code, you'll be happier to read comments than code to figure out what you were thinking.

-floating point precision errors are a bitch to find and debug. If you're comparing floats for equivalence without a tolerance threshold, you're doing it wrong.

-If you're creating a mathematically oriented function and you know the range of valid inputs, throw it into a for loop and iterate through each valid value. Did you get divide by zero errors? did you handle negative values properly? if you're using floats, was your step size small enough to test for floating point precision errors?

-Sometimes it helps to create classes in a seperate project so that you can test and develop them in isolation. Once you know that your class and its member functions are rock solid, you can copy them into your main project and have a higher degree of confidence that they'll work without problems. This also helps to keep your classes loosely coupled.

-Aside from the debugger, my second most useful tool for debugging is pen and paper. Draw out the conceptual idea you're trying to implement and then synchronize the steps with the debugger (example: inserting nodes into a linked list at the front, tail and middle).

-The best bugs are the ones you don't have. A little bit of planning before code writing will go a LONG ways. There are three types of errors: Syntax errors, program errors, and design errors. Syntax errors prevent you from compiling. Program errors are stuff like referencing a null pointer or dividing by zero. Design errors are when you code a program with a broken design and you don't realize it until hours/days/weeks/months later. Planning and diagraming helps avoid them and helps keep your code organized.

-Lastly, stay disciplined. It's easy to get lazy and code something up really quick, but I've found that taking a little bit of extra effort to do things right the first time saves more time and effort since I don't have to refactor what I did out of laziness.

Good luck!

#4915938 Making Game Development team

Posted by slayemin on 23 February 2012 - 12:38 PM

You should probably post this in the Help Wanted section.

#4913706 Basic Game Development

Posted by slayemin on 16 February 2012 - 11:21 AM

After failing many projects, I can tell you what works and what doesn't work. (btw, I think this is more of a project management problem)
Here's how the typical project starts:

1. Someone has an idea. They start thinking about it and it generates a bunch of new ideas. They get super excited about it along the way. Then, they want to make the idea come to life. Either they can bring the idea to life by themselves or they have to find other people who can do it for them. The initial enthusiasm is the jolt of energy required to get people to start investing their time and money into the idea. A lot of game ideas fail to launch because they never get past this phase.

2. Either the idea dies on the vine or a more formalized process of development begins to take place. The idea is still nebulous, so lots of thought needs to be invested on nailing down the specifics for how the idea works. In terms of a game, this means defining the game mechanics, the units, the story, the player experience, interfaces, etc. This is typically done with a game design document or rapid prototyping.

3. The project eventually moves into the construction phase (if it's gotten this far). This is where the going gets tough and the initial spark of enthusiasm fades. Once the enthusiasm fades, people who aren't getting something from the project will quit (be it money, experience, satisfaction, promises, etc). If your project loses key people, it will most likely fail and/or the remaining team will suffer from lower morale. When the going gets tough, morale is everything because it alone is what keeps the team going forward with the project. The construction phase of the project is also where new ideas for features come up. Some of those features may really enhance the game. Other features may be cool "glitter" but will only waste time (but, consider the morale cost and chilling effect on creativity of excluding it). The most common case is the notorious 'feature creep' which is a feature which changes the size and scope of your project, which then translates into requiring more work and time, eventually leading to a project which grows beyond the capabilities of the existing team. If it seems that a project grows too big, it may never be completed and this leads to a sense of futility and despair with the team members, which also has a negative consequence to team morale and leads to project failure. You as a designer, are the gatekeeper for deciding which features get added and excluded. You must hold the reigns tight because the project success depends on it. Having a clearly written and well defined game design document will be like the light house of clarity in a sea of ideas.

4. If you've miraculously gotten past the construction phase, you'll move on into the testing phase of development. Here, you hunt for bugs, design flaws, and balance issues. Most likely, you'll have been doing lots of iterative game play testing during your construction phase, so the testing phase is a quality assurance and wrap up phase. I may only write a few sentences on it, but this phase may be one of the most important phases for guaranteeing project success. If you ship a non-working or buggy product, it will sell poorly and damage the reputation of your game and your company/team/organization and anyone affiliated with you. Lots of incomplete or buggy games have been shipped prematurely with the "oh, we'll just submit a patch a few weeks after release" mentality. Don't do this or overlook the importance of testing.

5. The next phase is deployment/release. This is where you get your game out in front of your users, turn on the registration servers, the login servers, the game servers, etc. and get ready for business. This phase of the project is a responsibility jointly shared by the business side and the technical side of the house. You can flub this up and all the hard work you and your team have put into the project leading up to this moment may have been for nothing, regardless of how great your product may be. Did you do marketing for the game prior to release? How are you distributing the game? (digital? retail? free download?) What technical work needs to be done? Can your hardware infrastructure handle the network load? etc etc. Doing well in this phase is an exponential multiplier. Based on some of the games I've seen, you could make wheelbarrows of money by selling polished turds if you execute this well (*cough* farmville *cough*).

6. The last phase is the training and maintenance phase of the project. It's often overlooked but also quite important because it extends the lifetime of your product (notice how the verbage has changed from 'project' to 'product'.) I've had the experience of developing a software tool and executed all the previous phases perfectly but seen the project fail because I couldn't maintain it or train end users on how to use the software. A lot of my life energy was wasted because the product couldn't be maintained (I wrote some software while I was in Iraq and I left the country). Your team may lose some members. With those members goes their technical expertise in your product. They may be fired or laid off by the company, may have some family emergency, get hit by a bus (or randomly blown up by a mortar/rocket), get hired by someone else, get bored and move on to bigger and better things, etc. How do you fill in the vacuume of knowledge left in their wake? Documentation. Cross training. Commented code. If your game has a critical bug fix that needs to be applied, who will do it and how will you get it out to your users? Take a lesson on the importance of this step in the project lifecycle from a company who did this well: Valve. Half-life came out in the late 1990's and had a good lifespan. Valve also encouraged and supported the modding community which extended the lifespan even further (via Counter-strike and other HL mods). The popularity of CS entrenched Valve in the minds of the customers. When HL2 came out, it was a sure bet that it would sell well. It then became the launching platform for Valves digital distribution hub "Steam", which was able to gain a majority of the market share for DD, further cementing their position as a major player in the game industry (and actually revolutionizing the distribution model).

All in all, when you're designing your game, take stock of your resources before deciding how complex it's going to be. It's better to create an overly simple game which gets finished and polished than to create an overly complicated game which may or may not get completed to a high standard of quality (hardest lesson to learn and remember). For a lesson on the bounties of simplicity, just look at the front page of Google. As one of my Operating Systems professors once said, "Make it simple for now, we can always add complexity later" (he's the windows kernel architect at Microsoft).

#4911919 Immutable World State for Parallelization

Posted by slayemin on 11 February 2012 - 03:38 AM

I recently did a small project with multithreading. I had a problem with race conditions, so I implemented a binary semaphoreto indicate if a shared resource was being used by another thread. It might be something you could find useful. Here is the general idea followed by pseudocode:

I have a static list of objects which need to be accessed by multiple threads. I also need to maintain the list of objects. Part of the list maintenance means that a thread may add or remove objects from the list. If two threads are modifying the size of the list, then a runtime error occurs. So, if a thread needs to access the list, I need to guarantee that the size of the list won't be changed by another thread. I create a static boolean variable to indicate whether or not the list is in use by another thread. When a thread wants to access the list, it checks to see if the list is unlocked before going forward.

static List<gameobject> m_objects = new list<gameobject>();
static bool m_listLocked = false;

Thread 1:
m_listLocked = true;
foreach(item in the list)
  do stuff;
m_listLocked = false;

Thread 2:
m_listLocked = true;
foreach(item in the list)
  do stuff;
m_listLocked = false;

I use an empty spin lock, but I could add a short sleep cycle inside of the while loop to save the CPU a bit.

Note that I don't do any thread synchronization with game frames.