Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - Clean code that works... how to?

Reply to topic
Author Message
  • Joined: 23 Mar 2013
  • Posts: 611
  • Location: Copenhagen, Denmark
Reply with quote
Clean code that works... how to?
Post Posted: Mon May 30, 2016 7:27 pm
I have taken a detour from developing Swabby for the SMS (http://www.smspower.org/forums/16052-SwabbySMSVersionDevelopmentThread), because I need to get some education regarding how to structure source code well. When I was coding an enemy wave generator for the Swabby game, I realized that I was again heading down the road of unclear dependencies, vague/bloated functions and generally creating code that would be hard for me to maintain and improve as the project grows. Then I have actually spent quite some time learning about refactoring, working with legacy code, etc. I have even gone so far (?) as to try my hand at a very simple, macro-based unit test framework for SMS test driven development. I read about code katas, and tried to make a clean-code-that-works bowling game scoring system, and.. blah blah.

Anyway, I hope some of you will contribute selected tips and principles you use when developing for the SMS. In the vein of this topic (http://www.smspower.org/forums/15794-AFewHintsOnCodingAMediumLargeSizedGameUsingWLADX), but with emphasis on code structuring. Nothing is too lame or basic.

Let me start:
* Make precise, descriptive names for your subroutines/functions.
* Subroutines do something - their names often start with a verb, i.e. initializeBuffer, createObject
* If a subroutine grows and performs multiple duties, it might be good to split it up into two or more separate subroutines, each clearly named and with a well defined job to do.
* Strive to never hardcode values. Clearly separate code and data, and feed data to code through well defined routines using either the registers, the stack and/or variables as arguments.
* Don't repeat yourself. Remove duplication (with the exception of unrolled loops, I guess)
* And..? :)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3841
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon May 30, 2016 7:56 pm
hang-on wrote
* Subroutines do something - their names often start with a verb, i.e. initializeBuffer, createObject


Right, and I usually use verbs that would give me also an idea about if the functions interact with screen (tilemap/sprites) or VRAM in general, or they initialize game maps/arrays. So I name them 'drawSomething', 'loadSomething', 'prepareSomething'. It isn't perfect, but it's a further step :)
  View user's profile Send private message Visit poster's website
  • Joined: 01 Jan 2014
  • Posts: 331
Reply with quote
Post Posted: Tue May 31, 2016 2:55 am
Assembly or C ?
  View user's profile Send private message
  • Joined: 23 Mar 2013
  • Posts: 611
  • Location: Copenhagen, Denmark
Reply with quote
Post Posted: Tue May 31, 2016 4:58 am
Agreed! I have my trusted old loadSAT routine that does exactly what it says it will do :)

I'm working with assembly.
  View user's profile Send private message Visit poster's website
  • Joined: 01 Jan 2014
  • Posts: 331
Reply with quote
Post Posted: Tue May 31, 2016 7:36 am
Code management is annoying.

Assembly puts additional twists on the topic as code is generally unintuitive to the human eye, difficult to ascertain in its purpose. On oldschool hardware measures to improve readability / scale-ability can be punitive to performance (modern day coding practices, implementation of higher level languages, etc...).

My opinion is where possible and feasible try the following;

- accept sms assembly will be a little messy, don't try to make it perfectly clean.
- put common functions in to routines / macros with clear names, vdp functions are obvious choice here.
- try to have calls including interrupt handler respect hardware state (return with same register values, etc).
- not all code is equally complex, apply code documentation relative to code complexity.
- document what is happening from perspective of problem domain.
- find coding / documentation format that works for you. be consistent with it within projects.


On the subject of macros I feel it is better to aim for broad application over narrow application. For instance the following macro...

WriteToVRAM <data location>, <vdp address>, <bytes>

... can be used for ...

; write buffered data to vdp sat
WriteToVRAM _satBuffer, _vdpSAT, 256

; write title screen name table
WriteToVRAM NATTitleScreen, $3800, NATTitleScreenEnd - NATTitleScreen



Pivoting a little low level project management i would also suggest the following.

- manage complexity. Greater complexity = harder to read + greater chance of bugs. Not everything has to be 100% optimal. Apply common sense and readability, you can always come back and optimize.

- compartmentalize problems where possible (and be cautious when you do not)! The combination of two or more problems is usually more complex than dealing with those problems in isolation.
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14751
  • Location: London
Reply with quote
Post Posted: Tue May 31, 2016 9:14 am
One thing I tend not to do, but may make sense to many, is to split the source into multiple files. This enforces some separation of the structure, and makes it harder to make spaghetti code. However, personally I find it easy enough to split things up within a single file (or maybe a few non-project-specific includes), and then it's a lot easier to search in a dumb text editor.

I would endorse using sections in WLA DX, local labels wherever possible, long label names (no updsatbuf please) and loads of comments. Where appropriate, document the registers that are in/out/trashed by your functions.
  View user's profile Send private message Visit poster's website
  • Joined: 23 Mar 2013
  • Posts: 611
  • Location: Copenhagen, Denmark
Reply with quote
Post Posted: Thu Jun 02, 2016 7:19 pm
Thanks for the feedback guys. It confirms most of my own thoughts on the subject of code management, and it have started some reflections on how to proceed with my current project. Anyway, all that is on hold at the moment since an extremely hot (early) Danish summer almost makes my laptop melt these days.
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 114
Reply with quote
Post Posted: Thu Jun 02, 2016 8:30 pm
As for naming conventions, I tend to use reverse names, I mean, first the thing, then the action. It seems more natural to me, at the first glance you know where to peek if you need to see what de function does or what's in action or whatever.

I mean this:

player_init, player_kill, player_update, player_render, etc.
enems_init, enems_update, enems_render, etc.
screen_draw, screen_redraw, screen_flick...

Of course, all related functions go in the same file.

Anyways, I try to create clean and readable code, but many times you need to get your hands dirty to shave 100 bytes or stretch a bit to fit in the frame time.
  View user's profile Send private message
  • Joined: 23 Mar 2013
  • Posts: 611
  • Location: Copenhagen, Denmark
Reply with quote
Post Posted: Sun Jun 05, 2016 9:37 am
Good point, na_th_an! I'm experimenting a little with using wla-dx structs to allocate ram. Using periods in the names, you can have something like:

player.x
player.y
player.init (subroutine)

It looks ok, but maybe the similarity to object oriented programming ends up being counterproductive.

psidum, your point about compartmentalising problems holds very true to my code management challenges: I'm often trying to build a low-level engine at the same time I'm thinking about gameplay elements etc. To a certain extent this is unavoidable (and I like the freedom), but I think I need to focus more on how to settle some engine level decisions before moving on... From a lower level to a higher level.
  View user's profile Send private message Visit poster's website
Reply to topic



Back to the top of this page

Back to SMS Power!