Synthetic Reality Forums Post New Topic  Post A Reply
my profile | directory login | register | search | faq | forum home

  next oldest topic   next newest topic
» Synthetic Reality Forums » Android Games » synSpace: Drone Runners » Meet synSpace: Drone Runners (Page 2)

  This topic comprises 5 pages: 1  2  3  4  5   
Author Topic: Meet synSpace: Drone Runners
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
My feeling is that I can release it as soon as it feels complete enough to the casual user, so long as I mention there is more I plan to add. But it has to feel like a complete game from day one.

In fact, since it already has the full function set (and more) of original synSpace, I thnk I have met that goal already, but the incomplete state of 'map editing' is what holds me back at the moment, I htink. That and making sure all my asset types are stable. (that I don't need to change the syntax with which they are stored).

But my experience with android is that people are pretty impatient and you only get one shot to be the new thing. Though it also helps if you release a new version every couple of weeks, so that argues for leaving things as un-done as possible :-)

I just never like to have people unhappy with me, especially since with android they actually have to pay a couple bucks. If they are unhappy, I need it to be because they are empty hollow beings with no joy inside :-)

I spelled pretty well in the post above. Often I lose my keyboard lock and then type gdlk jlk rjlwej rjklwej r jkwlej for awhile...

----

I'll go through my big list again and see what I feel I really have to have. But I think that's

* able to say a map editor exists, even if what you can do with it is not very powerful yet. [done]

* a complete (scripted) CTF implementation (as proof of concept for script API) [done]

* unlockables, if only to hand out the stock maps one by one [well, encrypted starmaps for now]

* some sort of Terms of Service you have to click OK on before connecting to other people the first time. [done]

* android options button with link to web assets (and appropriate web assets) [minmally done, but no real backing web site]

* some easy way to inflict music upon willing fellow players ('music chat') [USE IT for now]

* prune the stock FACEs of all the redundant boring ones

That's not too bad. I have about 30 pages of actual things to do, though that's all in rambly redundant talk, so maybe only a couple hundred actual action items.

[ 09-11-2016, 09:43 PM: Message edited by: samsyn ]

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
zim zim
Veteran Member
Member # 1233

Member Rated:
4
Icon 1 posted      Profile for zim zim   Author's Homepage   Email zim zim   Send New Private Message       Edit/Delete Post 
I can understand wanting everything to be perfect before a release. You defiantly don't want to release something that is buggy, hard to play/control, or doesn't cause players to get bored.

--------------------
I'll be around here until the plug gets pulled.
http://flashzz.webs.com/

Posts: 550 | From: USA-WI | Registered: Aug 2001  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
So, I have this automatic gain control for the music stuff, which is supposed to limit any overdriving in the signal.

It's very simple. whatever the sample value that I compute, I multiply it by the current agcPercentage which is normally 1.0 (no change) but drops down as the synthesizer generates louder samples (mainly due to multiple notes and the pulse at the beginning of most notes)

So simple that I just "knew" it worked, and I never got around to adding a visualization of what it was doing, and also constantly heard what sounded like over-driven signals. I managed to convince myself (since I knew I had a working AGC) that these sounds were actually due to thread starvation (also a problem).

But no, my AGC was NOT working, and I would never have known had I not added a visualization. It looked like the agcPercentage value was reacting well, it just wasn't quieting the signal in response. (this is a paraphrase)

Here's my error

code:
double sample = fromWhereverItCameFrom();
if( abs( sample ) > agcLimit ) {
agcPercentage *= 0.9; // make it a bit quieter
agcPercentage = max( agcPercentage, .01)
}
// adjust sample for agc
sample *= agcPercentage;

The PROBLEM with that is that since the original sample values are ALL too loud at this point, I need to apply the CURRENT correction BEFORE testing against the limits. Otherwise that test always says 'too loud'

I'd made a couple other little errors in that section of the code as well, that I probably would not have noticed otherwise. So it's always good to see the world in a new light as it were.

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
Not much to report this weekend, given the SuperBowl and a work project I am behind on.

For Script Support, I mainly just did some more thinking (trying to lay it out more wos-like with a single map having multiple 'scenes' that can all be running at the same time, with each scene 'hosted' ny one of the players.) I think I know what I am going to do with that.

Coding-wise, I just polished things, re-factoring some stuff where my 'class diagram' (if I had one) was pretty screwy. This had the result of consolidating three separate spots that I was doing signali processing on the microphone input. Which of course, broke pretty much everything until I smoothed it all out again. So I am pretty much just where I was at weekend start, but with marginally bettwe performance and a less embarassing code review :-)

But from my 'short list' I more or less did:

* added the unlockables (token/achievement) SYSTEM, so it is possible to lock/test for lock, but since I don'tactually lock anything yet, it's no perceived change

* added a basic Terms of Service on LAUNCH (until you say OK)

* added a link to the "droneNet Deep Web" site. (http://www.synthetic-reality.com/drone/synspaceAndroid.htm)

That turns out to be problematic since Android actively encurages apps to use the official android OPTIONS button, but now Android has removed the freaking options button from the display. I wish I could tell them "make the user slide in from the side to access any of those buttons) since they are generally in my way, but no, that's not legal either. ANYWAY, so I added the link to the in-game options page.

* Oh, probably the most significant change is that it is actually possible to share music now:

1.) compose a GROOVE
2.) on the GROOVE BROWSER is a 'USE IT' button that works the same as "USE" on the SHELL and FACE browsers. It marks a GROOVE as being your current one.

2.) open the INFO panel of a pilot in the StarMap Instance with you.

3.) If they have a current GROOVE selected, then you see an additional button.

4.) click that button and it opens the GROOVE browser with that groove selected (assuming it was transferred successfully in the background).

At which point you can just read about it, or press PLAY to listen to it.

Sharing a GROOVE also shares all the PATCHes used by that GROOVE.

ANyway, that's pretty nice. I like that.

progress video: https://www.youtube.com/watch?v=oEmAzlWTKeA&feature=youtu.be

[ 02-08-2016, 08:40 PM: Message edited by: samsyn ]

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
The bug that showed up in that video turns out to have been caused by my deleting track 1

Back when grooves were single track, I determined the lenght of the song by the length of that track. Then when I added more tracks, I never went back and changed that to use 'the longest track' so it alwaus uses track 1

And in this case, since track 1 was empty, thst psrt of ytyhe code thinks the song is over, but other parts know it hasn't started. resulting in vapor lock :-)

The other mystery (the clone of BOTTLE not sounding like BOTTLE is still a bit mysterious and probably indicates some horrible flaw :-)

[ 02-11-2016, 07:06 PM: Message edited by: samsyn ]

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
Just deleted 49 thousand bogus applications for forum accounts. The trick is to find the 2 or 3 legitimate ones.

Oddly satisfying, once I worked out how to do it at the shell level (the forum controls stop working with that many pending requests)

It's usually only 10-20 accounts created per day, but it adds up.

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
zim zim
Veteran Member
Member # 1233

Member Rated:
4
Icon 1 posted      Profile for zim zim   Author's Homepage   Email zim zim   Send New Private Message       Edit/Delete Post 
So I'm guessing the forums are easier to handle now that you've done that. If that is the case then congratulations. [Big Grin]

I've always hated seeing the forums go down.

--------------------
I'll be around here until the plug gets pulled.
http://flashzz.webs.com/

Posts: 550 | From: USA-WI | Registered: Aug 2001  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
This weekend's progress video:

https://youtu.be/iH2Fa0M3XcQ

* finished the BAND page of the GROOVE panel, which shows you all the PATCHes used in that GROOVE. Also the REPLACE button lets you re-orchestrate the GROOVE by assigning a different PATCH (the current Piano PATCH) to any you don't like.

* since I added a backup to sharedPreferences, I have not again lost my serial number, so I have extended that feature to back up all my preferences. I just can't trust the android sharedPreferences service to not reset itself unexpectedly. Probably my fault, but I only find fellow sufferers on the web, with no solutions that work for me. Anyway, hopefully this puts an end to the chaotic loss of all stats!

* I am trying out the FACE on the THUMB (instead of the SHELL). I know I want both, and some sort of animation between them that makes sense (like FACE becomes prominent specifically in reaction to a user action, like winning or losing, and SHELL becomes prominent when you detect movement, weapons targeting or something ship-ish?

* I also moved the thumb icons around a bit. Mindless fiddling :-)

* Starmaps imported from your Google Drive are now named "tempStarMap_1" (and if you imported 3 maps in the same play session, they would be _1, _2, _3)

* any starMap whose 'asset id' starts with 'temp' is only stored in memory, and not 'to disk.' So it disappears when you close the app (but you can easily import it again).

* You can start starmap instances on the server with temp maps, and other players will see them, can join you, and will then fetch the map directly from you. So you can quickly iterate your design with an IMPORT/FETCH cycle. And no one with a 'temp' copy should be left with it cluttering their 'drive' and scrolling map lists.

Once you love your temp map, just clone it to give it a real asset id (with your setnum) and then it can be shared normally with persistent copies.

* I added somee simple messaging at the end of the Import from GDrive, so you know it happened (or didn't)

* the new SCRIPT page (accessed via OPTIONS), has a new TAB CONTROL along the top, which lets me view LOG, SOURCE, or ERROR related to the lua scripting. The video shows an example of that.

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
DeranDark
Member
Member # 7969

Rate Member
Icon 1 posted      Profile for DeranDark   Email DeranDark   Send New Private Message       Edit/Delete Post 
Wow. Some nice progress! When can we see RocketClub for android [Wink]
Posts: 28 | Registered: Nov 2007  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
I tried to take the wormhole to your star, but it collapsed in mid-transit. But I left an article on DeranDark's Rocketeer page :-)

I wish android let you capture video of the display like Windows does. I like the Rocket Club newspaper system, and it would be nice to have video even more tightly integrated.

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
So, I was picking my fun project for this weekend, and was drawn to music again when I wanted to be drawn to scripting.

But I was thinking about how the LOOPs are used to create the background structure of the song (and then you play some melody lines on top of that).

Anyway, I thought.. how about some code that acts as a 'timed button masher' if you will, to turn LOOPs on and off in a formal pattern. Like an 8 bar section that repeats, only it has some sort of cut to drum solo in the 7th bar.

So, I ran off and started thinking about that, how I would organize the decision making, etc, when it hit me: Hey, this is exactly the sort of logic that could be done in a lua script!

So, serendipity, my fun project is also a useful infrastructure project!

So, I made only small changes to synSpace itself. A new event message to the script "BEAT" that is invoked once per beat (as set by the beats per minute knob), and a command the other direction LOOP that lets you turn on and off loops, as if the human had tapped the drumpad.

Then I used my Google drive to add some scripting to my stock starmap and saved it as "music of the spheres"

Now, I can import it via gdrive and play it in device, and iteratively improve it.

The new 'script' panel in game (last week) was actually useful in debugging, though still a little frustrating. For example, when I mis-spell a function name ("Log" instead of "log") it doesn't seem to want to say "unknown method" and instead points to a different line (far away) and says "expected parentheses" But at least now I KNOW it does that, so I look for bad function names when I see that :-)

Anyway, so now when I visit that Starmap, it starts insanely blasting away with whatever LOOPs you have loaded. Select a new GROOVE and it switches to using those LOOPs. You can erase and record new LOOPs and it uses them as welll.. It.. never... stops...

So, that took me to the point where I needed to support scripted buttons (that could be used, say, to turn it off!)

And I also needed scripted score panels for CTF anyway, so I made another simple script command DISPLAY that lets you define a couple bits of text on screen, roughly where you want it to appear.

I will presumably make a video tonight, but this isn't really all that exciting visually, and the music is still pretty mindless, though the lua script could be as fancy as you care to make it.

But the point is that it is a SCRIPTED music synthesizer (with space game included) now. THat has to be worth bonus points :-) And I was able to add 'weird extra behaviour' without (in theory) needing a new synspace release to achieve it.

so, here are the important bits from the starmap scripting

code:
function onMsg( from, to, command, argString )
--log( 1, 'received onMsg ' .. command .. "?" .. argString )

-- turn the args into a hash
local args = processArgs( argString )

if ( command == 'LAUNCH' ) then
local shipIndex = 0 + args['ship']
handleLAUNCHMessage( shipIndex )

elseif( command == 'BEAT' ) then
local step = 0 + args['step']
--log( 1, "saw BEAT message step: " .. step )
handleBEATMessage( step )

else
log( 1, "saw unknown message: " .. command .. '?' .. argString )
end

end

. . .

local glLastPhase = -1
local glLastBeat = -1

function handleBEATMessage( step )
if ( step ~= nil ) then
local beat = math.floor( step/4 )
local measure = math.floor( beat/4 )
local phase = (measure % 8)

-- update the beat display
if ( beat ~= glLastBeat ) then
local url = "DISPLAY?id=0&x=20&y=50&title=BEAT&score=" .. beat
game.sendMsg( "", url )
glLastBeat = beat
end

-- OK, if the phase changes, we advance the song
if( phase ~= glLastPhase ) then
if( phase == 0 ) then
log(1, "Starting Song Phase 0 intro or main loop" )
elseif (phase == 7 ) then
log(1, "Starting Song Phase 7 finale or drumroll" )
else
log(1, "Starting Song Phase 1-6 : " .. phase )
end
updateLoops( phase )

-- update the PHASE display
local url = "DISPLAY?id=1&x=80&y=50&title=PHASE&score=" .. phase
game.sendMsg( "", url )
glLastPhase = phase
end
end
end

. . .


-- phase is 0 to 7 and cycles.
-- intro and finale use drumpad top row
-- main uses drumpad middle row
-- drumroll in cycle 7 uses bottom row

-- the phase just changed
function updateLoops( phase )
-- work out list of desired loops to be on right now
-- turn off any previous loops that are not called
-- turn on the ones that are called and not on
if( phase == 7 ) then
-- drum solo tranition connector bridge
stopLoopsInRange( 5, 15 )
startLoop( 1 )
startLoop( 2 )
startLoop( 3 )
startLoop( 4 )
else
-- normal groove
stopLoopsInRange( 1, 5 )
stopLoopsInRange( 11, 15 )
startLoop( 6 )
startLoop( 7 )
startLoop( 8 )
startLoop( 9 )
end
-- add some random spice
if( phase > 3 ) then
startLoop( 11 )
end
if( math.random(100) > 20 ) then
startLoop( 12 )
end
if( math.random(100) > 40 ) then
startLoop( 13 )
end
if( math.random(100) > 60 ) then
startLoop( 14 )
end
if( math.random(100) > 80 ) then
startLoop( 15 )
end
end

Where ideallyt you would have some stochastic tables for which loops to turn on and off, but in my case I just declared certain LOOP numbers I would use for the different phases of the song.

The new bits being:

Creating a simple display

code:
   local url = "DISPLAY?id=1&x=80&y=50&title=PHASE&score=" .. phase
game.sendMsg( "", url )

Turning a loop on/off
code:
    local url = "LOOP?" .. "event=0&loopId=" .. i
game.sendMsg( "", url )

where event has several legal values for on/off whatever.

----

Anyway, it's not Mozart yet, but it.... it just won't shut up!

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
I notice the code evolved after the comments, but I am too lazy to resolve one to match the other :-)

Some musical timing notes. My sequence uses a 16 step sequence. I am currently hard wired to a 4:4 time signature.

This results in their being 4 'beats' in the 16 steps (one beat every 4 steps), and since each beat is 'a quarter note' that means that all sixteen steps togather represent a single whole note, and that each step is the equivalent of a 1/16th note.

Should the time signature change, so would that interpretation.

But the onBeat message is actually sent once per beat exactly (hence only one BEAT message every four steps)

Hence that math at the beginning to work out the beat and measure numbers. Then the phase is just my word for 'one bar' (one whole note in this case) of 'the song' which I then repeat on a pattern of:

AAAAAAAB

And that repeats forever

AAAAAAABAAAAAAABAAAAAAABAAAAAAAB

Where my thought was to add a start and end so as to have

CAAAAAABAAAAAAABAAAAAAABAAAAAAAD

So the starmap would impose that pattern (though no reason why it couldn't handle multiple patterns, share the currently selected pattern numbetr with other players, etc)

If I am trying to show off my work, I would use USEIT to select the groove whose loops I thought worked well with the pattern (and hence others could fetch my groove to hear the same loops I am hearing)

Or we can share each others grooves, and make new ones, while the map keeps the patten going constantly on all our devices :-)

It's kinda hypnotic on me, I admit.

Note that when I say A or B or C or D above, I mean "A = turn off all but loops 1, 2, 3 an 4" (for example). Then whenever a loop is ON, no matter who turned it on, the synthesizer/sequencer emits the notes bound to that loop, in sequence, forever, until the LOOP is turned off.

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
Weekend Progress Video

https://www.youtube.com/watch?v=JuxUCQJRvaE&feature=youtu.be

New messages TO script ('events'):

"BEAT?step=xxxx"

sent once per music beat, provides the step number at the start of that beat.

"OPTION_TAP?cmd=<Your message Id>

sent when the player/moderator taps one of the STARMAP options. The OPTIONS panel is now TABBED with the categories GENERAL, DEBUG, STARMAP

-----

New messages from script to game ('requests')

DISPLAY?id=n&x=25&y=50&title=Blue Score&score=3

this starts a new display with that id (0-9), centered at the proportional screen coords (x,y) (0-100)

eventually I will add more arguments to support other displays, but for CTF I figured I just needed

code:
   TEAM NAME
***
** **
***
** **
***

so the 'title' argument tells me to render some smallish text at the top of the display, and the 'score' argument tells me to add a huge centered (asseumed to be very short) text below.

I was hoping to evolve into a sort of language that described specific things you need s display to do, and then you would just add the arguments for the ones you want to appear, and I magically make it all fit appropriately.

Plus I should let you add an action word that I will send back to you if anyone interacts with the display (though most displays will want to be transparent to interaction, to avoid conflict with the game)

This particular display is inteded just for a score panel (for CTF) but demonstrates how the map lua script creates a display ONCE and then every frame the game renders it to the screen without needing to invoke lua sgsin in the process.

the script only issues commands when it needs to make a display appear, disappear, or change its contents, and it is up to the script designer to avoid wasteful messages.


LOOP?id=n&event=e

this 'taps the drumpad key for you' turning one of your currently selected GROOVE's LOOPs on or off. event 0 is off, 1 is on. Ids are just the 1-15 matching the drumpad labels

Again, this just blindly turns on or off those loops, and if YOUR groove has no loops, there will be no sound.

Likewise, if you select a new groove in the groove browser, the script immediately starts jamming out with THAT groove's loops.

---

If you watch the beat counter (no need for a beat counter, just a demo of the DISPLAY message), you can see it does not beat regularly. There is, I believe, a thread sync issue that prevents the script thread queues from moving data regularly enough, though I haven't tested the theory that it might be "when the script sends a lot of messages, it locks itself up"

Anyway, that, or something else, causes a long delay from the moment I send the BEAT command to the script, before I hear back with LOOP commands, and hence the LOOP commands arrive 'too late' to take effect at the start of the 'measure' And since there is often a strong beat expected at that spot, you really notice it when it is missing the first time around the LOOP.

I already tried scheduling it one step ahead of schedule, but it turns out the delay is more like 10 steps. Which feels sort of impossible, so I am pretty sure this is a solvable problem.

I like how the script is not emitting the sound itself, it is just a monkey assistant hitting the pianon and drumpad buttons on your behalf. You are free to play along or not.

And it feels appropriate for the script to be informed when YOU add your own contributions, so it can be a better playmate and follow your lead, change keys and time signature, etc.

And then the script can sync other amenable players where everyone feels a 'real time connection' between themselves and the script monkey, but the script monkey is constantly being updated by (delayed) performances of other players.

la la la...

Anyway, that was this weekend.

[ 02-26-2016, 03:11 PM: Message edited by: samsyn ]

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
had some lingering work work that delayed SR work, then some inevitable polishing of last week's code before digging in to this weekend's goals.

The Weekend Goal:

* pick one of the maps that is CTF friendly
* add a lua script that automates a CTF game
* some sort of map limiting so I can release these legacy maps over a period of releases ('for free' of course, since these were mostly member-submitted). I just don't want to overwhelm the new player with 50 maps.

Also I need to keep the small number of players focussed on a small number of maps initially.

----

But first I was still bugged by that lag in the step counter in my Music of the Spheres starMap. I was pretty sure I was sending the beat messages regularly, but just had unpredictable inter-thread behaviour. Still, it seemed worse after issuing a bunch of loop commands, so I suspected a simple bug in addition to subtle thread things.

so I added some time stamped logging to see where all the time was going, and was pleased to see it was mostly just delay in handling the request messages from the script, and that was because my architecture was intentionally limiting them to 30 per second, and I was sending 15 messages every beat (and more than one beat a second), so it took several frames before it got to the part of updating the display values. Easy fix for that and now that step counter looks nice and smooth.

Only now it's easy to see I don't have proper control over my absolute step number. I need that to start ar 0 at the beginning of a song, but otherwise be driven by the exact timing of the android audio library (16K samples per second).

Anyway, my auto-song technology needs a step counter that starts at 0. And the way I had it set up last weekend, it was starting somewhere between 0 and 7 depending on the exact moment you hit pLAY/RECORD.

Pretty much the same problem I have had to fix in a couple places already -- clearly a weakness in my head somewhere :-)

But now that messages are being handled promptly, I don't care quite so much :-)

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
Another disturbed weekend, this time by weather. We're getting a second batch of el Nino storms (which is great), but the weather/humidity swings are a bit tiring.. sweat, then freeze, then sweat again... plus our fish, Blue Star, passed away :-(

----

just starting work now. Still have to finish CTF support. It turns out I hadn't finished the architecture after all.

Plus I need to refactor it a little to put the script in charge. It should really be the script that controls whether it is 'capture the flag', or 'stop the meteor', or 'any other mini game that depends on players picking something up in one zone, and dropping it in another'.

and properties like "does it slow you down when you carry it" need to be real map properties, so they can be edited separately for clone variations.

though arguably I don't need that exactly for first release, just a working scripted CTF map.

and a scripted tutorial, which hopefully tells a little story, as you pick something up from one zone, and carry it to another :-)

---
oh, glad I said that. the script needs to be able to add/remove radar markers. So when you are carrying a flag it might add a pointer to your logical destination, but for some games that might be 'home' and for others it might be 'enemy base'
so the script needs to be in control.

maybe instead of another colored line, i use a small square of appropriate color to indicate the location of a base zone. And something for a quest location. Maybe a question mark... that would need to be rare though.

Or even a 'pinging radar.' You fire it like a weapon (pup is consumed), and it blasts out a huge 'ping ring' which is then reflected back to you by every ship / structure in the universe for a brief glowing ping on the compass.

Also exposing your own position to everyone else.

Probably used just before some other weapon that can be launched to a specific location or something.

Almost like a minimap that you have to ask for each time and only lasts a second. a snapMap. well, a snapMiniMap

---
Map needs to be able to define a powerup that exists only on that map.

it might be a new kind of weapon, with actually new behaviour and appearance, or it might be something LIKE a mine, that stays put after you drop it, but is actually a TOWER in the tower defense sense.

And can launch its own attacks on what it perceives to be an enemy,

and this powerup over here, can be dropped, and is then a factory, that makes new pups from a short menu of available ones, delivered straight to your pup bar upon completion.

Such factories would be at risk of destruction/takeover by other players, etc, etc.

Not that I DO do that, just that it ought to be possible to do that.

Maybe also a collaborative mode where the star system has a zillion bad drones in it. Your friends have joined up to hijack eight of those drones,

you are each playing tower defense by dropping defensive tower 'mines' here and there as you see fit,

then wave after wave (N waves to 'pointdown') of bad drones attack, as you defend a planet that conveniently appears out of nowhere for the duration of the 'quest'

like that, if not that.

---
I am addicted to tower defense though, so this is inevitable, and multiplayer tower defense is intriguing... (pure collaboration, other than betrayal), I am much more motivated to do a tower defense map than a capture the flag map :-) But my API still needs so many things that CTF still deserves to go first.

---
So, weekend goal: complete scripted CTF map, whether it is 'fun' or not, it should accurately keep score and declare a winner. Team size variations for bonus points.

Not sure if I mentioned this, but android synSpace has one more team mode, so in total that is: (groupings are implied by strategic gaps between the thumbs).

* no teams, death match, everyone for themselves (your weapons hurt everyone else)

* 1 team, collaborative, everyone working together against a common enemy or problem

* 2 teams, 4 players each, left thumbs vs right thumbs (map gets to pick team names)

* 4 teams, 2 players each, NW, NE, SW, SE 'islands of thumbs'

* 8 teams is probably the same as 0, but COULD be used in some group tournament sessions (if ever needed) where in this session, the 8 thumbs must represent 8 different 'guilds' and the results of the session can end up in Google PLay somewhere.

But finish CTF support first

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
Here's a neat race course map VoltE6 made back in the day (go, megavolt!)

 -

Made for Windows synSpace, but still works in android synSpace.

It has these really cool black stars creating a very tight gauntlet to get through.

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
Whew, lots of customer support for work this week, didn't make any progress at all on work projects.

Also little progress in synSpace for the last couple of weeks. I did ultimately implement the SEND command, which is how a lua script talks to copies of itself running on other devices.

For example, in capture the flag, the moderator's copy of the script periodically SENDs the game state (playMode, scores) when it changes.

the non-moderator's receive that SEND as in incoming message via their onMsg(SEND) handler.

non-moderators just obey what the moderator says (so he's the guy to hack, but please don't).

All API keywords are subject to change. And while all communications really are through that 'game' object, I think it will simplify most people's lives if I just preload some accessor routines so you can just invoke them and not have to actually have them in your script.

So, I think you would never directly call:

code:
  game.sendMsg( "", "LOG?msg=This is a message for the log)

Instead, I just give you a function like

code:
  function log( text )
game.sendMsg( "", "LOG?msg=" .. text)
end

So you get to just say

code:
   log( "This is a message for the log" )

Easier for you, plus I can change the api itself without you having to rewrite anything. maybe :-)

And those functions would all be pre-loaded for you, so you would not see them in your script, which can then focus just on the actual things you're trying to achieve.

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
Not really a weekend update, since Ben (my son) visited and we mainly just had fun. But I did re-shoot a demo of sharing a groove with another player, since the original demo was so flawed, and the interface has changed.

https://www.youtube.com/watch?v=cALmw2ZKRKk&feature=youtu.be

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
Mikeanike
Healthy Member
Member # 338

Member Rated:
4
Icon 1 posted      Profile for Mikeanike   Author's Homepage   Email Mikeanike   Send New Private Message       Edit/Delete Post 
And subscribed.

--------------------
Pig's are a gift to man respect them!

Posts: 271 | From: Gresham, Oregon USA | Registered: Jun 2000  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
So far this weekend, I have been uploading antique videos, just to get them out of the way. Hopefully there is enough footage there to pull together an actual commercial, so to speak.

But my big achievement this morning was adding PERCUSSION to the synthesizer. I was having a lot of trouble synthesizing percussion, so I just went the way people go these days and added pre-recorded samples for the standard General Midi percussion instruments.

https://www.youtube.com/watch?v=d7UoU8q_z9Y

the above video is an example of a two year old with a fancy drum kit :-)

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
zim zim
Veteran Member
Member # 1233

Member Rated:
4
Icon 1 posted      Profile for zim zim   Author's Homepage   Email zim zim   Send New Private Message       Edit/Delete Post 
Ya I seen you went video happy with posting on YouTube.

--------------------
I'll be around here until the plug gets pulled.
http://flashzz.webs.com/

Posts: 550 | From: USA-WI | Registered: Aug 2001  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
One oddity of playing pre-recorded sounds for percussion is that the sound goes through a pretty different path from the other music. Both paths have some delays, and the result is an uneven beat.

I can't decide if that's a defect or a feature. It still keeps better time than I can myself, and possibly seems less robotic with the variation.

I have a growing respect for drummers. I thought it was just about your lightning skills in hitting things, but really it's the quick thinking about what to hit next that makes all the difference.

But it does feel odd coming from a computer, where one expects precise repetition :-)

But don't blame the computer for my naive placement of stresses. I have to learn to just stress the first beat of each measure and save the fancy stuff for later. Less is more.

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
Weekend Update

So far, mainly just polishing the SOCIAL key

https://www.youtube.com/watch?v=ZiuftB8eEFU

you can now enable the social keyboards individually, so the SOCIAL key only toggles between the ones you actually care about.

for TEXT, I improved my bleep filter (turns a short list of vulgar words into the word 'bleep'), and now track your bleepage and assign you (automatically) a language rating, which is shared with other players (next to your name on the Pilot Info panel)

You then have an option to say "I only want to see text from players rated PG13 or lower" (for example), and it auto-mutes anyone measured as being raunchier than that.

Of course, the language rating is not a reliable measure of a person's saltiness, it's just a feedback feature to discourage saltiness :-)

I also added a simple spam filter, though you would be advised to just MUTE any player who insists on spamming.

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
Heh, another groove: New Thanks

https://www.youtube.com/watch?v=Ke9nvL2JH0A&feature=youtu.be

Even if the final result is not spectacular, it's pretty fun making these, and very low effort

---

Unlike the work of Michael New, whose music theory/composition videos are opening my eyes to the truth!

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
saxamophone0
Obsessive Member
Member # 2917

Member Rated:
4
Icon 1 posted      Profile for saxamophone0   Author's Homepage   Email saxamophone0   Send New Private Message       Edit/Delete Post 
Typo in the title "synSoace"

So there's absolutely something here in the music generation. I could see it being a core element to this game. Would you ever export it as a standalone app? It's reminiscent of music from (early) Japanther, or Prefuse 73. I'm just saying i'm sure the niche interest is there, inside and out of synSpace.

--------------------
Word is born.

Posts: 8539 | From: NYC | Registered: Oct 2002  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
thanks for the typo discovery :-)

I think you could argue for all the editable collectible types to have standalone apps, and they should intercommunicate with intents. So when synSpace wants to let you edit a FACE, it invokes the separate ($4.99) FACE editor app, which works with Drone Runnera ($4.99) and Rune Runners (4.99) and the GROOVE editor ($4.99), etc.

But I know you meant it more in the sense of "maybe you could cut out all the other bits of the game, so people could focus on the music". And yeah, that would be my port of 'synJam" then :-)

But for now SynSpace includes a free copy of SynJam!

------

I might have had a breakthrough on my 'app going to sleep' woes, especially on the Nexus 6P where it was impossible to wake the app back up, after a power/lock.

It hasn't happened again since, knock on wood. Plus I can 'shrink to icon and then come back to life using the android SQUARE button' and pretty much be working again (not frozen with a black display). So in theory, I can recover from a phone call, sort of. But not in the seamless way you might think you'd like. More of a 'ah heck, just start the game again and ask for the same server instance, if it is available'

As opposed to the server letting you reconnect directly to the slot you had before and magically recover all map state and continue without interruption.

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
Bah. my re-threadomg to achieve 'retyurn from phone call' seems to have somehow broken the vocoder. Plus I am having a bad eye day

I did make some progress this weekend, especially on trimming the list of remaining things before beta test.

* I added a GIVE command to the API so the script can give powerups to the local ship. I will also yse that for things like recharging your energy or refilling your weapons when you 'do something the script approves of'

* The game no longer gives you 10 homing misslles at start, for all maps. You get nada. But the individual MAPS can give you stuff, and the stock map 0 gives you some mines and defensive stuff. And the stuff that comes from script is properly placed on the powerup trigger bar

* pruned more assets (sounds and images) that I wasn't actually using (keep the download small)

* fixed some starmap sorting issues

* added a glissando option. no reason

* I added starmap version tracking, so you see a little glyph next to people whose copy of the starmap differs from yours (SHOULD be impossible, but it's good to check)

But mostly my time went into work work and a failed attempt at debugging the vocoder, which is still broken (I think I must be throwing an exception inside the high priority audio thread, but I haven't found any evidence other than the thread stops being called) Anyway, not what I want to work on at the moment, so it's just going to stay broken for a bit.

But hey, other than a large number of planned API commands and their testing, my MUST DO list is down to only 25 action items :-)

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
Well, I found the problem in the vocoder, though not exactly why it just started happening. It's semi interesting (to me), so I will blabber on about it.

Fundamentally, everything you hear (musically) from the game goes through the AudioPlayer system in android out to the speakers. In my case, it's just a bunch of 16 bit samples.

However, internally, to generate those 16 bit samples, I do a lot of double precision math, then at the last second, I 'cast' to just an integer, and send to the player.

one of the things that happens in double math is the reverb unit, where samples are fed into a delay line with multiple time varying tap points that can be mixed together for the reverb (multiple echoes from different distances)


the interesting thing there is that things all go through the reverb buffer, and there are several multiplications (weighting factors) along the way.

The thing about doubles is that in addition to just storing 'floating point numbers' they can also have values which mean specific things like 'I can't exactly express this, but basically I contain positive infinity'

And one such special value is NaN (not a number)

Sometime recently, I picked up a computation somewhere that generated a NaN (maybe a divide by zero? or possibly a scary thread issue?). One bad value would not be a big deal except that NaN is a virus. If you multiply a nice number by NaN, you get NaN. Same for add, etc.

So a single NaN making it to the reverb system quickly progagates until the entire system is Nan. It's still doing all the math as normal, but the samples are being contaminated by 'lingering NaNs' from the reverb buffer.

Turn reverb off, and it goes away (turn it back on and it is still OK since I also clear the buffer to zeroes at that point)

Anyway, NaN is a virus, pass it along!

----

My friend Jon also points out that there is a performance problem in many FPUs (mobile in particular) that if you use 'small, denormalized values' you can suddenly take a 10x hit in CPU when doing math with those values.

For example, in decimal floating point, 5E1, 0.5E2 and 50E-1 are all '5' since if we control the mantissa, we can use various exponents to get the same result.

we could say that 0.5E2 was our 'normalized' form (starting with 0. and then a non-zero digit.

Continuing in decimal, let's say your system limited the exponent to -100, so maybe the smallest non-zero number we can express is: 0.1 E-100

But that's the smallest NORMALIZED number. If we go DENORMAL, we can get even smaller values

0.000000001E-100

So still -100 in the exponent, but we use our mantissa in a non-normalized form to get in some extra zeroes. Of course, since we have a limited number of digits in out mantissa, we burn precision at the other end as less of the mantissa is available for 'real' values.

Which is why we normalize in the first place, so the mantissa is filled with juicy precision we hope to pass along to the results of our computations.

Anyway, I gather the issue is that FPUs are very fast when dealing with normalized values. Like one clock cycle to do bunches of these in parallel fast. And we are addicted to that speed.

When one of these denorms comes along, we have to choke our pipeline and run special microcode to deal with it. Still probably super fast, but 10x slower than normal.

anyway, this turns out to be an easy situation to get into in signal processing, so the work around is something like this. Assume you are processing an array of samples that are all denorm small non-zero values that you have to do lots of math against.. ok, even I am bored now :-) But the suggested trick is to alternately add and subtract a very small value, 1E-15 for example, is nice when working with doubles. The idea being that since it alternates it doesn't add a DC bias to your sample stream, and the noise it adds is so much less than what you've already got that it doesn't hurt you. Of course, it's noise at nyquist, which can't be good. But it's certainly imperceptibly small, one hopes.

But as I type that, I know I don't really grok the situation, since if addition was slow... you know what, I bet addition is NOT slow since it compares the exponents first and any real value is so far above these denorms that its going to win and the denorm won't even be added (being past the end of the larger values mantissa), so yeah, I guess this should work to avoid multiplying by denorms, which is where the danger is. Well, I think I learned something after all!

------

I was surprisingly productive yesterday (unlike today so far) and only added a handful of tasks to my lists :-)

I also tweaked the IMPORT FROM GDRIVE code, to be a little mode hand-holdy. Now, after the import succeeds, in addition to putting up a legible on-screen message, it also adds something useful to the Script Log and even auto-opens the script Log screen so you can confirm it did what you hoped it would do.

Found a bug, fixed it, and verified I could clone an imported map to make a new 'publishable' map.

Fixed that thing where I would let you launch on a map you hadn't loaded yet. So now, if you enter an instance where people are playing a map you don't have (which the server warned you about before hand, but this is how you get new maps):

* You see their 'thumbs' (decorated with hats)
* You see an overview of the starmap
* But it says 'unknown' and such
* if you click on a free Thumb, you get an error

If there is actually no one else in the instance, then this is all you will see. But as soon as someone else has launched into the map (proving they own a copy), you will automatically ask them for a copy. Once you fetch it, the Thumbs unlock and you can claim your channel and launch your drone.

Of course, normally you would only enter when it was non-empty, so your wait should be brief.

In addition to the starmaps having unique asset ids that guarantee that two players with the same asset id have the exact same map, I also added a CRC check so you can see on player's Thumbs if they are using a different version of the map than you are

Which, cool-ly enough, is true when you are in limbo waiting for a copy of the new starmap to arrive. And then resolves when you get it. And everyone just naturally knows the progress.

Plus I made a kickass sound effect for the background file transfers.

By 'file' I really mean 'string' though as strings go, starmaps can be pretty long.

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
I think I get to do NPCs next. I'm looking forward to that. I want to stay as close to possible to the NPCs being independent critters with their own behaviours, once released to the world.

But obviously they are there to meet the needs of the starmap, so occasionally they will be dumb immobile things that only move when the map moves them, and have no real mind of their own.

And I am going to try and use the word SCENE when I mean "one of several extended series of triggered events than can be running simultaneously on the same starmap, where each scene is hostrd by exactly one of the players (the one who 'tagged' the scene).. This is the WoS model, with refinements.

Unlike WoS, there is no separation of map and scene, visually. You are always on the map, and everyone could watch you if they were nearby.

Again, in WoS terms, a QUEST is made out of one or more SCENEs, and I would like to preserve that architecture. Since most quests/adventures are likely to be single-scene, I imagine I will play fast and loose as I have so far, but I hope I speak accurately, as consistent use of terms improves the subsequent design, I think :-)

Also, the SCENE and QUEST level concepts exist pretty much entirely within the starmap lua script, with the game itself only aware of the primitive API commands available to the SCENE. (give the player somthing, take something away, notice when the player dies or kills something, etc.

Which means we still need a nice template for scenes in lua. In WOS, I made my own language (QUEST) and it had its own state machine, which I could trigger in small doses (after which it returned control to the game). In lua, once I hand it control, it could go into an infinite loop if it wanted to. The game overall would not mind (separate threads), except that until it returned from handling that message from the game, no new messages could be handled, so the scene would just be wasting time.

So, in lua, I need tobe able to apply individual messages to potentially lots of scenes in the starmap. Like, say a player is destroyed, it might have to look something like this

code:
function onPlayerDestroyed( shipIndex )
for i=1, numScenes do
maybeApplyToScene( i, PLAYER_DESTROYED, shipIndex )
end
end

Where there was probably a lua table somewhere with an array of scene descriptions as a series of steps. So inside of fully powerful unstructures lua, you have these tables that act a lot like the old QUEST programs

maybe something like:

code:
function stepScene( sceneIndex )
currentCommand = sceneCommands(sceneIndex, sceneProgramCounter)
if( doCommand( currentCommand ) ) then
sceneProgramCounter += 1
end
end

so the commands in the scene's table would be big picture actions you expect to take place sequentially, like

ANNOUNCE "Get ready for the fight of your lif!"
WAIT 10
MOVESHIP x,y,z
WAIT 1
ANNOUNCE "GO!"
SPAWNNPC "Pirate Jack", x,y,x, aiModeInsane

yeah, then add the equivalent of labels on some lines and use the labels as the handler entry points for events (for that scene).

Messages have to be checked if they came from the scene host, and some actions must be cleared with the scene host first. And it is the MODERATOR who assigns the scene hosts.

---

Obviously each starmap can solve this problem individually, but for my own work, I am hoping I get to an architecture which makes it easy to add a scene to an existing starmap with minimal impact on the other scenes. I.e. the tutorial "how to steer' scene should be completely separate from the tutorial 'how to shoot' scene, other than something that enables them in order and forces the newbie to experience them.

So,

* a lua table of 'all scenes in this starmap'
* a QUEST-like framework for executing a series of timed actions (for cut scenes, if you will)
* individual actions are actually carried out by arbitrarily complicated lua code (for example, QUEST could not add two numbers together, and now you have a full expression parser)
* WoS QUEST limits you to a fairly restricted data set, while lua gives up all the data power you might like. You want an array of arrays of hashes of arrays? Go for it!

And while multiplayer is the life and blood of synSpace, I guess I should think about solo mode, if only for the case where a starmap is more of a solo experience (why not?)

Also, while I plan for this game to be only moderately successful, there is always the chance it will accidentally be popular and then I have to worry about server meltdowns, in which case it will be good to have had some amount of solo mode.

Maybe it could even be engigmatic, hiding from you the reality of being truly alone vs just not having access to the server. And then maybe it tries repeatedlt to connect (without drawing your attention to it) and then seemlessly is multiplayer, but from YOUR perspective, the other guyes just entered YOUR server, when really you just entered THEIRs... OK, maybe that's stupid, but I think it's possible for solo mode to be fun now (with scripts, I mean)

Anyway, I hope it will be a fun weekend. Though today I have to figure out how to pay taxes since my tax lady punted me to filing an extension (which I admit I am not completely happy about, since paying someone to do your taxes is not exactly cheap and you might hope they wouldn't put you in this position, without at least giving you a discount...)

Anyway, I have to start by printing a PDF, and I HATE PDFs....

end of lunch whining.

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
Okie Dokie, I have achieved 'SCENEs'. as in a single starmap can have multipl scenes, which are pretty easily defined individually, and can run simultaneously with any mix of players and scenes being active,

Mainbly thanks to lua treating code like data, so I can have a simple looking lua 'table' which acts a lot like an 'object' and then one of those per 'scene'

I re-implemented the capture the flag game as a SCENE and it only uses about 25 percent as many lines of lua code. Plus I think it's easier to read this way.

I also started another topic where I plan to put the final API specs, without the rambling real time decision making and mind-changing :-)

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
Just to post for posting's sake, here is what I ended up with for my simple capture the flag game re-implemented as a SCENE

This is a lua TABLE, a data object, but in lua, data is allowed to include functions private to that data (akin to 'an object')

One table per scene, so there is only a single data object to mess with for one scene, in theory.

Multiple scenes (if you like) per StarMap, each would have its own table.

It's possible that some of the 'private member functions' below could be refactored to be of general use, thus making the table even smaller

The cool part is that every scene can opt to have its very own notification from any game event/message.

code:
sceneCTF = {
-- data local to this scene
name = "CTF", -- each scene needs a unique tag to receive peer messages
state = 0,
hostSerNum = 0, -- playerSernum that is hosting this scene
scores = { 0, 0 },
teamNames = { "WEST", "EAST" },
scoreNeededToWin = 2,
checkForWinnerInThisManyBeats = 0,

-- service functions
initState = function( scene )
log( 1, "initState in sceneCTF was called" )
scene.state = 0
scene.resetScores( scene )
scene.updateDisplays( scene )
end,

resetScores = function( scene )
scene.scores[1] = 0
scene.scores[2] = 0
end,

updateDisplays = function( scene )
if ( scene.state == 0 ) then
-- no game in progres
displayOff( 0 )
displayOff( 1 )
displayOff( 2 )
option(0, 1, "uSTART_CTF", "Start Capture the Flag Match" )
else
-- game in progress or over but not reset
display(0, 15, 10, scene.teamNames[1], scene.scores[1] )
display(1, 85, 10, scene.teamNames[2], scene.scores[2] )
option(0, 1, "uSTOP_CTF", "Stop Capture the Flag Match" )
if (scene.state == 2 ) then
display(2, 50, 30, "(Check OPTIONS for starmap options)", "GAME OVER" )
else
displayOff( 2 )
end
end
end,

awardPointsToTeam = function( scene, teamIndex, numPoints )
scene.scores[ teamIndex ] = scene.scores[ teamIndex ] + numPoints
announce( "Team " .. scene.teamNames[ teamIndex ] .. " Scores!" )
soundId = 1072
playsound( soundId )
scene.updateDisplays( scene )
scene.checkForWinnerInThisManyBeats = 3
end,

startNewStateWithAnnouncement = function( scene, newState, soundId, msg )
announce( msg )
playsound( soundId )
scene.state = newState
scene.updateDisplays( scene )
end,

checkForWinner = function( scene )
leftCompleted = (scene.scores[1] >= scene.scoreNeededToWin)
rightCompleted = (scene.scores[2] >= scene.scoreNeededToWin)
soundId = 1065 -- any game sound id, includes percussion

if (leftCompleted and rightCompleted ) then -- a tie
scene.startNewStateWithAnnouncement( scene, 2, soundId,
"GAME OVER: Your team fought to a draw in the final beat!")
elseif (leftCompleted) then -- left won
scene.startNewStateWithAnnouncement( scene, 2, soundId,
"GAME OVER: ".. scene.teamNames[1] .." Defeats ".. scene.teamNames[2] .. "!")
elseif (rightCompleted) then -- right won
scene.startNewStateWithAnnouncement( scene, 2, soundId,
"GAME OVER: ".. scene.teamNames[2] .." Defeats ".. scene.teamNames[1] .. "!")
else
-- game not over yet
end
end,

-- if we are the scene host, we periodically send status updates
-- for this scene. state and scores in this case. These updates
-- are only of interest to our peer scenes, so we need a sceneId

lastSentState = 0,
lastSentScore1 = 0,
lastSentScore2 = 0,

maybeSendSceneStateUpdate = function( scene )
if ( iAmSceneHost( scene ) ) then
if ( scene.lastSentState ~= scene.state
or scene.lastSentScore1 ~= scene.scores[1]
or scene.lastSentScore2 ~= scene.scores[2] )
then
scene.lastSentState = scene.state
scene.lastSentScore1 = scene.scores[1]
scene.lastSentScore2 = scene.scores[2]
sendToScene( "sceneName=".. scene.name
.. "&state=" .. scene.state
.. "&score1=" .. scene.scores[1]
.. "&score2=" .. scene.scores[2]
)
end
end
end,

-- this is only called on the moderator's device's script
-- it means the flag (249/250 for example) was dropped
-- by ship (1-8) into zone (-1 or zone index)

-- zone 0 goal zone for even team, and home of even flag - 250
-- zone 1 goal zone for odd team, and home of odd flag - 249

handleFLAGMessage = function( scene, ship, flag, zone )
if( zone >= 0 and zone < 100 ) then
log(1, "Ship " .. ship .. " dropped flag " .. flag .. " in zone " .. zone )

if ( scene.state == 1 ) then
-- we only earn points when game is in progress
local shipTeam = ((ship-1) % 2)
local flagTeam = (flag % 2)
if ( shipTeam ~= flagTeam ) then
-- and only when dropped in enemy zone
scene.awardPointsToTeam( scene, shipTeam + 1, 1 )
else
log(1,"Flag ".. flag.. " returned to home zone " .. zone .. " by ship " .. ship)
end
else
-- state is not 1, so we are not playing right now
log(1,"Flag ".. flag.. " dropped in zone " .. zone .. " by ship " .. ship)
end
else
-- flag was dropped outside of any zone
log(1, "Ship " .. ship .. " dropped flag " .. flag .. " in no zone " )
end

-- in all cases, we need the flag to come back
if( flag > 200 ) then
resetPup( flag, 5 ) -- respawn it soon
end

end,


-- optional message handlers
handler = {
['LAUNCH'] = function( scene, args )
log( 1, "LAUNCH handler in sceneCTF was called" )
scene.initState( scene )
end,

['BEAT'] = function( scene, args )
--log( 1, "BEAT handler in sceneCTF was called" )
if( scene.checkForWinnerInThisManyBeats > 0 ) then
scene.checkForWinnerInThisManyBeats = scene.checkForWinnerInThisManyBeats - 1
if( scene.checkForWinnerInThisManyBeats <= 0 ) then
scene.checkForWinner( scene )
end
end
scene.maybeSendSceneStateUpdate( scene )
end,

['FLAG'] = function( scene, args )
log( 1, "FLAG handler in sceneCTF was called" )
local ship = 1 + args['ship'] -- lua ship indices are 1-8
local flag = 0 + args['flag']
local zone = 0 + args['zone']
log( 1, "saw FLAG message. Ship " .. ship .. " dropped flag " .. flag .. " in zone " .. zone )
scene.handleFLAGMessage( scene, ship, flag, zone )
end,

['SEND'] = function( scene, args )
log( 1, "SEND handler in sceneCTF was called" )
if ( scene.name == args['sceneName'] ) then
-- it is a message for this very scene!
-- and the only message we send is the state update
scene.state = args['state']
scene.scores[1] = args['score1']
scene.scores[2] = args['score2']
scene.updateDisplays( scene )
log( 1, "SEND handler in sceneCTF received scene state " .. scene.state )
end
end,

['uSTART_CTF'] = function( scene, args )
log( 1, "uSTART_CTF handler in sceneCTF was called" )
if( scene.state == 0 ) then
scene.state = 1 -- start game
scene.resetScores( scene )
scene.updateDisplays( scene )
end
end,

['uSTOP_CTF'] = function( scene, args )
log( 1, "uSTOP_CTF handler in sceneCTF was called" )
scene.initState( scene )
end,
},
}



--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
"checking for winner in n beats"

this is an example of an attempt to do a simple animation. In this case, after one side earns a point, you could IMMEDIATELY check if that was the point required and then announce game over.

Instead, I update the score board, and set this odd variable to a small number

then in the onBEAT handler, if that number is nonzero, I decrement it, and when it reaches zero, THEN I check for game over conditions.

This just gives me a '3 beat' delay after the score increments, before I display GAME OVER. I like that it is 'in beats' and not 'seconds' though I am sure to rue that decision.

This sort of ad hoc animation is probably what I will do in the short term, and perhaps from that be inspired to make a useful API for it.

that API has to also be friendly to Rune Runner with skeletal animations, and inter-character dialog replays.

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
I admit that until it became of supreme utility for SCENEs, I was always a little nervous about the lua 'code is data' deal. I can't say why, but hacking comes to mind. Like an SQLInjection attack, sort of. But there is nothing worth hacking in this environment (I hope) since android has already sandboxed us, (and then lua is further restricted to memory variables only).

ANYWAY, I refuse to worry about that. synSpace starmaps are Open Source, and every copy of the game includes a viewer, so if you suspect someone of doing something naughty (like swamping the server, which WILL be a problem).. well, then you can suspect it.

Probably will have to cave to some sort of banishment model eventually. That always happens. Just have to make it sensible, venge-less, and non-confrontational. No spiking the ball: "take, THAT muthahacker, u got pwned!" as everyone must be able to walk away with their dignity intact. But all of us should loosen up on the dignity thing, anyway.

---

But in case you are timid, like me, the syntax is super friendly

code:
-- AS A FUNCTION

function foo( arg )
doSomethingUseful( arg )
end

-- AS DATA

foo = function( arg )
doSomethingUseful( arg
end

--- usage is identical

result = foo( input )

And I believe internally they are truly identical, with the 'function' syntax just being 'syntactic sugar' to make normal looking functions, and the 'as data' format is the more correct expression of what is going on.

But my point is you just swap where 'function' goes, and you're set. No complicated lambda function you're never sure about.

And then, it is no big step to have an array/hash/table, that you can preinitialize

code:
myTable = {
age = 31, -- comma separated, don't forget
height = 76,
rebate = 0,

-- function as data
calculateRebate = function( this )
this.rebate = this.age * this.height
end, -- still need a comma, we're just data
}

So that is a simple TABLE of four elements, with the names 'age' 'weight' 'rebate' and 'calculateRebate' with that last one being a function.

You can access those like this

code:
  myAge = myTable['age']  -- look up by name

or invoke its functions like
code:
  myTable['calculateRebate']( myTable )

Note I include 'myTable' as the 'this' argument I pass to the function. The table itself has no concept of 'this' but is happy to work with a table reference, even back to itself.

I think this also works
code:
  myTable.calculateRebate( myTable )

And I chose to store the result back to the table in this case. I could also have returned it directly from the function.

So, after that table is composed, it becomes a nice contained little blob of data (all the data and ONLY the data of a single scene, so you don't have to work hard to avoid cross contamination)

You do have to remember to include an init functino to reset your scene's table if it modifies data over the life of the scene (it should). So at the end of the scene, when the corpse finally vanishes, you call init and the scene goes back into sleep mode, waiting for its trigger to re-awake.

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
I feel I should point out that more robust code would protect itself from expressing NIL pointers ( 'nil' in lua, is much like 'null' in other languages)

But for starmaps, I declare that's just a code bug, and so why gloss over it. Let the map crash! Let the villagers rise up in arms and fix the bug!

I think that's a valid tradeoff, given that we want an individual starmap to have a realistic amount of code in it. I don't know what that is, but I would be surprised if it exceeded 1000 lines.

I have some arbitrary limit in the file xfer system (mainly to dissuade people from using the game as some sort of dark net file sharing service), and nothing is encrypted, so no bad guys need to be thinking of hiding their illegal activities in game.

Assume your mother is listening at all times. I have her cell number.

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
I started my first NPC map last night. Nothing to report yet, but I am excited on the inside. Also did some experiments with grid animation, in case I want to make a sort of 'gravity wave' animation to go along with some really large weapon.

My secret plan is for the synSpace renderer to accomodate multiple vehicle modes (drone space ship, in space. Little sailboat, on ocean. Little tank, in battlezone, etc. And the ability to render 'the grid' as a fractal landscape is always high on my list of fun things to do. So long as I remember that synSpace is 2D at its core (where Rune Runner is 3D).

But I could totally do a fractal landscape grid, give wide friction so motion was damped (more like walking around where you just stop when you turn off your engines) let you either walk on it, or fly over it, with towers shooting at you, for example.

Also, I added a new game mechanic which is for 'area control' goals. the grid itself is only 32x32 with 1024 cross points. I'm going to let (some maps) drop persistent (qwll, long-lived) ovhects on the grid points, but only onw per point, so you 'claim' that point for your team.

Then probably some rules like "if your point touches 3 enemy points, it is converted to an enemy point, to make it a little GO-like. or LIFE-like and you can play until one side controls 75% of the map

and an RTS map would probably limite 'factories' or 'factory output nodes' to this same set of points (limiting the placement of factoriw to an area near 'your base' or another node you control

GOAL: first release contains a handful of maps, based on antique synSpace maps, but with prototype scripts for different styles of play

code:
TUT    tutorial
DM Deathmatch free for all
CTF Capture the Flag (variable teams)
RACE Fastest around the course
(with speed boost pups, etc)
NPC Mobs and a Boss



[ 05-01-2016, 06:31 PM: Message edited by: samsyn ]

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
Oh, my pal Jon reminded me about lua coroutines (very lightweight 'thread's) and it turns out they work in synSpace just fine.

So this allows me to now write my cutscenes in an entirely natural format, like

code:
function cutScene3()
groove( fanFare )
wait( 2 )
announce( "Check your Radars, pilots, incoming hostile!")
pirateJack = spawn( "Pirate Jack", shellX, XYZ)
wait 3
pirateJack.goal = "kill dan"
pirateJack.trashTalk = 100

end

which is then started by a normal message handler, and then runs in the background until it finishes

Then, much like the concept of every Scene being defined by a lua Table, each character on the map is defined by a lua table. And one of the things an npc can have in its table is a persistent brain co-routine.

So, for as long as that NPC is 'alive' it has an easy-to-read/write algorthm running in the background which controls its behaviour. So even if your map had no scenes at all, you could still have NPCs that spawned (well, OK, I guess You sort of need a scene to trigger the spawning, unless he auto-spawns on map load, which he totally could.

ANYWAY this character COULD just sit there between scene action, OR it can totally just live out its own little AI until some scene needs it. Like some mob that wanders around being mobbish, until some scene (who knows about the mob becajse of that list of npc tables) calls out to the mob by poking values into its table. "come help me" "attack dan some more" etc. You can assign a Thumb (special non-player colors) and put up a synthetic player bio, including the NPC's favorite GROOVE and win/loss stats.

For example a structure like this for a standard mob brain (not actual lua code, just illuminatging example). this function has the illusion of running continuously from the moment the bot is born until it's corpse has vanished. In fact, the code is peppered with 'yields' which pause execution (to let everything else happen) before resuming later to pick up at that same spot without the source code needing to worry about it. So you can just write like you own the machine.

code:
function botBrain( bot, args )
-- birth
id = init( bot, args ) -- have game spawn me
startThumb( id, bot.fakePilotInfo )
-- life
while alive( bot ) do
goal = maybePickNewGoal( bot )
switch( goal )
0: I am asleep until sometjomg kicks me into state 1
1: I am actively pursuing my attackers
2: I am running away, seeking recharge
3: I am collecting some resource
tactic = maybePickNewTactic()
pursueCurrentTactic( tactic )
maybeTrashTalkInTextChat()
coroutine.yield( co )
end
-- we just died, I guess
emitLoot()
changeToCorpse()
wait( 30 )
removeLoot()
-- release (available to do it again)
despawn( id ) -- game removes me from lists
end

You just have to be sure that any infinite or timed loops in your lazy code, include a coroutine.yield() in the loop. In the example above, that would be the wait(30) as in the main brain whileAlive loop

Then in the onBeat handler, you have to step over all pending coroutines and invoke .resume() on them as needed to advance to the next yield(). Much easier than it sounds.

This limits your pause precision to the beat handler rate, and also limits your bot decision making to a similar rate. So any decision the bot makes has to be held for at least one beat, basically, before it can change its mind and try something else.

But this is a wonderful day so far, and maybe I'm finally to the point where content creation is not very tedious...

---

Not sure if I mentioned it, but I have penciled in DropBox as another way to import starmap files (in addition to the google drive I have now). Unlike google drive, I think I can export back up to dropbox, and dropbox CLAIMS to work on kindle (no evidence of that yet)

Also, I'm still not completely happy linking to Google Play services. I'm sure they slow down my launch considerably. I mean, I will need GPS if I ever want to do inApp purchases, but until then it's not something I want to embrace too tightly.

But hey, screenplay format, full lua, non-blocking cut scenes, and persistent autonomous bot brains. A good weekend, indeed!

Now I just have to finish the coding to actually render the npc. Oh no, Pirate Jack is apparently a vicious looking red circle, permanently fixed in space at (0,0), and apparently unconscious! Have to start somewhere :-)

just flesh out the skeleton.

[ 05-01-2016, 08:38 PM: Message edited by: samsyn ]

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
OK,

I extended my moment of brilliance about SCENES to also apply to BOTs, so now a bot can register a handler for specific game messages it would like to receive directly.

So now I can have fully autonomous bots, with or without a related scene. Just makes it easier for me to type a few lines and have a new critter magically appear on the map.

In this case, the bots are full 'nemesis' level, which means that in addition to appearing in game as little ships, they also can be assigned to THUMBs and even have 'virtual profiles' and can use text chat, so they can look like other human players (though I use the normal 'gear' icon as the HAT for all bots)

So the bot brain (lua coroutine) manages the individual bot's personality, which controls its goals, tactics, and moment by moment actions. These actions then cause change in the wprld (destruction, mostly) which are reported to a scene, which may not have any direct connection at all to the bots, but just reacts to their activities indirectly.

Anyway, very flexible and not too hard to type. Also not done, and likely to change a lot

Made some new sound effects and finished the plumbing so a weapon definition can define the SFX used by that weapon (one step towards map-defined weapons, in addition to map-defined powerups in general). I reallu like my sound for 'launch mine' Has sort of a submarine PING hint that sounds mine-ish :-)

Half my sfx are me talking in a squeaky voice, and the other half are from the games synthesizer. Which gives me the ability to deliver on my dream of the sound effects all being 'in key' relative to one another, and in tune with the western scale in general. WHich sort of takes me back to WarParh classic where I used MIDI notes for most of the sound effects.

I decided the 'fizzle' sound for smart weapons would be a sort of r2d2 chatter that sounds disappointed.

The main bullets need to go "pew pew pew" but I foud I could not play the sound effect fast enough reliably, so I changed the sfx to have two pews "pew pew" so I can play it half as oftern with the same cadence, so long as you don't mind not being able to play a single shot. (which I COULD still do if it was too irritating).

Also found a huge bug that wasn't propagating bullets properly.

Happy Mother's Day tomorrow to all you muthas!

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
Had a pretty good series of weekends and made a lot of progress on the lua support for bots and scenes. I go on about it at great length in a long video I am uploading now to

https://www.youtube.com/user/Samsyn2/videos

But the cool one is this one:

https://www.youtube.com/watch?v=aBBzN_b3HdU

That's four bots that really hate me.

Here is an earlier version before they could move, but they still hate me. But for example, your starmap might use something like this for stationary defensive towers:

https://www.youtube.com/watch?v=tdz0pXDxzRU

The AI architecture as of TODAY is:

code:
luaTableForBot.ai = function( bot )
initTheBot( bot )
instantiateAVisibleNpCForTheBot( bot )
while( botIsAlive ) do
updateSenses( bot )
pickGoals( bot )
pickTactics( bot )
sendActionsToNpc( bot )
end
end

WHere a GOAL is something like "Kill All Humans"

a STRATEGY is like "find human, approach human, shoot at human, repeat until all humans dead"

an ACTION is like "navigate close to XYZ" "turn to face target" "select best weapon for target" "fire weapon when it has a chance to hit target", "fire engines when they have a chance to move us towards destination"

You proabably have several actions going at the same fime. For example, it doesn't travel to they guy and only then think about shooting him. It is constantly aware of whether or not the gun is aimed at the target, and any time it thinks it has a shot, it will shoot. Same with the engines, it doesn't wait for the perfect heading before firing, it just takes care not to fire when the directino is horrible, and to fire particularly when the directino is great. Then no matter who is steering, these systems work to achieve their goals usine what's available.

In this way, I claim the actions are like the human 'hind brain' and in this case run at 30 fps inside of the java game engine. But the forebrain neocortex is up in lua, making the big decisions, but slowly (one decision per beat).

Once the lua brain has picked the prioritized actin list, it sends that by peer to peer packet to all the other copies of the starmap (the other human players in the Starmap Instance), and they pass it along to their own NPC associated with that bot. But the actual NPC engines, in java, are not otherwise syncronized. They are all trying to achiece the same action, but actual position might be quite different. I don't know if I will worry about that or not (by synthesizing ship packets for all the NPCs. That wouldn't scale, but probably I don't need all that manu moving objects...).. Anyway, it looks great in solo mode right now. Haven't tried it with real distribution of bot state yet.

[ 05-25-2016, 01:19 AM: Message edited by: samsyn ]

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
work work has been keeping me too busy to do much with SS lately, but here is something:

---

I improved my 'chord extraction' code and attach an example. This ia an Amy Lee cover of "Sally's Song" fro mthe Nightmare before xmas, which I love (that song in particular, and amy lee, in general)

Anyway you will hear the sound about four times in the video

* first is the playback of the 'spectral recording' (series of harmonic frames)
* next is the transciption, turning time space all the way to midi events and then playback with my synth
* next is the original song
* but I let the vocoder try to 'sing along in real time'

while this makes a father's heart proud, I know it won't win any Emmy awards :-) The sing along is sticky since it is hearing its own output. More fun with headphones

oh, and I intentionally left a large fan running in the background and used a 3 foot air gap from PC speakers to tablet microphone, since that's my ultimate user (live voice i nthe vicinity)

https://www.youtube.com/watch?v=Pke4F65iwBU&feature=youtu.be

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
samsyn
Administrator
Member # 162

Member Rated:
4
Icon 1 posted      Profile for samsyn   Author's Homepage   Email samsyn   Send New Private Message       Edit/Delete Post 
Sorry to hit you twice in a row, but I found a dramatic improvement to my algorithms, ao I have to make you listen to "sally 3"

And I was so excited, I uploaded the wrong video (Big Data 'dangerous' under the name sally3), so here is the 'real one'

https://www.youtube.com/watch?v=jwUnlovv-jo&feature=youtu.be


The basic algorithm is very simple. First I compute the full spectrum to find current energy in every possible note of the midi keyboard

Then I analyze the shape of the spectrum (normalized scale, rejected silence) to find peaks, (by finding points that have 'shoulders' on both sides and guessing the center of the peak)

then I analyse just those peaks, and smooth/debounce/hysteresis them to find the ones with enough sustained energy to be remembered as a MIDI note event (but even the non MIDI peaks are remembered for use in spectrum recreation, where I just play the weighted peaks)

In theory, I can get 'velocity' info as well. Though I also need to back-annotate the note start, since I lose a bit of the leading edge with my debouncing.

I could also use VQ here.... I love VQ so very much.

My current auto-tune (only works for C and A minor at the moment, for completely guessable reasons), needs to move.

Right now I do that AFTER finding 'the 'white peaks' and really, I need to do it in the pre-white peaks. So I plan to insert another stage just before the MIDI note detector.

This stage will

1.) work out the primary notes being played right now (the starting peaks)

2.) find the chord that is being played right now, if any

3.) average out to determine the recent keysignature (and track over song, if it changes)

4.) use the current keysignature guess to 'nudge' peaks towards more appropriate notes (another VQ opportunity!)

Then process the NUDGED peaks for midi events.

This way my horrible singing can be snapped-to-grid more effectively, and it is less difficult to figure out which note to turn off later :-)

I also added the ability to xoom in on a track in a playing groove

You can still see some errors (mainly a little freq wobble at start of notes), which I think my new layer will filter nicely. (might filter some legitimate sharps and flats, though, depending on how smart I make it about chord progressions.....

but for a raw sound to midi-like transcription device, able to make game-ready 'grooves' for starmap playback, I think it has just hit 'good enough,' though it still needs a minimal bit of editing support (mainly to delete/move bad notes)

Of course, this is to let you sing your own grooves, not steal other people's songs. But capturing the essence of something and then adding tracks of your playing along, and then removal of the automatic transcription, could be a successful strategy.

I haven't tried looking for any other midi transcribers, as I am sure they must exist and be ten times better than this, but I know in 1990, I could not find one :-)

And, of course, I am but 'midi-like' so don't expect actual MIDI output... though who knows. Also, I am more of a chord detector than a melody detector, at the moment. But that fits my desire for it to sing live accompaniment someday.

--------------------
He knows when you are sleeping.

Posts: 11014 | From: California | Registered: Dec 1998  |  IP: Logged
  This topic comprises 5 pages: 1  2  3  4  5   

Quick Reply
Message:

HTML is not enabled.
UBB Code™ is enabled.

Instant Graemlins
   


Post New Topic  Post A Reply Close Topic   Unfeature Topic   Move Topic   Delete Topic next oldest topic   next newest topic
 - Printer-friendly view of this topic
Hop To:


Contact Us | Synthetic Reality

Copyright 2003 (c) Synthetic Reality Co.

Powered by UBB.classic™ 6.7.3