• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
The_Neverending_Loop

Unity
Threads + Concurrency & Weird Issue

10 posts in this topic

Hello all, I been having a weird issue with my code that I can't seem to get working so I thought I'd try asking the community.

Basically I have created a class called TimerManaged which extends a thread, this class has a loop that runs in its run() method that checks any TimedEvent added to it. the TimedEvent class is abstract and is overwritten by whatever class needs it, it does however have a float timeReference variable that references its start time with respect to the global time of TimerManaged.

The TimerManaged checks all these TimedEvents by calling their monitor method that checks to see if anything was suppose to happen at time T, if it was then execute that event.

Now the issue I'm having is that the events only get executed in the first run through, since alot of these events repeat at a later time the TimedEvent class also has a reset method that essentially resets its local time back to zero with respect to the global time. But the reset doesnt seem to work properly UNLESS i add a System.out.println("" + TimedEvent.LocalTime) call in either the TimedEvents.monitor() method, or inside the loop that is calling the TimedEvents monitor class. Things work perfectly when I have that system.out there, but it doesnt work other wise. I tried modifieing the LocalTime variable for the TimedEvents volatile, nothing was fixed. I also modified the add, remove, monitor for the TimedEvents and TimerManaged synchronized, but again this didn't fix anything.

I'm really pulling my hairs out with this issue so any help will be greatly appreciated. Thank you.
0

Share this post


Link to post
Share on other sites
Could you provide some code?

Also it almost sounds as if you are creating a thread for each event? And using another thread to activate them? Threads aren't some thing you should create a lot of. They will mostly just give you trouble. If you want to add timed events you should either only have one thread doing it, or even better, add a priority queue in your game loop and perform and remove/reinsert the event at the top of the queue if its time has expired.

But any ways post your code, then I'll take a look at it tomorrow :)
2

Share this post


Link to post
Share on other sites
Sorry bout the delay heres the 2 main classes

[source lang="java"]public class TimerManaged extends Thread
{
// TimerManaged can be either put into a do while loop, or run as a thread
Vector<TimedEvent> tes = new Vector<TimedEvent>();
float gTimeSRef; // in seconds
long gTimeTRef; // in ticks

float gTimeS;
long gTimeT;
TimedEventListener tel = null;

public TimerManaged()
{

}

public void setTimedEventListener(TimedEventListener _tel)
{
tel = _tel;
}

@Override public void run()
{
try
{
startGlobalTime();
while(true)
{
monitor();
}
}
catch(Exception e)
{

}
}

public void startGlobalTime()
{
gTimeTRef = System.nanoTime();
gTimeSRef = gTimeTRef/1000000000f;
}

public float ticksToSeconds(long ticks)
{
return ticks/1000000000f;
}

public long getGlobalTimeTicks()
{
return System.nanoTime() - gTimeTRef;
}

public float getGlobalTimeS()
{
return getGlobalTimeTicks()/1000000000f;
}

public synchronized void addTimedEvent(TimedEvent _te)
{
tes.add(_te);
}

public synchronized void removedTimedEvent(TimedEvent _te)
{
tes.remove(_te);
}

public synchronized void clearTimedEvents()
{
tes.clear();
}

public synchronized void monitor()
{
gTimeT = System.nanoTime() - gTimeTRef;
gTimeS = gTimeT/1000000000f;


for(int i=0; i < tes.size(); i++)
{
TimedEvent te = tes.get(i);

if(te.monitor(te.getLocalTime(gTimeS)))
{
// something happened
tel.interpretTimedMessage("", te, te.getLocalTime(gTimeS));
}
}
}
}[/source]

and

[source lang="java"]public abstract class TimedEvent
{
TimerManaged mngr;

volatile long lTimeTRef;
volatile float lTimeSRef;

public TimedEvent(TimerManaged _mngr)
{
mngr = _mngr; // all time events need a manager
}

public void setManager(TimerManaged _mngr)
{
mngr = _mngr;
}

public float getLocalTime(float totalTimePassed)
{
// System.out.println("TE[getLocalTime] " + (totalTimePassed - lTimeSRef));
return totalTimePassed - lTimeSRef;
}

public void start()
{
lTimeTRef = mngr.getGlobalTimeTicks();
lTimeSRef = mngr.ticksToSeconds(lTimeTRef);
// System.out.println("TE[Start] " + lTimeSRef);
}

public void reset()
{
lTimeTRef = mngr.getGlobalTimeTicks();
lTimeSRef = mngr.ticksToSeconds(lTimeTRef);
// System.out.println("TE[Reset] " + lTimeSRef);
}

public abstract boolean monitor(float tPassed);
}[/source]
0

Share this post


Link to post
Share on other sites
[quote]
I tried modifieing the LocalTime variable for the TimedEvents volatile, nothing was fixed. I also modified the add, remove, monitor for the TimedEvents and TimerManaged synchronized, but again this didn't fix anything.
[/quote]
This is not a good way to go about writing multi-threaded code. You need to understand why something is made volatile, and why something is synchronised. If you don't know, then your code is probably broken and not thread safe - even if it appears to work.
0

Share this post


Link to post
Share on other sites
@Rip-off its actually graphical application, and the issue is anytime I add console output for the TimedEvents localtime, the problem is fixed. However when I take it off it stops working.

Basically the intended use is you create a TimedEvent which is monitors by the TimerManaged class. The TimerManaged runs in its own thread and checks the TimedEvents assigned to it. The issue is that when I use TimedEvent.reset() to force that event to run again, it doesn't. I know synchornized is used for when you have two threads sharing the same information to ensure one completes before another one gets access to that data, and I know volatile is for atomic type operations to ensure that the data is the same across the threads.

Writing this response I start to think that maybe lTimeTRef = mngr.getGlobalTimeTicks(); is the issue since mngr.getGlobalTimeTicks isn't exactly a atomic operations. Ill try to change and see if that fixes anything, but any other suggestions are more then welcomed.
0

Share this post


Link to post
Share on other sites
[quote name='The_Neverending_Loop' timestamp='1355711729' post='5011473']
[...] and the issue is anytime I add console output for the TimedEvents localtime, the problem is fixed.[/quote]

Most console output will be automatically synchronized. That generally does not fix the problem, but makes it appear more consistent (either consistently breaking or consistently working). The key word here is 'appear', running the program on any other computer or making minor code changes can lead to completely different results.
A lot of things can go wrong with multithreading. It requires a lot of effort and experience to write safe, thread-safe code. I strongly advise reading [b]a lot[/b] about multithreading before writing the first line of code and only trying it out in test cases which are engineered to catch concurrency errors. Only after you have understood why all of your errors appeared and you know exactly how you fixed it ('I changed that and the error disappears' does not cut it - why exactly did the problem happen and why exactly did the change fix it), should you even think about adding multithreading to productive code. Otherwise, multithreading is just a huge pain.
Besides, if you have not really understood the problems above you cannot even decide if something could be multithreaded - a lot of people write 'multithreaded' code and by the time they have it largely bug-free it's so heavily synchronized it would have been better to keep it in one thread.
0

Share this post


Link to post
Share on other sites
I have two problems with what you're doing. The first is that while the TimerManaged class has used synchronized to protected the shared vector of TimedEvent objects, the TimedEvent objects themselves are not safe. For example, look at the following method in the TimedEvent class:

[source]
public void reset()
{
lTimeTRef = mngr.getGlobalTimeTicks();
lTimeSRef = mngr.ticksToSeconds(lTimeTRef);
// System.out.println("TE[Reset] " + lTimeSRef);
}
[/source]

While you use the volatile keyword to make sure the long values lTimeTRef and lTimeSRef are not cached, that doesn't make the reset() method atomic. The context can switch after setting the lTimeTRef variable but before setting the lTimeSRef variable.

Also, in the TimerManaged, even though the monitor method is synchronized, nothing prevents other threads from modifying the TimedEvent objects.

[source]
if(te.monitor(te.getLocalTime(gTimeS))) // TimedEvent accessed
{
// something happened
tel.interpretTimedMessage("", te, te.getLocalTime(gTimeS)); // TimedEvent could have been changed by now
}
[/source]

Perhaps thinking about what is actually shared between threads would help.

I suspect that the reason adding the System.out.println makes the code work is that this changes the timing
enough to alter the runtime behavior, but that is just a guess.

The second thing is having a super tight while loop continuosly calling a snychronized method is the
wrong way to handle this. One of the import concepts to understand when writing threaded code like this
is that while single threaded code should not block, code like this needs to block whenever there isn't
anything to do.

When the TimerManaged first runs, and there are no events to process, it should block, and wait for
something to be added to the queue. Then, perhaps it sleeps for about as long as the expected message
time, then wakes up, sends the message, and goes back to sleep. As the others have already pointed out,
this is an extremely difficult thing to get right, and the chance for weird, random race conditions that are
almost impossible to trigger on purpose requires that you know what you're doing.

But the best way to learn this stuff is to do it, so drive on. Just know that it will not be easy. If it was me, this solution
seems way too hard, and I'd try and figure out another way to solve the problem without all the threads. Edited by Glass_Knife
1

Share this post


Link to post
Share on other sites

Thanks glass, I tried fixing the issue but I took your suggesting and figured another way around the problem, I decided to have TimerManage extend TimerTask instead and have its run method be my monitor() call.  This fixed the problem.

 

As for my first attempt with the thread please be advised that alot of what you see in the code came after desperation where it wasn't working where I thought it should so I added synchronized methods where it wouldn't of been practical just because I wanted to try to get my code to work and then work backwards from there.

 

I will try to find a way to implement this with threads in the future but for now extending TimerTask instead is doing a great job, so I recommend anyone that might want to do somethign similair give TimerTask a chance.

0

Share this post


Link to post
Share on other sites
I will try to find a way to implement this with threads in the future but for now extending TimerTask instead is doing a great job, so I recommend anyone that might want to do somethign similair give TimerTask a chance.

 

When you're ready, I recommend 

 

http://amzn.com/0321349601

0

Share this post


Link to post
Share on other sites
I will try to find a way to implement this with threads in the future but for now extending TimerTask instead is doing a great job, so I recommend anyone that might want to do somethign similair give TimerTask a chance.

 

When you're ready, I recommend 

 

http://amzn.com/0321349601

Funny u mentioned that, I actually ordered that book this moring (before seeing this post) and it should be here by friday.  I'm a bit worried about it being 6 years old tho, but it seemed to have gotten great reviews.

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Similar Content

    • By LoverSoul
      Hello everyone.
      I had a problem with transferring my character from the creation editor to the game engine. I created the character in Adobe Fuse, then imported it to Mixamo to put rig and animation.
      However, the appearance of my character has deteriorated significantly, and after importing into Unity, the character even began to look like a meme from the Assassin's Creed. Can you please tell me how I can fix all this so that my character's hair does not look like bits of bacon sticking to her head, and her eyes and mouth have taken their stable position in the skull?
      Thank you for attention.



    • By ilovegames
      Simulator driving with two modes of play - a race and free game in the open world!   Features: - 2 game modes - race and free game - 3 modes of transport - Buggy, ATV, Jeep - The open world - Realistic control - Modern graphics



      DesertTournamentSetup.exe
    • By NajeNDa
      Hi there,
      I am a game programmer (C#/C++) who is looking for a project to join. I am computer science engineer plus Master Degree in Game Development, currently working in one the most renown mobile games company (2 yeras academic experience, 1 year working experience).
      I have developed several prototypes or even games almost ready to release, but I always lack of artists, so I am looking for a project already set up or few artist to begin working in something.
      My preferences are:
      Unity or Unreal Engine 4 based project (UE4 prefered) PC/Console game prefered but mobile is accepted too Not interested in VR Serious team with almost all the roles filled or pretending to be filled 3D project prefered over 2D Guaranteed 7 work hours per week, Crunch 20 work hours per week  European team (if timezone is not a problem for you, so its not for me) I am not looking for any kind of money income from games neither the team, I want to do this as a hobby and a way to improve my skills.
      Cheers
    • By INTwindwolf
      COMPANY AND THE PROJECT

      We are an indie game studio consisted of professional and friendly people. Additionally, we are a team of skilled artists and dedicated indie enthusiasts. Our current project is INT, developed on Unity Engine 5 for platforms Windows, Linux, and Mac.

      INT is a 3D Sci-fi RPG with a strong emphasis on story, role playing, and innovative RPG features such as randomized companions. The focus is on the journey through a war-torn world with fast-paced combat against hordes of enemies. The player must accomplish quests like a traditional RPG, complete objectives, and meet lively crew members who will aid in the player's survival. Throughout the game you can side and complete missions through criminal cartels, and the two major combatants, the UCE and ACP, of the Interstellar Civil War.
      For more information about us, follow the links listed below.
      INT Official website
      Steam Greenlight
      IndieDB page
      Also follow social media platforms for the latest news regarding our projects.
      Facebook
      Twitter
       
      TALENTS NEEDED
      Website Administrator
      Unity Engine Programmer
      Please note all of above are remote positions. You will not be required to travel or relocate.
       
      REVENUE-SHARE
      We are unable to offer wages or per-item payments at this time. However revenue-sharing from crowd-funding is offered to team members who contribute 15-20 hours per week to company projects, as well as maintain constant communication and adhere to deadlines. Currently the crowd-funding campaign is scheduled for the first half of year 2018. Your understanding is dearly appreciated.
       
      CONTACT
      Please click each position to view the job in detail, as well as application instructions.
      Thank you for your time! We look forward to hearing from you!
      John Shen
      HR Lead
      Starboard Games LLC
    • By McJug
      Hi,
      I'm looking for a 3D artist to join me in creating a new tower defense game with a twist. Very much a hobby project but one which I want to have a professional end product feeling, with something that we can eventually monetize. I have a lot of the base game design in my head but as a developer I'm doing the typical developer thing of thinking technically - so someone who would be enthusiastic about the idea and have input on the design too would be great.
      I usually start these things with people and they get bored so I'm left on my own with half a project - so really looking for someone who shares my enthusiasm (that doesn't mean sitting in front of a screen 24/7 either though - this is meant to be fun).
      A little about me - I am a development team leader in the real world and the last hobby project I worked on with one other developer was a puzzle game that got featured in popular IT magazine's, and ended up with over a million downloads. 
      If you're going to get in touch please provide a few samples
      Hope to be working with someone on this soon!
  • Popular Now