modular design + threads *WARNING: LONG POST*

Forum for technical discussions regarding development. If you have a general suggestion, problem or comment, please use one of the other forums.

Moderator: OpenTTD Developers

User avatar
Expresso
Tycoon
Tycoon
Posts: 1760
Joined: 09 Aug 2004 00:14
Location: Gouda, the Netherlands

modular design + threads *WARNING: LONG POST*

Post by Expresso »

Not really sure if the development forum is the right place for this (since it is a suggestion, but a technical one).

Currently openttd has a monolithic design. The monolithic design has the advantage of allowing the program to work faster (or so it seems) and seems more easy to code.

However, it has the following disadvantages:
  • Encourages spaghetti code.
  • Threading is extremely difficult to implement.
  • Things are difficult to modify; and if you do, you might cause bugs in unexpected places.
What I would like to see happen is a conversion to a modular design of the code (no, I'm not talking about a conversion to another language), which will most likely result in:
  • Clearer code (no vehicle related code in user interface code, etc.)
  • Much better ability to provide threading (because everything works seperate from other parts).
  • It'll become easier to produce working code.
But, the bad part of it:
  • It is a lot of work to implement something like this.
  • This will result in a total reorganisation of the code, as this touches nearly everything.
  • Might become a (slight?) performance bottleneck if implemented incorrectly.
How?
  1. Make a message system, which has the ability to queue messages. Move code to its appropriate location (no map code in vehicle code, no vehicle code in ui code, no ui code in sound code, etc.)
    The message queue should be simple enough to make, but there might be a need to skip some messages temporarily until they can be processed. The messages should contain as little information as possible and only contain relevant information. This to ensure both performance and simplicity. Some strange modifications might become needed for this.
  2. Build wrappers, to allow for a painless transition.
  3. Build message handlers in the appropriate places.
  4. convert wrappers to message system.
  5. Now start puting things in threads... I suggest the following
    1. User Interface (includes console) + viewport + OS interface (just needs to keep going with as little lag as possible).
    2. Network Interface + game ticks: would this help fight desyncs?
    3. Sound engine / mixer (just to be sure sound works, no matter what happens to the other parts of the game).
    4. AI players: unknown how much time a given AI player consumes.
    5. Pathfinder: keep game lag to a minimum.
    6. Vehicle database.
    7. Map engine.
    8. Message system
So instead of working directly with relevant information, you would end up with a query for it. This will allow the threads to work asynchronous without impeding each other too much. There would be a need for some exceptions though (the pathfinder comes to mind here).

Why?

This would change the code for the better, parts of it might become slower, parts of it might become faster. But the code will become cleaner and in the end the entire code base will consist of modules.

The end result might be that the code is more accessible for patchers and new devs. The current spaghetti might even become readable! :)

The multithreading will serve to keep the program running smoothly, even with lots of vehicles wandering around the map.

When?

The sooner the better, but not before 0.4.5.


Please, keep in mind that I'm only suggesting this. It's highly probable this text is filled with mistakes and I made erronous assumptions. That does not mean, however, that the core ideas (modular design + threading aided by messages) won't work.

Please forgive my bad English and perhaps a bad choice of words or phrasing of sentences.
kasper_vk
Engineer
Engineer
Posts: 8
Joined: 02 Sep 2004 13:04
Location: The Netherlands

Post by kasper_vk »

From a developers perspective, i would agree.

From the ottd developers perspective; i can imagine an initial reaction like 'oh yeah, yet another coder who thinks he knows better'. No offence :wink: !

I trully think you're right, but (i think) the problem is:
  • As you mentioned, it would be a hell of lot of work (you probably looked a the source multiple times, just like i did)
  • Users lately seem te growing more impatient for new releases/features, while the developers are already coding their **** off
These 2 factors combined, i think you're suggestion might just an utopia in the exact sense of the word; it is simply unreachable (with the time/mains available to the project).
User avatar
bobingabout
Tycoon
Tycoon
Posts: 1850
Joined: 21 May 2005 15:10
Location: Hull, England

Post by bobingabout »

imo, it should have been coded better in the first place.

i say we should go for it, but not all in 1 giant leap :P
JPG SUX!!! USE PNG!!!
There are times when JPG is useful, TTD screenshots is not one of them. Please use PNG instead.

[/url]
User avatar
prissi
Chief Executive
Chief Executive
Posts: 648
Joined: 15 Nov 2004 19:46
Location: Berlin, Germany
Contact:

Post by prissi »

I think it would be a good idea. However, the number of files(modules) is quite high already. I think thiy project is as important as the proper acess to map array values in the other thread for long term development.

Otherwise I think OTTD is not that bably fragmented and the modules does make sense mostly. I would avoid threads, since this are a nightmare on games not made to use them. It would rather require a different game, when e.g. each town is a thread (which would make sense with nowadays trend towards multiple CPUs).
User avatar
Dextro
Chief Executive
Chief Executive
Posts: 701
Joined: 12 Jan 2005 21:56
Location: Lisboa, Portugal
Contact:

Post by Dextro »

From a wannabe-developer point of view I can see why this would bring advantages but from the same point of view I can see living hell for those who might try to turn ottd code from monolithic to modular...

Still might be a good idea for ottd 2.x.x if it ever comes to existence? :)
Uncle Dex Says: Follow the KISS Principle!
User avatar
Expresso
Tycoon
Tycoon
Posts: 1760
Joined: 09 Aug 2004 00:14
Location: Gouda, the Netherlands

Post by Expresso »

kasper_vk wrote:From the ottd developers perspective; i can imagine an initial reaction like 'oh yeah, yet another coder who thinks he knows better'. No offence :wink: !
I don't think I know it better, I assume the dev team is very competent and I envy their ability. I just wanted to point something out which needs to happen sooner or later... adviseable would be sooner.
kasper_vk wrote:As you mentioned, it would be a hell of lot of work (you probably looked a the source multiple times, just like i did)
The amount of work to implement something like this will only become more and more, and the difficulty to implement this will increase too.
kasper_vk wrote:Users lately seem te growing more impatient for new releases/features, while the developers are already coding their **** off
That's why I suggested it as a project for after the next release (new features, bugfixes and some performance improvements). This release will keep most users happy for a while (long enough to do the conversion to a modular system).
kasper_vk wrote:These 2 factors combined, i think you're suggestion might just an utopia in the exact sense of the word; it is simply unreachable (with the time/mains available to the project).
Unreachable... no, it will just take long to get implemented. It's all a matter of priorities.
This is not something which should be discarded as "too much work" this should be kept right at the top of the todo list, as it will simply become more and more work to implement. The choice is simple... now, or sometime in the future, when it may be right next to impossible.
prissi wrote:I think it would be a good idea. However, the number of files(modules) is quite high already. I think thiy project is as important as the proper acess to map array values in the other thread for long term development.
With modules I did not intend the individual files. By modules I meant functional parts of the program (quite a difference). Multiple files haveing to do with the same thing should be sticked in the same module and communicate with the rest of the program using messages. This decreases complexity and allows for threading.
imho this might even be more important then the new map array... why? well, simply because this would make the implementation of new features a lot simpler (less code to modify). Most of the time it doesn't matter how one module functions to the other modules, as internal communication would go via messages most of the time.
prissi wrote:Otherwise I think OTTD is not that bably fragmented and the modules does make sense mostly. I would avoid threads, since this are a nightmare on games not made to use them. It would rather require a different game, when e.g. each town is a thread (which would make sense with nowadays trend towards multiple CPUs).
To make sure the nightmare remains with the conversion and goes away afterwards you use modules (note: the usage of the word is not intended as 'source files')
That's why the conversion to modules would be a good idea to do first. The message system would serve to isolate the modules as much as possible and that makes threading stuff even simpler... maybe even to the point of being trivial.
User avatar
webfreakz.nl
Director
Director
Posts: 627
Joined: 11 Aug 2005 08:22
Location: Localhost, 127.0.0.1, [The Netherlands: South Holland-> Westland]
Contact:

Post by webfreakz.nl »

Sounds great. Everything better organised is better for us (players) and better for the developers. The only thing left is the developers will have to agree this ;)
# Programming is like sex, one mistake and you have to support it for the rest of your life. (Michael Sinz)
Tyrell
Traffic Manager
Traffic Manager
Posts: 137
Joined: 10 Aug 2003 23:09

Post by Tyrell »

...
Last edited by Tyrell on 28 Jan 2006 19:47, edited 1 time in total.
User avatar
bobingabout
Tycoon
Tycoon
Posts: 1850
Joined: 21 May 2005 15:10
Location: Hull, England

Post by bobingabout »

this will probably kill all the patches that arn't merged yet... :(
JPG SUX!!! USE PNG!!!
There are times when JPG is useful, TTD screenshots is not one of them. Please use PNG instead.

[/url]
Bjarni
Tycoon
Tycoon
Posts: 2088
Joined: 08 Mar 2004 13:10

Post by Bjarni »

why would you want such a change? Multithreading tend to make more complex bugs and are harder to code
The only benefit that I can see in this huge work is that it can benefit from more than one CPU. I don't see a reason why we should make such complicated code to support something that so few people would benefit from, not to mention that having more than one CPU often means that the CPUs are decent too.
User avatar
Brianetta
Tycoon
Tycoon
Posts: 2566
Joined: 15 Oct 2003 22:00
Location: Jarrow, UK
Contact:

Post by Brianetta »

I think Expresso's main motivation is greater encapsulation of the code, not threading per se. Somebody could easily change the user interface for laying tracks, stations, signals etc. without breaking their functionality. They wouldn't even have to worry - that code would all be somewhere else, and operating independantly of the UI code.

Of course, it all comes down to whether the benefits are as great as postulated. The Linux kernel remained monolithic for a decade, because it was easier to shovel information around inside it. It's still largely monolithic now. The benefits of modularisation just weren't seen as large enough to counter the loss of the benefits of monolithic code.
PGP fingerprint: E66A 9D58 AA10 E967 41A6 474E E41D 10AE 082C F3ED
matthijs
Engineer
Engineer
Posts: 76
Joined: 25 Jun 2004 15:20
Location: Enschede, Netherlands
Contact:

Post by matthijs »

I like your ideas on some level, but I think you're pushing them so for.

Seperating code to be more segmented and have less cohesion is a good thing, without doubt. This is already happening on a file level, code is being moved to more logical places all the time. It might be wise to indentify more distinct modules, as you propose.

Using a thread for every module is probably too much. I am afraid that the extra overhead and challenges of threading (synchronization!) will not outweigh the advantages. Though most synchronization could be solved with a proper messaging system, not all communication can be resolved with messaging. Specifically, I'm pretty sure that if all map array access would happen via messages, the game would get a whole lot slower. Also, how would you code a simple GetTileType(tile) call asynchroniously?

Lastly, I simply do not think a rewrite of this magnitude is going to work. We have tried the map rewrite last year and failed. Not because we weren't putting in enough work or because it was too difficult. No, mainly because we ended up not only rewriting map accesses, but about half the code we changed.
The simple reason for this is that you can't properly convert code to a new map array nor move it around to the right module, if it isn't clear what exactly the code does or how it does it. Moving all code to the right modules would probably mean rewriting lots and lots of code...

I do have hope that sometime in the (near) future, so much of the OpenTTD codebase has improved in such a way that it is clear and well-documented, so changes like this can easily be undertaken... At the same time I think once we get there, most of the needed separation will already be there...

Matthijs
Bjarni
Tycoon
Tycoon
Posts: 2088
Joined: 08 Mar 2004 13:10

Post by Bjarni »

I see your point and we are going to make it more modular like the map rewrite. Only one place in the code will access the map and then other parts of the code can call certain functions to get/set the data for each tile, but only one file (module) will know how and where the different types like road/railroad/buildings... are actully stored in the memory.

Since a CPU is non-threading by nature, so threading would most likely just create an overhead without benefit. You need to have the ability to run threads in parallel to gain a real benefit, so the non-threading code is ok.

However you did give me one idea. Drawing on the screen is really slow, so if it were given it's own thread, we could make the core run at a fixed speed (like now) and then skip a frame if the previous frame is not done drawing. The result from this would be that if a computer got problems keeping up the speed, it would start frame skipping instead of slowing down the game. In large network games, some clients might get problems keeping the speed, but if they start frame skipping to ensure that the core keeps the same speed as the server, they would not desync, like a core slowdown will. It would also speed up on multiple CPU computers as all the core functions can run on one CPU and the drawing can run on another. It could also mean that the settings could alter the framerate to slow down on purpose, like you say that you only want 5 fps in fast forward while you like the current framerate when not fast forwarding. This would make fast forward a lot faster and slow computers would benefit from this. Also computers running on battery would benefit from this as less battery power is needed to fast forward say a year

However this is not an easy task and it do have some unanswered questions, like: if we mark say a replace window dirty, it will be cached to be redrawn in the next loop. While redrawing, it loops all vehicles, but if the video thread do that while the core is altering it, then what will happen... something that was not the intension, that is for sure. I guess the code contains plenty of those cases and all of them would have to be found. The solution is not to make a thread to read/write the info for the vehicles as it would slow down vehicle movement a lot with such requests all the time. They need direct access to the memory
Another issue is that I don't know how to code this, at least not yet
Because of those issues, I'm not sure if it will be done. One thing is for sure, you will not see it tomorrow


but the general idea of building modules is our goal, but they are most likely to be in the same thread to reduce overhead
User avatar
Dextro
Chief Executive
Chief Executive
Posts: 701
Joined: 12 Jan 2005 21:56
Location: Lisboa, Portugal
Contact:

Post by Dextro »

Bjarni ow there's a great idea :D If I'm not mistaken the quake engines use something like that: every single player game is actually a server running in the background and then the client connects to it and shows the game (If you're familiar with X just switch the "client" and "server" in my sentence :mrgreen: ).

What worries me is that put simply the game would have lag even in single-player if the computer isn't fast enough... That would probably look wierd in older computers no? :roll:

Still it's an hell of an idea the way I see it and it would probably also mean that adding eye candy (like changing how the gui looks and/or works) wouldn't involve touching the back-end code :)
Uncle Dex Says: Follow the KISS Principle!
User avatar
prissi
Chief Executive
Chief Executive
Posts: 648
Joined: 15 Nov 2004 19:46
Location: Berlin, Germany
Contact:

Post by prissi »

I wish you good luck with threads. But my experience is that threads are a nightmare to debug and so many more collisions nobody though before may arise.

However, doing the screen update independently of the game loop might work (if the simulation is halted or nothing moves during update). But then, a simple routine called a certain intervals would do the same trick and also ensure not motion was done during this the update. (This way it had been done in simutrans too.)
Bjarni
Tycoon
Tycoon
Posts: 2088
Joined: 08 Mar 2004 13:10

Post by Bjarni »

Dextro wrote:What worries me is that put simply the game would have lag even in single-player if the computer isn't fast enough... That would probably look wierd in older computers no? :roll:
we can just add a "wait for screen update" flag in the core so it will act like it do now if we like
Dextro wrote:Still it's an hell of an idea the way I see it and it would probably also mean that adding eye candy (like changing how the gui looks and/or works) wouldn't involve touching the back-end code :)
so the task would be to create a new thread that works independantly from the core, draws on the monitor and will use the current video drivers so we don't have to rewrite all of those. Now the question is how to do it and if it is worth such a big change. I have no idea how much code that needs to be changed to make this work
ganzpopp
Engineer
Engineer
Posts: 46
Joined: 20 Oct 2004 20:36
Location: The Netherlands

Post by ganzpopp »

I would like to say that I see great advantages in using a modular approach. It will be much easier to implement patches. Now various functions in the code are meant for only one task; it is difficult to expand them without altering the the code too much and changing the outcome. At least, that was the case, for example, when drawing diagrams etc.

:lol: dreaming about a plug-in system... :lol:
Bjarni
Tycoon
Tycoon
Posts: 2088
Joined: 08 Mar 2004 13:10

Post by Bjarni »

don't get your hopes up too high. Nobody got an idea to prevent the screen update to read from something that the core writes to without getting into problems. Unless somebody comes up with a bright and fast design for this issue, this idea will not be coded
TrueBrain
OpenTTD Developer
OpenTTD Developer
Posts: 1370
Joined: 31 May 2004 09:21

Re: modular design + threads *WARNING: LONG POST*

Post by TrueBrain »

Expresso wrote:Not really sure if the development forum is the right place for this (since it is a suggestion, but a technical one).

Currently openttd has a monolithic design. The monolithic design has the advantage of allowing the program to work faster (or so it seems) and seems more easy to code.

(..)
Hehe, you might like the thing I and Igor2Code are currently working on. Modular AIs :)

We created GPMI, a simple library that allows loading of modules and packages (libraries), in an easy and controlled way. With that, allowing modules to be build in scripts like TCL, PHP, Python, ...

Now what I did for OpenTTD: I made a bunch of wrappers around the core functions of OpenTTD, put in some hooks (in OpenTTD), and that was that. Now every person who knows a little about programming, can make his own AI in any language he likes.

Why I think you might like it, is because it also allows to do what you talk about. Maybe not all the way, but for example you can get the industry-code out of OpenTTD, and put it in a module / package.

This has an other big adventage, it allows Total Conversions very easy.

So, slowly I move on with my GPMI stuff, together with Igor2Code, slowly allowing more and more code to be done inside packages and modules, and maybe, one day, we can indeed put all code in packages and modules.

Short: your idea is not bad, and a game that is set up modular is most of the time far more useful. But, the road is long and hard.. we will see ;)
CmdKewin
Traffic Manager
Traffic Manager
Posts: 227
Joined: 09 Aug 2003 17:31
Location: Lugano, Switzerland

Post by CmdKewin »

And now, for the "Most usefull thread 2005 Award"...
The winner IIIIISSSSS



"For my part, I love spaghetti code! :twisted: " by, CmdKewin.



...

Will he give a proper answer to the proposal?

Stay tuned for more, well see us after a small commercial break.
"I'm an engineer!"
http://www.cmdkewin.net/ (Out of Order)

Eve: Since Beta Phase 2
Civilizazion Fan: Seems like forever...
SimCity Fan: SC 2000 is still the best
TT Fan: Since 1995
Switzerland: Since 1291
Post Reply

Return to “OpenTTD Development”

Who is online

Users browsing this forum: No registered users and 8 guests