Jump to content
IGNORED

Clear for Action


Vorticon

Recommended Posts

This is an overview of my upcoming XB game called Clear for Action, which is a naval combat simulation in the age of sail. Given that my Ultimate Planet project was still lagging, I had decided about 3 weeks prior to the Chicago Faire to quickly develop a program I could demo at the Faire, and XB was the fastest way to do it. And so it happens that I had recently bought an Avalon Hill game of the same name on Ebay for my TRS80 Model IV which came on tape and was also programmed in Basic (Also available for the Atari 400/800), and it was a blast to play.

 

Clear For Action.gif

 

Even better, the simulation was extremely detailed, and the game came with 2 manuals that practically laid out most of the guts of the game it terms of mechanics, formulas and tables (but unfortunately not all, most notably the AI algorithm). I my infinite wisdom, I figured I could do it in the 3 weeks available to me, and in some fashion I did have a workable, albeit very buggy, version just in time for the Faire, with over 760 lines of code so far... A minor miracle. Clearly the program would not fit in one piece, and so I had to break it up into 3 separate programs chained to each other, exchanging variables via a common data file. I have nearly completed all the debugging, and am working at optimizing the AI a bit more, although at it stands it will shred you to pieces if you are too cavalier (see below), but there is still a lot of improvement to be made if it is to provide a decent challenge to a strategically astute player.

My main problem now is that it simply takes too long to load each chained program when it is called, even though the execution speed itself is quite acceptable for XB. As a result, a single turn from ship movement to combat to status display will take about 2 min and 14 seconds, most of it spent waiting for the programs to load. You might as well be playing chess... Do you guys have any suggestions for improvement here? I am aware of prescanning, but my early experimentation has not resulted in huge improvements because most of the loading time is taken by the data file which contains a large number of variables, each occupying a single file record thanks to the designers of XB...

When I play the game in Classic 99 with CPU overdrive on my high end Alienware desktop, the delay is only a few seconds, but for the average computer, the delay was still quite substantial as the owners of laptops at the Faire figured out as I harassed every one of them to try to run my game prior to the demo :-D

In the mean time, here are some snapshots of a game I played this morning:

 

CFA%20Intro.gif

 

CFA%20Scenarios.gif

There are 8 built-in historical scenarios, but you can also create your own.

 

CFA%20Sail.gif

You can set the sails and then the ship direction, taking into account the wind, sailing speed, and points of sail.

 

CFA%20Grapple.gif

If you get too close, you may grapple to enemy ship. There is also a chance your sails will become fouled.

 

CFA%20Guns.gif

Fire away! You control your guns' loadout which in turn affects the ballistics and the range of the guns. Reloading is not instantaneous either and is affected by the number of gun crews, gun damage factor, and type of load.

 

CFA%20Boarding.gif

If your ship is grappled or fouled, you may attempt to board. This can be devastating to either ship in terms of crew casualties...

 

CFA%20Player%20Status.gif

I'm in real trouble here, with all of my port guns destroyed and a third of my masts and sails gone!

 

CFA%20Computer%20Status.gif

My computer opponent on the other hand is fairing much better...

 

CFA%20Struck.gif

And it just handed me my ass :roll:

Edited by Vorticon
Link to comment
Share on other sites

The demo for this at the Faire was pretty neat, even with the one BSOD ;) Is the video posted, yet?

 

As for speed, how about recoding in TurboForth? I assume compiling it would not speed up as the wait time is loading. What exactly is it loading? Maybe some way to pre-load program or data into expansion RAM?

Link to comment
Share on other sites

The demo for this at the Faire was pretty neat, even with the one BSOD ;) Is the video posted, yet?

 

As for speed, how about recoding in TurboForth? I assume compiling it would not speed up as the wait time is loading. What exactly is it loading? Maybe some way to pre-load program or data into expansion RAM?

 

The actual execution speed is fine for XB. The problem lies with loading the chained programs and the data form disk. As you know, large XB programs take a noticeable time to load when run, and this game goes back and forth between two main large programs. In order to preserve the large number of variables needed for this rather complex simulation, I'm using a data file that is updated prior to calling another program, and read by the called program. Apparently XB allows only one variable or data item per file record, and so the disk is accessed for each variable, creating a significant slowdown in loading. Using Forth or another language is probably not the answer.

On the other hand, I do like the idea of loading the variables in RAM rather than disk outside of the XB space, but I don't know if that is possible or even where I would find a protected space. Obviously assembly will be needed for saving and loading of the variables, and I can do that if somebody here can give me some guidance... How about using the SAMS card? Can it be accessed from within the XB environment? Clearly RAM will be much faster than disk access...

Link to comment
Share on other sites

Similar game from SSI and a complex looking manual - http://www.atarimani...dsides_796.html

 

Interesting! The description seems almost similar to Clear for Action, and since it came out a year earlier, I wonder if it was not the inspiration for it. I should look up that game on Ebay. The screen shots look incredibly detailed as it seems like the Hires mode was used. This level of screen detail could probably be achieved in bitmap mode on the TI under assembly, but it would magnitudes more of time to program.

Edited by Vorticon
Link to comment
Share on other sites

The demo for this at the Faire was pretty neat, even with the one BSOD ;) Is the video posted, yet?

 

As for speed, how about recoding in TurboForth? I assume compiling it would not speed up as the wait time is loading. What exactly is it loading? Maybe some way to pre-load program or data into expansion RAM?

 

The actual execution speed is fine for XB. The problem lies with loading the chained programs and the data form disk. As you know, large XB programs take a noticeable time to load when run, and this game goes back and forth between two main large programs. In order to preserve the large number of variables needed for this rather complex simulation, I'm using a data file that is updated prior to calling another program, and read by the called program. Apparently XB allows only one variable or data item per file record, and so the disk is accessed for each variable, creating a significant slowdown in loading. Using Forth or another language is probably not the answer.

On the other hand, I do like the idea of loading the variables in RAM rather than disk outside of the XB space, but I don't know if that is possible or even where I would find a protected space. Obviously assembly will be needed for saving and loading of the variables, and I can do that if somebody here can give me some guidance... How about using the SAMS card? Can it be accessed from within the XB environment? Clearly RAM will be much faster than disk access...

 

I seem to remember passing variables between chained programs by coding them as a character definition in one program and then disassembling the code in the receiving program. I do not remember much details but I do remember that I was not passing many variables and although I had 3 or 4 programs in the chain, only one was very active. The principle being that characters 96 to 143 hold their definition between program runs.

Edited by jacquesg
Link to comment
Share on other sites

I seem to remember passing variables between chained programs by coding them as a character definition in one program and then disassembling the code in the receiving program. I do not remember much details but I do remember that I was not passing many variables and although I had 3 or 4 programs in the chain, only one was very active. The principle being that characters 96 to 143 hold their definition between program runs.

 

I did not know that. This would be problematic for non-integer variables though but not impossible. I have somewhere around 30 different variables to track for each ship, for a total of around 60, a mix of integers, decimals and characters. I'll have to give it some thought to see if I have enough free characters for storage and devise an encoding scheme. Thanks for the tip!

Edited by Vorticon
Link to comment
Share on other sites

couldn't you save the varibles as one long string which would be only one record then. sure the program would have to break it out but that would be alot faster then disk access. I try to do as much as possible with strings cause they are the fastest way in basic and the lowest memory usage.

Yup, that's one option I'm exploring :)

Link to comment
Share on other sites

I seem to remember passing variables between chained programs by coding them as a character definition in one program and then disassembling the code in the receiving program. I do not remember much details but I do remember that I was not passing many variables and although I had 3 or 4 programs in the chain, only one was very active. The principle being that characters 96 to 143 hold their definition between program runs.

 

That is a damn good idea, IMHO. Otherwise, I was thinking serializing the data into a string (which I believe you also mentioned, too lazy to look back) like web developers do for cookies and session data. You might want to have some kind of sanity check on the data to make sure the program is not being fed deliberately bad data.

Link to comment
Share on other sites

You would have to work out some kind of encoding. You will not use the raw characters, per se, since, as you noted, you only have A-F, but you DO have the ability to code/decode based on the actual values represented. For instance, if you wanted to save the name "VORTICON" in a character definition, you could use the ASCII values of (86,79,82,84,73,67,79,78) and encode them into a CALL CHAR of "8679828473677978" or using the hexadecimal equivalents. The problem is that this requires encoding and decoding time, but I would suspect that is far faster than disk I/O.

 

Does XB have native HEX/DEC functions? I cannot recall. That would save a good bit of time decoding in XB.

Link to comment
Share on other sites

CALL HEX in RXB will do this for you.

 

It figures out which one is first and puts the result into the next variable.

Also RXB CALL HEX is designed around CALL PEEK or CALL LOAD so the values are -34768 to 32767

 

So in answer to your question:

http://www.youtube.com/watch?v=J0graDiKSkY

 

 

Now almost all of these demos use CALL HEX for various reasons.

Edited by RXB
Link to comment
Share on other sites

How would one encode string data within a character definition given that only letters A to F are valid? I suppose I could convert each character in a particular string to its individual ASCII code and encode it that way, but is there something more efficient available?

 

It's not just A-F it's a hex value 0-F, so the 16 character string is really a 8 byte data storage. 01,23,45,67,89,AB,CD,EF.

So depending on your usage in the game, if variables are never higher the 255, I would store them has hex values, 8 per CHAR string. And depending on the decimal precision you can have hundredth value in hex from to. so per 2 FF sets you can have decimal values from 0 to 255.99.

 

I think this is most efficient way.

 

but if you have values out side of that range you can use 2 bytes, FFFF, sets which is 32767 and get a range to 32767.9999

 

The hard part is XB has no HEX conversion built in. But I found these DEF somewhere a long time ago, they convert 1 byte numbers so 0-255, 0-FF

10 HEX$="0123456789ABCDEF"

20 DEF HEX2DEC(X$)=(POS(HEX$,SEG$(X$,1,1),1)-1)*16+POS(HEX$,SEG$(X$,2,1),1)-1

30 DEF DEC2HEX$(X)=SEG$(HEX$,INT(X/16)+1,1)&SEG$(HEX$,X-INT(X/16)*16+1,1)

40 PRINT HEX2DEC("FE")

50 PRINT DEC2HEX$(256)

Link to comment
Share on other sites

Given that the majority of my variables are either 1 or 3 digit integers, the latter frequently greater than 255, it's just simpler to encode them as is. For floating point variables, I will multiply them by 100 and encode them as 3 digit integers. There is a loss of precision as a result, but for the purposes of this game it should not make a huge difference. For strings, I guess just encoding the ASCII value of each character is the way to go. There is no significant benefit in doing Hex conversions under these circumstances.

Now the problem lies in finding enough free characters to use for storage... Worst case scenario is that I'll encode as much as I can in char defs, and the leftovers will go into a disk file. I should still see that way a significant improvement in loading time.

I'll keep you posted as I test this out.

Link to comment
Share on other sites

 

The hard part is XB has no HEX conversion built in. But I found these DEF somewhere a long time ago, they convert 1 byte numbers so 0-255, 0-FF

10 HEX$="0123456789ABCDEF"

20 DEF HEX2DEC(X$)=(POS(HEX$,SEG$(X$,1,1),1)-1)*16+POS(HEX$,SEG$(X$,2,1),1)-1

30 DEF DEC2HEX$(X)=SEG$(HEX$,INT(X/16)+1,1)&SEG$(HEX$,X-INT(X/16)*16+1,1)

40 PRINT HEX2DEC("FE")

50 PRINT DEC2HEX$(256)

 

I'm going to keep that in my files for future use!

Edited by Vorticon
Link to comment
Share on other sites

You know, the other thing I just thought about is, you *are* using XB so you have a good bit of memory manipulation available. Between PEEKV and POKEV, at the very least, you could store information in unused VDP RAM -- though CHAR and CHARDEF are probably faster for moving data but with the cost of encoding and decoding time. It might also be possible to write some simple ML to move data between CPU RAM and VDP RAM, without requiring the 32k expansion.

 

A lot of possibilities there.

 

I keep thinking about compiling, also. Does a compiled program load any differently than a regular program? If not, is a compiled program any smaller?

Link to comment
Share on other sites

Well, I spent the entire evening reworking the program, and I managed to store over half of the variables inside character definitions. The single integer ones were stored as is, whereas the 2 and some of the 3 integer ones were first converted to hex format. The rest of the variables were stored on disk. The verdict? The additional code needed for these modifications ended up forcing me to break up the project into 4 instead of 3 sections, adding more delays, and in the end a single turn was taking about 4 minutes instead of the original 2 :( The encoding and decoding process for so many variables is probably just as slow, if not slower, than disk access.

So that's a bust. I don't think XB is well suited for recursive chaining of programs as compared to linear chaining, and I may have to just live with the loading delays...

I suppose I could try to explore the possibility of embedding some assembly routines to store variables in the VDP, but I think I'll focus on finishing the program and documentation first and see how much energy I have left.

Link to comment
Share on other sites

Well, shot that one all to shyte. Better save this thread for the benefit of others who tread in our foot steps :)

Nothing like trying to push the envelope :)

I am set on learning Forth this year, and apparently Wilsy is working on providing direct SAMS access from within it, so I just might convert that program to TurboForth as a learning exercise. The TRS80 version is in 80col but with only ASCII graphics and text, monochrome of course, and with Matt's 9918 replacement project, I will be able to use 80cols too!

Link to comment
Share on other sites

Turboforth v1.1 already does sams :) although you might not need it at all - Turboforth gives you just over 31k of free RAM on a 32k TI.

 

Take a look at bcd to encode your values in hex strings in xb - one *nybble* per digit. Very simple to encode and extract...

 

:)

Link to comment
Share on other sites

Turboforth v1.1 already does sams :) although you might not need it at all - Turboforth gives you just over 31k of free RAM on a 32k TI.

 

Take a look at bcd to encode your values in hex strings in xb - one *nybble* per digit. Very simple to encode and extract...

 

:)

I will. Thanks :) But first I need to finish the debugging. Everytime I play the game, something unexpected comes up because it's such a complex simulation and testing every possible situation is difficult. I will declare the game fully debugged (well sort of) when I can play 5 games in a row without any issues. Not there yet, but close :D

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...