Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 02:22 18 Nov 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : CMM2: Dragonfly 2D Game Engine

Author Message
epsilon

Senior Member

Joined: 30/07/2020
Location: Belgium
Posts: 255
Posted: 09:07pm 26 Mar 2021
Copy link to clipboard 
Print this post

Hi all,

In an earlier post I mentioned that I came across a book by Mark Claypool about the development of a 2D Game Engine:

https://dragonfly.wpi.edu

I worked my way through the book and now have a by-the-book C++ 2D Game Engine. But may more interesting to TBS is that, as I went, I also created a roughly equivalent CMM2 MMBasic version (with a generous dollop of CSUBs). This was a great exercise: Not just learning about 2D Game Engines, but also mapping of C++ OO concepts to MMBasic was an interesting puzzle. Also interesting were the profiling based optimizations, absolutely necessary to squeeze a minimum of performance out of this engine.

Regarding performance, more optimizations are needed to make the engine work well with more than a handful of objects. However, I wanted to release a snapshot of the engine as it is now, now that it's still close to Mark Claypool's book. As I continue with optimizations and new features, the code base will only stray further from the original design.

Included in the code base is a little demo game using the game engine. Here's a potato quality video of me lasting a whole 5s in the game:

Video clip: https://youtu.be/3-vFXHYETiM






I don't really intend to support this code base in its current form. I just wanted to leave it here in case anybody's interested in Mark Claypool's book and wanted a CMM2 MMBasic version to cross-check against.

Hopefully, I can develop this further into a game engine, and an actual game, that I do want to support. Things I'll be working on next are:
- sprite sheets
- tiles
- performance optimizations
- a commander cx16 version

I'm including a compressed archive of the game engine (df.mz1), along with the mar.bas tool to extract it. To extract, run the following command: *mar xz df.mz1.

You can also download the whole thing from GitHub of course:
https://github.com/epsilon537/df_cmm2

Cheers,
Ruben/Epsilon.

README.md:

Dragonfly Game Engine for CMM2
------------------------------
Author: Mark Claypool
CMM2 port by Epsilon

Changelog
---------
0.1: Initial version

Description
-----------
Dragonfly is a text-based game engine, primarily designed to teach about game engine development.
The author wrote a free book that teaches how to program a game engine from scratch.
For more info, see the Dragonfly website:

https://dragonfly.wpi.edu

This is a CMM2 MMBasic port of the Dragonfly Game Engine. Dragonfly as documented on the website
and book, is a C++ Object Oriented Design. The CMM2 version, although written in MMBasic, has
retained most of the Object Oriented Design, with some compromises for the sake of performance.

Features:
--------
* Sprite Animation
* Simple Kinematics
* World/View representation
* Timing support
* Bounding Box based collision detection
* Object Management
* Event Dispatching (E.g. collision, keyboard or nunchuk input events, user defined events...)
* Nunchuk support
* Sound support
* HUD support

Directory Layout:
----------------
* INC/ contains the game engine implementation
* TEST/ contain game engine test cases. They roughly match the assignments in the book but have
evolved a bit more there to make sure that they can run against the finalized version of the
game engine. The test code is messy but all test cases work and it's a good repository to check
to see how certain parts of the API work.
* SaucerShooter/ A demo mini-game used to demonstrate most of the features of the game engine.
SaucerShooter also serves as my benchmark for performance tuning:
 *ss_game: Starts the game
 *ss_game L: Starts the game and displays the game loop timing in the upper left corner.
 *ss_game F: Starts the game with frame rate limiting disabling and xProfiling enabled (ref. https://github.com/epsilon537/xprof_cmm2  for more info on xProf).

Required CMM2 FW:
----------------
V5.07.00b2 or later

GitHub:
------
CMM2 code base: https://github.com/epsilon537/df_win
Windows MSVC code base: https://github.com/epsilon537/df_cmm2


df.zip
Epsilon CMM2 projects
 
RetroJoe

Senior Member

Joined: 06/08/2020
Location: Canada
Posts: 290
Posted: 02:15pm 27 Mar 2021
Copy link to clipboard 
Print this post

Wow! That's an amazing piece of work !!

Out of curiosity, did you need to implement so much of the functionality in CSUBs for performance reasons, or was it a matter of easier porting from the book's implementation?

The book itself is a great reference - I must have missed it the first time you posted it, because these game engine concepts and tutorials are exactly the kinds of resources I am looking for. Some people have the gift of "intuiting" these concepts when writing games for the CMM and/or acquired them in previous programming lives - I, alas, am not one of them :)

Hopefully, I'll have some time to play around with this - text-based action games are obviously ready for a renaissance! In particular, the game libraries for the TRS-80, Sinclair ZX-80/81 and Commodore PET all seem like great sources of inspiration.
Edited 2021-03-28 00:18 by RetroJoe
Enjoy Every Sandwich / Joe P.
 
epsilon

Senior Member

Joined: 30/07/2020
Location: Belgium
Posts: 255
Posted: 03:47pm 27 Mar 2021
Copy link to clipboard 
Print this post

  RetroJoe said  Wow! That's an amazing piece of work !!

Out of curiosity, did you need to implement so much of the functionality in CSUBs for performance reasons, or was it a matter of easier porting from the book's implementation?


Thank you. Everything was entirely written in MMBasic originally. That worked fine for the testcases, but when I tried SaucerShooter, the frame rate was around 1fps. Since then lot of accessor functions, layering, encapsulation etc. disappeared, but to get to a 25x improvement I had to use CSUBs as well. The CSUB code is based on the Basic code it's replacing, not the C++ code of the PC version.

I know that use of CSUBs is sort of frowned upon, but it is my go-to fix when I hit a bottleneck. That's probably stupid, but I just haven't figure out yet how to write fast Basic.
The CMM2 is easy to program, but I find it pretty hard to understand the device from a performance point of view. My understanding so far is roughly this:
- a line of MMBasic is slow. Two lines of MMBasic are twice as slow.
- global variables are faster than local variables.
- Graphics primitives are super fast.
- CSUBs are infinitely fast.

I'm used to thinking about performance in terms of limited memory bandwidth, cache locality of reference, working out of register space, pipeline depth, latency, etc. All of that goes out of the window in MMBasic as far as I can tell. If I want to learn to write fast basic, I think I'm going to have to figure out how the firmware works. Or lurk here on TBS until somebody writes a great post about it ;-)

  RetroJoe said  The book itself is a great reference


I sent an e-mail to the author, to introduce him to the CMM2 with Saucer Shooter running on it. It made his day. Like many here, he started out on TRS 80, in Basic of course.
Epsilon CMM2 projects
 
RetroJoe

Senior Member

Joined: 06/08/2020
Location: Canada
Posts: 290
Posted: 04:33pm 27 Mar 2021
Copy link to clipboard 
Print this post

Maybe CSUBs are frowned upon by those who don't know how to write them :)

Kidding aside, they can obviously create a barrier to understanding and learning, OTOH, a well-structured, well-tested library of game engine components could actually have the opposite effect e.g. "mere mortals" like me with an idea for a game could implement them faster and cleaner than a bunch of spaghetti code in MMBasic.

One of the things that attracted me to the CMM2 was the fact that one could theoretically write arcade-quality games purely in interpreted BASIC. Growing up in the early 8-bit 1MHz CPU era, that was certainly not the case. Even if you didn't write full-on assembler, almost every game written in BASIC had some machine language POKEs and CALLs going on to speed up specific parts of the game loop. As for home game consoles, fuggedaboudit! Developing independent or home brew games on your Atari or Nintendo was unheard of. That's why Activision caused such a stir - they were the first "rebel" developers to leave the Atari plantation.

I think the Holy Grail for the CMM2 is something along the lines of the early POKE-type techniques i.e. a self-hosted mechanism to write and call machine language routines, if necessary, without having to fire up a GCC tool chain, which frankly is not in the realm of feasibility for a lot of folks.

To your point about the necessity of CSUBs vs optimizing the performance envelope of the MMBasic interpreter, Peter M. has made some pretty impressive optimizations in the last few FW releases (something to do with variable lookups), and Mauro, the "Canadian Petes" and many others have demonstrated that 100% pure MMBasic games are entirely possible, albeit without the layers of abstraction inherent in a game engine vs "hardwired" game code.

in any event, I think it's still early days for the CMM platform - looking forward to the next few years as the community keeps pushing the envelope, and sharing their tools and techniques.
Edited 2021-03-28 02:36 by RetroJoe
Enjoy Every Sandwich / Joe P.
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025