或曰

-- 2004年3月中旬 --

Last-modified: Mon, 03 Jan 2005 00:15:01 JST
[dynamic,cache:on]
powered by tds-1.6.2

[著者管理] < = > [上旬] [中旬] [下旬] [一覧] [アクセス解析]
[最新版] [2003年12月以前] [2003年2月以前]


お名前 名前記録
一言
最近の一言
09/07 14:38読んだよ
09/07 14:38読んだよ
04/17 20:30ゆんGNU ld 遅い問題。うちの現在進行中のプロジェクトでも同じ問題に悩んでいたのですが、-Mapオプションを外したところ劇的に速度が改善されました。まさかこんな事だったとは。感謝。そして、ボトルネック調査の重要性を痛感した次第です。
03/01 22:40一生>はりあさん ありがとうございます。後でチェックしてみます。
02/28 13:10はりあ失礼します。BYACC / JAVA(http://troi.lincom-asg.com/~rjamison/byacc/) というのがあります。参考までに。

2004/3/10(Wed) [n]

%1

09:00 起床, 09:50 会社着。

%2[Work] お仕事

@ リプレイ

なかなか一筋縄ではいかないが、 それなりに見えるものを作ってみる。

この手の機能は、 設計段階から意識してシステムを作っておけば実現できる見込みがあるが、 後から追加するのは極めて難しい。 随時、メンテナンスしておくのが吉。

@ メモリリーク

該当箇所を絞り込んで、 その部分をメンテナンスしている人間に投げ。 後でコードレビューした方が良さそうだ。

この数日、メモリがらみの問題が立て続けに出たけど、 やっぱり手作業でメモリの確保・解放を行ったり、 グローバル変数使うのは良くないという結論に達しそう。 ハンドラやスマートポインタの類を使い、 デストラクタで勝手に後始末するよう徹底してる人のところでは、 リークが一度も発生していないし。

@ 帰宅

20:10 離脱。

%3[Web巡回] Web巡回

@ その場でコンストラクタから関数オブジェクト

あの後 boost::function と boost::lambda::new_ptr を使って書き直したのですが、 「boost::function 使うとヒープ使うしイマイチだよなぁ」と思ってました。

ありがたく利用させて頂きます。

%4 お買い物 キャンセル

amzaon で注文していた 21st Century Compilers。 いつになっても発送の連絡がこないと思ったら発売延期 (2004/08/31) なのね。 ひとまず注文キャンセル。

代わりに Knuth 御大の書籍でも買うかね。


2004/3/11(Thu) [n]

%1

09:00 起床, 10:00 会社着。

%2[Work] お仕事

@ 環境整備

新しくプロジェクトに来た人の環境整備。 前にドキュメントを書いておいたので、 それを読みつつサクサクと設定。

@ メモリ断片化

本来断片化しないはずなのに、微妙に断片化してるのが気になったので調査。 不要なアライメント指定してる場所を見つけて潰す。

あとはメモリアロケータで best fit 使ってる部分を first fit に書き直す準備。 テスト中に別の用事が入ったので、続きは明日。

@ メモリリーク

してるみたいなので調べておいてね、と担当者に連絡しておいた件。

std::vector は clear() を読んでもメモリを解放しない。

という罠にはまっていたので、 swap() trick を使って解決。

STL を使う人間には、 全員 Effective STL を読んでもらった方が良いのかな。 会社の私物本棚には英語版 Effective STL があるが、 これを読んでもらうのはキツすぎなので邦訳を用意する方向で。

@ hang up

企画の人の環境で、特定のタイミングでプログラムが停止するという報告。 適当に当たりをつけて、とりあえず機能を落として止まらない環境を作る。 企画側は、これでしばらく作業継続してもらうことに。

その間に本格的な原因究明。 再現条件を詰めた感じ、 どうもうちのプロジェクトの問題ではなさそうな気がしてきた。 さて、どうしたものかね。

@ hang up

私の作業用 Windows PC が……。 最近、一日一回ぐらい落ちてる気がするな。 暖かくなってきたから?

機材関係の人に投げる方向で。

@ ミーティング

進捗報告。 微妙な感じだ。

@ 演出

私の関わる部分、プログラミングに関わる必要項目洗い出し。 これ以上は具体的な方向性が見えないとシステムの作りようがないため、 とりあえずコンテ切ってもらって、それを元に話を詰める方向で。

そろそろライトの使い方もまじめに考える時期だ。 見直しかけよう。

@ 帰宅

21:00.

%3[Web巡回] Web巡回

@ Re: 続・その場でコンストラクタから関数オブジェクト

こんな感じです。

#include <boost/function.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/construct.hpp>

struct IFoo { virtual ~IFoo() {} };
class Foo1 : public IFoo { public: Foo1(int) {} };
class Foo2 : public IFoo { public: Foo2(int) {} };

enum PRIO_TYPE { PRIO_LOW, PRIO_NORMAL, PRIO_HIGH };
enum FOO_TYPE { FOO1, FOO2, FOO3 };
void addQueue(IFoo* foo, PRIO_TYPE prio);

void Create(int id)
{
    struct create_tbl
    {
        FOO_TYPE foo_type;
        boost::function<IFoo* (int)> creator;
        int param;
        PRIO_TYPE prio;
    };

    using boost::lambda::new_ptr;
    static create_tbl const db[] = {
        { FOO1, new_ptr<Foo1>(), 0, PRIO_LOW    },
        { FOO2, new_ptr<Foo2>(), 0, PRIO_NORMAL },
        { FOO3, new_ptr<Foo2>(), 1, PRIO_LOW    },
    };

    for (size_t i = 0; i < sizeof(db) / sizeof(db[0]); ++i) {
        create_tbl const* p = &db[i];
        if (p->foo_type == id) {
            IFoo* foo = (p->creator)(p->param);
            addQueue(foo, p->prio);
            return;
        }
    }
}

2004/3/12(Fri) [n]

%1

09:15 起床, 10:00 会社着。

%2[Work] お仕事

@ 作業優先順位の見直し

メインプログラマを捕まえて、 年単位の作業優先順位決め。 ま、だいたい見えた。

一つ近い内に手をつけようかと思っていたことは、 しばらく先送りで良いや。 ただ実装は後の時期にならなと手をつけられないが、 そのための下準備は今からしておかないと困るという扱いが微妙な代物で、 どうスケジュールに織り込んでいくかは未だ考慮中。

@ フェード

エフェクトをきれいに見せるためには、 画面を暗くすると良い。 というわけで、そのへんのシステム作り。

フェードアウト要求などはスクリプトから指示させる形にするが、 問題は競合する要求をどう捌くか。 これはシーンの全体設計がもう少し見えてこないと、 何とも言えないな。

@ サポート

デザイナさんの作業環境関係で何件か。 サクッと済ませる。

@ 作業用 PC

ハードウェア一部交換。

@ 動作不良

特定の条件でプログラムが止まる件。 これは IOP 側のメモリが断片化してる気がする。 調査しようにも、 プログラムが死んでしまうのでどうにもならんが。

@ 帰宅

20:40 離脱。

%3[Book] 読書記録

反戦小説と言われているけど、そうなの?  ヘルシングとかベルセルクを読んで面白いと言えるなら、 これも文句なしに楽しめると思うけど。


2004/3/13(Sat) [n]

%1

12:00 起床。

%2 マジスパ

ビーフ, 虚空100, ライス大盛り, スープ大盛り。 食後にココナッツプリン。 新作デザートらしい。


2004/3/14(Sun) [n]

%1

10:50 起床。

%2[Work] お仕事

別に出勤してるワケじゃないけど、思いつきメモ。

@ スクリプト システム関数登録 (1) 現状

現在のスクリプトシステムは、 スクリプト中から C++ 側の関数を呼び出せるようになっている。 そのための枠組みは次の通り。

スクリプト側

  1. システム関数番号と、システム関数のプロトタイプをスクリプトシステム関数定義ファイルファイルに記述しておく。
  2. スクリプトコンパイラはスクリプトシステム関数定義ファイルを読み、システム関数を覚えておく。
  3. スクリプトコードのコンパイル時にシステム関数呼び出しを見つけたら、
    1. 引数を処理
    2. 「システム関数 n 番呼び出し」という意味のスクリプトバイトコードを出力。
    とする。
// #system の直後にシステム関数番号を書く
// システム関数番号を省略すると、直前のシステム関数の次の番号が割り当てられる

// #usertype は型チェックの厳しい typedef みたいなもの

#define SYSFUNC_ISSEI_START 512

/*
 * デバッグメッセージ出力
 */
#system SYSFUNC_ISSEI_START void dbPrint(char);

/*
 * プレイヤーを透明状態に移行
 * 引数
 *   pl    透明状態に移行するプレイヤーオブジェクト
 *   time  透明状態継続時間
 */
#usertype handle player_t
#system void plSetInvisible(player_t pl, float time);

int
main(player_t pl)
{
	plSetInvisible(pl, 1.0F);
}

C++ 側

  1. フリー関数*1としてシステム関数を作成。
  2. 初期化時に、フリー関数のポインタとインデクスの対をスクリプト仮想マシンに登録。
  3. スクリプト仮想マシンはスクリプトバイトコードを読み出し、逐次実行。
  4. 「システム関数 n 番呼び出し」というバイトコードを見つけたら、スクリプト仮想マシンを引数として、事前に登録されたフリー関数を呼び出す。
  5. フリー関数では、引数として渡ってきたスクリプト仮想マシンから引数を取り出し、それを元に処理。
static int
plSetInvisible(Script* scr)
{
    // scr->getSystemArgument(n) で n 番目の引数取得
    // union なので、適当な型のフィールドを持ってきて使う
    Player* pl = reinterpret_cast<Script*>(scr->getSystemArgument(0).h);
    pl->scr_SetInvisible(scr->getSystemArgument(1).f);

    return 0;
}

int
script_init()
{
    Script::SetSystemFunction(513, &plSetInvisible);
}

@ スクリプト システム関数登録 (2) 問題点と解決策

問題点

  1. システム関数のインデクス管理を手作業で行っているが、これが非常に面倒。
  2. システム関数として登録する C++ フリー関数は、たいてい
    1. 第一引数をオブジェクトのポインタにキャスト。
    2. 第二引数以下を実引数として、メンバ関数を呼び出す。
    3. (必要なら) メンバ関数の戻り値をスクリプト仮想マシンに渡す。
    という決まり切った処理だが、これを手で書く必要がある。
  3. システム関数を登録し忘れても、実行時までそのエラーを検出できない。

いろいろ考えていたのだけど、 スクリプトシステム関数定義ファイルから

を自動生成すれば良いんじゃないかという結論に。 さらにスクリプトから操作するオブジェクト側が実装すべきメンバ関数一覧も生成できるから、

とすると、労せずしてインターフェースと実装を分離できる。

@ スクリプト システム関数登録 (3) 実装

考えがまとまったところで、 ちゃちゃっと Perl でスクリプト書き。 本物のスクリプトコンパイラは lex + yacc で書いてあるけど、 システム関数定義の解析程度なら perl の方が良いだろう。

微妙に面倒なのはシステム関数番号の解析ぐらい。 ここは単なる整数値とは限らず四則演算が出てくる可能性があるので、 自前で数式を解析・計算する必要がある。

ファイル

だいたい動いたかな。 実際のスクリプト処理系のコードなどは会社に行かないとアクセスできないので、 明日組み込もう。

入力

scrsysfunc.h (スクリプトシステム関数定義)

/**
 * スクリプト共通定義
 * $Issei: scrsysfunc.h,v 1.1 2004/03/14 05:43:29 issei Exp $
 */

#ifndef __SCRSYSFUNC_H
#define __SCRSYSFUNC_H

#define SYSFUNC_ISSEI_BEGIN             1024
#define SYSFUNC_ISSEI_DB_MAX            64
#define SYSFUNC_ISSEI_BTPLACT_MAX     128
#define SYSFUNC_ISSEI_BTPL_MAX        128

#define SYSFUNC_ISSEI_DB_BEGIN          SYSFUNC_ISSEI_BEGIN
#define SYSFUNC_ISSEI_BTPLACT_BEGIN   (SYSFUNC_ISSEI_DB_BEGIN + SYSFUNC_ISSEI_BTPLACT_MAX)
#define SYSFUNC_ISSEI_BTPL_BEGIN      (SYSFUNC_ISSEI_BTPLACT_BEGIN + SYSFUNC_ISSEI_BTPL_MAX)

#endif // !__SCRSYSFUNC_H

bt_pl_act.h (スクリプトシステム関数定義)

/**
 * プレイヤー制御関連スクリプト
 * $Issei: bt_pl_act.h,v 1.4 2004/03/14 05:39:01 issei Exp $
 */

#ifndef __BT_PL_ACT_H
#define __BT_PL_ACT_H

#include "scrsysfunc.h"

/*
 * デバッグ用
 */
#system SYSFUNC_ISSEI_DB_BEGIN void dbPrintf(int);

/*
 * プレイヤーアクションスクリプト
 */
#usertype handle bt_pl_act_t [isBattle::Player::ICtxScriptAction, isbt_pl_ctx_scr_action.h]
#usertype uint hittype_t

#system SYSFUNC_ISSEI_BTPLACT_BEGIN void btPlAct_createFrontCollision(bt_pl_act_t acthdl, hittype_t hit_type)
#system int btPlAct_createFrontCollision2(bt_pl_act_t acthdl, handle foo, hittype_t hit_type)
#system void btPlAct_requireCamera(bt_pl_act_t acthdl)
#system void btPlAct_releaseCamera(bt_pl_act_t acthdl)
#system void btPlAI_setActionString(bt_pl_act_t acthdl, char name)

/*
 * プレイヤー基本制御スクリプト
 */
#usertype handle bt_pl_ai_t [isBattle::IPlayer]
#usertype uint hp_t

#system SYSFUNC_ISSEI_BTPL_BEGIN hp_t btPlAI_getHP(bt_pl_ai_t aihdl)
#system hp_t btPlAI_getMaxHP(bt_pl_ai_t aihdl)

#endif // !__BT_PL_ACT_H

出力

script_bt_pl_act.cc (フリー関数とシステム関数登録処理)

// DO NOT EDIT
// THIS FILE IS GENERATED AUTOMATICALLY BY `aksc_cpp.pl 1.5'

#include "script.h"
#include "isbt_pl_ctx_scr_action.h"

static int
btPlAct_createFrontCollision(SCRIPT* scr)
{
    isBattle::Player::ICtxScriptAction* p =
        reinterpret_cast<isBattle::Player::ICtxScriptAction*>(scr->getSystemArgument(0).h);

    p->scr_btPlAct_createFrontCollision(
        scr->getSystemArgument(1).u
    );
    return 0;
}

static int
btPlAct_createFrontCollision2(SCRIPT* scr)
{
    isBattle::Player::ICtxScriptAction* p =
        reinterpret_cast<isBattle::Player::ICtxScriptAction*>(scr->getSystemArgument(0).h);
    s32 ret = p->scr_btPlAct_createFrontCollision2(
        scr->getSystemArgument(1).h,
        scr->getSystemArgument(2).u
    );
    scr->setReturnValue(*reinterpret_cast<SCRIPT_REG*>(&ret));
    return 0;
}

static int
btPlAct_requireCamera(SCRIPT* scr)
{
    isBattle::Player::ICtxScriptAction* p =
        reinterpret_cast<isBattle::Player::ICtxScriptAction*>(scr->getSystemArgument(0).h);

    p->scr_btPlAct_requireCamera(

    );
    return 0;
}

static int
btPlAct_releaseCamera(SCRIPT* scr)
{
    isBattle::Player::ICtxScriptAction* p =
        reinterpret_cast<isBattle::Player::ICtxScriptAction*>(scr->getSystemArgument(0).h);

    p->scr_btPlAct_releaseCamera(

    );
    return 0;
}

static int
btPlAI_setActionString(SCRIPT* scr)
{
    isBattle::Player::ICtxScriptAction* p =
        reinterpret_cast<isBattle::Player::ICtxScriptAction*>(scr->getSystemArgument(0).h);

    p->scr_btPlAI_setActionString(
        scr->getSystemArgument(1).c
    );
    return 0;
}

static int
btPlAI_getHP(SCRIPT* scr)
{
    isBattle::IPlayer* p =
        reinterpret_cast<isBattle::IPlayer*>(scr->getSystemArgument(0).h);
    u32 ret = p->scr_btPlAI_getHP(

    );
    scr->setReturnValue(*reinterpret_cast<SCRIPT_REG*>(&ret));
    return 0;
}

static int
btPlAI_getMaxHP(SCRIPT* scr)
{
    isBattle::IPlayer* p =
        reinterpret_cast<isBattle::IPlayer*>(scr->getSystemArgument(0).h);
    u32 ret = p->scr_btPlAI_getMaxHP(

    );
    scr->setReturnValue(*reinterpret_cast<SCRIPT_REG*>(&ret));
    return 0;
}

void
SCRIPT_bt_pl_act()
{
    SCRIPT::setSystemFunction(1152, &btPlAct_createFrontCollision);
    SCRIPT::setSystemFunction(1153, &btPlAct_createFrontCollision2);
    SCRIPT::setSystemFunction(1154, &btPlAct_requireCamera);
    SCRIPT::setSystemFunction(1155, &btPlAct_releaseCamera);
    SCRIPT::setSystemFunction(1156, &btPlAI_setActionString);
    SCRIPT::setSystemFunction(1280, &btPlAI_getHP);
    SCRIPT::setSystemFunction(1281, &btPlAI_getMaxHP);
}

isbt_pl_ctx_scr_action.h (スクリプトから呼び出すメンバ関数一覧)

// DO NOT EDIT
// THIS FILE IS GENERATED AUTOMATICALLY BY `aksc_cpp.pl 1.5'

#ifndef __ISBT_PL_CTX_SCR_ACTION_H
#define __ISBT_PL_CTX_SCR_ACTION_H

namespace isBattle { namespace Player {

struct ICtxScriptAction
{
    virtual ~ICtxScriptAction() {}
    virtual void btPlAct_createFrontCollision(u32 hit_type) = 0;
    virtual s32 btPlAct_createFrontCollision2(void* foo, u32 hit_type) = 0;
    virtual void btPlAct_requireCamera() = 0;
    virtual void btPlAct_releaseCamera() = 0;
    virtual void btPlAI_setActionString(char const* name) = 0;
};

}}

#endif // !__ISBT_PL_CTX_SCR_ACTION_H

@ このへん

Windows なら IDL でインターフェース定義を書いておけば、 言語に依らず宜しくできるんだけどね。 本格的な IDL のパーサや COM 実行環境を用意するのはさすがにオーバースペックなので、 この辺で適当にお茶を濁しておく。

あ……、isbt_pl_ctx_scr_action.h の純粋仮想関数、 名前に scr_ つけ忘れてる。 面倒なので、全部明日送り。


*1: this ポインタなしで呼び出せる一般の関数、あるいは static メンバ関数。

%3 部活動

行ってきます。

1km 泳いで帰宅。人が多すぎ。

%4[Book] お買い物

@[Book] 書籍

%5[Web巡回] Web巡回

@ Re: さっき

私が書くとしたら、こうかな。

#include <algorithm>
#include <iostream>
#include <vector>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>

class hoge
{
public:
    virtual ~hoge() {}
    virtual void show() = 0;
};

class uni : public hoge
{
public:
    void show(){ std::cout << "uni" << std::endl;}
};

class unya : public hoge
{
public:
    void show(){ std::cout << "unya" << std::endl;}
};

int main()
{
    typedef boost::shared_ptr<hoge> THogePtr;
    std::vector<THogePtr> v;
    v.push_back(THogePtr(new uni));
    v.push_back(THogePtr(new unya));

    std::for_each(v.begin(), v.end(), boost::bind(&hoge::show, _1));
    return 0;
}

boost::shared_ptr だと問題ないのですが、 一般には多態を使う場合、 基底クラスで仮想デストラクタを定義しておかないと極めて不幸なことになるので注意して下さい。 あと <, > あたりが正しく &lt;, &gt; になってないようで、 ブラウザで見ると vector の後が未知のタグ <hoge> と見なされて欠落してます。


2004/3/15(Mon) [n]

%1

09:00 起床, 10:00 会社着。

%2[Work] お仕事

@ スクリプトシステム関数登録

昨日 書いてたヤツ。 スクリプト担当してる人間に概要を説明して、 組み込み。 よしよし、うまく動いてるな。

@ モノ探し

「どこにあるか知りませんか?」と聞かれて、思い当たる節があったので一緒に探す。 灯台下暗し。

@ 非公式ミーティング (1)

デザイナの作業の進め方について確認。 とりあえず、それで。

@ 非公式ミーティング (2)

ディレクションする予定の人とプログラマで、 立ち話しつつ意識のすりあわせ。

どうも認識にズレがあるのではないかと危惧していた事があったのだけど、 やっぱりズレていた模様。 修正を図る。

どうしてもプロジェクトに最初から居て、 プロジェクトの紆余曲折・中核メンバーの為人を知っている人間と、 途中から参加した人間では、 持っている情報の量も違うし、 新規に同じ情報を入手しても解釈の精度に差が出てきてしまう。 それを見つけて埋めていくのも、まぁ仕事だ。

@ エフェクト

サブプログラマの人がスクリプトを使って作り込んでいるのだけど、 かなり良い感じになってきてる。 やるじゃん。

しかし、そろそろ C++ のコードを書きたい様子がチラチラと……。 ごめん。

@ 帰宅

21:50 離脱。 遅すぎ。


2004/3/16(Tue) [n]

%1

08:50 起床, 10:00 会社着。

%2[Work] お仕事

常に増して断片化された時間を過ごす。 絶え間なく到来する要件を捌いていたら、 一日終わりという感じ。

@ 帰宅

20:30 離脱。


2004/3/17(Wed) [n]

%1

09:00 起床, 10:00 会社着。

%2[Work] お仕事

@ スクリプト

例の C++ 側の関数自動生成スクリプトの都合に合わせて、 スクリプトコンパイラ自体に少し手を入れる。

@ Makefile

ビルド時のログをファイルに残すように細工。 コマンド実行部分を $(SHELL) -c "..." | tee log と書き直したのだけど、 うっかり exit ${PIPESTATUS[0]} をつけ忘れて、 tee の終了ステータスを拾うミス発生。

気づいたところでさっさと修正。

@ デザイナさんの環境作り

さらに二人。 一件はメインプログラマに任せて、もう一件は私が対処。

「パスフレーズなしの ssh 秘密鍵を作ったのに、ログイン時にパスワードを聞かれます」 「~/.ssh と ~/.ssh/authorized_keys のグループ書き込み権限を確認せよ」

@ 引っ越し

日程確定。

@ コリジョン

長らく TODO リストに載っていた複合型コリジョンを実装。 球・円柱といった基本的な形状のコリジョンをまとめて、 1 つのコリジョンとして扱うための仕組み。

@ ヒット設計

サブプログラマに任せてあるヒットオブジェクト関連で、 いくつか設計上の相談。

@ 帰宅

20:30 離脱。


2004/3/18(Thu) [n]

%1

09:00 起床, 10:00 会社着。

%2[Work] お仕事

@ 掃除

もう使ってないが、 コンパイルを通すためだけに残っていたコードをざっくり切り捨て。

@ ミーティング

プログラマの進捗確認と、 その場でスケジュールの調整。

私は作業が先行してるので、 月末から来月頭あたりは微妙な感じだ。 私の手伝いをお願いしていたサブプログラマの人には、 先行して作業出来る部分に回ってもらおう。

@ human affairs

動きアリ。よしよし。

@ エフェクト

単に絵素材を動かすだけのビューアなら描画部分を担当している人にお願いできるが、 ゲーム中のルールに従って動くエフェクトを動かすとなると、 ゲーム部分を書いている人間が書くしかない。

私のコードはインターフェースを細かく分けてあるので、 エフェクトを動かすだけなら純粋仮想関数 5 個だけ定義したクラスを継承し、 それに対して適切な挙動をすれば OK。 「適切な挙動」を実装するにも既存のパーツを使い回せるから、 とりあえず動かすだけなら今日明日で終わるだろう。

その先は、 ゲームシステムに関する理解を深めてもらう意味も兼ねて、 サブプログラマに任せる方向で。 いきなり現状のシステム全部見ようとすると疲れるから、 まずはサブセットのエフェクトビューアぐらいで遊んでもらう。

@ 企画ブレスト

お手伝い。

しょせんゲームだから、 論文を書けそうな意欲的な技術テーマに対して正面から挑む必要はない。 むしろアイデアの本質的な面白さだけ抽出して、 技術的には大したことがない手法で実現できるように作り替えてしまった方が望ましい。 根本的なアイデアを出したり企画書を書くのは手伝えないけど、 思いつき程度のアイデア出し・技術的な可否の問い合わせ・代替策作りに関しては助言します。

とまぁ、そんなスタンスで仕事してる今日この頃。 アイデア出しを手伝う以外に、 どんなに素晴らしいアイデアであっても結局はプログラマが実装できるものしか実現できないので、 無理なものは早めにその旨を伝えておく意味もある。

しかし企画陣の方でも人によって重視する部分が微妙に違うようで、 マネージメントする人はお疲れ様という感じ。 技術的な話なら技術的にケリがつくけど、 企画案やマーケティングのデータ解釈といった本質的に不確実性を含むものに対して判断を下すのは難しい。 また競合する案が二つある場合、「明確にこちらの方が良い」と示せない状況で一方の案を却下することになるから、 やり方によっては痼りを残す。

私が思いつき程度のネタしか出さないのは、 単にアイデア不足・本業はプログラミングという理由もあるが、 このあたりにも理由がある。 私が真剣に自分のアイデアを暖めていると、 相手も「ちょっと相談なんだけど」と気軽に話を持ってこられなくなるし。

@ 帰宅

20:40 離脱。

%3 グラン・デル・バル

ドトールで買ってきたコーヒー豆を開封。 それなり。

%4 読書記録

ようやく読了。 この手の本は読み終わったところが「終わり」ではなく「出発点」だから、 読了したからどうということはなく。


2004/3/19(Fri) [n]

%1

09:00 起床, 10:00 出社。

%2 お仕事

後で補完予定。

@ 帰宅

21:00 離脱。

%3 MagicDraw

7.5 release. これまでは Pure Java アプリケーションとして提供されてきたが、 今回は Windows 版限定で native バイナリもあるみたい。 native バイナリを試してみたけど、 起動が遅いが起動してしまえば快適。

%4 読書記録


以上、10日分です。 (直前の日記

このページはTomsoft Diary System 1.6.2を用いて生成されています。
Copyright (C) 2004
Issei Suzuki <issei@issei.org>