New Game Development
Jacob Diaz (2657) 1 post |
I too have inculcated interest in game development. I would try to get it from the scratch. Currenlty waiting for the upcoming acheter project cars . |
Anthony Vaughan Bartram (2454) 458 posts |
Lots of play testing later… I’ve finished regression checks and have sent the release candidate out for further testing. Thanks to everyone for all the help. It would have been much more difficult (or impossible) to complete the game otherwise. If it looks version 1.22 is ok then I will send it to Drag’N’Drop for review. Tony |
David Feugey (2125) 2709 posts |
… and to RISC OS FR :) (we’re still here, lot of work is coming). |
David Williams (2619) 103 posts |
Anthony, just letting you know that I’ve adopted your method (described by you earlier in this thread) for reducing the usually-horrible flicker you get on the Raspberry Pi if you do double buffering the usual way under RISC OS. So, if I now issue a wait-for-VSync command (WAIT or OS_Byte 19) just prior to the screen bank swap (via OS_Byte 112 & 113), specifying the same bank numbers for the two calls, the flicker is practically eliminated (unless the graphics rendering takes an excessive amount of time). You still sometimes get odd glitches as if some background OS process is hogging the CPU for a few thousand clock cycles (perhaps that’s the case!). So, thank you. :) I have a thread going over at the Raspberry Pi RISC OS forum where I’ve linked to programs I knocked together recently which make use of your flicker-reduction idea. http://www.raspberrypi.org/forums/viewtopic.php?f=55&t=105693 I’ll be posting more graphical ditties to that thread over the coming days. What I think is needed now is a reliable means of detecting if one’s program is running on an RPi. May I ask how you did it (assuming you’ve included RPi detection in your game code)? [EDIT: Just ran the rotating RPi logo program on a freshly-booted-up RPi 2… and it’s flickering badly and running at half the usual frame rate! Then when I rebooted the machine, I get the glorious flicker-free 60 fps again. This lack of consistency is quite annoying, and I’m wondering if it’s down to some alignment issues involving the BASIC interpreter or something else in the OS.] [EDIT 2: Yup. Depending on the wind direction, the programs run at the full frame rate (60 fps) with practically no flicker on the RPi2; other times, they run at 30 fps. I strongly suspect an alignment issue somewhere. Will have to investigate. Perhaps ensuring that HIMEM is 64-byte aligned might do the trick? Must investigate…] Sorry for hijacking your thread. I look forward to buying & playing your game! David. |
Anthony Vaughan Bartram (2454) 458 posts |
Hi David, Thanks for your comments and interest. I am on holiday at the moment with limited access to the internet & none to source code. However, I have seen the reduced frame rate behaviour that you describe. In my testing, it reliably re-produces for me on the Raspberry Pi 1 with RC12. When it occured, the reduced framerate was due to the video buffer switch waiting for the vertical blank. So disabling vsync wait fixed it and also results in no flicker. Therefore the double buffering code required two modes of operation : one with an explict vertical blank wait, and one without. I added detection for when the framerate is reduced by iterating a loop for 1 second that ran the double buffering code and counting whether the framerate was below 50 (+/- a couple of frames for error) i.e. detecting the 30 frame rate with tolerance. I have implemented triple buffering as per Jeffrey Lee’s recommendation so that the delay in video switch by 1 frame does not cause the draw and video buffer to be incorrectly synced. If it is useful, then when I am back home on the 4th of April, I will post the code fragment from the game that implements triple buffering. I will also post the code that detects whether the frame buffer swap is waiting on the vertical blank and changes the mode of the triple buffering code. Best Regards, Tony |
David Williams (2619) 103 posts |
Tony, You wrote: “If it is useful, then when I am back home on the 4th of April, I will post the code fragment from the game that implements triple buffering. I will also post the code that detects whether the frame buffer swap is waiting on the vertical blank and changes the mode of the triple buffering code.” Thanks, it certainly would be useful! Out of curiosity, is your triple buffering code implemented in BASIC? I have some source code from a particularly skillful Acorn demoscene coder (Alain “Baah” Brobecker of ArmsTech) which shows how to do triple buffering, but I shan’t pretend that I understand it (at least not at first glance!). I think a RISC OS Wiki for game developers (fingers of one hand, sadly) which contains well-written, robust code for properly setting up screen modes (especially 8/32bpp), allocating memory, and triple buffering of course, and many other useful things, and that would work on a wide range of RISC OS versions and hardware, would be very welcome. This is what I’m kind of struggling with at the moment. Things that are easy to do with (and forgive me for saying this) ‘BBC BASIC for Windows’ are proving fiddly with BASIC V/RISC OS. Lack of familiarity is obviously an important factor, but I’ve been having some very frustrating experiences with my recent return to RISC OS in the past few weeks. David. |
Anthony Vaughan Bartram (2454) 458 posts |
Hi David, Yes the code is in BASIC as is the game code. In addition, the game’s code (but not the graphics or music) will be licensed such they can be reused by anyone without restriction in their own future projects after the game’s release. I also plan to release a BASIC library that provides routines for game coding which handle mode switching, particles, 3d star fields, screen transitions (fade out / collapse to centre) sprite plotting etc. Having a wiki is a good idea and I would like to contribute to that. I started using RISC OS in June as a first time user and I recognise the challenges in porting RISC OS to the Pi & other hardware. I think the porting work is an impressive achievement and is continually being improved. Once the library / code elements exist then I hope game development will pick up. I’ve enjoyed the technical issues as a challenge and hope to be able to contribute to RISC OS itself going forward. Tony |
Anthony Vaughan Bartram (2454) 458 posts |
I’m planning to tune the code slightly and produce a release candidate 2 with a couple of localisation fixes & (hopefully) support for RISC OS 4. Also, I’m thinking of changing the particle graphics to scaled sprites to make them more visible + look better & adding a health display for the Overlord. Raik, Michael, David Feugey, Malcolm, does that sound ok? Thanks, Tony |
David Williams (2619) 103 posts |
Tony, I’ve just experimented using a so-called ‘back buffer’ as an alternative to double (or triple) buffering. Practically all my games and animated graphical ditties made with ‘BBC BASIC for Windows’ (BB4W) essentially use a back buffer technique to eliminate flicker (although the mechanics of it are largely hidden, and it’s something I had never given any thought to). Tearing can still be a problem, especially in the Windows environment where it’s difficult or nigh-on impossible to accurately synchronise software-rendered graphics display with the screen’s refresh. I had never tried it with RISC OS before, but it seems to work nicely. You render all your graphics in a private buffer (or switch VDU output to a sprite), and then when you’ve rendered the entire frame, blit as fast as you possibly can to the screen immediately after a WAIT (or OS_Byte 19). Flicker is practically impossible – unless the time it takes to blit a frame is longer than the screen refresh period (1/60th of a second in my case), then you’ll get tearing of course. It’s especially nice if the blit (back buffer to screen memory) can be hardware accelerated (I suspect this is what happens on many Windows machines). If not accelerated then a shedload of LDMs & STMs are needed (which is what I did). Advantages: absolutely no flicker – ever – on the Raspberry Pi! Double buffering is currently problematic, as we’ve discovered. It’s easy and only requires one screen bank, but requires assembly language to do the blitting. Disadvantage: It’s far less efficient than multi-buffering. It requires transferring a lot of extra data (an extra 73MB/s for 640×480×32bpp — that’s fair amount of memory bandwidth!). At the end of the day, though, I suspect triple buffering will beat double- and back-buffering hands down. Has triple buffering completely eliminated flicker or jitter with your game on the Raspberry Pi, or reduced it considerably? [EDIT: I don’t think there could be any flicker with triple buffering, because as I understand it, only completely rendered frames get presented to the screen.] David. |
David Feugey (2125) 2709 posts |
Definitively what I would like to get with the (still opened) BBC Basic programming contest.
Sounds great :)
It’s a good idea, especially if you want to make a ‘windowed’ game. It can be very easy to make desktop applications this way. Just need some examples of how to set up the initial window. |
Anthony Vaughan Bartram (2454) 458 posts |
Triple buffering appears to have eliminated flickering and jitter in my testing. There are occasionally some slight imperfections when I’m streaming the in game music via the MP3 decoder (first few seconds of loading the MP3 & barely perceptibly when streaming on a good SD card). n.b. the calls to this decoder are encapsulated in procedures so as to make the code easily reusable. My goal with the BASIC library is to get a coding experience similar to the AGK/Dark Game SDK on Windows & AMOS on the Amiga i.e. to have high levels of encapsulation and to use handles to simplify calls e.g. I use handles to a object location array for tracking the erase of objects in Overlord because this avoided having to do a whole screen erase which appeared to fractionally reduce the frame rate i.e. I store coordinates against a handle for a frame and when the sprite is erased for the frame, I retrieve the stored coordinates using this handle – which corresponds to a sprite ID number. I did consider writing in ARM assembler for the game, and might add some routines in the library for this purpose where a speed advantage would be gained. But I felt BASIC was more open and more than quick enough for my requirements, although I have fond memories of writing a 6502 game on the BBC (which lives in the found part of Stairway to hell). Writing AMOS games 20 years ago on the Amiga and distributing via Aminet was generally a good experience at the time but it lacked an easy way to hit the OS routines directly and this is where RISC OS certainly has a significant advantage over the other BASICs which I’ve looked at. |
Anthony Vaughan Bartram (2454) 458 posts |
Hi David, and, although I’ve not tried it myself, wondered if this would help with structure support / porting: Tony |
David Williams (2619) 103 posts |
Certainly I intend to look at Basalt, and upon a glance at the docs, Steve Drain appears to have done great work. But, with all due respect to Steve, I think natively-supported structures in BBC BASIC are pretty much essential (and they have been discussed for over a decade). I will explore Basalt in the coming months (nice that it provides an ATAN2 keyword as well!). At the moment, I’m slightly concerned how !StrongBS (which I’m having major problems with as it is) will cope with Basalt-extended BBC BASIC code. I don’t use !StrongBS to obfuscate or hide my code, but because my interest is in graphical ditties & games, I need my code to execute as fast as possible (I’m increasingly averse to writing assembly language; I’m about to hit 40, life’s too darn short). Several things are making my return to RISC OS a misery at the moment – including RISC OS, FileCore (argggh!), !ArcFSr/w, !Zap, !StrongBS, PRMs, and to some extent, BASIC V. But apart from that… :) David. |
Steve Drain (222) 1620 posts |
Much longer than that. The latest version of Basalt provides for structures, but they are not very much like those in BB4W, for which you would need to modify the BASIC module quite extensively. My arguments as to why this would not be a ‘good thing’ have rattled around for some time as well. ;-) The Basalt structures are actually in some ways a bit more flexible than BB4W, but they do require the breakout character ‘\’ before all structure references. As I have not used them in anger myself and have had not had other feedback, they may be buggy, so some serious testing would be welcome.
I was pleased with that myself.
Unless you know better, I do not think there is a 32-bit version of StrongBS, which rather puts it out of the picture. I wonder if any one has access to the source, because it is not otherwise supported. Basalt in its earlier forms could be crunched. For StrongBS you needed a suitable SBSMake file alongside the program. It is a long time since I looked at whether later developments would be amenable to this. |
David Williams (2619) 103 posts |
If I have time (because I should actually be job-hunting at the moment!) I will knock-together a quick game which will make fairly extensive use of Basalt-enabled structures and some of its other offerings. That should provide some testing, and if anything untoward happens that I can’t attribute to error on my part, I’ll be sure to let you know. I’m still slightly fascinated that, given that the BASIC V source has been available for many years, why structures haven’t been natively implemented given their great simplifying, productivity-enhancing usefulness! Ever since Richard Russell – very cleverly – introduced them to BB4W, I can barely live without them. They would simplify WIMP programming no-end. I dream that, one day, he’ll introduce the ability to nest structure arrays within structures, viz.: DIM myStruct{(99) myInt%, myByte&, myDouble#, \ So, therefore myStuct{(I%)}.struct2{(J%)}.b& += 1 etc. Very nice and useful, but probably a nightmare to implement. (And besides, the development of BB4W has now ceased, sadly.) [EDIT: Misaligned structure members are less problematic with BB4W as they would be with ARM BBC BASIC because the x86 handles misaligned memory addresses pretty well – you can still get excellent performance, but misaligned structure members are going to be much slower to handle on the ARM, so how does one get around that?] Cheers, David. |
Fred Graute (114) 645 posts |
StrongBS 3.05 is 32-bit and can be found here A quick try suggests it even runs on ARMv7 but I’ve not done any serious testing. |
David Williams (2619) 103 posts |
v3.05 is the one I’ve been using. I’m generally very impressed with it, and Mohsen Alshayef has done a good job, but it has a tendency to, amongst other things, append modified variable names to assembler branch (B) instructions, e.g.: B myRoutine%becoming Bxd% which trips up the assembler on the RPi. I could give similar examples. Also, at least once it has generated a strange side effect which changed how my program behaves (even though I endeavoured to write the program properly with StrongBS actually in mind). I haven’t yet got to the bottom of it. It’s a pity, really. It’s an amazing utility, but it needs fixing. Same for !Zap (I use the 32-bit version, but it still has some issues). David. |
Steve Drain (222) 1620 posts |
StrongBS Many thanks. How did I miss that? I must do some experimenting. |
Steve Drain (222) 1620 posts |
There is at least one person I know to have written structures into the BASIC module, but at the time could not or did not want to release it. The real problem with new versions of BASIC is the way the module works – you cannot RMEnsure the latest version you want. As an example, some while ago Steve Revill added some enhancements to the version of BASIC that ROOL now supplies, among which is the very useful DIM LOCAL. You would think that developers would take the chance to use this, but if they did, they would have to ensure that every machine that ran their application had that version of the BASIC module installed at start-up. The likelihoood of that is low.
If you use the Toolbox, structures become less important for Wimp programming.
Basalt structures are designed to be nested. Structure arrays can be arrays of structures, so not quite as neat. I have not touched or tested this for over a year, but I think my syntax goes like this:
There are no guarantees that that this works as published, and I have a slightly different version on the stocks here.
Basalt structures are completely byte-aligned. BASIC is full of byte-aligned transfers so there are routines to provide best performance. These can never be as fast as native processor transfers, but do not seem to do much harm to BASIC’s speed overall. |
GavinWraith (26) 1563 posts |
There are lots of possible ingredients that can go into a programming language. I think it is only rarely that a new ingredient can be added to a soup already cooked. It is how well the ingredients interact that determines the character of the language and the taste of the soup. It is the intended use of the language which determines which ingredients are desirable. For example, if the language is to be secure then you do not want to have explicit manipulation of memory; pointers, peek and poke and so on, are out. There are secure ways to construct complex datatypes without using pointers. If the code is to be reusable than you must have a language with local scopes. If it is to be used for scripting it should make it easy to pick up commandline arguments and do pattern-matching. Do you want a language with garbage collected memory – an automatic rather than a manual gear change? It certainly makes a lot of problems easier to program. When Kemeny and Kurtz developed the first BASIC I doubt that they were in a position to decide beforehand what features should be in or out. They simply produced something that was possible for its time. Now we have many languages, developed over many years, with different goals. What goals did you have in mind for an enhanced BASIC? And would it still be BASIC after enhancement? I have a suspicion that for some enthusiasts of BASIC (I count myself as one) nostalgia may be one of the goals :) |
Jeffrey Lee (213) 6048 posts |
One thing I’ve been thinking about recently is that it would be nice for the ARM unaligned load/store behaviour to be controllable on a per-application basis. So on ARMv6+ BASIC could quite happily use unaligned loads/stores while other apps can run with different settings. However my ideal way of implementing this would be to make the kernel manage it, as part of a larger “teach the kernel about process management” task – so don’t hold your breath waiting for me to implement it! |
Martin Avison (27) 1494 posts |
Beware! Back in 2009 I did some considerable testing of StrongBS v3.05, as it looked good and I was hoping it would replace the excellent !BasCompress which is only 26bit. I found some significant problems – one of which resulted in two different variables being changed to use the same name. This caused my application to loop nastily, and took some time to diagnose. I still have the details! I attempted to contact Mohsen at the time, and several times since, without any response. Unsuprisingly the Basic part of StrongBS is compressed, which makes fixing the problems rather tedious, so I gave up. I fear that he put considerable effort into StrongBS over a short time, and then disappeared. If anyone knows how to contact him, please let me know. |
Steve Drain (222) 1620 posts |
Ah! That will be why I have put StrongBS to one side, not the lack of a 32-bit version. |
Anthony Vaughan Bartram (2454) 458 posts |
Hi David, Regarding languages, I like the rapid and interactive nature of BBC BASIC for game development. Professionally I use C++ and LUA a lot, so BASIC is a nice contrast to those paradigms for me. Here are the triple buffering routines that I’m using: REM Triple buffering procedures DEF PROCUseTripleBuffering DEF PROCCalibrateTripleBufferMode VSync% = 1 REM ~1/3rd tolerance & allow for 50 hz frame rate DEF PROCTripleBuffer SYS “OS_Byte”, 113, BANK ENDPROC DEF PROCSwitchDrawBuffer REM Unset Triple Buffering & Draw Buffer DEF PROCCls |
David Williams (2619) 103 posts |
Thanks for the code, Tony! I’ll be diving into the PRMs in the next few days to nail down, once and for all, exactly what OS_Byte 112, 113, 114 (and some other video-related calls) do. I was using 112 & 113 over 20 years ago without any thought as to precisely what they did, only that they seem to work! The following loop (originating with Jan Vibe in the early 90s) was my staple: J% = 1 Recently it’s become: bank% = 1 It’s equivalent, of course. But it’s time to get into some triple buffering… Thanks again. David. |